summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2012-08-02 11:09:40 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2012-08-02 11:09:40 +0000
commit6dfd5d507d9863f987b30b0a5ab4268aea2ed875 (patch)
tree9c3de66b4aaa1e6bfa3c6442d807ec70bc479d11
parentf4792ba1a7785220fef5adb1cb3e7ce8ac40152f (diff)
download2012-php-weave-6dfd5d507d9863f987b30b0a5ab4268aea2ed875.tar.gz
2012-php-weave-6dfd5d507d9863f987b30b0a5ab4268aea2ed875.tar.bz2
2012-php-weave-6dfd5d507d9863f987b30b0a5ab4268aea2ed875.zip
J'étais parti sur un download pourri de Cake. Les gars on abusé sur GitHub.
git-svn-id: file:///var/svn/2012-php-weave/trunk@7 d972a294-176a-4cf9-8ea1-fcd5b0c30f5c
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/bootstrap.php46
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/core.php146
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/database.php.default74
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/inflections.php72
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/routes.php46
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/sql/db_acl.sql38
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/index.php26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css.php102
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css/cake.generic.css250
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/cake.power.pngbin3053 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_css.pngbin299 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_xhtml10.pngbin321 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/index.php87
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/js/vendors.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/VERSION.txt9
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_controller.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_model.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/basics.php1156
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/bootstrap.php104
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/config.php28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/paths.php175
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/dispatcher.php429
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cache.php137
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cake_log.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/class_registry.php117
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/configure.php354
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/component.php139
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl.php196
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl_base.php63
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/db_acl.php310
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aclnode.php309
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aco.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/acoaction.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aro.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aros_aco.php63
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/iniacl/ini_acl.php180
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/request_handler.php412
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/security.php202
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/session.php306
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/controller.php998
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/pages_controller.php105
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/scaffold.php432
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/error.php347
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/file.php293
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/flay.php278
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/folder.php328
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/inflector.php437
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/legacy.php70
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/connection_manager.php243
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/datasource.php519
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/dbo_source.php1967
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_adodb.php437
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mssql.php604
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysql.php681
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysqli.php441
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_odbc.php437
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_pear.php241
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_postgres.php595
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_sqlite.php409
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php4.php1719
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php5.php1716
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_array.php318
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_string.php88
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/object.php259
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/router.php230
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/sanitize.php245
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/security.php151
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/session.php757
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/set.php805
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/validators.php45
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helper.php167
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/ajax.php853
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/cache.php272
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/form.php491
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/html.php1257
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/javascript.php317
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/number.php88
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/session.php198
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/text.php238
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/time.php397
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/elements/dump.thtml32
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/error404.thtml28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_action.thtml37
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_class.thtml36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_file.thtml35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_connection.thtml30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_controller.thtml36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_class.thtml35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_file.thtml35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_layout.thtml30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_model.thtml36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_scaffolddb.thtml30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_table.thtml29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_view.thtml30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/private_action.thtml29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/scaffold_error.thtml33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/ajax.thtml27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/default.thtml58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/flash.thtml45
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/pages/home.thtml75
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/add.thtml40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/edit.thtml56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/index.thtml95
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/view.thtml166
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/view.php765
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/acl.php853
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/bake.php2635
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/.htaccess5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_controller.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_model.php43
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/bootstrap.php46
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/core.php146
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/database.php.default74
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/inflections.php72
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/routes.php46
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/db_acl.sql30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/sessions.sql11
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/controllers/pages_controller.php105
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/index.php26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/ajax.thtml30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/default.thtml30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/flash.thtml50
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/.htaccess6
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css.php100
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css/cake.generic.css251
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/favicon.icobin4973 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/img/cake.power.pngbin3053 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/index.php87
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/js/vendors.php43
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/views/home.thtml16
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/CHANGELOG.txt13
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/COPYING.txt24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/INSTALL.txt40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/README.txt19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/index.php77
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.gitignore9
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.htaccess (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/.htaccess)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.travis.yml111
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/README28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/.htaccess (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/.htaccess)2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.php72
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.sql40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.php49
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.sql26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/sessions.php46
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/sessions.sql (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/sql/sessions.sql)6
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/acl.ini.php (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/acl.ini.php)30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/acl.php134
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/bootstrap.php181
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/core.php278
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/database.php.default83
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/email.php.default97
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/routes.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Command/AppShell.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Command/Task/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/controllers/components/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Templates/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/models/empty)0
-rwxr-xr-xpoc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.bat32
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.php33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/AppController.php35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/Component/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/plugins/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/PagesController.php75
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Lib/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Locale/eng/LC_MESSAGES/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/models/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/AppModel.php34
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/Behavior/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/persistent/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/Datasource/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/views/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Plugin/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/Controller/Component/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/logs/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/Model/Behavior/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/sessions/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/View/Helper/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/tests/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Fixture/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/vendors/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Vendor/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/elements/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Elements/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/errors/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/html/default.ctp25
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/text/default.ctp19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error400.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error500.ctp28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Helper/AppHelper.php34
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/html/default.ctp29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/text/default.ctp21
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/ajax.ctp19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/default.ctp61
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/error.ctp61
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/flash.ctp37
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/js/default.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/rss/default.ctp14
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/xml/default.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Pages/home.ctp188
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Scaffolds/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/helpers/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/index.php17
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/models/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/layouts/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/persistent/empty (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/pages/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/views/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/controllers/components/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/logs/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/models/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/sessions/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/plugins/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/tests/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/.htaccess (renamed from poc/poc02-compiling-cake/src/workdir/in/app/webroot/.htaccess)4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/css/cake.generic.css739
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/favicon.icobin0 -> 372 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/files/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/models/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.icon.pngbin0 -> 943 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.power.gifbin0 -> 201 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-error-icon.png (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/favicon.ico)bin4973 -> 3358 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-fail-icon.pngbin0 -> 496 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-pass-icon.pngbin0 -> 783 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-skip-icon.pngbin0 -> 1207 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/index.php92
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/js/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/persistent/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/test.php92
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.properties12
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.xml214
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/index.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Cache.php501
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/CacheEngine.php179
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/ApcEngine.php186
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/FileEngine.php373
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/MemcacheEngine.php291
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/RedisEngine.php219
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/WincacheEngine.php190
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/XcacheEngine.php209
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/config.php21
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/routes.php86
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0080_00ff.php73
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0100_017f.php106
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0180_024F.php148
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0250_02af.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0370_03ff.php102
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0400_04ff.php164
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0500_052f.php50
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0530_058f.php78
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1e00_1eff.php168
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1f00_1fff.php216
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2100_214f.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2150_218f.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2460_24ff.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php87
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php48
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c80_2cff.php90
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/ff00_ffef.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/ConfigReaderInterface.php33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/IniReader.php184
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/PhpReader.php103
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AclShell.php610
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ApiShell.php238
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AppShell.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/BakeShell.php248
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/CommandListShell.php174
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ConsoleShell.php359
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/I18nShell.php121
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/SchemaShell.php533
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/BakeTask.php93
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ControllerTask.php471
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/DbConfigTask.php384
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ExtractTask.php754
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/FixtureTask.php421
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ModelTask.php996
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/PluginTask.php225
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ProjectTask.php421
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TemplateTask.php219
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TestTask.php537
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ViewTask.php468
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestShell.php434
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestsuiteShell.php101
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/UpgradeShell.php861
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleErrorHandler.php98
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInput.php51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputArgument.php170
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputOption.php221
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputSubcommand.php121
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOptionParser.php651
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOutput.php292
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/HelpFormatter.php201
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Shell.php847
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ShellDispatcher.php356
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/TaskCollection.php82
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/actions/controller_actions.ctp161
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/controller.ctp81
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/fixture.ctp65
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/model.ctp182
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/test.ctp82
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/form.ctp65
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/index.ctp93
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/view.ctp139
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/.htaccess (renamed from poc/poc02-compiling-cake/src/workdir/in/app/.htaccess)2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php74
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php48
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/sessions.sql (renamed from poc/poc02-compiling-cake/src/workdir/in/app/config/sql/sessions.sql)6
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/acl.ini.php (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/acl.ini.php)30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/bootstrap.php108
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/core.php336
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/database.php.default84
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/email.php.default97
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/routes.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Command/Task/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/views/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Templates/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.bat32
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.php33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/AppController.php35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/Component/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/logs/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/PagesController.php67
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Lib/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/sessions/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Locale/eng/LC_MESSAGES/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/tmp/tests/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/AppModel.php34
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/Behavior/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/vendors/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/Datasource/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/views/elements/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Plugin/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/views/errors/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/Controller/Component/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/views/helpers/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/Model/Behavior/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/views/layouts/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/View/Helper/empty (renamed from poc/poc02-compiling-cake/src/workdir/in/app/views/pages/empty)0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Fixture/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Vendor/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Elements/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp25
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/error.ctp59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/flash.ctp37
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/js/default.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/rss/default.ctp14
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/xml/default.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Pages/home.ctp188
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Scaffolds/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/index.php17
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/models/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/persistent/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/views/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/logs/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/sessions/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/tests/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/.htaccess (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/.htaccess)4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/css/cake.generic.css739
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/favicon.icobin0 -> 372 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/files/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.icon.pngbin0 -> 943 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gifbin0 -> 201 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-error-icon.png (renamed from poc/poc02-compiling-cake/src/workdir/in/app/webroot/favicon.ico)bin4973 -> 3358 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-fail-icon.pngbin0 -> 496 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-pass-icon.pngbin0 -> 783 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-skip-icon.pngbin0 -> 1207 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/index.php97
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/js/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/test.php94
-rwxr-xr-xpoc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.bat32
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php82
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php165
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php70
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php160
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php172
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php539
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php178
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php143
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php162
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php128
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php67
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php102
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php271
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php68
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php722
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php523
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php464
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php383
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php730
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php598
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php190
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php129
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php1228
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php447
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/App.php929
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/CakePlugin.php228
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Configure.php402
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Object.php205
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ErrorHandler.php261
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ExceptionRenderer.php301
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/exceptions.php579
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEvent.php132
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventListener.php48
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventManager.php276
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/I18n.php631
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/L10n.php480
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/Multibyte.php1134
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/LICENSE.txt (renamed from poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/LICENSE.txt)6
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLog.php550
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLogInterface.php37
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/BaseLog.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/ConsoleLog.php86
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/FileLog.php90
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/LogEngineCollection.php73
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AclNode.php182
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aco.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AcoAction.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aro.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/AclBehavior.php142
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/ContainableBehavior.php428
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TranslateBehavior.php627
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TreeBehavior.php1007
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/BehaviorCollection.php296
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/CakeSchema.php710
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ConnectionManager.php266
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/CakeSession.php688
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DataSource.php442
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Mysql.php688
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Postgres.php907
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlite.php571
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlserver.php783
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DboSource.php3268
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CacheSession.php90
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CakeSessionHandlerInterface.php72
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/DatabaseSession.php144
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/I18nModel.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Model.php3402
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelBehavior.php236
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelValidator.php599
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Permission.php257
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationRule.php333
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationSet.php350
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeRequest.php871
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeResponse.php1154
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeSocket.php280
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/AbstractTransport.php76
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/CakeEmail.php1588
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/DebugTransport.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/MailTransport.php54
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/SmtpTransport.php240
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/BasicAuthentication.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/DigestAuthentication.php105
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpResponse.php448
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpSocket.php977
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Dispatcher.php281
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/DispatcherFilter.php86
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/AssetDispatcher.php159
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/CacheDispatcher.php67
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/CakeRoute.php532
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/PluginShortRoute.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/RedirectRoute.php117
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Router.php1141
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllBehaviorsTest.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCacheTest.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllComponentsTest.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConfigureTest.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConsoleTest.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllControllerTest.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCoreTest.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllDatabaseTest.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllErrorTest.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllEventTest.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllHelpersTest.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllI18nTest.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllLogTest.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllNetworkTest.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllRoutingTest.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestSuiteTest.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestsTest.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllUtilityTest.php39
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllViewTest.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/BasicsTest.php942
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/CacheTest.php412
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php273
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php455
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php479
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php335
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php263
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php272
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/IniReaderTest.php188
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/PhpReaderTest.php170
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleLibsTest.php48
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleTest.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllShellsTest.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllTasksTest.php42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/AclShellTest.php311
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/ApiShellTest.php96
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/BakeShellTest.php124
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php118
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php492
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php652
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php133
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php462
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php388
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php1189
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php207
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php369
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php165
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php783
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php731
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/TestShellTest.php335
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php134
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOptionParserTest.php594
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOutputTest.php242
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/HelpFormatterTest.php505
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellDispatcherTest.php576
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellTest.php875
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/TaskCollectionTest.php124
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php543
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/IniAclTest.php69
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php337
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php91
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php192
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php206
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php84
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php185
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php306
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php193
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php1290
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php602
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/EmailComponentTest.php889
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php1194
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php879
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php1375
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php294
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php178
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentTest.php305
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerMergeVarsTest.php252
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerTest.php1441
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/PagesControllerTest.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ScaffoldTest.php350
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/AppTest.php851
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/CakePluginTest.php268
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ConfigureTest.php408
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ObjectTest.php673
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ErrorHandlerTest.php296
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ExceptionRendererTest.php776
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventManagerTest.php406
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventTest.php85
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/I18nTest.php1952
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/L10nTest.php955
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/MultibyteTest.php9228
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/CakeLogTest.php676
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php136
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/FileLogTest.php83
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/AclNodeTest.php385
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/AclBehaviorTest.php491
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php3660
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php1061
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php77
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php1379
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php316
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorTest.php43
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php255
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php1185
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/CakeSchemaTest.php1091
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ConnectionManagerTest.php346
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php754
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php250
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php3623
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php945
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php419
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php679
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php1102
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php117
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php188
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelCrossSchemaHabtmTest.php232
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelDeleteTest.php865
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelIntegrationTest.php2426
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelReadTest.php7881
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTest.php47
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTestBase.php96
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelValidationTest.php2201
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelWriteTest.php6877
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php155
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php321
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/models.php4989
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeRequestTest.php1890
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeResponseTest.php1009
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeSocketTest.php217
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php1793
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php77
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php265
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/BasicAuthenticationTest.php64
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/DigestAuthenticationTest.php195
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php558
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php1629
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/DispatcherTest.php1746
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php124
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php883
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/PluginShortRouteTest.php72
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/RedirectRouteTest.php107
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/RouterTest.php2669
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php342
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php499
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestSuiteTest.php104
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php564
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php231
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeNumberTest.php526
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeTimeTest.php1052
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ClassRegistryTest.php349
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/DebuggerTest.php499
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FileTest.php556
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FolderTest.php937
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/HashTest.php2151
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/InflectorTest.php440
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php595
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SanitizeTest.php462
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SecurityTest.php207
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SetTest.php3542
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/StringTest.php650
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ValidationTest.php2217
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/XmlTest.php1064
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php650
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/FormHelperTest.php8004
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php1910
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php373
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JsHelperTest.php928
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php378
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php107
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php2501
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php386
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/RssHelperTest.php720
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php192
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TextHelperTest.php301
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php170
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperCollectionTest.php188
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperTest.php941
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/JsonViewTest.php101
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/MediaViewTest.php402
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ScaffoldViewTest.php463
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ThemeViewTest.php265
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ViewTest.php1448
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/XmlViewTest.php130
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AccountFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoActionFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoFixture.php68
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoTwoFixture.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdFixture.php63
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdvertisementFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AfterTreeFixture.php62
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AnotherArticleFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AppleFixture.php64
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorFixture.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorsPlayerFixture.php67
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroFixture.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroTwoFixture.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoTwoFixture.php76
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedFixture.php59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedsTagsFixture.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFixture.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticlesTagFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AssertTagsTestCase.php118
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AttachmentFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserCustomFieldFixture.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserFixture.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthorFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticleFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticlesBakeTagFixture.php51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeCommentFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeTagFixture.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BasketFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BidFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingMessageFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BinaryTestFixture.php50
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BookFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CacheTestModelFixture.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CallbackFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CampaignFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryFixture.php62
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryThreadFixture.php61
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CdFixture.php54
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CommentFixture.php62
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentAccountFixture.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostFixture.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostNonstandardPrimaryKeyFixture.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserFixture.php40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserNonstandardPrimaryKeyFixture.php39
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DataTestFixture.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DatatypeFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DependencyFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeCategoryFixture.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeFixture.php59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentDirectoryFixture.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainFixture.php65
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainsSiteFixture.php66
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ExteriorTypeCategoryFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeatureSetFixture.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeaturedFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FilmFileFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FixturizedTestCase.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FlagTreeFixture.php51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitsUuidTagFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GroupUpdateAllFixture.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildFixture.php54
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildsPlayerFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/HomeFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ImageFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/InnoFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemFixture.php59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemsPortfolioFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinABFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinACFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinAFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinBFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinCFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinThingFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MessageFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyProductsFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyUsersFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoryFixture.php54
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyProductFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyUserFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NodeFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeFixture.php50
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeTwoFixture.php51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumericArticleFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/OverallFavoriteFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PersonFixture.php64
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PlayerFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PortfolioFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostFixture.php59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostsTagFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrefixTestFixture.php37
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrimaryModelFixture.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductFixture.php61
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductUpdateAllFixture.php65
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProjectFixture.php54
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SampleFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SecondaryModelFixture.php52
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SessionFixture.php51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SiteFixture.php61
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingElseFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoriesTagFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoryFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SyfileFixture.php59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TagFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginArticleFixture.php59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginCommentFixture.php62
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThePaperMonkiesFixture.php50
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThreadFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateArticleFixture.php80
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateFixture.php80
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateTableFixture.php63
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateWithPrefixFixture.php84
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedArticleFixture.php57
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedItemFixture.php55
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnconventionalTreeFixture.php49
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnderscoreFieldFixture.php59
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UserFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTagFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTreeFixture.php47
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemFixture.php58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioNumericidFixture.php56
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidportfolioFixture.php53
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/rss.xml33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/sample.xml9
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_request.xml12
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_response.xml12
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.ini.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.php74
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/empty.php2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_minimized.ini2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_tags.php8
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/nested.ini17
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/no_section.ini2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/routes.php23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test.php12
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test2.php13
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/SampleShell.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/Task/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/classes/test_object.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/views/admin_edit.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/AppController.php36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/Component/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/PagesController.php80
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestAppsErrorController.php14
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsController.php48
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsPostsController.php73
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Error/TestAppsExceptionRenderer.php21
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Cache/Engine/TestAppCacheEngine.php44
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Library.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Log/Engine/TestAppLog.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Utility/TestUtilityClass.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/default.po5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom1.po8
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom2.po8
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/eng/LC_MESSAGES/validation_messages.po5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/ja_jp/LC_TIME48
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MESSAGES/default.po76
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MONETARY/default.po18
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_TIME60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/core.mobin0 -> 673 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/default.mobin0 -> 617 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/core.po21
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/default.po24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/core.mobin0 -> 845 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/default.mobin0 -> 759 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/core.po24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/default.po27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/core.mobin0 -> 858 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/default.mobin0 -> 762 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/core.po25
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/default.po25
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/core.mobin0 -> 821 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/default.mobin0 -> 735 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/core.po24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/default.po24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/core.mobin0 -> 865 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/default.mobin0 -> 779 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/core.po24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/default.po24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/core.mobin0 -> 769 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/default.mobin0 -> 693 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/default.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/core.mobin0 -> 704 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/default.mobin0 -> 638 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/core.po22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/default.po25
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/core.mobin0 -> 699 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/default.mobin0 -> 633 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/core.po22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/default.po25
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/core.mobin0 -> 790 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/default.mobin0 -> 714 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/default.po26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/core.mobin0 -> 758 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/default.mobin0 -> 682 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/default.po26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/core.mobin0 -> 806 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/default.mobin0 -> 658 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/default.po24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/core.mobin0 -> 841 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/default.mobin0 -> 765 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/default.po26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/core.mobin0 -> 850 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/default.mobin0 -> 774 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/default.po26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/core.mobin0 -> 774 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/default.mobin0 -> 698 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/default.po26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/core.mobin0 -> 819 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/default.mobin0 -> 743 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/core.po23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/default.po26
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/time_test/LC_TIME42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/AppModel.php35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterOneBehaviorBehavior.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterTwoBehaviorBehavior.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Comment.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Database/TestLocalDriver.php5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2OtherSource.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2Source.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterOne.php60
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterTwo.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Post.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/Config/bootstrap.php2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/one/plugin_one.js1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/plugin_js.js1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/Schema/schema.php35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/bootstrap.php2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/custom_config.php2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/load.php19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/more.load.php19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/routes.php2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/ExampleShell.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/Task/OtherTaskTask.php21
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Templates/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/OtherComponent.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/PluginsComponent.php23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginComponent.php23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginOtherComponent.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginAppController.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginController.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestsController.php37
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Cache/Engine/TestPluginCacheEngine.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Custom/Package/CustomLibClass.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Error/TestPluginExceptionRenderer.php35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Log/Engine/TestPluginLog.php28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/Test2DispatcherFilter.php33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/TestDispatcherFilter.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginLibrary.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginOtherLibrary.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MESSAGES/test_plugin.po50
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MONETARY/test_plugin.po22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterOneBehavior.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterTwoBehavior.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/DboDummy.php10
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/TestDriver.php3
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestOtherSource.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestSource.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAppModel.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthUser.php41
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthors.php28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginComment.php28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginPost.php71
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Utility/TestPluginEngine.php5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/Example/ExampleExample.php4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/sample/sample_plugin.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/welcome.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/plugin_element.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/sub_dir/sub_element.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/test_plugin_element.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/translate.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Emails/text/test_plugin_tpl.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/OtherHelperHelper.php21
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/PluggedHelperHelper.php22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/TestPluginAppHelper.php4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/Emails/text/plug_default.ctp4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/default.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/index.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/scaffold.form.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/test_plugin_asset.css1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/theme_one.htc1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/unknown.extension1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/flash/plugin_test.swf1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/img/cake.icon.gifbin0 -> 233 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/js/test_plugin/test.js1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/root.js1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Config/bootstrap.php2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/ExampleShell.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/Task/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/WelcomeShell.php29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Templates/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Utility/TestAppEngine.php5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/MyTest.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/hello.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/css/test_asset.css1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test.jpgbin0 -> 5308 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test_2.JPGbin0 -> 5308 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/sample/configure_test_vendor_sample.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/somename/some.name.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/welcome.php20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_element.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/html_call.ctp3
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/contains_nocache.ctp5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/plain.ctp4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub1.ctp8
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub2.ctp6
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/parent_element.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/session_helper.ctp5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.xml1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/type_check.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/custom.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/default.ctp25
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/image.ctp23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/japanese.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/nested_element.ctp3
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom_helper.ctp19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/default.ctp19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/japanese.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/wide.ctp20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error400.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error500.ctp28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Helper/BananaHelper.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/default.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/japanese.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/thin.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/default.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/japanese.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax.ctp19
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax2.ctp22
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/banana.ctp5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_empty_sections.ctp13
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_layout.ctp31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/default.ctp58
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/flash.ctp37
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/js/default.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/json/default.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/multi_cache.ctp39
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/rss/default.ctp17
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/xml/default.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/extract.ctp24
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/home.ctp163
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/page.home.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/alt_ext.alt1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_empty_sections.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_form.ctp14
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_element.ctp3
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop_inner.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_self.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/helper_overwrite.ctp4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/index.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/json/index.ctp27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/multiple_nocache.ctp15
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nested_extends.ctp5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nocache_multiple_element.ctp9
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/open_block.ctp3
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_1.ctp5
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_2.ctp3
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_view.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/scaffold.form.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/sequencial_nocache.ctp23
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/test_nocache_tags.ctp142
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/xml/index.ctp6
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Scaffolds/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/index.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/json/index.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Elements/test_element.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Emails/text/themed.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Layouts/default.ctp2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Emails/text/test_plugin_tpl.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Layouts/plugin_default.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Tests/index.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/index.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/scaffold.index.ctp1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/themed.ctp4
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/test_asset.css1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/theme_webroot.css1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/flash/theme_test.swf1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/cake.power.gifbin0 -> 201 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/test.jpgbin0 -> 5308 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/one/theme_one.js1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/theme.js1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/pdfs/theme_test.pdf1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/space image.text1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/tmp/dir_map2
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/img/cake.power.gifbin0 -> 201 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/theme_webroot.css1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/webroot_test.css1
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/cake.power.gifbin0 -> 201 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/test.jpgbin0 -> 5308 bytes
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestCase.php679
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestLoader.php123
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestRunner.php103
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuite.php63
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteCommand.php171
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php276
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/ControllerTestCase.php378
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/BaseCoverageReport.php179
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/HtmlCoverageReport.php201
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/TextCoverageReport.php63
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php282
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestFixture.php269
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestModel.php70
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php210
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php377
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeTextReporter.php187
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/footer.php36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/header.php146
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/menu.php51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/missing_connection.php27
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/phpunit.php36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/xdebug.php28
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php296
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php1057
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php368
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php817
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php568
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php780
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php974
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php551
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php326
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php264
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Security.php192
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Set.php1108
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/String.php605
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Validation.php937
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Xml.php370
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/VERSION.txt20
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp75
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp74
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp35
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp42
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp30
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp40
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp45
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp33
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp38
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp29
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp36
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php914
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php321
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php2604
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php1214
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php361
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php592
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php434
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php376
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php149
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php901
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php370
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php345
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php163
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php277
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php458
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php203
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php108
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php238
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php91
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp51
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp94
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp146
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php31
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php1129
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php158
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php113
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/basics.php755
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/bootstrap.php160
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/plugins/empty0
-rw-r--r--poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/vendors/empty0
l---------poc/poc02-compiling-cake/src/workdir/in/.htaccess2
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/config/acl.ini.php76
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/config/bootstrap.php46
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/config/core.php146
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/config/database.php.default74
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/config/inflections.php72
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/config/routes.php46
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/config/sql/db_acl.sql38
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/index.php26
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/webroot/css.php102
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/webroot/css/cake.generic.css250
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/cake.power.pngbin3053 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_css.pngbin299 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_xhtml10.pngbin321 -> 0 bytes
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/webroot/index.php87
-rw-r--r--poc/poc02-compiling-cake/src/workdir/in/app/webroot/js/vendors.php44
l---------poc/poc02-compiling-cake/src/workdir/in/cake1
l---------poc/poc02-compiling-cake/src/workdir/in/index.php2
l---------poc/poc02-compiling-cake/src/workdir/in/lib1
l---------poc/poc02-compiling-cake/src/workdir/in/plugins1
1152 files changed, 238551 insertions, 34267 deletions
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/bootstrap.php
deleted file mode 100644
index ef4cedf..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/bootstrap.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/* SVN FILE: $Id: bootstrap.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.10.8.2117
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- *
- * This file is loaded automatically by the app/webroot/index.php file after the core bootstrap.php is loaded
- * This is an application wide file to load any function that is not used within a class define.
- * You can also use this to include or require any files in your application.
- *
- */
-/**
- * The settings below can be used to set additional paths to models, views and controllers.
- * This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
- *
- * $modelPaths = array('full path to models', 'second full path to models', 'etc...');
- * $viewPaths = array('this path to views', 'second full path to views', 'etc...');
- * $controllerPaths = array('this path to controllers', 'second full path to controllers', 'etc...');
- *
- */
-//EOF
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/core.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/core.php
deleted file mode 100644
index 77cf1ff..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/core.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-/* SVN FILE: $Id: core.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * If you do not have mod rewrite on your system
- * or if you prefer to use CakePHP pretty urls.
- * uncomment the line below.
- * Note: If you do have mod rewrite but prefer the
- * CakePHP pretty urls, you also have to remove the
- * .htaccess files
- * release/.htaccess
- * release/app/.htaccess
- * release/app/webroot/.htaccess
- */
-// define ('BASE_URL', env('SCRIPT_NAME'));
-/**
- * Set debug level here:
- * - 0: production
- * - 1: development
- * - 2: full debug with sql
- * - 3: full debug with sql and dump of the current object
- *
- * In production, the "flash messages" redirect after a time interval.
- * With the other debug levels you get to click the "flash message" to continue.
- *
- */
- define('DEBUG', 1);
-/**
- * Turn of caching checking wide.
- * You must still use the controller var cacheAction inside you controller class.
- * You can either set it controller wide, or in each controller method.
- * use var $cacheAction = true; or in the controller method $this->cacheAction = true;
- */
- define('CACHE_CHECK', false);
-/**
- * Error constant. Used for differentiating error logging and debugging.
- * Currently PHP supports LOG_DEBUG
- */
- define('LOG_ERROR', 2);
-/**
- * CakePHP includes 3 types of session saves
- * database or file. Set this to your preferred method.
- * If you want to use your own save handler place it in
- * app/config/name.php DO NOT USE file or database as the name.
- * and use just the name portion below.
- *
- * Setting this to cake will save files to /cakedistro/tmp directory
- * Setting it to php will use the php default save path
- * Setting it to database will use the database
- *
- */
- define('CAKE_SESSION_SAVE', 'php');
-/**
- * If using you own table name for storing sessions
- * set the table name here.
- * DO NOT INCLUDE PREFIX IF YOU HAVE SET ONE IN database.php
- *
- */
- define('CAKE_SESSION_TABLE', 'cake_sessions');
-/**
- * Set a random string of used in session.
- *
- */
- define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
-/**
- * Set the name of session cookie
- *
- */
- define('CAKE_SESSION_COOKIE', 'CAKEPHP');
-/**
- * Set level of Cake security.
- *
- */
- define('CAKE_SECURITY', 'high');
-/**
- * Set Cake Session time out.
- * If CAKE_SECURITY define is set
- * high: multiplied by 10
- * medium: is multiplied by 100
- * low is: multiplied by 300
- *
- * Number below is seconds.
- */
- define('CAKE_SESSION_TIMEOUT', '120');
-/**
- * Uncomment the define below to use cake built in admin routes.
- * You can set this value to anything you want.
- * All methods related to the admin route should be prefixed with the
- * name you set CAKE_ADMIN to.
- * For example: admin_index, admin_edit
- */
-// define('CAKE_ADMIN', 'admin');
-/**
- * The define below is used to turn cake built webservices
- * on or off. Default setting is off.
- */
- define('WEBSERVICES', 'off');
-/**
- * Compress output CSS (removing comments, whitespace, repeating tags etc.)
- * This requires a/var/cache directory to be writable by the web server (caching).
- * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use Controller::cssTag().
- */
- define('COMPRESS_CSS', false);
-/**
- * If set to true, helpers would output data instead of returning it.
- */
- define('AUTO_OUTPUT', false);
-/**
- * If set to false, session would not automatically be started.
- */
- define('AUTO_SESSION', true);
-/**
- * Set the max size of file to use md5() .
- */
- define('MAX_MD5SIZE', (5 * 1024) * 1024);
-/**
- * To use Access Control Lists with Cake...
- */
- define('ACL_CLASSNAME', 'DB_ACL');
- define('ACL_FILENAME', 'dbacl' . DS . 'db_acl');
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/database.php.default b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/database.php.default
deleted file mode 100644
index 4df48e1..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/database.php.default
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/* SVN FILE: $Id: database.php.default 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * In this file you set up your database connection details.
- *
- * @package cake
- * @subpackage cake.config
- */
-/**
- * Database configuration class.
- * You can specify multiple configurations for production, development and testing.
- *
- * driver =>
- * mysql, postgres, sqlite, adodb, pear-drivername
- *
- * connect =>
- * MySQL set the connect to either mysql_pconnect of mysql_connect
- * PostgreSQL set the connect to either pg_pconnect of pg_connect
- * SQLite set the connect to sqlite_popen sqlite_open
- * ADOdb set the connect to one of these
- * (http://phplens.com/adodb/supported.databases.html) and
- * append it '|p' for persistent connection. (mssql|p for example, or just mssql for not persistent)
- *
- * host =>
- * the host you connect to the database
- * MySQL 'localhost' to add a port number use 'localhost:port#'
- * PostgreSQL 'localhost' to add a port number use 'localhost port=5432'
- *
- */
-class DATABASE_CONFIG
-{
- var $default = array('driver' => 'mysql',
- 'connect' => 'mysql_connect',
- 'host' => 'localhost',
- 'login' => 'user',
- 'password' => 'password',
- 'database' => 'project_name',
- 'prefix' => '');
-
- var $test = array('driver' => 'mysql',
- 'connect' => 'mysql_connect',
- 'host' => 'localhost',
- 'login' => 'user',
- 'password' => 'password',
- 'database' => 'project_name-test',
- 'prefix' => '');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/inflections.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/inflections.php
deleted file mode 100644
index e08a7d8..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/inflections.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/* SVN FILE: $Id: inflections.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Custom Inflected Words.
- *
- * This file is used to hold words that are not matched in the normail Inflector::pluralize() and
- * Inflector::singularize()
- *
- * PHP versions 4 and %
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 1.0.0.2312
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * This is a key => value array of regex used to match words.
- * If key matches then the value is returned.
- *
- * $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
- */
- $pluralRules = array();
-/**
- * This is a key only array of plural words that should not be inflected.
- * Notice the last comma
- *
- * $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
- */
- $uninflectedPlural = array();
-/**
- * This is a key => value array of plural irregular words.
- * If key matches then the value is returned.
- *
- * $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
- */
- $irregularPlural = array();
-/**
- * This is a key => value array of regex used to match words.
- * If key matches then the value is returned.
- *
- * $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
- */
- $singularRules = array();
-/**
- * This is a key only array of singular words that should not be inflected.
- * You should not have to change this value below if you do change it use same format
- * as the $uninflectedPlural above.
- */
- $uninflectedSingular = $uninflectedPlural;
-/**
- * This is a key => value array of singular irregular words.
- * Most of the time this will be a reverse of the above $irregularPlural array
- * You should not have to change this value below if you do change it use same format
- *
- * $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
- */
- $irregularSingular = array_flip($irregularPlural);
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/routes.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/routes.php
deleted file mode 100644
index 45ae36a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/routes.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/* SVN FILE: $Id: routes.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * In this file, you set up routes to your controllers and their actions.
- * Routes are very important mechanism that allows you to freely connect
- * different urls to chosen controllers and their actions (functions).
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Here, we are connecting '/' (base path) to controller called 'Pages',
- * its action called 'display', and we pass a param to select the view file
- * to use (in this case, /app/views/pages/home.thtml)...
- */
- $Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
-/**
- * ...and connect the rest of 'Pages' controller's urls.
- */
- $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
-/**
- * Then we connect url '/test' to our test controller. This is helpfull in
- * developement.
- */
- $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index'));
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/sql/db_acl.sql b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/sql/db_acl.sql
deleted file mode 100644
index be8f200..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/sql/db_acl.sql
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id: db_acl.sql 6305 2008-01-02 02:33:56Z phpnut $
-#
-# Copyright 2005-2008, Cake Software Foundation, Inc.
-# 1785 E. Sahara Avenue, Suite 490-204
-# Las Vegas, Nevada 89104
-#
-# Licensed under The MIT License
-# Redistributions of files must retain the above copyright notice.
-# http://www.opensource.org/licenses/mit-license.php The MIT License
-
-CREATE TABLE acos (
- id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
- object_id INTEGER(10) NULL DEFAULT NULL,
- alias VARCHAR(255) NOT NULL DEFAULT '',
- lft INTEGER(10) NULL DEFAULT NULL,
- rght INTEGER(10) NULL DEFAULT NULL,
- PRIMARY KEY(id)
-);
-
-CREATE TABLE aros_acos (
- id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
- aro_id INTEGER(10) UNSIGNED NOT NULL,
- aco_id INTEGER(10) UNSIGNED NOT NULL,
- _create CHAR(2) NOT NULL DEFAULT 0,
- _read CHAR(2) NOT NULL DEFAULT 0,
- _update CHAR(2) NOT NULL DEFAULT 0,
- _delete CHAR(2) NOT NULL DEFAULT 0,
- PRIMARY KEY(id)
-);
-
-CREATE TABLE aros (
- id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
- foreign_key INTEGER(10) UNSIGNED NULL DEFAULT NULL,
- alias VARCHAR(255) NOT NULL DEFAULT '',
- lft INTEGER(10) NULL DEFAULT NULL,
- rght INTEGER(10) NULL DEFAULT NULL,
- PRIMARY KEY(id)
-); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/index.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/index.php
deleted file mode 100644
index bd8993b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/index.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css.php
deleted file mode 100644
index dc87218..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-/* SVN FILE: $Id: css.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-if (!defined('CAKE_CORE_INCLUDE_PATH')) {
- header('HTTP/1.1 404 Not Found');
- exit('File Not Found');
-}
-/**
- * Enter description here...
- */
- uses('file');
-/**
- * Enter description here...
- *
- * @param unknown_type $path
- * @param unknown_type $name
- * @return unknown
- */
- function make_clean_css($path, $name) {
- require(VENDORS . 'csspp' . DS . 'csspp.php');
- $data = file_get_contents($path);
- $csspp = new csspp();
- $output = $csspp->compress($data);
- $ratio = 100 - (round(strlen($output) / strlen($data), 3) * 100);
- $output = " /* file: $name, ratio: $ratio% */ " . $output;
- return $output;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $path
- * @param unknown_type $content
- * @return unknown
- */
- function write_css_cache($path, $content) {
- if (!is_dir(dirname($path))) {
- mkdir(dirname($path));
- }
- $cache = new File($path);
- return $cache->write($content);
- }
-
- if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
- die('Wrong file name.');
- }
-
- $filename = 'css/' . $regs[1];
- $filepath = CSS . $regs[1];
- $cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
-
- if (!file_exists($filepath)) {
- die('Wrong file name.');
- }
-
- if (file_exists($cachepath)) {
- $templateModified = filemtime($filepath);
- $cacheModified = filemtime($cachepath);
-
- if ($templateModified > $cacheModified) {
- $output = make_clean_css($filepath, $filename);
- write_css_cache($cachepath, $output);
- } else {
- $output = file_get_contents($cachepath);
- }
- } else {
- $output = make_clean_css($filepath, $filename);
- write_css_cache($cachepath, $output);
- $templateModified = time();
- }
-
- header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT');
- header("Content-Type: text/css");
- header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
- header("Cache-Control: cache"); // HTTP/1.1
- header("Pragma: cache"); // HTTP/1.0
- print $output;
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css/cake.generic.css b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css/cake.generic.css
deleted file mode 100644
index bc27d22..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/css/cake.generic.css
+++ /dev/null
@@ -1,250 +0,0 @@
-*{
-margin:0;
-padding:0;
-}
-
-body{
-font-family:"frutiger linotype","lucida grande",helvetica,arial,sans-serif;
-text-align:center;
-color:#333;
-font-size: 76%;
-}
-
-/* General Style Info */
-a{
-color:#003d4c;
-text-decoration:underline;
-}
-a:hover{
-color:#003d4c;
-text-decoration:none;
-}
-
-a img{
-border:none;
-}
-
-h1, h2, h3, h4{
-font-weight:normal;
-}
-
-h1{
-color: #003d4c;
-margin:0.3em 0;
-font-size: 180%;
-}
-
-h2{
-color:#c6c65b;
-padding-top: 1em;
-margin:0.3em 0;
-font-size: 180%;
-}
-
-h3{
-color:#c6c65b;
-padding-top:2em;
-font-size: 140%;
-}
-
-h4{
-color:#c6c65b;
-padding-top:0.5em;
-font-weight:normal;
-}
-
-em {
-font-size: 12px;
-}
-
-ul, li {
-margin: 0 12px;
-}
-
-/* Layout */
-
-#container{
-text-align:left;
-}
-
-#header{
-margin-top: 1em;
-padding: 4px 20px;
-}
-
-#content{
-clear:both;
-padding: 0px 40px 10px 40px;
-background-color: #fff;
-color: #333;
-}
-#footer{
-clear:both;
-padding: 6px 10px;
-text-align: right;
-}
-
-/* tables */
-
-table {
-width: 100%;
-border-top: 1px solid #ccc;
-border-left: 1px solid #ccc;
-border-bottom: 1px solid #ccc;
-color:#333;
-background-color: #fff;
-clear:both;
-padding: 0;
-margin: 0 0 2em 0;
-white-space: normal;
-}
-th {
-background-color: #e2e2e2;
-border-top: 1px solid #fff;
-border-left: 1px solid #fff;
-border-right: 1px solid #003d4c;
-border-bottom: 1px solid #003d4c;
-text-align: center;
-padding:1px 4px;
-}
-table tr td {
-border-right: 1px solid #ddd;
-padding:4px 4px;
-vertical-align:top;
-text-align: center;
-}
-table tr.altRow td {
-background: #f4f4f4;
-}
-table td.actions {
- white-space: nowrap;
-}
-#cakeSqlLog td {
-text-align: left;
-padding: 4px 8px;
-background: #fff;
-border-bottom: 2px solid #ccc;
-}
-
-/* scaffold show */
-
-div.related {
-clear:both;
-display:block;
-}
-dl {
-line-height:2em;
-margin:0em 1em;
-float:left;
-width: 400px;
-}
-dt {
-font-weight: bold;
-vertical-align:top;
-}
-dd {
-margin-left:10em;
-margin-top:-2em;
-vertical-align:top;
-}
-
-/* notices and errors */
-
-#flashMessage, .error, .error_message {
-color:#900;
-font-size: 16px;
-background-color: #fff;
-margin: 8px 0px;
-font-weight: bold;
-}
-.error_message {
-clear: both;
-}
-.error em {
-font-size: 18px;
-color: #003d4c;
-}
-.notice {
-color: #656565;
-font-size: 14px;
-background-color: #f4f4f4;
-padding: 0.5em;
-margin: 1em 0;
-display:block;
-}
-.tip {
-color: #656565;
-background-color: #ddd;
-}
-
-/* forms */
-
-form {
-margin-top: 2em;
-}
-form div{
-vertical-align: text-top;
-margin-left: 1em;
-margin-bottom:2em;
-}
-form div.date{
-margin-left: 0em;
-}
-label {
-display: block;
-width: 140px;
-font-size: 14px;
-padding-right: 20px;
-}
-input[type=checkbox] {
-float: left;
-clear: left;
-margin: 2px 6px 7px 2px;
-}
-input, textarea {
-clear: both;
-display:block;
-font-size: 14px;
-font-family: inherit;
-}
-select {
-clear: both;
-vertical-align: text-bottom;
-font-size: 14px;
-font-family: inherit;
-}
-option {
-font-size: 14px;
-font-family: inherit;
-padding: 0 0.3em;
-}
-input[type=submit] {
-display: inline;
-vertical-align: bottom;
-}
-div.required {
-clear: both;
-color:#222;
-font-weight:bold;
-}
-div.optional {
-clear: both;
-color:#555;
-}
-div.submit {
-clear: both;
-margin-top: 40px;
-margin-left: 140px;
-}
-/* action links */
-ul.actions {
-float: left;
-margin-left:20px;
-width: 200px;
-}
-ul.actions li {
-margin-top: 4px;
-}
-pre {
-padding: 1em;
-} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/cake.power.png b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/cake.power.png
deleted file mode 100644
index 699ef80..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/cake.power.png
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_css.png b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_css.png
deleted file mode 100644
index 706325e..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_css.png
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_xhtml10.png b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_xhtml10.png
deleted file mode 100644
index ec68644..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/img/w3c_xhtml10.png
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/index.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/index.php
deleted file mode 100644
index 48771ff..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/index.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Do not change
- */
- if (!defined('DS')) {
- define('DS', DIRECTORY_SEPARATOR);
- }
-/**
- * These defines should only be edited if you have cake installed in
- * a directory layout other than the way it is distributed.
- * Each define has a commented line of code that explains what you would change.
- *
- */
- if (!defined('ROOT')) {
- //define('ROOT', 'FULL PATH TO DIRECTORY WHERE APP DIRECTORY IS LOCATED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
- //You should also use the DS define to seperate your directories
- define('ROOT', dirname(dirname(dirname(__FILE__))));
- }
- if (!defined('APP_DIR')) {
- //define('APP_DIR', 'DIRECTORY NAME OF APPLICATION';
- define('APP_DIR', basename(dirname(dirname(__FILE__))));
- }
-/**
- * This only needs to be changed if the cake installed libs are located
- * outside of the distributed directory structure.
- */
- if (!defined('CAKE_CORE_INCLUDE_PATH')) {
- //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
- //You should also use the DS define to seperate your directories
- define('CAKE_CORE_INCLUDE_PATH', ROOT);
- }
-///////////////////////////////
-//DO NOT EDIT BELOW THIS LINE//
-///////////////////////////////
- if (!defined('WEBROOT_DIR')) {
- define('WEBROOT_DIR', basename(dirname(__FILE__)));
- }
- if (!defined('WWW_ROOT')) {
- define('WWW_ROOT', dirname(__FILE__) . DS);
- }
- if (!defined('CORE_PATH')) {
- if (function_exists('ini_set')) {
- ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'));
- define('APP_PATH', null);
- define('CORE_PATH', null);
- } else {
- define('APP_PATH', ROOT . DS . APP_DIR . DS);
- define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
- }
- }
- require CORE_PATH . 'cake' . DS . 'bootstrap.php';
- if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
- } else {
- $Dispatcher = new Dispatcher();
- $Dispatcher->dispatch($url);
- }
- if (Configure::read() > 0) {
- echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
- }
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/js/vendors.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/js/vendors.php
deleted file mode 100644
index cee6b77..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/js/vendors.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/* SVN FILE: $Id: vendors.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Short description for file.
- *
- * This file includes js vendor-files from /vendor/ directory if they need to
- * be accessible to the public.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot.js
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Enter description here...
- */
-if (isset($_GET['file'])) {
- $file = $_GET['file'];
- $pos = strpos($file, '..');
- if ($pos === false) {
- if (is_file('../../vendors/javascript/'.$file) && (preg_match('/(\/.+)\\.js/', $file))) {
- readfile('../../vendors/javascript/'.$file);
- return;
- }
- }
-}
-header('HTTP/1.1 404 Not Found');
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/VERSION.txt b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/VERSION.txt
deleted file mode 100644
index 75ad570..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/VERSION.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// +---------------------------------------------------------------------------------------------------+ //
-// + $Id: VERSION.txt 7692 2008-10-02 05:06:48Z nate $
-// + Last Modified: $Date: 2008-10-02 01:06:48 -0400 (Thu, 02 Oct 2008) $
-// + Modified By: $LastChangedBy: nate $
-// +---------------------------------------------------------------------------------------------------+ //
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-1.1.20.7692 \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_controller.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_controller.php
deleted file mode 100644
index 24a501c..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_controller.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-/* SVN FILE: $Id: app_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * This file is application-wide controller file. You can put all
- * application-wide controller-related methods here.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * This is a placeholder class.
- * Create the same file in app/app_controller.php
- *
- * Add your application-wide methods in the class below, your controllers
- * will inherit them.
- *
- * @package cake
- * @subpackage cake.cake
- */
-class AppController extends Controller {
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_model.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_model.php
deleted file mode 100644
index c20a518..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/app_model.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-/* SVN FILE: $Id: app_model.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Application model for Cake.
- *
- * This file is application-wide model file. You can put all
- * application-wide model-related methods here.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Application model for Cake.
- *
- * This is a placeholder class.
- * Create the same file in app/app_model.php
- * Add your application-wide methods to the class, your models will inherit them.
- *
- * @package cake
- * @subpackage cake.cake
- */
-class AppModel extends Model {
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/basics.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/basics.php
deleted file mode 100644
index 486584f..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/basics.php
+++ /dev/null
@@ -1,1156 +0,0 @@
-<?php
-/* SVN FILE: $Id: basics.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Basic Cake functionality.
- *
- * Core functions for including other source files, loading models and so forth.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Basic defines for timing functions.
- */
- define('SECOND', 1);
- define('MINUTE', 60 * SECOND);
- define('HOUR', 60 * MINUTE);
- define('DAY', 24 * HOUR);
- define('WEEK', 7 * DAY);
- define('MONTH', 30 * DAY);
- define('YEAR', 365 * DAY);
-/**
- * Patch for PHP < 4.3
- */
- if (!function_exists("ob_get_clean")) {
- function ob_get_clean() {
- $ob_contents = ob_get_contents();
- ob_end_clean();
- return $ob_contents;
- }
- }
-/**
- * Patch for PHP < 4.3
- */
- if (version_compare(phpversion(), '5.0') < 0) {
- eval ('
- function clone($object) {
- return $object;
- }');
- }
-/**
- * Computes the difference of arrays using keys for comparison
- *
- * @param array
- * @param array
- * @return array
- */
- if (!function_exists('array_diff_key')) {
- function array_diff_key() {
- $valuesDiff = array();
-
- if (func_num_args() < 2) {
- return false;
- }
-
- foreach (func_get_args() as $param) {
- if (!is_array($param)) {
- return false;
- }
- }
-
- $args = func_get_args();
- foreach ($args[0] as $valueKey => $valueData) {
- for ($i = 1; $i < func_num_args(); $i++) {
- if (isset($args[$i][$valueKey])) {
- continue 2;
- }
- }
- $valuesDiff[$valueKey] = $valueData;
- }
- return $valuesDiff;
- }
- }
-/**
- * Computes the intersection of arrays using keys for comparison
- *
- * @param array
- * @param array
- * @return array
- */
- if (!function_exists('array_intersect_key')) {
- function array_intersect_key($arr1, $arr2) {
- $res = array();
- foreach ($arr1 as $key=>$value) {
- if (array_key_exists($key, $arr2)) {
- $res[$key] = $arr1[$key];
- }
- }
- return $res;
- }
- }
-/**
- * Loads all models.
- */
- function loadModels() {
- if (!class_exists('Model')) {
- require LIBS . 'model' . DS . 'model.php';
- }
- $path = Configure::getInstance();
- if (!class_exists('AppModel')) {
- if (file_exists(APP . 'app_model.php')) {
- require(APP . 'app_model.php');
- } else {
- require(CAKE . 'app_model.php');
- }
- if (phpversion() < 5 && function_exists("overload")) {
- overload('AppModel');
- }
- }
-
- foreach ($path->modelPaths as $path) {
- foreach (listClasses($path)as $model_fn) {
- list($name) = explode('.', $model_fn);
- $className = Inflector::camelize($name);
-
- if (!class_exists($className)) {
- require($path . $model_fn);
-
- if (phpversion() < 5 && function_exists("overload")) {
- overload($className);
- }
- }
- }
- }
- }
-/**
- * Loads all plugin models.
- *
- * @param string $plugin Name of plugin
- * @return
- */
- function loadPluginModels($plugin) {
- if (!class_exists('AppModel')) {
- loadModel();
- }
- $pluginAppModel = Inflector::camelize($plugin . '_app_model');
- $pluginAppModelFile = APP . 'plugins' . DS . $plugin . DS . $plugin . '_app_model.php';
- if (!class_exists($pluginAppModel)) {
- if (file_exists($pluginAppModelFile)) {
- require($pluginAppModelFile);
- } else {
- die('Plugins must have a class named ' . $pluginAppModel);
- }
- if (phpversion() < 5 && function_exists("overload")) {
- overload($pluginAppModel);
- }
- }
-
- $pluginModelDir = APP . 'plugins' . DS . $plugin . DS . 'models' . DS;
-
- foreach (listClasses($pluginModelDir)as $modelFileName) {
- list($name) = explode('.', $modelFileName);
- $className = Inflector::camelize($name);
-
- if (!class_exists($className)) {
- require($pluginModelDir . $modelFileName);
-
- if (phpversion() < 5 && function_exists("overload")) {
- overload($className);
- }
- }
- }
- }
-/**
- * Loads custom view class.
- *
- */
- function loadView($viewClass) {
- if (!class_exists($viewClass . 'View')) {
- $paths = Configure::getInstance();
- $file = Inflector::underscore($viewClass) . '.php';
-
- foreach ($paths->viewPaths as $path) {
- if (file_exists($path . $file)) {
- return require($path . $file);
- }
- }
-
- if ($viewFile = fileExistsInPath(LIBS . 'view' . DS . $file)) {
- if (file_exists($viewFile)) {
- require($viewFile);
- return true;
- } else {
- return false;
- }
- }
- }
- }
-/**
- * Loads a model by CamelCase name.
- */
- function loadModel($name = null) {
- if (!class_exists('Model')) {
- require LIBS . 'model' . DS . 'model.php';
- }
- if (!class_exists('AppModel')) {
- if (file_exists(APP . 'app_model.php')) {
- require(APP . 'app_model.php');
- } else {
- require(CAKE . 'app_model.php');
- }
- if (phpversion() < 5 && function_exists("overload")) {
- overload('AppModel');
- }
- }
-
- if (!is_null($name) && !class_exists($name)) {
- $className = $name;
- $name = Inflector::underscore($name);
- $paths = Configure::getInstance();
-
- foreach ($paths->modelPaths as $path) {
- if (file_exists($path . $name . '.php')) {
- require($path . $name . '.php');
- if (phpversion() < 5 && function_exists("overload")) {
- overload($className);
- }
- return true;
- }
- }
- return false;
- } else {
- return true;
- }
- }
-/**
- * Loads all controllers.
- */
- function loadControllers() {
- $paths = Configure::getInstance();
- if (!class_exists('AppController')) {
- if (file_exists(APP . 'app_controller.php')) {
- require(APP . 'app_controller.php');
- } else {
- require(CAKE . 'app_controller.php');
- }
- }
- $loadedControllers = array();
-
- foreach ($paths->controllerPaths as $path) {
- foreach (listClasses($path) as $controller) {
- list($name) = explode('.', $controller);
- $className = Inflector::camelize(str_replace('_controller', '', $name));
-
- if (loadController($className)) {
- $loadedControllers[$controller] = $className;
- }
- }
- }
- return $loadedControllers;
- }
-/**
- * Loads a controller and its helper libraries.
- *
- * @param string $name Name of controller
- * @return boolean Success
- */
- function loadController($name) {
- $paths = Configure::getInstance();
- if (!class_exists('AppController')) {
- if (file_exists(APP . 'app_controller.php')) {
- require(APP . 'app_controller.php');
- } else {
- require(CAKE . 'app_controller.php');
- }
- }
-
- if ($name === null) {
- return true;
- }
-
- if (!class_exists($name . 'Controller')) {
- $name = Inflector::underscore($name);
-
- foreach ($paths->controllerPaths as $path) {
- if (file_exists($path . $name . '_controller.php')) {
- require($path . $name . '_controller.php');
- return true;
- }
- }
-
- if ($controller_fn = fileExistsInPath(LIBS . 'controller' . DS . $name . '_controller.php')) {
- if (file_exists($controller_fn)) {
- require($controller_fn);
- return true;
- } else {
- return false;
- }
- }
- } else {
- return false;
- }
- }
-/**
- * Loads a plugin's controller.
- *
- * @param string $plugin Name of plugin
- * @param string $controller Name of controller to load
- * @return boolean Success
- */
- function loadPluginController($plugin, $controller) {
- $pluginAppController = Inflector::camelize($plugin . '_app_controller');
- $pluginAppControllerFile = APP . 'plugins' . DS . $plugin . DS . $plugin . '_app_controller.php';
- if (!class_exists($pluginAppController)) {
- if (file_exists($pluginAppControllerFile)) {
- require($pluginAppControllerFile);
- } else {
- return false;
- }
- }
-
- if (empty($controller)) {
- if (!class_exists($plugin . 'Controller')) {
- if (file_exists(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php')) {
- require(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php');
- return true;
- }
- }
- }
-
- if (!class_exists($controller . 'Controller')) {
- $controller = Inflector::underscore($controller);
- $file = APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $controller . '_controller.php';
-
- if (file_exists($file)) {
- require($file);
- return true;
- } elseif (!class_exists(Inflector::camelize($plugin . '_controller'))) {
- if (file_exists(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php')) {
- require(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php');
- return true;
- } else {
- return false;
- }
- }
- }
- return true;
- }
-/**
- * Loads a helper
- *
- * @param string $name Name of helper
- * @return boolean Success
- */
- function loadHelper($name) {
- $paths = Configure::getInstance();
-
- if ($name === null) {
- return true;
- }
-
- if (!class_exists($name . 'Helper')) {
- $name=Inflector::underscore($name);
-
- foreach ($paths->helperPaths as $path) {
- if (file_exists($path . $name . '.php')) {
- require($path . $name . '.php');
- return true;
- }
- }
-
- if ($helper_fn = fileExistsInPath(LIBS . 'view' . DS . 'helpers' . DS . $name . '.php')) {
- if (file_exists($helper_fn)) {
- require($helper_fn);
- return true;
- } else {
- return false;
- }
- }
- } else {
- return true;
- }
- }
-/**
- * Loads a plugin's helper
- *
- * @param string $plugin Name of plugin
- * @param string $helper Name of helper to load
- * @return boolean Success
- */
- function loadPluginHelper($plugin, $helper) {
- if (!class_exists($helper . 'Helper')) {
- $helper = Inflector::underscore($helper);
- $file = APP . 'plugins' . DS . $plugin . DS . 'views' . DS . 'helpers' . DS . $helper . '.php';
- if (file_exists($file)) {
- require($file);
- return true;
- } else {
- return false;
- }
- } else {
- return true;
- }
- }
-/**
- * Loads a component
- *
- * @param string $name Name of component
- * @return boolean Success
- */
- function loadComponent($name) {
- $paths = Configure::getInstance();
-
- if ($name === null) {
- return true;
- }
-
- if (!class_exists($name . 'Component')) {
- $name=Inflector::underscore($name);
-
- foreach ($paths->componentPaths as $path) {
- if (file_exists($path . $name . '.php')) {
- require($path . $name . '.php');
- return true;
- }
- }
-
- if ($component_fn = fileExistsInPath(LIBS . 'controller' . DS . 'components' . DS . $name . '.php')) {
- if (file_exists($component_fn)) {
- require($component_fn);
- return true;
- } else {
- return false;
- }
- }
- } else {
- return true;
- }
- }
-/**
- * Loads a plugin's component
- *
- * @param string $plugin Name of plugin
- * @param string $helper Name of component to load
- * @return boolean Success
- */
- function loadPluginComponent($plugin, $component) {
- if (!class_exists($component . 'Component')) {
- $component = Inflector::underscore($component);
- $file = APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . 'components' . DS . $component . '.php';
- if (file_exists($file)) {
- require($file);
- return true;
- } else {
- return false;
- }
- } else {
- return true;
- }
- }
-/**
- * Returns an array of filenames of PHP files in given directory.
- *
- * @param string $path Path to scan for files
- * @return array List of files in directory
- */
- function listClasses($path) {
- $dir = opendir($path);
- $classes=array();
- while (false !== ($file = readdir($dir))) {
- if ((substr($file, -3, 3) == 'php') && substr($file, 0, 1) != '.') {
- $classes[] = $file;
- }
- }
- closedir($dir);
- return $classes;
- }
-/**
- * Loads configuration files
- *
- * @return boolean Success
- */
- function config() {
- $args = func_get_args();
- foreach ($args as $arg) {
- if (('database' == $arg) && file_exists(CONFIGS . $arg . '.php')) {
- include_once(CONFIGS . $arg . '.php');
- } elseif (file_exists(CONFIGS . $arg . '.php')) {
- include_once(CONFIGS . $arg . '.php');
-
- if (count($args) == 1) {
- return true;
- }
- } else {
- if (count($args) == 1) {
- return false;
- }
- }
- }
- return true;
- }
-/**
- * Loads component/components from LIBS.
- *
- * Example:
- * <code>
- * uses('flay', 'time');
- * </code>
- *
- * @uses LIBS
- */
- function uses() {
- $args = func_get_args();
- foreach ($args as $arg) {
- require_once(LIBS . strtolower($arg) . '.php');
- }
- }
-/**
- * Require given files in the VENDORS directory. Takes optional number of parameters.
- *
- * @param string $name Filename without the .php part.
- *
- */
- function vendor($name) {
- $args = func_get_args();
- foreach ($args as $arg) {
- if (file_exists(APP . 'vendors' . DS . $arg . '.php')) {
- require_once(APP . 'vendors' . DS . $arg . '.php');
- } else {
- require_once(VENDORS . $arg . '.php');
- }
- }
- }
-/**
- * Prints out debug information about given variable.
- *
- * Only runs if DEBUG level is non-zero.
- *
- * @param boolean $var Variable to show debug information for.
- * @param boolean $show_html If set to true, the method prints the debug data in a screen-friendly way.
- */
- function debug($var = false, $showHtml = false) {
- if (Configure::read() > 0) {
- print "\n<pre class=\"cake_debug\">\n";
- ob_start();
- print_r($var);
- $var = ob_get_clean();
-
- if ($showHtml) {
- $var = str_replace('<', '&lt;', str_replace('>', '&gt;', $var));
- }
- print "{$var}\n</pre>\n";
- }
- }
-/**
- * Returns microtime for execution time checking
- *
- * @return integer
- */
- if (!function_exists('getMicrotime')) {
- function getMicrotime() {
- list($usec, $sec) = explode(" ", microtime());
- return ((float)$usec + (float)$sec);
- }
- }
-/**
- * Sorts given $array by key $sortby.
- *
- * @param array $array
- * @param string $sortby
- * @param string $order Sort order asc/desc (ascending or descending).
- * @param integer $type
- * @return mixed
- */
- if (!function_exists('sortByKey')) {
- function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) {
- if (!is_array($array)) {
- return null;
- }
-
- foreach ($array as $key => $val) {
- $sa[$key] = $val[$sortby];
- }
-
- if ($order == 'asc') {
- asort($sa, $type);
- } else {
- arsort($sa, $type);
- }
-
- foreach ($sa as $key => $val) {
- $out[] = $array[$key];
- }
- return $out;
- }
- }
-/**
- * Combines given identical arrays by using the first array's values as keys,
- * and the second one's values as values. (Implemented for back-compatibility with PHP4)
- *
- * @param array $a1
- * @param array $a2
- * @return mixed Outputs either combined array or false.
- */
- if (!function_exists('array_combine')) {
- function array_combine($a1, $a2) {
- $a1 = array_values($a1);
- $a2 = array_values($a2);
- $c1 = count($a1);
- $c2 = count($a2);
-
- if ($c1 != $c2) {
- return false;
- }
- if ($c1 <= 0) {
- return false;
- }
-
- $output=array();
- for ($i = 0; $i < $c1; $i++) {
- $output[$a1[$i]] = $a2[$i];
- }
- return $output;
- }
- }
-/**
- * Convenience method for htmlspecialchars.
- *
- * @param string $text
- * @return string
- */
- function h($text) {
- if (is_array($text)) {
- return array_map('h', $text);
- }
- return htmlspecialchars($text);
- }
-/**
- * Returns an array of all the given parameters.
- *
- * Example:
- * <code>
- * a('a', 'b')
- * </code>
- *
- * Would return:
- * <code>
- * array('a', 'b')
- * </code>
- *
- * @return array
- */
- function a() {
- $args = func_get_args();
- return $args;
- }
-/**
- * Constructs associative array from pairs of arguments.
- *
- * Example:
- * <code>
- * aa('a','b')
- * </code>
- *
- * Would return:
- * <code>
- * array('a'=>'b')
- * </code>
- *
- * @return array
- */
- function aa() {
- $args = func_get_args();
- for ($l = 0, $c = count($args); $l < $c; $l++) {
- if ($l + 1 < count($args)) {
- $a[$args[$l]] = $args[$l + 1];
- } else {
- $a[$args[$l]] = null;
- }
- $l++;
- }
- return $a;
- }
-/**
- * Convenience method for echo().
- *
- * @param string $text String to echo
- */
- function e($text) {
- echo $text;
- }
-/**
- * Convenience method for strtolower().
- *
- * @param string $str String to lowercase
- */
- function low($str) {
- return strtolower($str);
- }
-/**
- * Convenience method for strtoupper().
- *
- * @param string $str String to uppercase
- */
- function up($str) {
- return strtoupper($str);
- }
-/**
- * Convenience method for str_replace().
- *
- * @param string $search String to be replaced
- * @param string $replace String to insert
- * @param string $subject String to search
- */
- function r($search, $replace, $subject) {
- return str_replace($search, $replace, $subject);
- }
-/**
- * Print_r convenience function, which prints out <PRE> tags around
- * the output of given array. Similar to debug().
- *
- * @see debug()
- * @param array $var
- */
- function pr($var) {
- if (Configure::read() > 0) {
- echo "<pre>";
- print_r($var);
- echo "</pre>";
- }
- }
-/**
- * Display parameter
- *
- * @param mixed $p Parameter as string or array
- * @return string
- */
- function params($p) {
- if (!is_array($p) || count($p) == 0) {
- return null;
- } else {
- if (is_array($p[0]) && count($p) == 1) {
- return $p[0];
- } else {
- return $p;
- }
- }
- }
-/**
- * Merge a group of arrays
- *
- * @param array First array
- * @param array Second array
- * @param array Third array
- * @param array Etc...
- * @return array All array parameters merged into one
- */
- function am() {
- $r = array();
- foreach (func_get_args()as $a) {
- if (!is_array($a)) {
- $a = array($a);
- }
- $r = array_merge($r, $a);
- }
- return $r;
- }
-/**
- * Returns the REQUEST_URI from the server environment, or, failing that,
- * constructs a new one, using the PHP_SELF constant and other variables.
- *
- * @return string URI
- */
- function setUri() {
- if (env('HTTP_X_REWRITE_URL')) {
- $uri = env('HTTP_X_REWRITE_URL');
- } elseif (env('REQUEST_URI')) {
- $uri = env('REQUEST_URI');
- } else {
- if (env('argv')) {
- $uri = env('argv');
-
- if (defined('SERVER_IIS')) {
- $uri = BASE_URL . $uri[0];
- } else {
- $uri = env('PHP_SELF') . '/' . $uri[0];
- }
- } else {
- $uri = env('PHP_SELF') . '/' . env('QUERY_STRING');
- }
- }
- return $uri;
- }
-/**
- * Gets an environment variable from available sources.
- * Used as a backup if $_SERVER/$_ENV are disabled.
- *
- * @param string $key Environment variable name.
- * @return string Environment variable setting.
- */
- function env($key) {
-
- if ($key == 'HTTPS') {
- if (isset($_SERVER) && !empty($_SERVER)) {
- return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on');
- } else {
- return (strpos(env('SCRIPT_URI'), 'https://') === 0);
- }
- }
-
- if (isset($_SERVER[$key])) {
- return $_SERVER[$key];
- } elseif (isset($_ENV[$key])) {
- return $_ENV[$key];
- } elseif (getenv($key) !== false) {
- return getenv($key);
- }
-
- if ($key == 'SCRIPT_FILENAME' && defined('SERVER_IIS') && SERVER_IIS === true) {
- return str_replace('\\\\', '\\', env('PATH_TRANSLATED') );
- }
-
- if ($key == 'DOCUMENT_ROOT') {
- $offset = 0;
- if (!strpos(env('SCRIPT_NAME'), '.php')) {
- $offset = 4;
- }
- return substr(env('SCRIPT_FILENAME'), 0, strlen(env('SCRIPT_FILENAME')) - (strlen(env('SCRIPT_NAME')) + $offset));
- }
- if ($key == 'PHP_SELF') {
- return r(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
- }
- return null;
- }
-/**
- * Returns contents of a file as a string.
- *
- * @param string $fileName Name of the file.
- * @param boolean $useIncludePath Wheter the function should use the include path or not.
- * @return mixed Boolean false or contents of required file.
- */
- if (!function_exists('file_get_contents')) {
- function file_get_contents($fileName, $useIncludePath = false) {
- $res=fopen($fileName, 'rb', $useIncludePath);
-
- if ($res === false) {
- trigger_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
- return false;
- }
- clearstatcache();
-
- if ($fileSize = @filesize($fileName)) {
- $data = fread($res, $fileSize);
- } else {
- $data = '';
-
- while (!feof($res)) {
- $data .= fread($res, 8192);
- }
- }
- return "$data\n";
- }
- }
-/**
- * Writes data into file.
- *
- * If file exists, it will be overwritten. If data is an array, it will be join()ed with an empty string.
- *
- * @param string $fileName File name.
- * @param mixed $data String or array.
- */
- if (!function_exists('file_put_contents')) {
- function file_put_contents($fileName, $data) {
- if (is_array($data)) {
- $data = join('', $data);
- }
- $res = @fopen($fileName, 'w+b');
- if ($res) {
- $write = @fwrite($res, $data);
- if ($write === false) {
- return false;
- } else {
- return $write;
- }
- }
- }
- }
-/**
- * Reads/writes temporary data to cache files or session.
- *
- * @param string $path File path within /tmp to save the file.
- * @param mixed $data The data to save to the temporary file.
- * @param mixed $expires A valid strtotime string when the data expires.
- * @param string $target The target of the cached data; either 'cache' or 'public'.
- * @return mixed The contents of the temporary file.
- */
- function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
- $now = time();
- if (!is_numeric($expires)) {
- $expires = strtotime($expires, $now);
- }
-
- switch(strtolower($target)) {
- case 'cache':
- $filename = CACHE . $path;
- break;
- case 'public':
- $filename = WWW_ROOT . $path;
- break;
- }
-
- $timediff = $expires - $now;
- $filetime = false;
- if (file_exists($filename)) {
- $filetime = @filemtime($filename);
- }
-
- if ($data === null) {
- // Read data from file
- if (file_exists($filename) && $filetime !== false) {
- if ($filetime + $timediff < $now) {
- // File has expired
- @unlink($filename);
- } else {
- $data = file_get_contents($filename);
- }
- }
- } else {
- file_put_contents($filename, $data);
- }
- return $data;
- }
-/**
- * Used to delete files in the cache directories, or clear contents of cache directories
- *
- * @param mixed $params As String name to be searched for deletion, if name is a directory all files in directory will be deleted.
- * If array, names to be searched for deletion.
- * If clearCache() without params, all files in app/tmp/cache/views will be deleted
- *
- * @param string $type Directory in tmp/cache defaults to view directory
- * @param string $ext The file extension you are deleting
- * @return true if files found and deleted false otherwise
- */
- function clearCache($params = null, $type = 'views', $ext = '.php') {
- if (is_string($params) || $params === null) {
- $params = preg_replace('/\/\//', '/', $params);
- $cache = CACHE . $type . DS . $params;
-
- if (is_file($cache . $ext)) {
- @unlink($cache . $ext);
- return true;
- } elseif (is_dir($cache)) {
- $files = glob("$cache*");
-
- if ($files === false) {
- return false;
- }
-
- foreach ($files as $file) {
- if (is_file($file)) {
- @unlink($file);
- }
- }
- return true;
- } else {
- $cache = CACHE . $type . DS . '*' . $params . $ext;
- $files = glob($cache);
-
- $cache = CACHE . $type . DS . '*' . $params . '_*' . $ext;
- $files = array_merge($files, glob($cache));
-
- if ($files === false) {
- return false;
- }
-
- foreach ($files as $file) {
- if (is_file($file)) {
- @unlink($file);
- }
- }
- return true;
- }
- } elseif (is_array($params)) {
- foreach ($params as $key => $file) {
- clearCache($file, $type, $ext);
- }
- return true;
- }
- return false;
- }
-/**
- * Recursively strips slashes from all values in an array
- *
- * @param unknown_type $value
- * @return unknown
- */
- function stripslashes_deep($value) {
- if (is_array($value)) {
- $return = array_map('stripslashes_deep', $value);
- return $return;
- } else {
- $return = stripslashes($value);
- return $return ;
- }
- }
-/**
- * Returns a translated string if one is found,
- * or the submitted message if not found.
- *
- * @param unknown_type $msg
- * @param unknown_type $return
- * @return unknown
- * @todo Not implemented fully till 2.0
- */
- function __($msg, $return = null) {
- if (is_null($return)) {
- echo($msg);
- } else {
- return $msg;
- }
- }
-/**
- * Counts the dimensions of an array
- *
- * @param array $array
- * @return int The number of dimensions in $array
- */
- function countdim($array) {
- if (is_array(reset($array))) {
- $return = countdim(reset($array)) + 1;
- } else {
- $return = 1;
- }
- return $return;
- }
-/**
- * Shortcut to Log::write.
- */
- function LogError($message) {
- if (!class_exists('CakeLog')) {
- uses('cake_log');
- }
- $bad = array("\n", "\r", "\t");
- $good = ' ';
- CakeLog::write('error', str_replace($bad, $good, $message));
- }
-/**
- * Searches include path for files
- *
- * @param string $file
- * @return Full path to file if exists, otherwise false
- */
- function fileExistsInPath($file) {
- $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
- foreach ($paths as $path) {
- $fullPath = $path . DIRECTORY_SEPARATOR . $file;
-
- if (file_exists($fullPath)) {
- return $fullPath;
- } elseif (file_exists($file)) {
- return $file;
- }
- }
- return false;
- }
-/**
- * Convert forward slashes to underscores and removes first and last underscores in a string
- *
- * @param string
- * @return string with underscore remove from start and end of string
- */
- function convertSlash($string) {
- $string = trim($string,"/");
- $string = preg_replace('/\/\//', '/', $string);
- $string = str_replace('/', '_', $string);
- return $string;
- }
-
-/**
- * chmod recursively on a directory
- *
- * @param string $path
- * @param int $mode
- * @return boolean
- */
- function chmodr($path, $mode = 0755) {
- if (!is_dir($path)) {
- return chmod($path, $mode);
- }
- $dir = opendir($path);
-
- while ($file = readdir($dir)) {
- if ($file != '.' && $file != '..') {
- $fullpath = $path . '/' . $file;
-
- if (!is_dir($fullpath)) {
- if (!chmod($fullpath, $mode)) {
- return false;
- }
- } else {
- if (!chmodr($fullpath, $mode)) {
- return false;
- }
- }
- }
- }
- closedir($dir);
-
- if (chmod($path, $mode)) {
- return true;
- } else {
- return false;
- }
- }
-/**
- * removed the plugin name from the base url
- *
- * @param string $base
- * @param string $plugin
- * @return base url with plugin name removed if present
- */
- function strip_plugin($base, $plugin) {
- if ($plugin != null) {
- $base = preg_replace('/' . $plugin . '/', '', $base);
- $base = str_replace('//', '', $base);
- $pos1 = strrpos($base, '/');
- $char = strlen($base) - 1;
-
- if ($pos1 == $char) {
- $base = substr($base, 0, $char);
- }
- }
- return $base;
- }
-/**
- * Wraps ternary operations. If $condition is a non-empty value, $val1 is returned, otherwise $val2.
- *
- * @param mixed $condition Conditional expression
- * @param mixed $val1
- * @param mixed $val2
- * @return mixed $val1 or $val2, depending on whether $condition evaluates to a non-empty expression.
- */
- function ife($condition, $val1 = null, $val2 = null) {
- if (!empty($condition)) {
- return $val1;
- }
- return $val2;
- }
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/bootstrap.php
deleted file mode 100644
index baed0e2..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/bootstrap.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-/* SVN FILE: $Id: bootstrap.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Basic Cake functionality.
- *
- * Core functions for including other source files, loading models and so forth.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Configuration, directory layout and standard libraries
- */
- if (!isset($bootstrap)) {
- require CORE_PATH . 'cake' . DS . 'basics.php';
- require APP_PATH . 'config' . DS . 'core.php';
- require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
- }
- $TIME_START = getMicrotime();
- require LIBS . 'object.php';
- require LIBS . 'session.php';
- require LIBS . 'security.php';
- require LIBS . 'inflector.php';
- require LIBS . 'configure.php';
- $paths = Configure::getInstance();
-/**
- * Enter description here...
- */
- if (empty($uri) && defined('BASE_URL')) {
- $uri = setUri();
-
- if ($uri === '/' || $uri === '/index.php' || $uri === '/'.APP_DIR.'/') {
- $_GET['url'] = '/';
- $url = '/';
- } else {
- if (strpos($uri, 'index.php') !== false) {
- $uri = r('?', '', $uri);
- $elements=explode('/index.php', $uri);
- } else {
- $elements = explode('/?', $uri);
- }
-
- if (!empty($elements[1])) {
- $_GET['url'] = $elements[1];
- $url = $elements[1];
- } else {
- $_GET['url'] = '/';
- $url = '/';
- }
- }
- } else {
- if (empty($_GET['url'])) {
- $url = null;
- } else {
- $url = $_GET['url'];
- }
- }
-
- if (strpos($url, 'ccss/') === 0) {
- include WWW_ROOT . DS . 'css.php';
- die();
- }
-
- Configure::write('debug', DEBUG);
-
- require CAKE . 'dispatcher.php';
-
- if (defined('CACHE_CHECK') && CACHE_CHECK === true) {
- if (empty($uri)) {
- $uri = setUri();
- }
- $filename=CACHE . 'views' . DS . convertSlash($uri) . '.php';
-
- if (file_exists($filename)) {
- uses(DS . 'controller' . DS . 'component', DS . 'view' . DS . 'view');
- $v = null;
- $view = new View($v);
- $view->renderCache($filename, $TIME_START);
- } elseif (file_exists(CACHE . 'views' . DS . convertSlash($uri) . '_index.php')) {
- uses(DS . 'controller' . DS . 'component', DS . 'view' . DS . 'view');
- $v = null;
- $view = new View($v);
- $view->renderCache(CACHE . 'views' . DS . convertSlash($uri) . '_index.php', $TIME_START);
- }
- }
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/config.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/config.php
deleted file mode 100644
index 6d907df..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/config.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/* SVN FILE: $Id: config.php 7692 2008-10-02 05:06:48Z nate $ */
-/**
- * Core Configurations.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 1.1.11.4062
- * @version $Revision: 7692 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 01:06:48 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-$config['Cake.version'] = '1.1.20.7692';
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/paths.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/paths.php
deleted file mode 100644
index a2f9659..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/config/paths.php
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-/* SVN FILE: $Id: paths.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * In this file you set paths to different directories used by Cake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * If the index.php file is used instead of an .htaccess file
- * or if the user can not set the web root to use the public
- * directory we will define ROOT there, otherwise we set it
- * here.
- */
- if (!defined('ROOT')) {
- define ('ROOT', '../');
- }
- if (!defined('WEBROOT_DIR')) {
- define ('WEBROOT_DIR', 'webroot');
- }
-/**
- * Path to the application's directory.
- */
- define ('CAKE', CORE_PATH.'cake'.DS);
-/**
- * Path to the application's directory.
- */
- define ('APP', ROOT.DS.APP_DIR.DS);
-/**
- * Path to the application's models directory.
- */
- define ('MODELS', APP.'models'.DS);
-/**
- * Path to the application's controllers directory.
- */
- define ('CONTROLLERS', APP.'controllers'.DS);
-/**
- * Path to the application's controllers directory.
- */
- define ('COMPONENTS', CONTROLLERS.'components'.DS);
-/**
- * Path to the application's views directory.
- */
- define ('VIEWS', APP.'views'.DS);
-/**
- * Path to the application's helpers directory.
- */
- define ('HELPERS', VIEWS.'helpers'.DS);
-/**
- * Path to the application's view's layouts directory.
- */
- define ('LAYOUTS', VIEWS.'layouts'.DS);
-/**
- * Path to the application's view's elements directory.
- * It's supposed to hold pieces of PHP/HTML that are used on multiple pages
- * and are not linked to a particular layout (like polls, footers and so on).
- */
- define ('ELEMENTS', VIEWS.'elements'.DS);
-/**
- * Path to the configuration files directory.
- */
- define ('CONFIGS', APP.'config'.DS);
-/**
- * Path to the libs directory.
- */
- define ('INFLECTIONS', CAKE.'config'.DS.'inflections'.DS);
-/**
- * Path to the libs directory.
- */
- define ('LIBS', CAKE.'libs'.DS);
-/**
- * Path to the public directory.
- */
- define ('CSS', WWW_ROOT.'css'.DS);
-/**
- * Path to the public directory.
- */
- define ('JS', WWW_ROOT.'js'.DS);
-/**
- * Path to the scripts direcotry.
- */
- define('SCRIPTS', CAKE.'scripts'.DS);
-/**
- * Path to the tests directory.
- */
- define ('TESTS', APP.'tests'.DS);
-/**
- * Path to the controller test directory.
- */
- define ('CONTROLLER_TESTS', TESTS.'cases'.DS.'controllers'.DS);
-/**
- * Path to the components test directory.
- */
- define ('COMPONENT_TESTS', TESTS.'cases'.DS.'components'.DS);
-/**
- * Path to the helpers test directory.
- */
- define ('HELPER_TESTS', TESTS.'cases'.DS.'views'.DS.'helpers'.DS);
-/**
- * Path to the models' test directory.
- */
- define ('MODEL_TESTS', TESTS.'cases'.DS.'models'.DS);
-/**
- * Path to the lib test directory.
- */
- define ('LIB_TESTS', TESTS.'lib'.DS);
-/**
- * Path to the temporary files directory.
- */
- define ('TMP', APP.'tmp'.DS);
-/**
- * Path to the logs directory.
- */
- define ('LOGS', TMP.'logs'.DS);
-/**
- * Path to the cache files directory. It can be shared between hosts in a multi-server setup.
- */
- define('CACHE', TMP.'cache'.DS);
-/**
- * Path to the vendors directory.
- */
- define ('VENDORS', CAKE_CORE_INCLUDE_PATH.DS.'vendors'.DS);
-/**
- * Path to the Pear directory
- * The purporse is to make it easy porting Pear libs into Cake
- * without setting the include_path PHP variable.
- */
- define ('PEAR', VENDORS.'Pear'.DS);
-/**
- * Full url prefix
- */
- $s = null;
- if (env('HTTPS')) {
- $s ='s';
- }
-
- $httpHost = env('HTTP_HOST');
-
- if (isset($httpHost)) {
- define('FULL_BASE_URL', 'http'.$s.'://'.$httpHost);
- }
- unset($httpHost, $s);
-/**
- * Web path to the public images directory.
- */
- define ('IMAGES_URL', 'img/');
-/**
- * Web path to the CSS files directory.
- */
- define ('CSS_URL', 'css/');
-/**
- * Web path to the js files directory.
- */
- define ('JS_URL', 'js/');
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/dispatcher.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/dispatcher.php
deleted file mode 100644
index c2325cf..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/dispatcher.php
+++ /dev/null
@@ -1,429 +0,0 @@
-<?php
-/* SVN FILE: $Id: dispatcher.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Dispatcher takes the URL information, parses it for paramters and
- * tells the involved controllers what to do.
- *
- * This is the heart of Cake's operation.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * List of helpers to include
- */
- uses('router', DS.'controller'.DS.'controller');
-/**
- * Dispatcher translates URLs to controller-action-paramter triads.
- *
- * Dispatches the request, creating appropriate models and controllers.
- *
- * @package cake
- * @subpackage cake.cake
- */
-class Dispatcher extends Object {
-/**
- * Base URL
- * @var string
- */
- var $base = false;
-/**
- * @var string
- */
- var $admin = false;
-/**
- * @var string
- */
- var $webservices = null;
-/**
- * @var string
- */
- var $plugin = null;
-/**
- * Constructor.
- */
- function __construct() {
- parent::__construct();
- }
-/**
- * Dispatches and invokes given URL, handing over control to the involved controllers, and then renders the results (if autoRender is set).
- *
- * If no controller of given name can be found, invoke() shows error messages in
- * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called
- * Actions).
- *
- * @param string $url URL information to work on.
- * @param array $additionalParams Settings array ("bare", "return"),
- * which is melded with the GET and POST params.
- * @return boolean Success
- */
- function dispatch($url, $additionalParams=array()) {
- $params = array_merge($this->parseParams($url), $additionalParams);
- $missingController = false;
- $missingAction = false;
- $missingView = false;
- $privateAction = false;
- $this->base = $this->baseUrl();
-
- if (empty($params['controller'])) {
- $missingController = true;
- } else {
- $ctrlName = Inflector::camelize($params['controller']);
- $ctrlClass = $ctrlName.'Controller';
-
- if (!loadController($ctrlName)) {
- $pluginName = Inflector::camelize($params['action']);
- if (!loadPluginController(Inflector::underscore($ctrlName), $pluginName)) {
- if (preg_match('/([\\.]+)/', $ctrlName)) {
- return $this->cakeError('error404', array(
- array('url' => strtolower($ctrlName),
- 'message' => 'Was not found on this server',
- 'base' => $this->base)));
- } elseif (!class_exists($ctrlClass)) {
- $missingController = true;
- } else {
- $params['plugin'] = null;
- $this->plugin = null;
- }
- } else {
- $params['plugin'] = Inflector::underscore($ctrlName);
- }
- } else {
- $params['plugin'] = null;
- $this->plugin = null;
- }
- }
-
- if (isset($params['plugin'])) {
- $plugin = $params['plugin'];
- $pluginName = Inflector::camelize($params['action']);
- $pluginClass = $pluginName.'Controller';
- $ctrlClass = $pluginClass;
- $oldAction = $params['action'];
- $params = $this->_restructureParams($params);
- $this->plugin = $plugin;
- loadPluginModels($plugin);
- $this->base = $this->base.'/'.Inflector::underscore($ctrlName);
-
- if (empty($params['controller']) || !class_exists($pluginClass)) {
- $params['controller'] = Inflector::underscore($ctrlName);
- $ctrlClass = $ctrlName.'Controller';
- if (!is_null($params['action'])) {
- array_unshift($params['pass'], $params['action']);
- }
- $params['action'] = $oldAction;
- }
- }
-
- if (empty($params['action'])) {
- $params['action'] = 'index';
- }
-
- if (defined('CAKE_ADMIN')) {
- if (isset($params[CAKE_ADMIN])) {
- $this->admin = '/'.CAKE_ADMIN ;
- $url = preg_replace('/'.CAKE_ADMIN.'(\/|$)/', '', $url);
- $params['action'] = CAKE_ADMIN.'_'.$params['action'];
- } elseif (strpos($params['action'], CAKE_ADMIN) === 0) {
- $privateAction = true;
- }
- }
-
- if ($missingController) {
- return $this->cakeError('missingController', array(
- array('className' => Inflector::camelize($params['controller']."Controller"),
- 'webroot' => $this->webroot,
- 'url' => $url,
- 'base' => $this->base)));
- } else {
- $controller =& new $ctrlClass();
- }
-
- $classMethods = get_class_methods($controller);
- $classVars = get_object_vars($controller);
-
- if ((in_array($params['action'], $classMethods) || in_array(strtolower($params['action']), $classMethods)) && strpos($params['action'], '_', 0) === 0) {
- $privateAction = true;
- }
-
- if (!in_array($params['action'], $classMethods) && !in_array(strtolower($params['action']), $classMethods)) {
- $missingAction = true;
- }
-
- if (in_array(strtolower($params['action']), array('object', 'tostring', 'requestaction', 'log',
- 'cakeerror', 'constructclasses', 'redirect',
- 'set', 'setaction', 'validate', 'validateerrors',
- 'render', 'referer', 'flash', 'flashout',
- 'generatefieldnames', 'postconditions', 'cleanupfields',
- 'beforefilter', 'beforerender', 'afterfilter'))) {
- $missingAction = true;
- }
-
- if (in_array('return', array_keys($params)) && $params['return'] == 1) {
- $controller->autoRender = false;
- }
-
- $controller->base = $this->base;
- $base = strip_plugin($this->base, $this->plugin);
- if (defined("BASE_URL")) {
- $controller->here = $base . $this->admin . $url;
- } else {
- $controller->here = $base . $this->admin . '/' . $url;
- }
- $controller->webroot = $this->webroot;
- $controller->params = $params;
- $controller->action = $params['action'];
-
- if (!empty($controller->params['data'])) {
- $controller->data =& $controller->params['data'];
- } else {
- $controller->data = null;
- }
-
- if (!empty($controller->params['pass'])) {
- $controller->passed_args =& $controller->params['pass'];
- $controller->passedArgs =& $controller->params['pass'];
- } else {
- $controller->passed_args = null;
- $controller->passedArgs = null;
- }
-
- if (!empty($params['bare'])) {
- $controller->autoLayout = !$params['bare'];
- } else {
- $controller->autoLayout = $controller->autoLayout;
- }
-
- $controller->webservices = $params['webservices'];
- $controller->plugin = $this->plugin;
-
- if (!is_null($controller->webservices)) {
- array_push($controller->components, $controller->webservices);
- array_push($controller->helpers, $controller->webservices);
- $component =& new Component($controller);
- }
- $controller->_initComponents();
- $controller->constructClasses();
-
- if ($missingAction && !in_array('scaffold', array_keys($classVars))) {
- $this->start($controller);
- return $this->cakeError('missingAction', array(
- array('className' => Inflector::camelize($params['controller']."Controller"),
- 'action' => $params['action'],
- 'webroot' => $this->webroot,
- 'url' => $url,
- 'base' => $this->base)));
- }
-
- if ($privateAction) {
- $this->start($controller);
- return $this->cakeError('privateAction', array(
- array('className' => Inflector::camelize($params['controller']."Controller"),
- 'action' => $params['action'],
- 'webroot' => $this->webroot,
- 'url' => $url,
- 'base' => $this->base)));
- }
- return $this->_invoke($controller, $params, $missingAction);
- }
-/**
- * Invokes given controller's render action if autoRender option is set. Otherwise the contents of the operation are returned as a string.
- *
- * @param object $controller
- * @param array $params
- * @param boolean $missingAction
- * @return string
- */
- function _invoke (&$controller, $params, $missingAction = false) {
- $this->start($controller);
- $classVars = get_object_vars($controller);
-
- if ($missingAction && in_array('scaffold', array_keys($classVars))) {
- uses(DS.'controller'.DS.'scaffold');
- return new Scaffold($controller, $params);
- } else {
- $output = call_user_func_array(array(&$controller, $params['action']), empty($params['pass'])? array(): $params['pass']);
- }
- if ($controller->autoRender) {
- $output = $controller->render();
- }
- $controller->output =& $output;
- $controller->afterFilter();
- return $controller->output;
- }
-/**
- * Starts up a controller
- *
- * @param object $controller
- */
- function start(&$controller) {
- if (!empty($controller->beforeFilter)) {
- if (is_array($controller->beforeFilter)) {
-
- foreach ($controller->beforeFilter as $filter) {
- if (is_callable(array($controller,$filter)) && $filter != 'beforeFilter') {
- $controller->$filter();
- }
- }
- } else {
- if (is_callable(array($controller, $controller->beforeFilter)) && $controller->beforeFilter != 'beforeFilter') {
- $controller->{$controller->beforeFilter}();
- }
- }
- }
- $controller->beforeFilter();
-
- foreach ($controller->components as $c) {
- $path = preg_split('/\/|\./', $c);
- $c = $path[count($path) - 1];
- if (isset($controller->{$c}) && is_object($controller->{$c}) && is_callable(array($controller->{$c}, 'startup'))) {
- $controller->{$c}->startup($controller);
- }
- }
- }
-
-/**
- * Returns array of GET and POST parameters. GET parameters are taken from given URL.
- *
- * @param string $from_url URL to mine for parameter information.
- * @return array Parameters found in POST and GET.
- */
- function parseParams($from_url) {
- $Route = new Router();
- include CONFIGS.'routes.php';
- $params = $Route->parse ($from_url);
-
- if (ini_get('magic_quotes_gpc') == 1) {
- if (!empty($_POST)) {
- $params['form'] = stripslashes_deep($_POST);
- }
- } else {
- $params['form'] = $_POST;
- }
-
- if (isset($params['form']['data'])) {
- $params['data'] = $Route->stripEscape($params['form']['data']);
- }
-
- if (isset($_GET)) {
- if (ini_get('magic_quotes_gpc') == 1) {
- $params['url'] = stripslashes_deep($_GET);
- } else {
- $params['url'] = $_GET;
- }
- }
-
- foreach ($_FILES as $name => $data) {
- if ($name != 'data') {
- $params['form'][$name] = $data;
- }
- }
-
- if (isset($_FILES['data'])) {
- foreach ($_FILES['data'] as $key => $data) {
-
- foreach ($data as $model => $fields) {
-
- foreach ($fields as $field => $value) {
- $params['data'][$model][$field][$key] = $value;
- }
- }
- }
- }
- $params['bare'] = empty($params['ajax'])? (empty($params['bare'])? 0: 1): 1;
- $params['webservices'] = empty($params['webservices']) ? null : $params['webservices'];
- return $params;
- }
-/**
- * Returns a base URL.
- *
- * @return string Base URL
- */
- function baseUrl() {
- $htaccess = null;
- $base = $this->admin;
- $this->webroot = '';
-
- if (defined('BASE_URL')) {
- $base = BASE_URL.$this->admin;
- }
-
- $docRoot = env('DOCUMENT_ROOT');
- $scriptName = env('PHP_SELF');
- $r = null;
- $appDirName = str_replace('/', '\/', preg_quote(APP_DIR));
- $webrootDirName = str_replace('/', '\/', preg_quote(WEBROOT_DIR));
-
- if (preg_match('/'.$appDirName.'\\'.DS.$webrootDirName.'/', $docRoot)) {
- $this->webroot = '/';
-
- if (preg_match('/^(.*)\/index\.php$/', $scriptName, $r)) {
-
- if (!empty($r[1])) {
- return $base.$r[1];
- }
- }
- } else {
- if (defined('BASE_URL')) {
- $webroot = setUri();
- $htaccess = preg_replace('/(?:'.APP_DIR.'\\/(.*)|index\\.php(.*))/i', '', $webroot).APP_DIR.'/'.$webrootDirName.'/';
- }
-
- if (preg_match('/^(.*)\\/'.$appDirName.'\\/'.$webrootDirName.'\\/index\\.php$/', $scriptName, $regs)) {
-
- if (APP_DIR === 'app') {
- $appDir = null;
- } else {
- $appDir = '/'.APP_DIR;
- }
- !empty($htaccess)? $this->webroot = $htaccess : $this->webroot = $regs[1].$appDir.'/';
- return $base.$regs[1].$appDir;
-
- } elseif (preg_match('/^(.*)\\/'.$webrootDirName.'([^\/i]*)|index\\\.php$/', $scriptName, $regs)) {
- !empty($htaccess)? $this->webroot = $htaccess : $this->webroot = $regs[0].'/';
- return $base.$regs[0];
-
- } else {
- !empty($htaccess)? $this->webroot = $htaccess : $this->webroot = '/';
- return $base;
- }
- }
- return $base;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $params
- * @return unknown
- */
- function _restructureParams($params) {
- $params['controller'] = $params['action'];
-
- if (isset($params['pass'][0])) {
- $params['action'] = $params['pass'][0];
- array_shift($params['pass']);
- } else {
- $params['action'] = null;
- }
- return $params;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cache.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cache.php
deleted file mode 100644
index 9d59ef6..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cache.php
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-/* SVN FILE: $Id: cache.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Caching for Cake.
- *
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
- if (!class_exists('Model')) {
- uses(DS . 'model' . DS . 'model');
- }
-/**
- * Caching for Cake.
- *
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Cache extends Model{
-/**
- * Identifier. Either an MD5 string or NULL.
- *
- * @var string
- */
- var $id = null;
-/**
- * Content container for cache data.
- *
- * @var unknown_type
- */
- var $data = null;
-/**
- * Content to be cached.
- *
- * @var unknown_type
- */
- var $for_caching = null;
-/**
- * Name of the database table used for caching.
- *
- * @var string
- */
- var $useTable = 'cache';
-/**
- * Constructor. Generates an md5'ed id for internal use. Calls the constructor on Model as well.
- *
- * @param unknown_type $id
- */
- function __construct($id) {
- $this->id = (md5($id));
- parent::__construct($this->id);
- }
-/**
- * Returns this object's id after setting it. If called without parameters the current object's id is returned.
- *
- * @param unknown_type $id
- * @return unknown
- */
- function id($id = null) {
- if (!$id) {
- return $this->id;
- }
- return ($this->id = $id);
- }
-/**
- * Store given content in cache database.
- *
- * @param string $content Content to keep in cache.
- * @param int $keep_for Number of seconds to keep data in cache.
- * @return boolean Success
- */
- function remember($content, $keep_for = CACHE_PAGES_FOR) {
- $data = addslashes($this->for_caching . $content);
- $expire = date("Y-m-d H:i:s", time() + ($keep_for > 0 ? $keep_for : 999999999));
- return $this->query("REPLACE {$this->useTable} (id,data,expire) VALUES ('{$this->id}', '{$data}', '{$expire}')");
- }
-/**
- * Returns content from the Cache object itself, if the Cache object has a non-empty data property.
- * Else from the database cache.
- *
- * @return unknown
- */
- function restore() {
- if (empty($this->data['data'])) {
- return $this->find("id='{$this->id}' AND expire>NOW()");
- }
- return $this->data['data'];
- }
-/**
- * Returns true if the cache data property has current (non-stale) content for given id.
- *
- * @return boolean
- */
- function has() {
- return is_array($this->data = $this->find("id='{$this->id}' AND expire>NOW()"));
- }
-/**
- * Appends $string to the for_caching property of the Cache object.
- *
- * @param string $string
- */
- function append($string) {
- $this->for_caching .= $string;
- }
-/**
- * Clears the cache database table.
- *
- * @return unknown
- */
- function clear() {
- return $this->query("DELETE FROM {$this->useTable}");
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cake_log.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cake_log.php
deleted file mode 100644
index 7f6e7e0..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/cake_log.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/* SVN FILE: $Id: cake_log.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Logging.
- *
- * Log messages to text files.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
- if (!class_exists('File')) {
- uses('file');
- }
-/**
- * Logs messages to text files
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class CakeLog{
-/**
- * Writes given message to a log file in the logs directory.
- *
- * @param string $type Type of log, becomes part of the log's filename
- * @param string $msg Message to log
- * @return boolean Success
- */
- function write($type, $msg) {
- $filename = LOGS . $type . '.log';
- $output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $msg . "\n";
- $log = new File($filename);
- return $log->append($output);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/class_registry.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/class_registry.php
deleted file mode 100644
index 45b1822..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/class_registry.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/* SVN FILE: $Id: class_registry.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Class collections.
- *
- * A repository for class objects, each registered with a key.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.9.2
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Class Collections.
- *
- * A repository for class objects, each registered with a key.
- * If you try to add an object with the same key twice, nothing will come of it.
- * If you need a second instance of an object, give it another key.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class ClassRegistry{
-/**
- * Names of classes with their objects.
- *
- * @var array
- * @access private
- */
- var $_objects = array();
-/**
- * Return a singleton instance of the ClassRegistry.
- *
- * @return ClassRegistry instance
- */
- function &getInstance() {
- static $instance = array();
- if (!$instance) {
- $instance[0] = &new ClassRegistry;
- }
- return $instance[0];
- }
-/**
- * Add $object to the registry, associating it with the name $key.
- *
- * @param string $key
- * @param mixed $object
- */
- function addObject($key, &$object) {
- $_this =& ClassRegistry::getInstance();
- $key = Inflector::underscore($key);
- if (array_key_exists($key, $_this->_objects) === false) {
- $_this->_objects[$key] = &$object;
- }
- }
-/**
- * Remove object which corresponds to given key.
- *
- * @param string $key
- * @return void
- */
- function removeObject($key) {
- $_this =& ClassRegistry::getInstance();
- $key = Inflector::underscore($key);
- if (array_key_exists($key, $_this->_objects) === true) {
- unset($_this->_objects[$key]);
- }
- }
-/**
- * Returns true if given key is present in the ClassRegistry.
- *
- * @param string $key Key to look for
- * @return boolean Success
- */
- function isKeySet($key) {
- $_this =& ClassRegistry::getInstance();
- $key = Inflector::underscore($key);
- return array_key_exists($key, $_this->_objects);
- }
-/**
- * Get all keys from the regisrty.
- *
- * @return array
- */
- function keys() {
- $_this =& ClassRegistry::getInstance();
- return array_keys($_this->_objects);
- }
-/**
- * Return object which corresponds to given key.
- *
- * @param string $key
- * @return mixed
- */
- function &getObject($key) {
- $_this =& ClassRegistry::getInstance();
- $key = Inflector::underscore($key);
- return $_this->_objects[$key];
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/configure.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/configure.php
deleted file mode 100644
index 677db20..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/configure.php
+++ /dev/null
@@ -1,354 +0,0 @@
-<?php
-/* SVN FILE: $Id: configure.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 1.0.0.2363
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Configure extends Object {
-/**
- * Hold array with paths to view files
- *
- * @var array
- * @access public
- */
- var $viewPaths = array();
-/**
- * Hold array with paths to controller files
- *
- * @var array
- * @access public
- */
- var $controllerPaths = array();
-/**
- * Enter description here...
- *
- * @var array
- * @access public
- */
- var $modelPaths = array();
-/**
- * Enter description here...
- *
- * @var array
- * @access public
- */
- var $helperPaths = array();
-/**
- * Enter description here...
- *
- * @var array
- * @access public
- */
- var $componentPaths = array();
-/**
- * Enter description here...
- *
- * @var integer
- * @access public
- */
- var $debug = null;
-/**
- * Return a singleton instance of Configure.
- *
- * @return Configure instance
- * @access public
- */
- function &getInstance() {
- static $instance = array();
- if (!$instance) {
- $instance[0] =& new Configure;
- $instance[0]->__loadBootstrap();
- }
- return $instance[0];
- }
-/**
- * Used to write a dynamic var in the Configure instance.
- *
- * Usage
- * Configure::write('One.key1', 'value of the Configure::One[key1]');
- * Configure::write(array('One.key1' => 'value of the Configure::One[key1]'));
- * Configure::write('One', array('key1'=>'value of the Configure::One[key1]', 'key2'=>'value of the Configure::One[key2]');
- * Configure::write(array('One.key1' => 'value of the Configure::One[key1]', 'One.key2' => 'value of the Configure::One[key2]'));
- *
- * @param array $config
- * @return void
- * @access public
- */
- function write($config, $value = null) {
- $_this =& Configure::getInstance();
-
- if (!is_array($config) && $value !== null) {
- $name = $_this->__configVarNames($config);
-
- if (count($name) > 1) {
- $_this->{$name[0]}[$name[1]] = $value;
- } else {
- $_this->{$name[0]} = $value;
- }
- } else {
-
- foreach ($config as $names => $value) {
- $name = $_this->__configVarNames($names);
- if (count($name) > 1) {
- $_this->{$name[0]}[$name[1]] = $value;
- } else {
- $_this->{$name[0]} = $value;
- }
- }
- }
-
- if ($config == 'debug' || (is_array($config) && in_array('debug', $config))) {
- if ($_this->debug) {
- error_reporting(E_ALL);
-
- if (function_exists('ini_set')) {
- ini_set('display_errors', 1);
- }
- } else {
- error_reporting(0);
- }
- }
- }
-/**
- * Used to read Configure::$var
- *
- * Usage
- * Configure::read('Name'); will return all values for Name
- * Configure::read('Name.key'); will return only the value of Configure::Name[key]
- *
- * @param string $var
- * @return string value of Configure::$var
- * @access public
- */
- function read($var = 'debug') {
- $_this =& Configure::getInstance();
- if ($var === 'debug') {
- if (!isset($_this->debug)) {
- $_this->debug = DEBUG;
- }
- return $_this->debug;
- }
-
- $name = $_this->__configVarNames($var);
- if (count($name) > 1) {
- if (isset($_this->{$name[0]}[$name[1]])) {
- return $_this->{$name[0]}[$name[1]];
- }
- return null;
- } else {
- if (isset($_this->{$name[0]})) {
- return $_this->{$name[0]};
- }
- return null;
- }
- }
-/**
- * Used to delete a var from the Configure instance.
- *
- * Usage:
- * Configure::delete('Name'); will delete the entire Configure::Name
- * Configure::delete('Name.key'); will delete only the Configure::Name[key]
- *
- * @param string $var the var to be deleted
- * @return void
- * @access public
- */
- function delete($var = null) {
- $_this =& Configure::getInstance();
-
- $name = $_this->__configVarNames($var);
- if (count($name) > 1) {
- unset($_this->{$name[0]}[$name[1]]);
- } else {
- unset($_this->{$name[0]});
- }
- }
-/**
- * Will load a file from app/config/configure_file.php
- * variables in the files should be formated like:
- * $config['name'] = 'value';
- * These will be used to create dynamic Configure vars.
- *
- * Usage Configure::load('configure_file');
- *
- * @param string $fileName name of file to load, extension must be .php and only the name should be used, not the extenstion
- * @return Configure::write
- * @access public
- */
- function load($fileName) {
- $_this =& Configure::getInstance();
-
- if (!file_exists(CONFIGS . $fileName . '.php')) {
- trigger_error("Configure::load() - $fileName.php not found", E_USER_WARNING);
- return false;
- }
- include(CONFIGS . $fileName . '.php');
- if (!isset($config)) {
- trigger_error("Configure::load() - no variable \$config found in $fileName.php", E_USER_WARNING);
- return false;
- }
- return $_this->write($config);
- }
-
-/**
- * Used to determine the current version of CakePHP
- *
- * Usage Configure::version();
- *
- * @return string Current version of CakePHP
- * @access public
- */
- function version() {
- $_this =& Configure::getInstance();
- if (!isset($_this->Cake['version'])) {
- require(CORE_PATH . 'cake' . DS . 'config' . DS . 'config.php');
- $_this->write($config);
- }
- return $_this->Cake['version'];
- }
-/**
- * Checks $name for dot notation to create dynamic Configure::$var as an array when needed.
- *
- * @param mixed $name
- * @return array
- * @access private
- */
- function __configVarNames($name) {
- if (is_string($name)) {
- if (strpos($name, ".")) {
- $name = explode(".", $name);
- } else {
- $name = array($name);
- }
- }
- return $name;
- }
-/**
- * Sets the var modelPaths
- *
- * @param array $modelPaths
- * @access private
- */
- function __buildModelPaths($modelPaths) {
- $_this =& Configure::getInstance();
- $_this->modelPaths[] = MODELS;
- if (isset($modelPaths)) {
- foreach ($modelPaths as $value) {
- $_this->modelPaths[] = $value;
- }
- }
- }
-/**
- * Sets the var viewPaths
- *
- * @param array $viewPaths
- * @access private
- */
- function __buildViewPaths($viewPaths) {
- $_this =& Configure::getInstance();
- $_this->viewPaths[] = VIEWS;
- if (isset($viewPaths)) {
- foreach ($viewPaths as $value) {
- $_this->viewPaths[] = $value;
- }
- }
- }
-/**
- * Sets the var controllerPaths
- *
- * @param array $controllerPaths
- * @access private
- */
- function __buildControllerPaths($controllerPaths) {
- $_this =& Configure::getInstance();
- $_this->controllerPaths[] = CONTROLLERS;
- if (isset($controllerPaths)) {
- foreach ($controllerPaths as $value) {
- $_this->controllerPaths[] = $value;
- }
- }
- }
-/**
- * Sets the var helperPaths
- *
- * @param array $helperPaths
- * @access private
- */
- function __buildHelperPaths($helperPaths) {
- $_this =& Configure::getInstance();
- $_this->helperPaths[] = HELPERS;
- if (isset($helperPaths)) {
- foreach ($helperPaths as $value) {
- $_this->helperPaths[] = $value;
- }
- }
- }
-/**
- * Sets the var componentPaths
- *
- * @param array $componentPaths
- * @access private
- */
- function __buildComponentPaths($componentPaths) {
- $_this =& Configure::getInstance();
- $_this->componentPaths[] = COMPONENTS;
- if (isset($componentPaths)) {
- foreach ($componentPaths as $value) {
- $_this->componentPaths[] = $value;
- }
- }
- }
-/**
- * Loads the app/config/bootstrap.php
- * If the alternative paths are set in this file
- * they will be added to the paths vars
- *
- * @access private
- */
- function __loadBootstrap() {
- $_this =& Configure::getInstance();
- $_this->write('Session.checkAgent', true);
- $modelPaths = null;
- $viewPaths = null;
- $controllerPaths = null;
- $helperPaths = null;
- $componentPaths = null;
- require APP_PATH . 'config' . DS . 'bootstrap.php';
- $_this->__buildModelPaths($modelPaths);
- $_this->__buildViewPaths($viewPaths);
- $_this->__buildControllerPaths($controllerPaths);
- $_this->__buildHelperPaths($helperPaths);
- $_this->__buildComponentPaths($componentPaths);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/component.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/component.php
deleted file mode 100644
index d604269..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/component.php
+++ /dev/null
@@ -1,139 +0,0 @@
-<?php
-/* SVN FILE: $Id: component.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller
- * @since CakePHP(tm) v TBD
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Component
- *
- * Used to create instances of applications components
- *
- * @package cake
- * @subpackage cake.cake.libs.controller
- */
-class Component extends Object {
-/**
- * Instance Controller
- *
- * @var object
- * @access private
- */
- var $__controller = null;
-/**
- * Constructor
- */
- function __construct() {
- }
-/**
- * Used to initialize the components for current controller
- *
- * @param object $controller
- * @access public
- */
- function init(&$controller) {
- $this->__controller =& $controller;
-
- if ($this->__controller->components !== false) {
- $loaded = array();
- $this->__controller->components = array_merge(array('Session'), $this->__controller->components);
- $loaded = $this->__loadComponents($loaded, $this->__controller->components);
-
- foreach (array_keys($loaded)as $component) {
- $tempComponent =& $loaded[$component];
-
- if (isset($tempComponent->components) && is_array($tempComponent->components)) {
- foreach ($tempComponent->components as $subComponent) {
- $this->__controller->{$component}->{$subComponent} =& $loaded[$subComponent];
- }
- }
- if (is_callable(array($tempComponent, 'initialize'))) {
- $tempComponent->initialize($controller);
- }
- }
- }
- }
-
-/**
- * Enter description here...
- *
- * @param array $loaded
- * @param array $components
- * @return loaded components
- * @access private
- */
- function &__loadComponents(&$loaded, $components) {
- foreach ($components as $component) {
- $parts = preg_split('/\/|\./', $component);
-
- if (count($parts) === 1) {
- $plugin = $this->__controller->plugin;
- } else {
- $plugin = Inflector::underscore($parts['0']);
- $component = $parts[count($parts) - 1];
- }
-
- $componentCn = $component . 'Component';
-
- if (in_array($component, array_keys($loaded)) !== true) {
-
- if (!class_exists($componentCn)) {
-
- if (is_null($plugin) || !loadPluginComponent($plugin, $component)) {
-
- if (!loadComponent($component)) {
- $this->cakeError('missingComponentFile', array(array(
- 'className' => $this->__controller->name,
- 'component' => $component,
- 'file' => Inflector::underscore($component) . '.php',
- 'base' => $this->__controller->base)));
- exit();
- }
- }
-
- if (!class_exists($componentCn)) {
- $this->cakeError('missingComponentClass', array(array(
- 'className' => $this->__controller->name,
- 'component' => $component,
- 'file' => Inflector::underscore($component) . '.php',
- 'base' => $this->__controller->base)));
- exit();
- }
- }
-
- if ($componentCn == 'SessionComponent') {
- $param = strip_plugin($this->__controller->base, $this->__controller->plugin) . '/';
- } else {
- $param = null;
- }
- $this->__controller->{$component} =& new $componentCn($param);
- $loaded[$component] =& $this->__controller->{$component};
-
- if (isset($this->__controller->{$component}->components) && is_array($this->__controller->{$component}->components)) {
- $loaded =& $this->__loadComponents($loaded, $this->__controller->{$component}->components);
- }
- }
- }
- return $loaded;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl.php
deleted file mode 100644
index 1c2792a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl.php
+++ /dev/null
@@ -1,196 +0,0 @@
-<?php
-/* SVN FILE: $Id: acl.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Access Control List factory class.
- *
- * Permissions system.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Access Control List factory class.
- *
- * Looks for ACL implementation class in core config, and returns an instance of that class.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- */
-class AclComponent extends Object {
-/**
- * Instance of ACL_CLASSNAME set in app/config/core.php
- *
- * @var object
- */
- var $_instance = null;
-/**
- * Enter description here...
- *
- * @var boolean
- */
- var $controller = true;
-/**
- * Constructor.
- *
- * Will return an instance of the correct ACL class.
- */
- function __construct() {
- $this->getACL();
- }
-/**
- * Static function used to gain an instance of the correct ACL class.
- *
- * @return object instance of ACL_CLASSNAME set in app/config/core.php
- * @access public
- */
- function &getACL() {
- if ($this->_instance == null) {
- uses('controller' . DS . 'components' . DS . ACL_FILENAME);
- $classname = ACL_CLASSNAME;
- $this->_instance = new $classname;
- }
-
- if ($classname == 'DB_ACL') {
- $this->Aro = new Aro();
- $this->Aco = new Aco();
- }
- return $this->_instance;
- }
-/**
- * Empty class defintion, to be overridden in subclasses.
- *
- * @access public
- */
- function _initACL() {
- }
-/**
- * Pass-thru function for ACL check instance.
- *
- * @param string $aro
- * @param string $aco
- * @param string $action : default = *
- * @return boolean
- * @access public
- */
- function check($aro, $aco, $action = "*") {
- return $this->_instance->check($aro, $aco, $action);
- }
-/**
- * Pass-thru function for ACL allow instance.
- *
- * @param string $aro
- * @param string $aco
- * @param string $action : default = *
- * @return boolean
- * @access public
- */
- function allow($aro, $aco, $action = "*") {
- return $this->_instance->allow($aro, $aco, $action);
- }
-/**
- * Pass-thru function for ACL deny instance.
- *
- * @param string $aro
- * @param string $aco
- * @param string $action : default = *
- * @return boolean
- * @abstract public
- */
- function deny($aro, $aco, $action = "*") {
- return $this->_instance->deny($aro, $aco, $action);
- }
-/**
- * Pass-thru function for ACL inherit instance.
- *
- * @return boolean
- * @abstract public
- */
- function inherit($aro, $aco, $action = "*") {
- return $this->_instance->inherit($aro, $aco, $action);
- }
-/**
- * Pass-thru function for ACL grant instance.
- *
- * @param string $aro
- * @param string $aco
- * @param string $action : default = *
- * @return boolean
- * @access public
- */
- function grant($aro, $aco, $action = "*") {
- return $this->_instance->grant($aro, $aco, $action);
- }
-/**
- * Pass-thru function for ACL grant instance.
- *
- * @param string $aro
- * @param string $aco
- * @param string $action : default = *
- * @return boolean
- * @access public
- */
- function revoke($aro, $aco, $action = "*") {
- return $this->_instance->revoke($aro, $aco, $action);
- }
-/**
- * Sets the current ARO instance to object from getAro
- *
- * @param string $id
- * @return boolean
- * @access public
- */
- function setAro($id) {
- return $this->Aro = $this->_instance->getAro($id);
- }
-/**
-* Sets the current ACO instance to object from getAco
- *
- * @param string $id
- * @return boolean
- * @access public
- */
- function setAco($id) {
- return $this->Aco = $this->_instance->getAco($id);
- }
-/**
- * Pass-thru function for ACL getAro instance
- * that gets an ARO object from the given id or alias
- *
- * @param string $id
- * @return object Aro
- * @access public
- */
- function getAro($id) {
- return $this->_instance->getAro($id);
- }
-/**
- * Pass-thru function for ACL getAco instance.
- * that gets an ACO object from the given id or alias
- *
- * @param string $id
- * @return object Aco
- * @access public
- */
- function getAco($id) {
- return $this->_instance->getAco($id);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl_base.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl_base.php
deleted file mode 100644
index 82e162a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/acl_base.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/* SVN FILE: $Id: acl_base.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Access Control List abstract class.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Access Control List abstract class. Not to be instantiated.
- * Subclasses of this class are used by AclComponent to perform ACL checks in Cake.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- * @abstract
- */
-class AclBase extends Object {
-/**
- * This class should never be instantiated, just subclassed.
- *
- * No instantiations or constructor calls (even statically)
- *
- * @return AclBase
- * @abstract
- */
- function __construct() {
- if (strcasecmp(get_class($this), "AclBase") == 0 || !is_subclass_of($this, "AclBase")) {
- trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
- return null;
- }
- }
-/**
- * Empty method to be overridden in subclasses
- *
- * @param string $aro
- * @param string $aco
- * @param string $action
- * @abstract
- */
- function check($aro, $aco, $action = "*") {
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/db_acl.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/db_acl.php
deleted file mode 100644
index f575a2a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/db_acl.php
+++ /dev/null
@@ -1,310 +0,0 @@
-<?php
-/* SVN FILE: $Id: db_acl.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.componenets.dbacl
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-if (!defined('ACL_DATABASE')) {
- define('ACL_DATABASE', 'default');
-}
-uses('controller' . DS . 'components' . DS . 'acl_base');
-uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aclnode');
-uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aco');
-uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'acoaction');
-uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aro');
-uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aros_aco');
-/**
- * In this file you can extend the AclBase.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl
- */
-class DB_ACL extends AclBase {
-/**
- * Enter description here...
- *
- */
- function __construct() {
- }
-/**
- * Enter description here...
- *
- * @param string $aro
- * @param string $aco
- * @param string $action
- * @return boolean
- * @access public
- */
- function check($aro, $aco, $action = "*") {
- $Perms = new ArosAco();
- $Aro = new Aro();
- $Aco = new Aco();
-
- if ($aro == null || $aco == null) {
- return false;
- }
-
- $permKeys = $this->_getAcoKeys($Perms->loadInfo());
- $aroPath = $Aro->getPath($aro);
- $tmpAcoPath = $Aco->getPath($aco);
-
- if ($tmpAcoPath === null) {
- return false;
- }
- $tmpAcoPath = array_reverse($tmpAcoPath);
- $acoPath = array();
-
- if ($action != '*' && !in_array('_' . $action, $permKeys)) {
- trigger_error('ACO permissions key "' . $action . '" does not exist in DB_ACL::check()', E_USER_NOTICE);
- return false;
- }
-
- foreach ($tmpAcoPath as $a) {
- $acoPath[] = $a['Aco']['id'];
- }
-
- for ($i = count($aroPath) - 1; $i >= 0; $i--) {
- $perms = $Perms->findAll(array('ArosAco.aro_id' => $aroPath[$i]['Aro']['id'],
- 'ArosAco.aco_id' => $acoPath), null,
- 'Aco.lft desc');
- if ($perms == null || count($perms) == 0) {
- continue;
- } else {
- foreach ($perms as $perm) {
- if ($action == '*') {
- // ARO must be cleared for ALL ACO actions
- foreach ($permKeys as $key) {
- if (isset($perm['ArosAco'])) {
- if ($perm['ArosAco'][$key] != 1) {
- return false;
- }
- }
- }
- return true;
-
- } else {
- switch($perm['ArosAco']['_' . $action]) {
- case -1:
- return false;
- case 0:
- continue;
- break;
- case 1:
- return true;
- break;
- }
- }
- }
- }
- }
- return false;
- }
-/**
- * Enter description here...
- *
- * @param string $aro
- * @param string $aco
- * @param string $action
- * @param integer $value
- * @return boolean
- * @access public
- */
- function allow($aro, $aco, $action = "*", $value = 1) {
- $Perms = new ArosAco();
- $perms = $this->getAclLink($aro, $aco);
- $permKeys = $this->_getAcoKeys($Perms->loadInfo());
- $save = array();
-
- if ($perms == false) {
- trigger_error('DB_ACL::allow() - Invalid node', E_USER_WARNING);
- return false;
- }
-
- if (isset($perms[0])) {
- $save = $perms[0]['ArosAco'];
- }
-
- if ($action == "*") {
- $permKeys = $this->_getAcoKeys($Perms->loadInfo());
-
- foreach ($permKeys as $key) {
- $save[$key] = $value;
- }
- } else {
- if (in_array('_' . $action, $permKeys)) {
- $save['_' . $action] = $value;
- } else {
- trigger_error('DB_ACL::allow() - Invalid ACO action', E_USER_WARNING);
- return false;
- }
- }
-
- $save['aro_id'] = $perms['aro'];
- $save['aco_id'] = $perms['aco'];
-
- if ($perms['link'] != null && count($perms['link']) > 0) {
- $save['id'] = $perms['link'][0]['ArosAco']['id'];
- }
- return $Perms->save(array('ArosAco' => $save));
- }
-/**
- * Enter description here...
- *
- * @param string $aro
- * @param string $aco
- * @param string $action
- * @return boolean
- * @access public
- */
- function deny($aro, $aco, $action = "*") {
- return $this->allow($aro, $aco, $action, -1);
- }
-/**
- * Enter description here...
- *
- * @param string $aro
- * @param string $aco
- * @param string $action
- * @return boolean
- * @access public
- */
- function inherit($aro, $aco, $action = "*") {
- return $this->allow($aro, $aco, $action, 0);
- }
-/**
- * Enter description here...
- *
- * @param string $aro
- * @param string $aco
- * @param string $action
- * @return boolean
- * @access public
- */
- function grant($aro, $aco, $action = "*") {
- return $this->allow($aro, $aco, $action);
- }
-/**
- * Enter description here...
- *
- * @param string $aro
- * @param string $aco
- * @param string $action
- * @return boolean
- * @access public
- */
- function revoke($aro, $aco, $action = "*") {
- return $this->deny($aro, $aco, $action);
- }
-/**
- * Get an ARO object from the given id or alias
- *
- * @param mixed $id
- * @return object Aro
- * @access public
- */
- function getAro($id = null) {
- return $this->__getObject($id, 'Aro');
- }
-/**
- * Get an ACO object from the given id or alias
- *
- * @param mixed $id
- * @return object Aco
- * @access public
- */
- function getAco($id = null) {
- return $this->__getObject($id, 'Aco');
- }
- function __getObject($id = null, $object) {
- if ($id == null) {
- trigger_error('Null id provided in DB_ACL::get' . $object, E_USER_WARNING);
- return null;
- }
-
- $obj = new $object;
-
- if (is_numeric($id)) {
- $key = 'foreign_key';
- if ($object == 'Aco') {
- $key = 'object_id';
- }
-
- $conditions = array($object . '.' . $key => $id);
- } else {
- $conditions = array($object . '.alias' => $id);
- }
-
- $tmp = $obj->find($conditions);
- $obj->id = $tmp[$object]['id'];
- return $obj;
- }
-/**
- * Get an array of access-control links between the given Aro and Aco
- *
- * @param mixed $aro
- * @param mixed $aco
- * @return array
- * @access public
- */
- function getAclLink($aro, $aco) {
- $Aro = new Aro();
- $Aco = new Aco();
- $Link = new ArosAco();
-
- $obj = array();
- $obj['Aro'] = $Aro->find($Aro->_resolveID($aro));
- $obj['Aco'] = $Aco->find($Aco->_resolveID($aco));
- $obj['Aro'] = $obj['Aro']['Aro'];
- $obj['Aco'] = $obj['Aco']['Aco'];
-
- if ($obj['Aro'] == null || count($obj['Aro']) == 0 || $obj['Aco'] == null || count($obj['Aco']) == 0) {
- return false;
- }
- return array('aro' => $obj['Aro']['id'],
- 'aco' => $obj['Aco']['id'],
- 'link' => $Link->findAll(array(
- 'ArosAco.aro_id' => $obj['Aro']['id'],
- 'ArosAco.aco_id' => $obj['Aco']['id'])));
- }
-/**
- * Enter description here...
- *
- * @param object $keys
- * @return array
- * @access protected
- */
- function _getAcoKeys($keys) {
- $newKeys = array();
- $keys = $keys->value;
-
- foreach ($keys as $key) {
- if ($key['name'] != 'id' && $key['name'] != 'aro_id' && $key['name'] != 'aco_id') {
- $newKeys[] = $key['name'];
- }
- }
- return $newKeys;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aclnode.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aclnode.php
deleted file mode 100644
index 6ea9753..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aclnode.php
+++ /dev/null
@@ -1,309 +0,0 @@
-<?php
-/* SVN FILE: $Id: aclnode.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Load AppModel class
- */
-loadModel();
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- *
- */
-class AclNode extends AppModel {
-/**
- * Database configuration to use
- *
- * @var string
- */
- var $useDbConfig = ACL_DATABASE;
-/**
- * Cache Queries
- *
- * @var boolean
- */
- var $cacheQueries = false;
-/**
- * Creates a new ARO/ACO node
- *
- * @param int $linkId
- * @param mixed $parentId
- * @param string $alias
- * @return boolean True on success, false on fail
- * @access public
- */
- function create($linkId = 0, $parentId = null, $alias = '') {
- parent::create();
- if (strtolower(get_class($this)) == "aclnode") {
- trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
- return null;
- }
- extract ($this->__dataVars());
-
- if ($parentId == null || $parentId === 0) {
- $parent = $this->find(null, 'MAX(rght) as rght', null, -1);
- $parent['lft'] = $parent[0]['rght'];
-
- if ($parent[0]['rght'] == null || !$parent[0]['rght']) {
- $parent['lft'] = 0;
- }
- } else {
- $parent = $this->find($this->_resolveID($parentId), null, null, 0);
- if ($parent == null || count($parent) == 0) {
- trigger_error("Null parent in {$class}::create()", E_USER_WARNING);
- return null;
- }
- $parent = $parent[$class];
- $this->_syncTable(1, $parent['lft'], $parent['lft']);
- }
- $return = $this->save(array($class => array($secondary_id => $linkId,
- 'alias' => $alias,
- 'lft' => $parent['lft'] + 1,
- 'rght' => $parent['lft'] + 2)));
- $this->id = $this->getLastInsertID();
- return $return;
- }
-/**
- * Get the ARO/ACO ID with the given alias
- *
- * @param mixed $alias The alias of an ARO/ACO node
- * @return mixed The ID of an ARO/ACO node, or false if not found.
- * @access public
- */
- function id($alias) {
- extract($this->__dataVars());
- return $this->find(array($this->name . '.alias' => $alias), array($secondary_id), null, -1);
- }
-/**
- * Deletes the ARO/ACO node with the given ID
- *
- * @param mixed $id The id or alias of an ARO/ACO node
- * @return boolean True on success, false on fail
- * @access public
- */
- function delete($id) {
- extract ($this->__dataVars());
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- $result = $this->find($this->_resolveID($id));
- $object = $result[$class];
- if ($object == null || count($object) == 0) {
- return false;
- }
-
- $children = $this->findAll(array("{$class}.rght" => "< {$result[$class]['rght']}", "{$class}.lft" => "> {$result[$class]['lft']}"), 'id', null, null, null, -1);
- $idList = Set::extract($children, '{n}.' . $class . '.id');
- $idList[] = $result[$class]['id'];
-
- $this->ArosAco->query('DELETE FROM ' . $db->fullTableName($this->ArosAco) . " WHERE {$class}_id in (" . implode(', ', $idList) . ')');
-
- $table = $db->fullTableName($this);
- $this->query("DELETE FROM {$table} WHERE {$table}.lft >= {$result[$class]['lft']} AND {$table}.rght <= {$result[$class]['rght']}");
-
- $shift = 1 + $result[$class]['rght'] - $result[$class]['lft'];
- $this->query('UPDATE ' . $table . ' SET ' . $db->name('rght') . ' = ' . $db->name('rght') . ' - ' . $shift . ' WHERE ' . $db->name('rght') . ' > ' . $result[$class]['rght']);
- $this->query('UPDATE ' . $table . ' SET ' . $db->name('lft') . ' = ' . $db->name('lft') . ' - ' . $shift . ' WHERE ' . $db->name('lft') . ' > ' . $result[$class]['lft']);
- return true;
- }
-/**
- * Sets the parent of the given node
- *
- * @param mixed $parentId
- * @param mixed $id
- * @return boolean True on success, false on failure
- * @access public
- */
- function setParent($parentId = null, $id = null) {
- if (strtolower(get_class($this)) == "aclnode") {
- trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
- return null;
- }
- extract ($this->__dataVars());
-
- if ($id == null && $this->id == false) {
- return false;
- } elseif ($id == null) {
- $id = $this->id;
- }
- $object = $this->find($this->_resolveID($id), null, null, 0);
-
- if ($object == null || count($object) == 0) {
- return false;
- }
- $object = $object[$class];
- $parent = $this->getParent($id);
-
- if (($parent == null && $parentId == null) || ($parentId == $parent[$class][$secondary_id] && $parentId != null) || ($parentId == $parent[$class]['alias'] && $parentId != null)) {
- return false;
- }
-
- if ($parentId == null) {
- $newParent = $this->find(null, 'MAX(rght) as lft', null, -1);
- $newParent = $newParent[0];
- $newParent['rght'] = $newParent['lft'];
- } else {
- $newParent = $this->find($this->_resolveID($parentId), null, null, 0);
- $newParent = $newParent[$class];
- }
-
- if ($parentId != null && $newParent['lft'] <= $object['lft'] && $newParent['rght'] >= $object['rght']) {
- return false;
- }
- $this->_syncTable(0, $object['lft'], $object['lft']);
-
- if ($object['lft'] < $newParent['lft']) {
- $newParent['lft'] = $newParent['lft'] - 2;
- $newParent['rght'] = $newParent['rght'] - 2;
- }
-
- if ($parentId != null) {
- $this->_syncTable(1, $newParent['lft'], $newParent['lft']);
- }
- $object['lft'] = $newParent['lft'] + 1;
- $object['rght'] = $newParent['lft'] + 2;
- $this->save(array($class => $object));
-
- if ($newParent['lft'] == 0) {
- $this->_syncTable(2, $newParent['lft'], $newParent['lft']);
- }
- return true;
- }
-/**
- * Get the parent node of the given Aro or Aco
- *
- * @param moxed $id
- * @return array
- * @access public
- */
- function getParent($id) {
- $path = $this->getPath($id);
- if ($path == null || count($path) < 2) {
- return null;
- } else {
- return $path[count($path) - 2];
- }
- }
-/**
- * Gets the path to the given Aro or Aco
- *
- * @param mixed $id
- * @return array
- * @access public
- */
- function getPath($id) {
- if (strtolower(get_class($this)) == "aclnode") {
- trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
- return null;
- }
- extract ($this->__dataVars());
- $item = $this->find($this->_resolveID($id), null, null, 0);
-
- if ($item == null || count($item) == 0) {
- return null;
- }
- return $this->findAll(array($class . '.lft' => '<= ' . $item[$class]['lft'], $class . '.rght' => '>= ' . $item[$class]['rght']), null, array($class . '.lft' => 'ASC'), null, null, 0);
- }
-/**
- * Get the child nodes of the given Aro or Aco
- *
- * @param mixed $id
- * @return array
- * @access public
- */
- function getChildren($id) {
- if (strtolower(get_class($this)) == "aclnode") {
- trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
- return null;
- }
-
- extract ($this->__dataVars());
- $item = $this->find($this->_resolveID($id), null, null, 0);
- return $this->findAll(array($class . '.lft' => '> ' . $item[$class]['lft'], $class . '.rght' => '< ' . $item[$class]['rght']), null, null, null, null, null, 0);
- }
-/**
- * Gets a conditions array to find an Aro or Aco, based on the given id or alias
- *
- * @param mixed $id
- * @return array Conditions array for a find/findAll call
- * @access public
- */
- function _resolveID($id) {
- extract($this->__dataVars());
- $key = (is_numeric($id) ? $secondary_id : 'alias');
- return array($this->name . '.' . $key => $id);
- }
-/**
- * Shifts the left and right values of the aro/aco tables
- * when a node is added or removed
- *
- * @param unknown_type $dir
- * @param unknown_type $lft
- * @param unknown_type $rght
- * @access protected
- */
- function _syncTable($dir, $lft, $rght) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- if ($dir == 2) {
- $shift = 1;
- $dir = '+';
- } else {
- $shift = 2;
-
- if ($dir > 0) {
- $dir = '+';
- } else {
- $dir = '-';
- }
- }
- $db->query('UPDATE ' . $db->fullTableName($this) . ' SET ' . $db->name('rght') . ' = ' . $db->name('rght') . ' ' . $dir . ' ' . $shift . ' WHERE ' . $db->name('rght') . ' > ' . $rght);
- $db->query('UPDATE ' . $db->fullTableName($this) . ' SET ' . $db->name('lft') . ' = ' . $db->name('lft') . ' ' . $dir . ' ' . $shift . ' WHERE ' . $db->name('lft') . ' > ' . $lft);
- }
-/**
- * Infers data based on the currently-intantiated subclass.
- *
- * @return array
- * @access private
- */
- function __dataVars() {
- $vars = array();
- $class = strtolower(get_class($this));
- if ($class == 'aro') {
- $vars['secondary_id'] = 'foreign_key';
- } else {
- $vars['secondary_id'] = 'object_id';
- }
- $vars['class'] = ucwords($class);
- return $vars;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aco.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aco.php
deleted file mode 100644
index 988f8b1..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aco.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/* SVN FILE: $Id: aco.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- *
- */
-class Aco extends AclNode{
-/**
- * Model name
- *
- * @var string
- */
- var $name = 'Aco';
-/**
- * Has many association
- *
- * @var array
- */
- var $hasMany = array('ArosAco');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/acoaction.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/acoaction.php
deleted file mode 100644
index 5e33b80..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/acoaction.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/* SVN FILE: $Id: acoaction.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description.
- */
-loadModel();
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- *
- */
-class AcoAction extends AppModel {
-/**
- * Model name
- *
- * @var string
- */
- var $name = 'AcoAction';
-/**
- * Belongs to association
- *
- * @var string
- */
- var $belongsTo = 'Aco';
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aro.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aro.php
deleted file mode 100644
index 1db67eb..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aro.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/* SVN FILE: $Id: aro.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- *
- */
-class Aro extends AclNode {
-/**
- * Model name
- *
- * @var string
- */
- var $name = 'Aro';
-/**
- * Has many association
- *
- * @var array
- */
- var $hasMany = array('ArosAco');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aros_aco.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aros_aco.php
deleted file mode 100644
index dade2cc..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/dbacl/models/aros_aco.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/* SVN FILE: $Id: aros_aco.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components.dbacl.models
- */
-class ArosAco extends AppModel {
-/**
- * Cache Queries
- *
- * @var boolean
- */
- var $cacheQueries = false;
-/**
- * Model name
- *
- * @var string
- */
- var $name = 'ArosAco';
-/**
- * Table this model uses
- *
- * @var string
- */
- var $useTable = 'aros_acos';
-/**
- * Belongs to association
- *
- * @var array
- */
- var $belongsTo = array('Aro', 'Aco');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/iniacl/ini_acl.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/iniacl/ini_acl.php
deleted file mode 100644
index e99de6f..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/iniacl/ini_acl.php
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-/* SVN FILE: $Id: ini_acl.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.componenets.iniacl
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * load AclBase
- */
-uses('controller/components/acl_base');
-/**
- * In this file you can extend the AclBase.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.componenets.iniacl
- */
-class INI_ACL extends AclBase {
-/**
- * Array with configuration, parsed from ini file
- *
- * @var array
- */
- var $config = null;
-/**
- * Constructor
- *
- */
- function __construct() {
- }
-
-/**
- * Main ACL check function. Checks to see if the ARO (access request object) has access to the ACO (access control object).
- * Looks at the acl.ini.php file for permissions (see instructions in/config/acl.ini.php).
- *
- * @param string $aro
- * @param string $aco
- * @return boolean
- * @access public
- */
- function check($aro, $aco, $acoAction = null) {
- if ($this->config == null) {
- $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php');
- }
- $aclConfig = $this->config;
-
- //First, if the user is specifically denied, then DENY
- if (isset($aclConfig[$aro]['deny'])) {
- $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny']));
-
- if (array_search($aco, $userDenies)) {
- //echo "User Denied!";
- return false;
- }
- }
-
- //Second, if the user is specifically allowed, then ALLOW
- if (isset($aclConfig[$aro]['allow'])) {
- $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow']));
-
- if (array_search($aco, $userAllows)) {
- //echo "User Allowed!";
- return true;
- }
- }
-
- //Check group permissions
- if (isset($aclConfig[$aro]['groups'])) {
- $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
-
- foreach ($userGroups as $group) {
- //If such a group exists,
- if (array_key_exists($group, $aclConfig)) {
- //If the group is specifically denied, then DENY
- if (isset($aclConfig[$group]['deny'])) {
- $groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
-
- if (array_search($aco, $groupDenies)) {
- //echo("Group Denied!");
- return false;
- }
- }
-
- //If the group is specifically allowed, then ALLOW
- if (isset($aclConfig[$group]['allow'])) {
- $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
-
- if (array_search($aco, $groupAllows)) {
- //echo("Group Allowed!");
- return true;
- }
- }
- }
- }
- }
-
- //Default, DENY
- //echo("DEFAULT: DENY.");
- return false;
- }
-
-/**
- * Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly.
- *
- * @param string $fileName
- * @return array
- */
- function readConfigFile($fileName) {
- $fileLineArray = file($fileName);
-
- foreach ($fileLineArray as $fileLine) {
- $dataLine = trim($fileLine);
- $firstChar = substr($dataLine, 0, 1);
-
- if ($firstChar != ';' && $dataLine != '') {
- if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
- $sectionName = preg_replace('/[\[\]]/', '', $dataLine);
- } else {
- $delimiter = strpos($dataLine, '=');
-
- if ($delimiter > 0) {
- $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
- $value = trim(substr($dataLine, $delimiter + 1));
-
- if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
- $value = substr($value, 1, -1);
- }
-
- $iniSetting[$sectionName][$key]=stripcslashes($value);
- } else {
- if (!isset($sectionName)) {
- $sectionName = '';
- }
-
- $iniSetting[$sectionName][strtolower(trim($dataLine))]='';
- }
- }
- } else {
- }
- }
-
- return $iniSetting;
- }
-/**
- * Removes trailing spaces on all array elements (to prepare for searching)
- *
- * @param array $array Array to trim
- * @return array Trimmed array
- * @access public
- */
- function arrayTrim($array) {
- foreach ($array as $key => $value) {
- $array[$key] = trim($value);
- }
- array_unshift($array, "");
- return $array;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/request_handler.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/request_handler.php
deleted file mode 100644
index c307799..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/request_handler.php
+++ /dev/null
@@ -1,412 +0,0 @@
-<?php
-/* SVN FILE: $Id: request_handler.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Request object for handling alternative HTTP requests
- *
- * Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers, and the like.
- * These units have no use for Ajax requests, and this Component can tell how Cake should respond to the different
- * needs of a handheld computer and a desktop machine.
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- * @since CakePHP(tm) v 0.10.4.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-if (!defined('REQUEST_MOBILE_UA')) {
- define('REQUEST_MOBILE_UA',
- '(AvantGo|BlackBerry|DoCoMo|NetFront|Nokia|PalmOS|PalmSource|portalmmm|Plucker|ReqwirelessWeb|SonyEricsson|Symbian|UP\.Browser|Windows CE|Xiino)');
-}
-/**
- * Request object for handling alternative HTTP requests
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- *
- */
-class RequestHandlerComponent extends Object{
-/**
- * Enter description here...
- *
- * @var object
- * @access public
- */
- var $controller = true;
-/**
- * The layout that will be switched to for Ajax requests
- *
- * @var string
- * @access public
- * @see RequestHandler::setAjax()
- */
- var $ajaxLayout = 'ajax';
-/**
- * Determines whether or not callbacks will be fired on this component
- *
- * @var boolean
- * @access public
- */
- var $disableStartup = false;
-/**
- * Friendly content-type mappings used to set response types and determine
- * request types. Can be modified with RequestHandler::setContent()
- *
- * @var array
- * @access private
- * @see RequestHandlerComponent::setContent
- */
- var $__requestContent = array(
- 'js' => 'text/javascript',
- 'css' => 'text/css',
- 'html' => 'text/html',
- 'form' => 'application/x-www-form-urlencoded',
- 'file' => 'multipart/form-data',
- 'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
- 'xml' => array('application/xml', 'text/xml'),
- 'rss' => 'application/rss+xml',
- 'atom' => 'application/atom+xml'
- );
-/**
- * Content-types accepted by the client. If extension parsing is enabled in the
- * Router, and an extension is detected, the corresponding content-type will be
- * used as the overriding primary content-type accepted.
- *
- * @var array
- * @access private
- */
- var $__acceptTypes = array();
-/**
- * Constructor. Parses the accepted content types accepted by the client using
- * HTTP_ACCEPT
- *
- * @access public
- * @return void
- */
- function __construct() {
- $this->__acceptTypes = explode(',', env('HTTP_ACCEPT'));
-
- foreach ($this->__acceptTypes as $i => $type) {
- if (strpos($type, ';')) {
- $type = explode(';', $type);
- $this->__acceptTypes[$i] = $type[0];
- }
- }
- parent::__construct();
- }
-/**
- * Startup
- *
- * @param object A reference to the controller
- * @return null
- * @access public
- */
- function startup(&$controller) {
- if ($this->disableStartup) {
- return;
- }
- $this->setAjax($controller);
- }
-/**
- * Sets a controller's layout based on whether or not the current call is Ajax
- *
- * Add UTF-8 header for IE6 on XPsp2 bug if RequestHandlerComponent::isAjax()
- *
- * @param object The controller object
- * @return null
- * @access public
- */
- function setAjax(&$controller) {
- if ($this->isAjax()) {
- $controller->layout = $this->ajaxLayout;
- // Add UTF-8 header for IE6 on XPsp2 bug
- header ('Content-Type: text/html; charset=UTF-8');
- }
- }
-/**
- * Returns true if the current call is from Ajax, false otherwise
- *
- * @return bool True if call is Ajax
- * @access public
- */
- function isAjax() {
- if (env('HTTP_X_REQUESTED_WITH') != null) {
- return env('HTTP_X_REQUESTED_WITH') == "XMLHttpRequest";
- } else {
- return false;
- }
- }
-/**
- * Returns true if the current call accepts an XML response, false otherwise
- *
- * @return bool True if client accepts an XML response
- * @access public
- */
- function isXml() {
- return $this->accepts('xml');
- }
-/**
- * Returns true if the current call accepts an RSS response, false otherwise
- *
- * @return bool True if client accepts an RSS response
- * @access public
- */
- function isRss() {
- return $this->accepts('rss');
- }
-/**
- * Returns true if the current call accepts an RSS response, false otherwise
- *
- * @return bool True if client accepts an RSS response
- * @access public
- */
- function isAtom() {
- return $this->accepts('atom');
- }
-/**
- * Returns true if the current call a POST request
- *
- * @return bool True if call is a POST
- * @access public
- */
- function isPost() {
- return (strtolower(env('REQUEST_METHOD')) == 'post');
- }
-/**
- * Returns true if the current call a PUT request
- *
- * @return bool True if call is a PUT
- * @access public
- */
- function isPut() {
- return (strtolower(env('REQUEST_METHOD')) == 'put');
- }
-/**
- * Returns true if the current call a GET request
- *
- * @return bool True if call is a GET
- * @access public
- */
- function isGet() {
- return (strtolower(env('REQUEST_METHOD')) == 'get');
- }
-/**
- * Returns true if the current call a DELETE request
- *
- * @return bool True if call is a DELETE
- * @access public
- */
- function isDelete() {
- return (strtolower(env('REQUEST_METHOD')) == 'delete');
- }
-/**
- * Gets Prototype version if call is Ajax, otherwise empty string.
- * The Prototype library sets a special "Prototype version" HTTP header.
- *
- * @return string Prototype version of component making Ajax call
- * @access public
- */
- function getAjaxVersion() {
- if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
- return env('HTTP_X_PROTOTYPE_VERSION');
- }
- return false;
- }
-/**
- * Adds/sets the Content-type(s) for the given name
- *
- * @param string $name The name of the Content-type, i.e. "html", "xml", "css"
- * @param mixed $type The Content-type or array of Content-types assigned to the name
- * @return void
- * @access public
- */
- function setContent($name, $type) {
- $this->__requestContent[$name] = $type;
- }
-/**
- * Gets the server name from which this request was referred
- *
- * @return string Server address
- * @access public
- */
- function getReferrer() {
- if (env('HTTP_HOST') != null) {
- $sess_host = env('HTTP_HOST');
- }
-
- if (env('HTTP_X_FORWARDED_HOST') != null) {
- $sess_host = env('HTTP_X_FORWARDED_HOST');
- }
- return trim(preg_replace('/:.*/', '', $sess_host));
- }
-/**
- * Gets remote client IP
- *
- * @return string Client IP address
- * @access public
- */
- function getClientIP() {
- if (env('HTTP_X_FORWARDED_FOR') != null) {
- $ipaddr = preg_replace('/,.*/', '', env('HTTP_X_FORWARDED_FOR'));
- } else {
- if (env('HTTP_CLIENT_IP') != null) {
- $ipaddr = env('HTTP_CLIENT_IP');
- } else {
- $ipaddr = env('REMOTE_ADDR');
- }
- }
-
- if (env('HTTP_CLIENTADDRESS') != null) {
- $tmpipaddr = env('HTTP_CLIENTADDRESS');
-
- if (!empty($tmpipaddr)) {
- $ipaddr = preg_replace('/,.*/', '', $tmpipaddr);
- }
- }
- return trim($ipaddr);
- }
-/**
- * Returns true if user agent string matches a mobile web browser
- *
- * @return bool True if user agent is a mobile web browser
- * @access public
- */
- function isMobile() {
- return (preg_match('/' . REQUEST_MOBILE_UA . '/i', env('HTTP_USER_AGENT')) > 0);
- }
-/**
- * Strips extra whitespace from output
- *
- * @param string $str
- * @return string
- * @access public
- */
- function stripWhitespace($str) {
- $r = preg_replace('/[\n\r\t]+/', '', $str);
- return preg_replace('/\s{2,}/', ' ', $r);
- }
-/**
- * Strips image tags from output
- *
- * @param string $str
- * @return string
- * @access public
- */
- function stripImages($str) {
- $str = preg_replace('/(<a[^>]*>)(<img[^>]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5<br />', $str);
- $str = preg_replace('/(<img[^>]+alt=")([^"]*)("[^>]*>)/i', '$2<br />', $str);
- $str = preg_replace('/<img[^>]*>/i', '', $str);
- return $str;
- }
-/**
- * Strips scripts and stylesheets from output
- *
- * @param string $str
- * @return string
- * @access public
- */
- function stripScripts($str) {
- return preg_replace('/(<link[^>]+rel="[^"]*stylesheet"[^>]*>|<img[^>]*>|style="[^"]*")|<script[^>]*>.*?<\/script>|<style[^>]*>.*?<\/style>|<!--.*?-->/i', '', $str);
- }
-/**
- * Strips extra whitespace, images, scripts and stylesheets from output
- *
- * @param string $str
- * @return string
- * @access public
- */
- function stripAll($str) {
- $str = $this->stripWhitespace($str);
- $str = $this->stripImages($str);
- $str = $this->stripScripts($str);
- return $str;
- }
-/**
- * Strips the specified tags from output
- *
- * @return string
- * @access public
- */
- function stripTags() {
- $params = params(func_get_args());
- $str = $params[0];
-
- for ($i = 1; $i < count($params); $i++) {
- $str = preg_replace('/<' . $params[$i] . '[^>]*>/i', '', $str);
- $str = preg_replace('/<\/' . $params[$i] . '[^>]*>/i', '', $str);
- }
- return $str;
- }
-
-/**
- * Determines which content types the client accepts
- *
- * @param mixed $type Can be null (or no parameter), a string type name, or an
- * array of types
- * @return mixed If null or no parameter is passed, returns an array of content
- * types the client accepts. If a string is passed, returns true
- * if the client accepts it. If an array is passed, returns true
- * if the client accepts one or more elements in the array.
- * @access public
- */
- function accepts($type = null) {
- if ($type == null) {
- return $this->__acceptTypes;
- } elseif (is_array($type)) {
- foreach ($type as $t) {
- if ($this->accepts($t) == true) {
- return true;
- }
- }
- return false;
- } elseif (is_string($type)) {
- // If client only accepts */*, then assume default HTML browser
- if ($type == 'html' && $this->__acceptTypes === array('*/*')) {
- return true;
- }
-
- if (!in_array($type, array_keys($this->__requestContent))) {
- return false;
- }
-
- $content = $this->__requestContent[$type];
-
- if (is_array($content)) {
- foreach ($content as $c) {
- if (in_array($c, $this->__acceptTypes)) {
- return true;
- }
- }
- } else {
- if (in_array($content, $this->__acceptTypes)) {
- return true;
- }
- }
- }
- }
-/**
- * Determines which content types the client prefers
- *
- * @param mixed $type
- * @returns mixed
- * @access public
- */
- function prefers($type = null) {
- if ($type == null) {
- return $this->accepts(null);
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/security.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/security.php
deleted file mode 100644
index 52a8582..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/security.php
+++ /dev/null
@@ -1,202 +0,0 @@
-<?php
-/* SVN FILE: $Id: security.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- * @since CakePHP(tm) v 0.10.8.2156
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- */
-class SecurityComponent extends Object {
-/**
- * Holds an instance of the core Security object
- *
- * @var object Security
- * @access public
- */
- var $Security = null;
-/**
- * The controller method that will be called if this request is black-hole'd
- *
- * @var string
- * @access public
- */
- var $blackHoleCallback = null;
-/**
- * List of controller actions for which a POST request is required
- *
- * @var array
- * @access public
- * @see SecurityComponent::requirePost()
- */
- var $requirePost = array();
-/**
- * List of actions that require a valid authentication key
- *
- * @var array
- * @access public
- * @see SecurityComponent::requireAuth()
- */
- var $requireAuth = array();
-/**
- * Controllers from which actions of the current controller are allowed to receive
- * requests.
- *
- * @var array
- * @see SecurityComponent::requireAuth()
- */
- var $allowedControllers = array();
-/**
- * Actions from which actions of the current controller are allowed to receive
- * requests.
- *
- * @var array
- * @see SecurityComponent::requireAuth()
- */
- var $allowedActions = array();
-/**
- * Other components used by the Security component
- *
- * @var array
- * @access public
- */
- var $components = array('RequestHandler', 'Session');
-/**
- * Security class constructor
- */
- function __construct () {
- $this->Security = Security::getInstance();
- }
-/**
- * Component startup. All security checking happens here.
- *
- * @param object $controller
- * @return unknown
- * @access public
- */
- function startup(&$controller) {
- if (is_array($this->requirePost) && !empty($this->requirePost)) {
-
- if (in_array($controller->action, $this->requirePost)) {
-
- if (!$this->RequestHandler->isPost()) {
-
- if (!$this->blackHole($controller)) {
- return null;
- }
- }
- }
- }
-
- if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($controller->params['form'])) {
- if (in_array($controller->action, $this->requireAuth)) {
-
- if (!isset($controller->params['data']['_Token'])) {
-
- if (!$this->blackHole($controller)) {
- return null;
- }
- }
- $token = $controller->params['data']['_Token']['key'];
-
- if ($this->Session->check('_Token')) {
- $tData = $this->Session->read('_Token');
- if (!(intval($tData['expires']) > strtotime('now')) || $tData['key'] !== $token) {
-
- if (!$this->blackHole($controller)) {
- return null;
- }
- }
-
- if (!empty($tData['allowedControllers']) && !in_array($controller->params['controller'], $tData['allowedControllers']) ||!empty($tData['allowedActions']) && !in_array($controller->params['action'], $tData['allowedActions'])) {
- if (!$this->blackHole($controller)) {
- return null;
- }
- }
- } else {
- if (!$this->blackHole($controller)) {
- return null;
- }
- }
- }
- }
-
- if (!isset($controller->params['requested']) || $controller->params['requested'] != 1) {
- // Add auth key for new form posts
- $authKey = Security::generateAuthKey();
- $expires = strtotime('+'.Security::inactiveMins().' minutes');
- $token = array(
- 'key' => $authKey,
- 'expires' => $expires,
- 'allowedControllers' => $this->allowedControllers,
- 'allowedActions' => $this->allowedActions
- );
- if (!isset($controller->params['data'])) {
- $controller->params['data'] = array();
- }
- $controller->params['_Token'] = $token;
- $this->Session->write('_Token', $token);
- }
- }
-/**
- * Black-hole an invalid request with a 404 error or custom callback
- *
- * @param object $controller
- * @return callback in controller
- * @access public
- */
- function blackHole(&$controller) {
- if ($this->blackHoleCallback == null) {
- header('HTTP/1.0 404 Not Found');
- exit();
- } elseif (method_exists($controller, $this->blackHoleCallback)) {
- return $controller->{$this->blackHoleCallback}();
- }
- }
-/**
- * Sets the actions that require a POST request, or empty for all actions
- *
- * @access public
- * @return void
- */
- function requirePost() {
- $this->requirePost = func_get_args();
- }
-/**
- * Sets the actions that require an authenticated request, or empty for all actions
- *
- * @access public
- * @return void
- */
- function requireAuth() {
- $this->requireAuth = func_get_args();
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/session.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/session.php
deleted file mode 100644
index ce89ac9..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/components/session.php
+++ /dev/null
@@ -1,306 +0,0 @@
-<?php
-/* SVN FILE: $Id: session.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Session Component.
- *
- * Session handling from the controller.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller.components
- *
- */
-class SessionComponent extends CakeSession {
-/**
- * Used to determine if methods implementation is used, or bypassed
- *
- * @var boolean
- * @access private
- */
- var $__active = true;
-/**
- * Used to determine if Session has been started
- *
- * @var boolean
- * @access private
- */
- var $__started = false;
-/**
- * Used to determine if request are from an Ajax request
- *
- * @var boolean
- * @access private
- */
- var $__bare = 0;
-/**
- * Class constructor
- *
- * @param string $base The base path for the Session
- */
- function __construct($base = null) {
- if (!defined('AUTO_SESSION') || AUTO_SESSION === true) {
- parent::__construct($base);
- } else {
- $this->__active = false;
- }
- }
-/**
- * Initializes the component, gets a reference to Controller::$param['bare'].
- *
- * @param object $controller A reference to the controller
- * @access public
- */
- function initialize(&$controller) {
- if (isset($controller->params['bare'])) {
- $this->__bare = $controller->params['bare'];
- }
- }
-/**
- * Startup method.
- *
- * @param object $controller Instantiating controller
- * @access public
- */
- function startup(&$controller) {
- if ($this->__started === false && $this->__active === true) {
- $this->__start();
- }
- }
-/**
- * Starts Session on if 'Session.start' is set to false in core.php
- *
- * @param string $base The base path for the Session
- * @access public
- */
- function activate($base = null) {
- if ($this->__active === true) {
- return;
- }
- parent::__construct($base);
- $this->__active = true;
- }
-/**
- * Used to write a value to a session key.
- *
- * In your controller: $this->Session->write('Controller.sessKey', 'session value');
- *
- * @param string $name The name of the key your are setting in the session.
- * This should be in a Controller.key format for better organizing
- * @param string $value The value you want to store in a session.
- * @access public
- */
- function write($name, $value = null) {
- if ($this->__active === true) {
- $this->__start();
- if (is_array($name)) {
- foreach ($name as $key => $value) {
- if (parent::write($key, $value) === false) {
- return false;
- }
- }
- return true;
- }
- if (parent::write($name, $value) === false) {
- return false;
- }
- return true;
- }
- return false;
- }
-/**
- * Used to read a session values for a key or return values for all keys.
- *
- * In your controller: $this->Session->read('Controller.sessKey');
- * Calling the method without a param will return all session vars
- *
- * @param string $name the name of the session key you want to read
- * @return mixed value from the session vars
- * @access public
- */
- function read($name = null) {
- if ($this->__active === true) {
- $this->__start();
- return parent::read($name);
- }
- return false;
- }
-/**
- * Used to delete a session variable.
- *
- * In your controller: $this->Session->del('Controller.sessKey');
- *
- * @param string $name the name of the session key you want to delete
- * @return boolean true is session variable is set and can be deleted, false is variable was not set.
- * @access public
- */
- function del($name) {
- if ($this->__active === true) {
- $this->__start();
- return parent::del($name);
- }
- return false;
- }
-/**
- * Wrapper for SessionComponent::del();
- *
- * In your controller: $this->Session->delete('Controller.sessKey');
- *
- * @param string $name the name of the session key you want to delete
- * @return boolean true is session variable is set and can be deleted, false is variable was not set.
- * @access public
- */
- function delete($name) {
- if ($this->__active === true) {
- $this->__start();
- return $this->del($name);
- }
- return false;
- }
-/**
- * Used to check if a session variable is set
- *
- * In your controller: $this->Session->check('Controller.sessKey');
- *
- * @param string $name the name of the session key you want to check
- * @return boolean true is session variable is set, false if not
- * @access public
- */
- function check($name) {
- if ($this->__active === true) {
- $this->__start();
- return parent::check($name);
- }
- return false;
- }
-/**
- * Used to determine the last error in a session.
- *
- * In your controller: $this->Session->error();
- *
- * @return string Last session error
- * @access public
- */
- function error() {
- if ($this->__active === true) {
- $this->__start();
- return parent::error();
- }
- return false;
- }
-/**
- * Used to set a session variable that can be used to output messages in the view.
- *
- * In your controller: $this->Session->setFlash('This has been saved');
- *
- * Additional params below can be passed to customize the output, or the Message.[key]
- *
- * @param string $message Message to be flashed
- * @param string $layout Layout to wrap flash message in
- * @param array $params Parameters to be sent to layout as view variables
- * @param string $key Message key, default is 'flash'
- * @access public
- */
- function setFlash($message, $layout = 'default', $params = array(), $key = 'flash') {
- if ($this->__active === true) {
- $this->__start();
- $this->write('Message.' . $key, compact('message', 'layout', 'params'));
- }
- }
-/**
- * Used to renew a session id
- *
- * In your controller: $this->Session->renew();
- *
- * @access public
- */
- function renew() {
- if ($this->__active === true) {
- $this->__start();
- parent::renew();
- }
- }
-/**
- * Used to check for a valid session.
- *
- * In your controller: $this->Session->valid();
- *
- * @return boolean true is session is valid, false is session is invalid
- * @access public
- */
- function valid() {
- if ($this->__active === true) {
- $this->__start();
- return parent::valid();
- }
- return false;
- }
-/**
- * Used to destroy sessions
- *
- * In your controller: $this->Session->destroy();
- *
- * @access public
- */
- function destroy() {
- if ($this->__active === true) {
- $this->__start();
- parent::destroy();
- }
- }
-/**
- * Returns Session id
- *
- * If $id is passed in a beforeFilter, the Session will be started
- * with the specified id
- *
- * @param $id string
- * @return string
- * @access public
- */
- function id($id = null) {
- return parent::id($id);
- }
-/**
- * Starts Session if SessionComponent is used in Controller::beforeFilter(),
- * or is called from
- *
- * @access private
- */
- function __start(){
- if ($this->__started === false) {
- if (!$this->id() && parent::start()) {
- $this->__started = true;
- parent::_checkValid();
- } else {
- $this->__started = parent::start();
- }
- }
- return $this->__started;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/controller.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/controller.php
deleted file mode 100644
index 482100b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/controller.php
+++ /dev/null
@@ -1,998 +0,0 @@
-<?php
-/* SVN FILE: $Id: controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Base controller class.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Include files
- */
- uses(DS . 'controller' . DS . 'component', DS . 'view' . DS . 'view');
-/**
- * Controller
- *
- * Application controller (controllers are where you put all the actual code)
- * Provides basic functionality, such as rendering views (aka displaying templates).
- * Automatically selects model name from on singularized object class name
- * and creates the model object if proper class exists.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller
- *
- */
-class Controller extends Object{
-/**
- * Name of the controller.
- *
- * @var string
- * @access public
- */
- var $name = null;
-/**
- * Stores the current URL (for links etc.)
- *
- * @var string
- * @access public
- */
- var $here = null;
-/**
- * The webroot of the application
- *
- * @var string
- * @access public
- */
- var $webroot = null;
-/**
- * Action to be performed.
- *
- * @var string
- * @access public
- */
- var $action = null;
-/**
- * An array of names of models the particular controller wants to use.
- *
- * @var mixed A single name as a string or a list of names as an array.
- * @access protected
- */
- var $uses = false;
-/**
- * An array of names of built-in helpers to include.
- *
- * @var mixed A single name as a string or a list of names as an array.
- * @access protected
- */
- var $helpers = array('Html');
-/**
- * Parameters received in the current request, i.e. GET and POST data
- *
- * @var array
- * @access public
- */
- var $params = array();
-/**
- * POST'ed model data
- *
- * @var array
- * @access public
- */
- var $data = array();
-/**
- * Directory where controllers views are stored
- * Normaly this is automatically set
- *
- * @var string
- * @access public
- */
- var $viewPath = null;
-/**
- * Variables for the view
- *
- * @var array
- * @access public
- */
- var $viewVars = array();
-/**
- * Web page title
- *
- * @var boolean
- * @access public
- */
- var $pageTitle = false;
-/**
- * An array of model objects.
- *
- * @var array Array of model objects.
- * @access public
- */
- var $modelNames = array();
-/**
- * Base url path
- *
- * @var string
- * @access public
- */
- var $base = null;
-/**
- * Layout file to use (see /app/views/layouts/default.thtml)
- *
- * @var string
- * @access public
- */
- var $layout = 'default';
-/**
- * Automatically render the view (the dispatcher checks for this variable before running render())
- *
- * @var boolean
- * @access public
- */
- var $autoRender = true;
-/**
- * Automatically render the layout
- *
- * @var boolean
- * @access public
- */
- var $autoLayout = true;
-/**
- * Array of components a controller will use
- *
- * @var array
- * @access public
- */
- var $components = array();
-/**
- * The name of the View class a controller sends output to
- *
- * @var string
- * @access public
- */
- var $view = 'View';
-/**
- * File extension for view templates. Defaults to Cake's conventional ".thtml".
- *
- * @var string
- * @access public
- */
- var $ext = '.thtml';
-/**
- * Instance of $view class create by a controller
- *
- * @var object
- * @access private
- */
- var $__viewClass = null;
-/**
- * The output of the requested action. Contains either a variable
- * returned from the action, or the data of the rendered view;
- * You can use this var in Child classes afterFilter() to alter output.
- *
- * @var string
- * @access public
- */
- var $output = null;
-/**
- * Automatically set to the name of a plugin.
- *
- * @var string
- * @access public
- */
- var $plugin = null;
-/**
- * Used to set methods a controller will allow the View to cache
- *
- * @var mixed
- * @access public
- */
- var $cacheAction = false;
-/**
- * Used to create cached instances of models a controller uses.
- * When set to true all models related to the controller will be cached,
- * this can increase performance in many cases
- *
- * @var boolean
- * @access public
- */
- var $persistModel = false;
-/**
- * Replaced with Controller::beforeFilter();
- *
- * @deprecated will not be avialable after 1.1.x.x
- */
- var $beforeFilter = null;
-/**
- * Replaced with Router::parseExtensions();
- *
- * @deprecated will not be avialable after 1.1.x.x
- */
- var $webservices = null;
-/**
- * Constructor.
- */
- function __construct() {
- if ($this->name === null) {
- $r = null;
-
- if (!preg_match('/(.*)Controller/i', get_class($this), $r)) {
- die ("Controller::__construct() : Can't get or parse my own class name, exiting.");
- }
- $this->name = $r[1];
- }
-
- if ($this->viewPath == null) {
- $this->viewPath = Inflector::underscore($this->name);
- }
-
- $this->modelClass = Inflector::classify($this->name);
- $this->modelKey = Inflector::underscore($this->modelClass);
-
- if (is_subclass_of($this, 'AppController')) {
- $appVars = get_class_vars('AppController');
- $uses = $appVars['uses'];
- $merge = array('components', 'helpers');
-
- if ($uses == $this->uses && !empty($this->uses)) {
- array_unshift($this->uses, $this->modelClass);
- } elseif ($this->uses !== null || $this->uses !== false) {
- $merge[] = 'uses';
- }
-
- foreach ($merge as $var) {
- if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) {
- $this->{$var} = array_merge($this->{$var}, array_diff($appVars[$var], $this->{$var}));
- }
- }
- }
- parent::__construct();
- }
-
- function _initComponents() {
- $component = new Component();
- $component->init($this);
- }
-/**
- * Loads and instantiates models required by this controller.
- * If Controller::persistModel; is true, controller will create cached model instances on first request,
- * additional request will used cached models
- *
- * @return mixed true when single model found and instance created error returned if models not found.
- * @access public
- */
- function constructClasses() {
- if ($this->uses === null || ($this->uses === array())) {
- return false;
- }
- if (empty($this->passedArgs) || !isset($this->passedArgs['0'])) {
- $id = false;
- } else {
- $id = $this->passedArgs['0'];
- }
- $cached = false;
- $object = null;
-
- if ($this->persistModel === true) {
- uses('neat_array');
- }
- if ($this->uses === false) {
- if (!class_exists($this->modelClass)) {
- loadModel($this->modelClass);
- }
- }
-
- if (class_exists($this->modelClass) && ($this->uses === false)) {
- if ($this->persistModel === true) {
- $cached = $this->_persist($this->modelClass, null, $object);
- }
-
- if (($cached === false)) {
- $model =& new $this->modelClass($id);
- $this->modelNames[] = $this->modelClass;
- $this->{$this->modelClass} =& $model;
-
- if ($this->persistModel === true) {
- $this->_persist($this->modelClass, true, $model);
- $registry = ClassRegistry::getInstance();
- $this->_persist($this->modelClass . 'registry', true, $registry->_objects, 'registry');
- }
- } else {
- $this->_persist($this->modelClass . 'registry', true, $object, 'registry');
- $this->_persist($this->modelClass, true, $object);
- $this->modelNames[] = $this->modelClass;
- }
- return true;
- } elseif ($this->uses === false) {
- return $this->cakeError('missingModel', array(array('className' => $this->modelClass, 'webroot' => '', 'base' => $this->base)));
- }
-
- if ($this->uses) {
- $uses = is_array($this->uses) ? $this->uses : array($this->uses);
- $this->modelClass = $uses[0];
-
- foreach ($uses as $modelClass) {
- $id = false;
- $cached = false;
- $object = null;
- $modelKey = Inflector::underscore($modelClass);
-
- if (!class_exists($modelClass)) {
- loadModel($modelClass);
- }
-
- if (class_exists($modelClass)) {
- if ($this->persistModel === true) {
- $cached = $this->_persist($modelClass, null, $object);
- }
-
- if (($cached === false)) {
- $model =& new $modelClass($id);
- $this->modelNames[] = $modelClass;
- $this->{$modelClass} =& $model;
-
- if ($this->persistModel === true) {
- $this->_persist($modelClass, true, $model);
- $registry = ClassRegistry::getInstance();
- $this->_persist($modelClass . 'registry', true, $registry->_objects, 'registry');
- }
- } else {
- $this->_persist($modelClass . 'registry', true, $object, 'registry');
- $this->_persist($modelClass, true, $object);
- $this->modelNames[] = $modelClass;
- }
- } else {
- return $this->cakeError('missingModel', array(array('className' => $modelClass, 'webroot' => '', 'base' => $this->base)));
- }
- }
- return true;
- }
- }
-/**
- * Redirects to given $url, after turning off $this->autoRender.
- * Please notice that the script execution is not stopped after the redirect.
- *
- * @param string $url
- * @param integer $status
- * @access public
- */
- function redirect($url, $status = null) {
- $this->autoRender = false;
- $pos = strpos($url, '://');
- $base = strip_plugin($this->base, $this->plugin);
- if ($pos === false) {
- if (strpos($url, '/') !== 0) {
- $url = '/' . $url;
- }
- $url = FULL_BASE_URL . $base . $url;
- }
-
- if (function_exists('session_write_close')) {
- session_write_close();
- }
-
- if (!empty($status)) {
- $codes = array(
- 100 => "HTTP/1.1 100 Continue",
- 101 => "HTTP/1.1 101 Switching Protocols",
- 200 => "HTTP/1.1 200 OK",
- 201 => "HTTP/1.1 201 Created",
- 202 => "HTTP/1.1 202 Accepted",
- 203 => "HTTP/1.1 203 Non-Authoritative Information",
- 204 => "HTTP/1.1 204 No Content",
- 205 => "HTTP/1.1 205 Reset Content",
- 206 => "HTTP/1.1 206 Partial Content",
- 300 => "HTTP/1.1 300 Multiple Choices",
- 301 => "HTTP/1.1 301 Moved Permanently",
- 302 => "HTTP/1.1 302 Found",
- 303 => "HTTP/1.1 303 See Other",
- 304 => "HTTP/1.1 304 Not Modified",
- 305 => "HTTP/1.1 305 Use Proxy",
- 307 => "HTTP/1.1 307 Temporary Redirect",
- 400 => "HTTP/1.1 400 Bad Request",
- 401 => "HTTP/1.1 401 Unauthorized",
- 402 => "HTTP/1.1 402 Payment Required",
- 403 => "HTTP/1.1 403 Forbidden",
- 404 => "HTTP/1.1 404 Not Found",
- 405 => "HTTP/1.1 405 Method Not Allowed",
- 406 => "HTTP/1.1 406 Not Acceptable",
- 407 => "HTTP/1.1 407 Proxy Authentication Required",
- 408 => "HTTP/1.1 408 Request Time-out",
- 409 => "HTTP/1.1 409 Conflict",
- 410 => "HTTP/1.1 410 Gone",
- 411 => "HTTP/1.1 411 Length Required",
- 412 => "HTTP/1.1 412 Precondition Failed",
- 413 => "HTTP/1.1 413 Request Entity Too Large",
- 414 => "HTTP/1.1 414 Request-URI Too Large",
- 415 => "HTTP/1.1 415 Unsupported Media Type",
- 416 => "HTTP/1.1 416 Requested range not satisfiable",
- 417 => "HTTP/1.1 417 Expectation Failed",
- 500 => "HTTP/1.1 500 Internal Server Error",
- 501 => "HTTP/1.1 501 Not Implemented",
- 502 => "HTTP/1.1 502 Bad Gateway",
- 503 => "HTTP/1.1 503 Service Unavailable",
- 504 => "HTTP/1.1 504 Gateway Time-out"
- );
- if (is_string($status)) {
- $codes = array_combine(array_values($codes), array_keys($codes));
- }
- if (isset($codes[$status])) {
- $code = ife(is_numeric($status), $status, $codes[$status]);
- $msg = ife(is_string($status), $status, $codes[$status]);
- $status = "HTTP/1.1 {$code} {$msg}";
- } else {
- $status = null;
- }
- }
- if (!empty($status)) {
- header($status);
- }
- header('Location: ' . $url);
- if (!empty($status) && ($status >= 300 && $status < 400)) {
- header($status);
- }
- }
-/**
- * Saves a variable to use inside a template.
- *
- * @param mixed $one A string or an array of data.
- * @param mixed $two Value in case $one is a string (which then works as the key). Unused if $one is an associative array, otherwise serves as the values to $one's keys.
- * @return mixed string or array of variables set
- * @access public
- */
- function set($one, $two = null) {
- if (is_array($one)) {
- if (is_array($two)) {
- return $this->_setArray(array_combine($one, $two));
- } else {
- return $this->_setArray($one);
- }
- } else {
- return $this->_setArray(array($one => $two));
- }
- }
-/**
- * Internally redirects one action to another
- *
- * @param string $action The new action to be redirected to
- * @param mixed Any other parameters passed to this method will be passed as
- * parameters to the new action.
- * @access public
- */
- function setAction($action) {
- $this->action = $action;
- $args = func_get_args();
- unset($args[0]);
- call_user_func_array(array(&$this, $action), $args);
- }
-/**
- * Returns number of errors in a submitted FORM.
- *
- * @return int Number of errors
- * @access public
- */
- function validate() {
- $args = func_get_args();
- $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
-
- if ($errors === false) {
- return 0;
- }
- return count($errors);
- }
-/**
- * Validates a FORM according to the rules set up in the Model.
- *
- * @return int Number of errors
- * @access public
- */
- function validateErrors() {
- $objects = func_get_args();
- if (!count($objects)) {
- return false;
- }
-
- $errors = array();
- foreach ($objects as $object) {
- $errors = array_merge($errors, $this->{$object->name}->invalidFields($object->data));
- }
- return $this->validationErrors = (count($errors) ? $errors : false);
- }
-/**
- * Gets an instance of the view object and prepares it for rendering the output, then
- * asks the view to actualy do the job.
- *
- * @param string $action
- * @param string $layout
- * @param string $file
- * @return controllers related views
- * @access public
- */
- function render($action = null, $layout = null, $file = null) {
- $viewClass = $this->view;
- if ($this->view != 'View') {
- $viewClass = $this->view . 'View';
- loadView($this->view);
- }
- $this->beforeRender();
- $this->__viewClass =& new $viewClass($this);
-
- if (!empty($this->modelNames)) {
- $models = array();
- foreach ($this->modelNames as $currentModel) {
- if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model')) {
- $models[] = Inflector::underscore($currentModel);
- }
- if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model') && !empty($this->$currentModel->validationErrors)) {
- $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $this->$currentModel->validationErrors;
- }
- }
- $models = array_diff(ClassRegistry::keys(), $models);
- foreach ($models as $currentModel) {
- if (ClassRegistry::isKeySet($currentModel)) {
- $currentObject =& ClassRegistry::getObject($currentModel);
- if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
- $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors;
- }
- }
- }
- }
- $this->autoRender = false;
- return $this->__viewClass->render($action, $layout, $file);
- }
-/**
- * Gets the referring URL of this request
- *
- * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers
- * @param boolean $local If true, restrict referring URLs to local server
- * @access public
- */
- function referer($default = null, $local = false) {
- $ref = env('HTTP_REFERER');
- $base = FULL_BASE_URL . $this->webroot;
-
- if ($ref != null && (defined(FULL_BASE_URL) || FULL_BASE_URL)) {
- if (strpos($ref, $base) === 0) {
- return substr($ref, strlen($base) - 1);
- } elseif (!$local) {
- return $ref;
- }
- }
-
- if ($default != null) {
- return $default;
- } else {
- return '/';
- }
- }
-/**
- * Sets data for this view. Will set title if the key "title" is in given $data array.
- *
- * @param array $data Array of
- * @access protected
- */
- function _setArray($data) {
- foreach ($data as $name => $value) {
- if ($name == 'title') {
- $this->_setTitle($value);
- } else {
- $this->viewVars[$name] = $value;
- }
- }
- }
-/**
- * Set the title element of the page.
- *
- * @param string $pageTitle Text for the title
- * @access private
- */
- function _setTitle($pageTitle) {
- $this->pageTitle = $pageTitle;
- }
-/**
- * Shows a message to the user $time seconds, then redirects to $url if DEBUG == 0. If DEBUG > 0, warnings and SQL output may halt redirection.
- * Uses flash.thtml as a layout for the messages
- *
- * @param string $message Message to display to the user
- * @param string $url Relative URL to redirect to after the time expires
- * @param int $time seconds to show the message
- * @access public
- */
- function flash($message, $url, $pause = 1) {
- $this->autoRender = false;
- $this->autoLayout = false;
- $this->set('url', $this->base . $url);
- $this->set('message', $message);
- $this->set('pause', $pause);
- $this->set('page_title', $message);
-
- if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
- $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
- } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
- }
- $this->render(null, false, $flash);
- }
-/**
- * Replaced with Controller::flash();
- * @deprecated will not be avialable after 1.1.x.x
- */
- function flashOut($message, $url, $pause = 1) {
- trigger_error('(Controller::flashOut()) Deprecated: Use Controller::flash() instead', E_USER_WARNING);
- $this->autoRender = false;
- $this->autoLayout = false;
- $this->set('url', $url);
- $this->set('message', $message);
- $this->set('pause', $pause);
- $this->set('page_title', $message);
-
- if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
- $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
- } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
- }
- $this->render(null, false, $flash);
- }
-/**
- * This function creates a $fieldNames array for the view to use.
- *
- * @param array $data
- * @param boolean $doCreateOptions
- * @return field name arrays for the view
- * @access public
- */
- function generateFieldNames($data = null, $doCreateOptions = true) {
- $fieldNames = array();
- $model = $this->modelClass;
- $modelKey = $this->modelKey;
- $table = $this->{$model}->table;
- $objRegistryModel =& ClassRegistry::getObject($modelKey);
-
- foreach ($objRegistryModel->_tableInfo->value as $tabl) {
- if ($objRegistryModel->isForeignKey($tabl['name'])) {
- if (false !== strpos($tabl['name'], "_id")) {
- $niceName = substr($tabl['name'], 0, strpos($tabl['name'], "_id" ));
- } else {
- $niceName = $niceName = $tabl['name'];
- }
- $fkNames = $this->{$model}->keyToTable[$tabl['name']];
- $fieldNames[$tabl['name']]['table'] = $fkNames[0];
- $fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($niceName);
- $fieldNames[$tabl['name']]['model'] = $fkNames[1];
- $fieldNames[$tabl['name']]['modelKey'] = $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']];
- $fieldNames[$tabl['name']]['controller'] = Inflector::pluralize($this->{$model}->tableToModel[$fkNames[0]]);
- $fieldNames[$tabl['name']]['foreignKey'] = true;
-
- } elseif ('created' != $tabl['name'] && 'updated' != $tabl['name']) {
- $fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($tabl['name']);
- } elseif ('created' == $tabl['name']) {
- $fieldNames[$tabl['name']]['prompt'] = 'Created';
- } elseif ('updated' == $tabl['name']) {
- $fieldNames[$tabl['name']]['prompt'] = 'Modified';
- }
- $fieldNames[$tabl['name']]['tagName'] = $model . '/' . $tabl['name'];
- $validationFields = $objRegistryModel->validate;
-
- if (isset($validationFields[$tabl['name']])) {
- if (VALID_NOT_EMPTY == $validationFields[$tabl['name']]) {
- $fieldNames[$tabl['name']]['required'] = true;
- $fieldNames[$tabl['name']]['errorMsg'] = "Required Field";
- }
- }
- $lParenPos = strpos($tabl['type'], '(');
- $rParenPos = strpos($tabl['type'], ')');
-
- if (false != $lParenPos) {
- $type = substr($tabl['type'], 0, $lParenPos);
- $fieldLength = substr($tabl['type'], $lParenPos + 1, $rParenPos - $lParenPos - 1);
- } else {
- $type = $tabl['type'];
- }
-
- switch($type) {
- case "text":
- $fieldNames[$tabl['name']]['type'] = 'area';
- break;
- case "string":
- if (isset($fieldNames[$tabl['name']]['foreignKey'])) {
- $fieldNames[$tabl['name']]['type'] = 'select';
- $fieldNames[$tabl['name']]['options'] = array();
- $otherModel =& ClassRegistry::getObject(Inflector::underscore($fieldNames[$tabl['name']]['modelKey']));
-
- if (is_object($otherModel)) {
- if ($doCreateOptions) {
- $otherDisplayField = $otherModel->getDisplayField();
- $otherModel->recursive = 0;
- $rec = $otherModel->findAll();
-
- foreach ($rec as $pass) {
- foreach ($pass as $key => $value) {
- if ($key == $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']] && isset($value[$otherModel->primaryKey]) && isset($value[$otherDisplayField])) {
- $fieldNames[$tabl['name']]['options'][$value[$otherModel->primaryKey]] = $value[$otherDisplayField];
- }
- }
- }
- }
- $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
- }
- } else {
- $fieldNames[$tabl['name']]['type'] = 'input';
- }
- break;
- case "boolean":
- $fieldNames[$tabl['name']]['type'] = 'checkbox';
- break;
- case "integer":
- case "float":
- if (strcmp($tabl['name'], $this->$model->primaryKey) == 0) {
- $fieldNames[$tabl['name']]['type'] = 'hidden';
- } elseif (isset($fieldNames[$tabl['name']]['foreignKey'])) {
- $fieldNames[$tabl['name']]['type'] = 'select';
- $fieldNames[$tabl['name']]['options'] = array();
- $otherModel =& ClassRegistry::getObject(Inflector::underscore($fieldNames[$tabl['name']]['modelKey']));
-
- if (is_object($otherModel)) {
- if ($doCreateOptions) {
- $otherDisplayField = $otherModel->getDisplayField();
- $otherModel->recursive = 0;
- $rec = $otherModel->findAll();
-
- foreach ($rec as $pass) {
- foreach ($pass as $key => $value) {
- if ($key == $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']] && isset($value[$otherModel->primaryKey]) && isset($value[$otherDisplayField])) {
- $fieldNames[$tabl['name']]['options'][$value[$otherModel->primaryKey]] = $value[$otherDisplayField];
- }
- }
- }
- }
- $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
- }
- } else {
- $fieldNames[$tabl['name']]['type'] = 'input';
- }
- break;
- case "enum":
- $fieldNames[$tabl['name']]['type'] = 'select';
- $fieldNames[$tabl['name']]['options'] = array();
- $enumValues = split(',', $fieldLength);
-
- foreach ($enumValues as $enum) {
- $enum = trim($enum, "'");
- $fieldNames[$tabl['name']]['options'][$enum] = $enum;
- }
-
- $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
- break;
- case "date":
- case "datetime":
- case "time":
- case "year":
- if (0 != strncmp("created", $tabl['name'], 7) && 0 != strncmp("modified", $tabl['name'], 8)) {
- $fieldNames[$tabl['name']]['type'] = $type;
- }
-
- if (isset($data[$model][$tabl['name']])) {
- $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
- } else {
- $fieldNames[$tabl['name']]['selected'] = null;
- }
-
- break;
- default:
- break;
- }
- }
-
- foreach ($objRegistryModel->hasAndBelongsToMany as $relation => $relData) {
- $modelName = $relData['className'];
- $manyAssociation = $relation;
- $modelKeyM = Inflector::underscore($modelName);
- $modelObject =& new $modelName();
-
- if ($doCreateOptions) {
- $otherDisplayField = $modelObject->getDisplayField();
- $fieldNames[$relation]['model'] = $modelName;
- $fieldNames[$relation]['prompt'] = "Related " . Inflector::humanize(Inflector::pluralize($relation));
- $fieldNames[$relation]['type'] = "selectMultiple";
- $fieldNames[$relation]['tagName'] = $manyAssociation . '/' . $manyAssociation;
- $modelObject->recursive = 0;
- $rec = $modelObject->findAll();
-
- foreach ($rec as $pass) {
- foreach ($pass as $key => $value) {
- if ($key == $modelName && isset($value[$modelObject->primaryKey]) && isset($value[$otherDisplayField])) {
- $fieldNames[$relation]['options'][$value[$modelObject->primaryKey]] = $value[$otherDisplayField];
- }
- }
- }
-
- if (isset($data[$manyAssociation])) {
- foreach ($data[$manyAssociation] as $key => $row) {
- $fieldNames[$relation]['selected'][$row[$modelObject->primaryKey]] = $row[$modelObject->primaryKey];
- }
- }
- }
- }
- return $fieldNames;
- }
-/**
- * Converts POST'ed model data to a model conditions array, suitable for a find or findAll Model query
- *
- * @param array $data POST'ed data organized by model and field
- * @return array An array of model conditions
- * @access public
- */
- function postConditions($data) {
- if (!is_array($data) || empty($data)) {
- return null;
- }
- $conditions = array();
-
- foreach ($data as $model => $fields) {
- foreach ($fields as $field => $value) {
- $conditions[$model . '.' . $field] = $value;
- }
- }
- return $conditions;
- }
-/**
- * Cleans up the date fields of current Model.
- *
- * @param string $modelName
- * @access public
- */
- function cleanUpFields($modelName = null) {
- if ($modelName == null) {
- $modelName = $this->modelClass;
- }
-
- foreach ($this->{$modelName}->_tableInfo->value as $field) {
- if ('date' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
- $newDate = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
- $newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
- $newDate .= $this->params['data'][$modelName][$field['name'] . '_day'];
- unset($this->params['data'][$modelName][$field['name'] . '_year']);
- unset($this->params['data'][$modelName][$field['name'] . '_month']);
- unset($this->params['data'][$modelName][$field['name'] . '_day']);
- unset($this->params['data'][$modelName][$field['name'] . '_hour']);
- unset($this->params['data'][$modelName][$field['name'] . '_min']);
- unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
- $this->params['data'][$modelName][$field['name']] = $newDate;
- $this->data[$modelName][$field['name']] = $newDate;
-
- } elseif ('datetime' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
- $hour = $this->params['data'][$modelName][$field['name'] . '_hour'];
-
- if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
- $hour = $hour + 12;
- }
-
- $newDate = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
- $newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
- $newDate .= $this->params['data'][$modelName][$field['name'] . '_day'] . ' ';
- $newDate .= $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
- unset($this->params['data'][$modelName][$field['name'] . '_year']);
- unset($this->params['data'][$modelName][$field['name'] . '_month']);
- unset($this->params['data'][$modelName][$field['name'] . '_day']);
- unset($this->params['data'][$modelName][$field['name'] . '_hour']);
- unset($this->params['data'][$modelName][$field['name'] . '_min']);
- unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
- $this->params['data'][$modelName][$field['name']] = $newDate;
- $this->data[$modelName][$field['name']] = $newDate;
-
- } elseif ('time' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_hour'])) {
- $hour = $this->params['data'][$modelName][$field['name'] . '_hour'];
-
- if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
- $hour = $hour + 12;
- }
- if ($hour == 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'am' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
- $hour = '00';
- }
-
- $newDate = $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
- unset($this->params['data'][$modelName][$field['name'] . '_hour']);
- unset($this->params['data'][$modelName][$field['name'] . '_min']);
- unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
- $this->params['data'][$modelName][$field['name']] = $newDate;
- $this->data[$modelName][$field['name']] = $newDate;
- }
- }
- }
-/**
- * Called before the controller action. Overridden in subclasses.
- *
- * @access public
- */
- function beforeFilter() {
- }
-/**
- * Called after the controller action is run, but before the view is rendered. Overridden in subclasses.
- *
- * @access public
- */
- function beforeRender() {
- }
-/**
- * Called after the controller action is run and rendered. Overridden in subclasses.
- *
- * @access public
- */
- function afterFilter() {
- }
-/**
- * This method should be overridden in child classes.
- *
- * @param string $method name of method called example index, edit, etc.
- * @return boolean
- * @access protected
- */
- function _beforeScaffold($method) {
- return true;
- }
-/**
- * This method should be overridden in child classes.
- *
- * @param string $method name of method called either edit or update.
- * @return boolean
- * @access protected
- */
- function _afterScaffoldSave($method) {
- return true;
- }
-/**
- * This method should be overridden in child classes.
- *
- * @param string $method name of method called either edit or update.
- * @return boolean
- * @access protected
- */
- function _afterScaffoldSaveError($method) {
- return true;
- }
-/**
- * This method should be overridden in child classes.
- * If not it will render a scaffold error.
- * Method MUST return true in child classes
- *
- * @param string $method name of method called example index, edit, etc.
- * @return boolean
- * @access protected
- */
- function _scaffoldError($method) {
- return false;
- }
-/**
- * Used to convert HABTM data into an array for selectTag
- *
- * @param array $data
- * @param string $key
- * @return array
- * @access protected
- */
- function _selectedArray($data, $key = 'id') {
- $array = array();
- if (!empty($data)) {
- foreach ($data as $var) {
- $array[$var[$key]] = $var[$key];
- }
- }
- return $array;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/pages_controller.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/pages_controller.php
deleted file mode 100644
index 4182ba7..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/pages_controller.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-/* SVN FILE: $Id: pages_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * Short description for file.
- *
- * This file is application-wide controller file. You can put all
- * application-wide controller-related methods here.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Short description for class.
- *
- * This file is application-wide controller file. You can put all
- * application-wide controller-related methods here.
- *
- * Add your application-wide methods in the class below, your controllers
- * will inherit them.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller
- */
-class PagesController extends AppController{
-
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $name = 'Pages';
-
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $helpers = array('Html');
-
-/**
- * This controller does not use a model
- *
- * @var $uses
- */
- var $uses = array();
-
-/**
- * Displays a view
- *
- */
- function display() {
- if (!func_num_args()) {
- $this->redirect('/');
- }
-
- $path=func_get_args();
-
- if (!count($path)) {
- $this->redirect('/');
- }
-
- $count =count($path);
- $page =null;
- $subpage=null;
- $title =null;
-
- if (!empty($path[0])) {
- $page = $path[0];
- }
-
- if (!empty($path[1])) {
- $subpage = $path[1];
- }
-
- if (!empty($path[$count - 1])) {
- $title = ucfirst($path[$count - 1]);
- }
-
- $this->set('page', $page);
- $this->set('subpage', $subpage);
- $this->set('title', $title);
- $this->render(join('/', $path));
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/scaffold.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/scaffold.php
deleted file mode 100644
index e8d7037..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/controller/scaffold.php
+++ /dev/null
@@ -1,432 +0,0 @@
-<?php
-/* SVN FILE: $Id: scaffold.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Scaffold.
- *
- * Automatic forms and actions generation for rapid web application development.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.controller
- * @since Cake v 0.10.0.1076
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Scaffolding is a set of automatic views, forms and controllers for starting web development work faster.
- *
- * Scaffold inspects your database tables, and making educated guesses, sets up a
- * number of pages for each of your Models. These pages have data forms that work,
- * and afford the web developer an early look at the data, and the possibility to over-ride
- * scaffolded actions with custom-made ones.
- *
- * @package cake
- * @subpackage cake.cake.libs.controller
- */
-class Scaffold extends Object{
-/**
- * Name of view to render
- *
- * @var string
- */
- var $actionView = null;
-/**
- * Class name of model
- *
- * @var unknown_type
- */
- var $modelKey = null;
-/**
- * Controller object
- *
- * @var Controller
- */
- var $controllerClass = null;
-/**
- * Name of scaffolded Model
- *
- * @var string
- */
- var $modelName = null;
-/**
- * Title HTML element for current scaffolded view
- *
- * @var string
- */
- var $scaffoldTitle = null;
-/**
- * Base URL
- *
- * @var string
- */
- var $base = false;
-/**
- * Construct and set up given controller with given parameters.
- *
- * @param object $controller instance of controller
- * @param array $params
- */
- function __construct(&$controller, $params) {
- $this->controllerClass =& $controller;
- $this->actionView = $controller->action;
- $this->modelKey = ucwords(Inflector::singularize($controller->name));
- $this->scaffoldTitle = Inflector::humanize($this->modelKey);
- $this->viewPath = Inflector::underscore($controller->name);
- $this->controllerClass->pageTitle = $this->scaffoldTitle;
- $this->controllerClass->pageTitle = 'Scaffold :: ' . Inflector::humanize($controller->action) . ' :: ' .
- Inflector::humanize(Inflector::pluralize($this->modelKey));
- $this->__scaffold($params);
- }
-/**
- * Renders a view view of scaffolded Model.
- *
- * @param array $params
- * @return A rendered view of a row from Models database table
- * @access private
- */
- function __scaffoldView($params) {
- if ($this->controllerClass->_beforeScaffold('view')) {
-
- if (isset($params['pass'][0])) {
- $this->controllerClass->{$this->modelKey}->id = $params['pass'][0];
-
- } elseif (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid() != false) {
- $this->controllerClass->Session->setFlash('No id set for ' . Inflector::humanize($this->modelKey) . '::view().');
- $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
-
- } else {
- return $this->controllerClass->flash('No id set for ' . Inflector::humanize($this->modelKey) . '::view().',
- '/' . Inflector::underscore($this->controllerClass->viewPath));
- }
-
- $this->controllerClass->params['data'] = $this->controllerClass->{$this->modelKey}->read();
- $this->controllerClass->set('data', $this->controllerClass->params['data']);
- $this->controllerClass->set('fieldNames',$this->controllerClass->generateFieldNames(
- $this->controllerClass->params['data'], false));
-
- if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.view.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . $this->viewPath . DS . 'scaffold.view.thtml');
-
- } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.view.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . 'scaffold' . DS . 'scaffold.view.thtml');
- } else {
- return $this->controllerClass->render($this->actionView, '',
- LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'view.thtml');
- }
- } elseif ($this->controllerClass->_scaffoldError('view') === false) {
- return $this->__scaffoldError();
- }
- }
-/**
- * Renders List view of scaffolded Model.
- *
- * @param array $params
- * @return A rendered view listing rows from Models database table
- * @access private
- */
- function __scaffoldIndex($params) {
- if ($this->controllerClass->_beforeScaffold('index')) {
- $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames(null, false));
- $this->controllerClass->{$this->modelKey}->recursive = 0;
- $this->controllerClass->set('data', $this->controllerClass->{$this->modelKey}->findAll());
-
- if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.index.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . $this->viewPath . DS . 'scaffold.index.thtml');
-
- } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.index.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . 'scaffold' . DS . 'scaffold.index.thtml');
- } else {
- return $this->controllerClass->render($this->actionView, '',
- LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'index.thtml');
- }
- } elseif ($this->controllerClass->_scaffoldError('index') === false) {
- return $this->__scaffoldError();
- }
- }
-/**
- * Renders an Add or Edit view for scaffolded Model.
- *
- * @param array $params
- * @param string $params add or edit
- * @return A rendered view with a form to edit or add a record in the Models database table
- * @access private
- */
- function __scaffoldForm($params = array(), $type) {
- $thtml = 'edit';
- $form = 'Edit';
-
- if ($type === 'add') {
- $thtml = 'add';
- $form = 'Add';
- }
-
- if ($this->controllerClass->_beforeScaffold($type)) {
- if ($type == 'edit') {
-
- if (isset($params['pass'][0])) {
- $this->controllerClass->{$this->modelKey}->id = $params['pass'][0];
-
- } elseif (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid() != false) {
- $this->controllerClass->Session->setFlash('No id set for ' . Inflector::humanize($this->modelKey) . '::edit().');
- $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
-
- } else {
- return $this->controllerClass->flash('No id set for ' . Inflector::humanize($this->modelKey) . '::edit().',
- '/' . Inflector::underscore($this->controllerClass->viewPath));
- }
-
- $this->controllerClass->params['data']=$this->controllerClass->{$this->modelKey}->read();
- $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames(
- $this->controllerClass->params['data']));
- $this->controllerClass->set('data', $this->controllerClass->params['data']);
- } else {
- $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames());
- }
- $this->controllerClass->set('type', $form);
-
- if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.' . $thtml . '.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . $this->viewPath . DS . 'scaffold.' . $thtml . '.thtml');
- } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml');
- } else {
- return $this->controllerClass->render($this->actionView, '',
- LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'edit.thtml');
- }
- } elseif ($this->controllerClass->_scaffoldError($type) === false) {
- return $this->__scaffoldError();
- }
- }
-/**
- * Saves or updates a model.
- *
- * @param array $params
- * @param string $type create or update
- * @return success on save/update, add/edit form if data is empty or error if save or update fails
- * @access private
- */
- function __scaffoldSave($params = array(), $type) {
- $thtml = 'edit';
- $form = 'Edit';
- $success = 'updated';
- $formError = 'edit';
-
- if ($this->controllerClass->_beforeScaffold($type)) {
- if (empty($this->controllerClass->params['data'])) {
- if ($type === 'create') {
- $formError = 'add';
- }
- return $this->__scaffoldForm($params, $formError);
- }
- $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames());
- $this->controllerClass->cleanUpFields();
-
- if ($type == 'create') {
- $this->controllerClass->{$this->modelKey}->create();
- $thtml = 'add';
- $form = 'Add';
- $success = 'saved';
- }
-
- if ($this->controllerClass->{$this->modelKey}->save($this->controllerClass->params['data'])) {
-
- if ($this->controllerClass->_afterScaffoldSave($type)) {
-
- if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid() != false) {
- $this->controllerClass->Session->setFlash('The ' . Inflector::humanize($this->modelKey) . ' has been ' . $success . '.');
- $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
- } else {
- return $this->controllerClass->flash('The ' . Inflector::humanize($this->modelKey) . ' has been ' . $success . '.',
- '/' . Inflector::underscore($this->controllerClass->viewPath));
- }
- } else {
- return $this->controllerClass->_afterScaffoldSaveError($type);
- }
- } else {
- if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid() != false) {
- $this->controllerClass->Session->setFlash('Please correct errors below.');
- }
- $this->controllerClass->set('data', $this->controllerClass->params['data']);
- $this->controllerClass->set('fieldNames',
- $this->controllerClass->generateFieldNames($this->__rebuild($this->controllerClass->params['data'])));
- $this->controllerClass->validateErrors($this->controllerClass->{$this->modelKey});
- $this->controllerClass->set('type', $form);
-
- if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.' . $thtml . '.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . $this->viewPath . DS . 'scaffold.' . $thtml . '.thtml');
- } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml');
- } else {
- return $this->controllerClass->render($this->actionView, '',
- LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'edit.thtml');
- }
- }
- } elseif ($this->controllerClass->_scaffoldError($type) === false) {
- return $this->__scaffoldError();
- }
- }
-/**
- * Performs a delete on given scaffolded Model.
- *
- * @param array $params
- * @return success on delete error if delete fails
- * @access private
- */
- function __scaffoldDelete($params = array()) {
- if ($this->controllerClass->_beforeScaffold('delete')) {
- $id = $params['pass'][0];
-
- if ($this->controllerClass->{$this->modelKey}->del($id)) {
-
- if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid() != false) {
- $this->controllerClass->Session->setFlash('The ' . Inflector::humanize($this->modelKey) . ' with id: ' . $id . ' has been deleted.');
- $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
- } else {
- return $this->controllerClass->flash('The ' . Inflector::humanize($this->modelKey) . ' with id: ' . $id . ' has been deleted.',
- '/' . Inflector::underscore($this->controllerClass->viewPath));
- }
- } else {
- if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid() != false) {
- $this->controllerClass->Session->setFlash('There was an error deleting the ' . Inflector::humanize($this->modelKey) . ' with the id ' . $id);
- $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
- } else {
- return $this->controllerClass->flash('There was an error deleting the ' . Inflector::humanize($this->modelKey) . ' with the id ' . $id,
- '/' . Inflector::underscore($this->controllerClass->viewPath));
- }
- }
- } elseif ($this->controllerClass->_scaffoldError('delete') === false) {
- return $this->__scaffoldError();
- }
- }
-/**
- * Enter description here...
- *
- * @return unknown
- */
- function __scaffoldError() {
- if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.error.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . $this->viewPath . DS . 'scaffold.error.thtml');
- } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.error.thtml')) {
- return $this->controllerClass->render($this->actionView, '',
- APP . 'views' . DS . 'scaffold' . DS . 'scaffold.error.thtml');
- } else {
- return $this->controllerClass->render($this->actionView, '',
- LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . 'scaffold_error.thtml');
- }
- }
-/**
- * When forms are submited the arrays need to be rebuilt if
- * an error occured, here the arrays are rebuilt to structure needed
- *
- * @param array $params data passed to forms
- * @return array rebuilds the association arrays to pass back to Controller::generateFieldNames()
- */
- function __rebuild($params) {
- foreach ($params as $model => $field) {
- if (!empty($field) && is_array($field)) {
- $match = array_keys($field);
-
- if ($model == $match[0]) {
- $count = 0;
-
- foreach ($field[$model] as $value) {
- $params[$model][$count][$this->controllerClass->{$this->modelKey}->{$model}->primaryKey] = $value;
- $count++;
- }
- unset ($params[$model][$model]);
- }
- }
- }
- return $params;
- }
-/**
- * When methods are now present in a controller
- * scaffoldView is used to call default Scaffold methods if:
- * <code>
- * var $scaffold;
- * </code>
- * is placed in the controller's class definition.
- *
- * @param string $url
- * @param string $controller_class
- * @param array $params
- * @since Cake v 0.10.0.172
- * @access private
- */
- function __scaffold($params) {
- if (!in_array('Form', $this->controllerClass->helpers)) {
- $this->controllerClass->helpers[] = 'Form';
- }
- if ($this->controllerClass->constructClasses()) {
- $db =& ConnectionManager::getDataSource($this->controllerClass->{$this->modelKey}->useDbConfig);
-
- if (isset($db)) {
- if ($params['action'] === 'index' || $params['action'] === 'list' || $params['action'] === 'view'
- || $params['action'] === 'add' || $params['action'] === 'create'
- || $params['action'] === 'edit' || $params['action'] === 'update'
- || $params['action'] === 'delete') {
-
- switch($params['action']) {
- case 'index':
- $this->__scaffoldIndex($params);
- break;
- case 'view':
- $this->__scaffoldView($params);
- break;
- case 'list':
- $this->__scaffoldIndex($params);
- break;
- case 'add':
- $this->__scaffoldForm($params, 'add');
- break;
- case 'edit':
- $this->__scaffoldForm($params, 'edit');
- break;
- case 'create':
- $this->__scaffoldSave($params, 'create');
- break;
- case 'update':
- $this->__scaffoldSave($params, 'update');
- break;
- case 'delete':
- $this->__scaffoldDelete($params);
- break;
- }
- } else {
- return $this->cakeError('missingAction',
- array(array('className' => Inflector::camelize($params['controller'] . "Controller"),
- 'base' => $this->controllerClass->base,
- 'action' => $params['action'],
- 'webroot' => $this->controllerClass->webroot)));
- }
- } else {
- return $this->cakeError('missingDatabase', array(array('webroot' => $this->controllerClass->webroot)));
- }
- } else {
- return $this->cakeError('missingModel', array(array('className' => $this->modelKey, 'webroot' => '', 'base' => $this->base)));
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/error.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/error.php
deleted file mode 100644
index 852e6b4..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/error.php
+++ /dev/null
@@ -1,347 +0,0 @@
-<?php
-/* SVN FILE: $Id: error.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.10.5.1732
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-uses('sanitize');
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class ErrorHandler extends Object {
- var $controller = null;
-
-/**
- * Class constructor.
- *
- * @param string $method
- * @param array $messages
- * @return unknown
- */
- function __construct($method, $messages) {
- parent::__construct();
- static $__previousError = null;
- $allow = array('.', '/', '_', ' ', '-', '~');
- if (substr(PHP_OS,0,3) == "WIN") {
- $allow = array_merge($allow, array('\\', ':') );
- }
- $clean = new Sanitize();
- $messages = $clean->paranoid($messages, $allow);
- if (!class_exists('Dispatcher')) {
- require CAKE . 'dispatcher.php';
- }
- $this->__dispatch =& new Dispatcher();
-
- if ($__previousError != array($method, $messages)) {
- $__previousError = array($method, $messages);
-
- if (!class_exists('AppController')) {
- loadController(null);
- }
-
- $this->controller =& new AppController();
- if (!empty($this->controller->uses)) {
- $this->controller->constructClasses();
- }
- $this->controller->_initComponents();
- $this->controller->cacheAction = false;
- $this->__dispatch->start($this->controller);
-
- if (method_exists($this->controller, 'apperror')) {
- return $this->controller->appError($method, $messages);
- }
- } else {
- $this->controller =& new Controller();
- $this->controller->cacheAction = false;
- }
- if (Configure::read() > 0 || $method == 'error') {
- call_user_func_array(array(&$this, $method), $messages);
- } else {
- call_user_func_array(array(&$this, 'error404'), $messages);
- }
- }
-/**
- * Displays an error page (e.g. 404 Not found).
- *
- * @param array $params
- */
- function error($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->webroot = $this->_webroot();
- $this->controller->viewPath='errors';
- $this->controller->set(array('code' => $code,
- 'name' => $name,
- 'message' => $message,
- 'title' => $code . ' ' . $name));
- $this->controller->render('error404');
- exit();
- }
-/**
- * Convenience method to display a 404 page.
- *
- * @param array $params
- */
- function error404($params) {
- extract($params);
-
- if (!isset($url)) {
- $url = $action;
- }
- if (!isset($message)) {
- $message = '';
- }
- if (!isset($base)) {
- $base = '';
- }
-
- header("HTTP/1.0 404 Not Found");
- $this->error(array('code' => '404',
- 'name' => 'Not found',
- 'message' => sprintf("The requested address %s was not found on this server.", $url, $message),
- 'base' => $base));
- exit();
- }
-/**
- * Renders the Missing Controller web page.
- *
- * @param array $params
- */
- function missingController($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->webroot = $webroot;
- $this->controller->viewPath ='errors';
- $controllerName = str_replace('Controller', '', $className);
- $this->controller->set(array('controller' => $className,
- 'controllerName' => $controllerName,
- 'title' => 'Missing Controller'));
- $this->controller->render('missingController');
- exit();
- }
-/**
- * Renders the Missing Action web page.
- *
- * @param array $params
- */
- function missingAction($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->webroot = $webroot;
- $this->controller->viewPath = 'errors';
- $this->controller->set(array('controller' => $className,
- 'action' => $action,
- 'title' => 'Missing Method in Controller'));
- $this->controller->render('missingAction');
- exit();
- }
-/**
- * Renders the Private Action web page.
- *
- * @param array $params
- */
- function privateAction($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->webroot = $webroot;
- $this->controller->viewPath = 'errors';
- $this->controller->set(array('controller' => $className,
- 'action' => $action,
- 'title' => 'Trying to access private method in class'));
- $this->controller->render('privateAction');
- exit();
- }
-/**
- * Renders the Missing Table web page.
- *
- * @param array $params
- */
- function missingTable($params) {
- extract($params);
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('model' => $className,
- 'table' => $table,
- 'title' => 'Missing Database Table'));
- $this->controller->render('missingTable');
- exit();
- }
-/**
- * Renders the Missing Database web page.
- *
- * @param array $params
- */
- function missingDatabase($params = array()) {
- extract($params);
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('title' => 'Scaffold Missing Database Connection'));
- $this->controller->render('missingScaffolddb');
- exit();
- }
-/**
- * Renders the Missing View web page.
- *
- * @param array $params
- */
- function missingView($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('controller' => $className,
- 'action' => $action,
- 'file' => $file,
- 'title' => 'Missing View'));
- $this->controller->render('missingView');
- exit();
- }
-/**
- * Renders the Missing Layout web page.
- *
- * @param array $params
- */
- function missingLayout($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->layout = 'default';
- $this->controller->set(array('file' => $file,
- 'title' => 'Missing Layout'));
- $this->controller->render('missingLayout');
- exit();
- }
-/**
- * Renders the Database Connection web page.
- *
- * @param array $params
- */
- function missingConnection($params) {
- extract($params);
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('model' => $className,
- 'title' => 'Missing Database Connection'));
- $this->controller->render('missingConnection');
- exit();
- }
-/**
- * Renders the Missing Helper file web page.
- *
- * @param array $params
- */
- function missingHelperFile($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('helperClass' => Inflector::camelize($helper) . "Helper",
- 'file' => $file,
- 'title' => 'Missing Helper File'));
- $this->controller->render('missingHelperFile');
- exit();
- }
-/**
- * Renders the Missing Helper class web page.
- *
- * @param array $params
- */
- function missingHelperClass($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('helperClass' => Inflector::camelize($helper) . "Helper",
- 'file' => $file,
- 'title' => 'Missing Helper Class'));
- $this->controller->render('missingHelperClass');
- exit();
- }
-/**
- * Renders the Missing Component file web page.
- *
- * @param array $params
- */
- function missingComponentFile($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('controller' => $className,
- 'component' => $component,
- 'file' => $file,
- 'title' => 'Missing Component File'));
- $this->controller->render('missingComponentFile');
- exit();
- }
-/**
- * Renders the Missing Component class web page.
- *
- * @param array $params
- */
- function missingComponentClass($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('controller' => $className,
- 'component' => $component,
- 'file' => $file,
- 'title' => 'Missing Component Class'));
- $this->controller->render('missingComponentClass');
- exit();
- }
-/**
- * Renders the Missing Model class web page.
- *
- * @param unknown_type $params
- */
- function missingModel($params) {
- extract($params);
- $this->controller->base = $base;
- $this->controller->viewPath = 'errors';
- $this->controller->webroot = $this->_webroot();
- $this->controller->set(array('model' => $className,
- 'title' => 'Missing Model'));
- $this->controller->render('missingModel');
- exit();
- }
-/**
- * Path to the web root.
- *
- * @return string full web root path
- */
- function _webroot() {
- $this->__dispatch->baseUrl();
- return $this->__dispatch->webroot;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/file.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/file.php
deleted file mode 100644
index 4801226..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/file.php
+++ /dev/null
@@ -1,293 +0,0 @@
-<?php
-/* SVN FILE: $Id: file.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Convenience class for reading, writing and appending to files.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
- if (!class_exists('Object')) {
- uses ('object');
- }
-
- if (!class_exists('Folder')) {
- uses ('folder');
- }
-/**
- * Convenience class for reading, writing and appending to files.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class File extends Object{
-/**
- * Folder of the File
- *
- * @var Folder
- */
- var $folder = null;
-/**
- * Filename
- *
- * @var string
- */
- var $name = null;
-/**
- * Constructor
- *
- * @param string $path
- * @param boolean $create Create file if it does not exist
- * @return File
- */
- function __construct($path, $create = false) {
- parent::__construct();
- $this->folder = new Folder(dirname($path), $create);
- $this->name = basename($path);
- if (!$this->exists()) {
- if ($create === true) {
- if (!$this->create()) {
- return false;
- }
- } else {
- return false;
- }
- }
- }
-/**
- * Return the contents of this File as a string.
- *
- * @return string Contents
- */
- function read() {
- $contents = file_get_contents($this->getFullPath());
- return $contents;
- }
-/**
- * Append given data string to this File.
- *
- * @param string $data Data to write
- * @return boolean Success
- */
- function append($data) {
- return $this->write($data, 'a');
- }
-/**
- * Write given data to this File.
- *
- * @param string $data Data to write to this File.
- * @param string $mode Mode of writing. {@link http://php.net/fwrite See fwrite()}.
- * @return boolean Success
- */
- function write($data, $mode = 'w') {
- $file = $this->getFullPath();
- if (!($handle = fopen($file, $mode))) {
- print ("[File] Could not open $file with mode $mode!");
- return false;
- }
-
- if (!fwrite($handle, $data)) {
- return false;
- }
-
- if (!fclose($handle)) {
- return false;
- }
- return true;
- }
-/**
- * Get md5 Checksum of file with previous check of Filesize
- *
- * @param string $force Data to write to this File.
- * @return string md5 Checksum {@link http://php.net/md5_file See md5_file()}
- */
- function getMd5($force = false) {
- $md5 = '';
- if ($force == true || $this->getSize(false) < MAX_MD5SIZE) {
- $md5 = md5_file($this->getFullPath());
- }
- return $md5;
- }
-/**
- * Returns the Filesize, either in bytes or in human-readable format.
- *
- * @param boolean $humanReadeble Data to write to this File.
- * @return string|int filesize as int or as a human-readable string
- */
- function getSize() {
- $size = filesize($this->getFullPath());
- return $size;
- }
-/**
- * Returns the File extension.
- *
- * @return string The Fileextension
- */
- function getExt() {
- $ext = '';
- $parts = explode('.', $this->getName());
-
- if (count($parts) > 1) {
- $ext = array_pop($parts);
- } else {
- $ext = '';
- }
- return $ext;
- }
-/**
- * Returns the filename.
- *
- * @return string The Filename
- */
- function getName() {
- return $this->name;
- }
-/**
- * Returns the File's owner.
- *
- * @return int the Fileowner
- */
- function getOwner() {
- $fileowner = fileowner($this->getFullPath());
- return $fileowner;
- }
-/**
- * Returns the File group.
- *
- * @return int the Filegroup
- */
- function getGroup() {
- $filegroup = filegroup($this->getFullPath());
- return $filegroup;
- }
-/**
- * Creates the File.
- *
- * @return boolean Success
- */
- function create() {
- $dir = $this->folder->pwd();
-
- if (file_exists($dir) && is_dir($dir) && is_writable($dir) && !$this->exists()) {
- if (!touch($this->getFullPath())) {
- print ('[File] Could not create '.$this->getName().'!');
- return false;
- } else {
- return true;
- }
- } else {
- print ('[File] Could not create '.$this->getName().'!');
- return false;
- }
- }
-/**
- * Returns true if the File exists.
- *
- * @return boolean
- */
- function exists() {
- $exists = file_exists($this->getFullPath());
- return $exists;
- }
-/**
- * Deletes the File.
- *
- * @return boolean
- */
- function delete() {
- $unlink = unlink($this->getFullPath());
- return $unlink;
- }
-/**
- * Returns true if the File is writable.
- *
- * @return boolean
- */
- function writable() {
- $writable = is_writable($this->getFullPath());
- return $writable;
- }
-/**
- * Returns true if the File is executable.
- *
- * @return boolean
- */
- function executable() {
- $executable = is_executable($this->getFullPath());
- return $executable;
- }
-/**
- * Returns true if the File is readable.
- *
- * @return boolean
- */
- function readable() {
- $readable = is_readable($this->getFullPath());
- return $readable;
- }
-/**
- * Returns last access time.
- *
- * @return int timestamp
- */
- function lastAccess() {
- $fileatime = fileatime($this->getFullPath());
- return $fileatime;
- }
-/**
- * Returns last modified time.
- *
- * @return int timestamp
- */
- function lastChange() {
- $filemtime = filemtime($this->getFullPath());
- return $filemtime;
- }
-/**
- * Returns the current folder.
- *
- * @return Folder
- */
- function getFolder() {
- return $this->folder;
- }
-/**
- * Returns the "chmod" (permissions) of the File.
- *
- * @return string
- */
- function getChmod() {
- $substr = substr(sprintf('%o', fileperms($this->getFullPath())), -4);
- return $substr;
- }
-/**
- * Returns the full path of the File.
- *
- * @return string
- */
- function getFullPath() {
- return $this->folder->slashTerm($this->folder->pwd()) . $this->getName();
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/flay.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/flay.php
deleted file mode 100644
index dfe105f..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/flay.php
+++ /dev/null
@@ -1,278 +0,0 @@
-<?php
-/* SVN FILE: $Id: flay.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Text-to-HTML parser.
- *
- * Text-to-html parser, similar to {@link http://textism.com/tools/textile/ Textile} or {@link http://www.whytheluckystiff.net/ruby/redcloth/ RedCloth}.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
- if (!class_exists('Object')) {
- uses ('object');
- }
-/**
- * Text-to-HTML parser.
- *
- * Text-to-html parser, similar to Textile or RedCloth, only with a little different syntax.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Flay extends Object{
-/**
- * Text to be parsed.
- *
- * @var string
- */
- var $text = null;
-/**
- * Set this to allow HTML in the markup.
- *
- * @var boolean
- */
- var $allow_html = false;
-/**
- * Constructor.
- *
- * @param string $text
- */
- function __construct($text = null) {
- $this->text = $text;
- parent::__construct();
- }
-/**
- * Returns given text translated to HTML using the Flay syntax.
- *
- * @param string $text String to format
- * @param boolean $bare Set this to only do <p> transforms and > to &gt;, no typography additions.
- * @param boolean $allowHtml Set this to trim whitespace and disable all HTML
- * @return string Formatted text
- */
- function toHtml($text = null, $bare = false, $allowHtml = false) {
- if (empty($text) && empty($this->text)) {
- return false;
- }
- $text = $text ? $text : $this->text;
- // trim whitespace and disable all HTML
- if ($allowHtml) {
- $text = trim($text);
- } else {
- $text = str_replace('<', '&lt;', str_replace('>', '&gt;', trim($text)));
- }
-
- if (!$bare) {
- // multi-paragraph functions
- $text=preg_replace('#(?:[\n]{0,2})"""(.*)"""(?:[\n]{0,2})#s', "\n\n%BLOCKQUOTE%\n\n\\1\n\n%ENDBLOCKQUOTE%\n\n", $text);
- $text=preg_replace('#(?:[\n]{0,2})===(.*)===(?:[\n]{0,2})#s', "\n\n%CENTER%\n\n\\1\n\n%ENDCENTER%\n\n", $text);
- }
-
- // pre-parse newlines
- $text=preg_replace("#\r\n#", "\n", $text);
- $text=preg_replace("#[\n]{2,}#", "%PARAGRAPH%", $text);
- $text=preg_replace('#[\n]{1}#', "%LINEBREAK%", $text);
- $out ='';
-
- foreach (split('%PARAGRAPH%', $text)as $line) {
- if ($line) {
- if (!$bare) {
- $links = array();
- $regs = null;
-
- if (preg_match_all('#\[([^\[]{4,})\]#', $line, $regs)) {
- foreach ($regs[1] as $reg) {
- $links[] = $reg;
- $line = str_replace("[{$reg}]", '%LINK' . (count($links) - 1) . '%', $line);
- }
- }
- // bold
- $line = ereg_replace("\*([^\*]*)\*", "<strong>\\1</strong>", $line);
- // italic
- $line = ereg_replace("_([^_]*)_", "<em>\\1</em>", $line);
- }
- // entities
- $line = str_replace(' - ', ' &ndash; ', $line);
- $line = str_replace(' -- ', ' &mdash; ', $line);
- $line = str_replace('(C)', '&copy;', $line);
- $line = str_replace('(R)', '&reg;', $line);
- $line = str_replace('(TM)', '&trade;', $line);
- // guess e-mails
- $emails = null;
- if (preg_match_all("#([_A-Za-z0-9+-+]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#", $line, $emails)) {
- foreach ($emails[1] as $email) {
- $line = str_replace($email, "<a href=\"mailto:{$email}\">{$email}</a>", $line);
- }
- }
-
- if (!$bare) {
- $urls = null;
- if (preg_match_all("#((?:http|https|ftp|nntp)://[^ ]+)#", $line, $urls)) {
- foreach ($urls[1] as $url) {
- $line = str_replace($url, "<a href=\"{$url}\">{$url}</a>", $line);
- }
- }
-
- if (preg_match_all("#(www\.[^\n\%\ ]+[^\n\%\,\.\ ])#", $line, $urls)) {
- foreach ($urls[1] as $url) {
- $line = str_replace($url, "<a href=\"http://{$url}\">{$url}</a>", $line);
- }
- }
-
- if (count($links)) {
- for ($ii = 0; $ii < count($links); $ii++) {
- if (preg_match("#^(http|https|ftp|nntp)://#", $links[$ii])) {
- $prefix = null;
- } else {
- $prefix = 'http://';
- }
- if (preg_match('#^[^\ ]+\.(jpg|jpeg|gif|png)$#', $links[$ii])) {
- $with = "<img src=\"{$prefix}{$links[$ii]}\" alt=\"\" />";
- } elseif (preg_match('#^([^\]\ ]+)(?:\ ([^\]]+))?$#', $links[$ii], $regs)) {
- if (isset($regs[2])) {
- if (preg_match('#\.(jpg|jpeg|gif|png)$#', $regs[2])) {
- $body = "<img src=\"{$prefix}{$regs[2]}\" alt=\"\" />";
- } else {
- $body = $regs[2];
- }
- } else {
- $body = $links[$ii];
- }
- $with = "<a href=\"{$prefix}{$regs[1]}\" target=\"_blank\">{$body}</a>";
- } else {
- $with = $prefix . $links[$ii];
- }
- $line = str_replace("%LINK{$ii}%", $with, $line);
- }
- }
- }
- $out .= str_replace('%LINEBREAK%', "<br />\n", "<p>{$line}</p>\n");
- }
- }
-
- if (!$bare) {
- $out = str_replace('<p>%BLOCKQUOTE%</p>', "<blockquote>", $out);
- $out = str_replace('<p>%ENDBLOCKQUOTE%</p>', "</blockquote>", $out);
- $out = str_replace('<p>%CENTER%</p>', "<center>", $out);
- $out = str_replace('<p>%ENDCENTER%</p>', "</center>", $out);
- }
- return $out;
- }
-/**
- * Return the words of the string as an array.
- *
- * @param string $string
- * @return array Array of words
- */
- function extractWords($string) {
- $split = preg_split('/[\s,\.:\/="!\(\)<>~\[\]]+/', $string);
- return $split;
- }
-/**
- * Return given string with words in array colorMarked, up to a number of times (defaults to 5).
- *
- * @param array $words Words to look for and markup
- * @param string $string String to look in
- * @param integer $max_snippets Max number of snippets to extract
- * @return string
- * @see colorMark
- */
- function markedSnippets($words, $string, $max_snippets = 5) {
- $string = strip_tags($string);
- $snips = array();
- $rest = $string;
- foreach ($words as $word) {
- if (preg_match_all("/[\s,]+.{0,40}{$word}.{0,40}[\s,]+/i", $rest, $r)) {
- foreach ($r as $result) {
- $rest = str_replace($result, '', $rest);
- }
- $snips = array_merge($snips, $r[0]);
- }
- }
-
- if (count($snips) > $max_snippets) {
- $snips = array_slice($snips, 0, $max_snippets);
- }
- $joined = join(' <b>...</b> ', $snips);
- $snips = $joined ? "<b>...</b> {$joined} <b>...</b>" : substr($string, 0, 80) . '<b>...</b>';
- return $this->colorMark($words, $snips);
- }
-/**
- * Returns string with EM elements with color classes added.
- *
- * @param array $words Array of words to be colorized
- * @param string $string Text in which the words might be found
- * @return string
- */
- function colorMark($words, $string) {
- $colors=array('yl', 'gr', 'rd', 'bl', 'fu', 'cy');
- $nextColorIndex = 0;
- foreach ($words as $word) {
- $string = preg_replace("/({$word})/i", '<em class="' . $colors[$nextColorIndex % count($colors)] . "\">\\1</em>", $string);
- $nextColorIndex++;
- }
- return $string;
- }
-/**
- * Returns given text with tags stripped out.
- *
- * @param string $text
- * @return string
- */
- function toClean($text) {
- $strip = strip_tags(html_entity_decode($text, ENT_QUOTES));
- return $strip;
- }
-/**
- * Return parsed text with tags stripped out.
- *
- * @param string $text
- * @return string
- */
- function toParsedAndClean($text) {
- return $this->toClean(Flay::toHtml($text));
- }
-/**
- * Return a fragment of a text, up to $length characters long, with an ellipsis after it.
- *
- * @param string $text Text to be truncated.
- * @param integer $length Max length of text.
- * @param string $ellipsis Sign to print after truncated text.
- * @return string
- */
- function fragment($text, $length, $ellipsis = '...') {
- $soft = $length - 5;
- $hard = $length + 5;
- $rx = '/(.{' . $soft . ',' . $hard . '})[\s,\.:\/="!\(\)<>~\[\]]+.*/';
-
- if (preg_match($rx, $text, $r)) {
- $out = $r[1];
- } else {
- $out = substr($text, 0, $length);
- }
- $out = $out . (strlen($out) < strlen($text) ? $ellipsis : null);
- return $out;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/folder.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/folder.php
deleted file mode 100644
index 331abee..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/folder.php
+++ /dev/null
@@ -1,328 +0,0 @@
-<?php
-/* SVN FILE: $Id: folder.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Convenience class for handling directories.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
- if (!class_exists('Object')) {
- uses ('object');
- }
-/**
- * Folder structure browser, lists folders and files.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Folder extends Object{
-/**
- * Path to Folder.
- *
- * @var string
- */
- var $path = null;
-/**
- * Sortedness.
- *
- * @var boolean
- */
- var $sort = false;
-/**
- * Constructor.
- *
- * @param string $path
- * @param boolean $path
- */
- function __construct($path = false, $create = false, $mode = false) {
- parent::__construct();
- if (empty($path)) {
- $path = getcwd();
- }
-
- if (!file_exists($path) && $create == true) {
- $this->mkdirr($path, $mode);
- }
- $this->cd($path);
- }
-/**
- * Return current path.
- *
- * @return string Current path
- */
- function pwd() {
- return $this->path;
- }
-/**
- * Change directory to $desired_path.
- *
- * @param string $desired_path Path to the directory to change to
- * @return string The new path. Returns false on failure
- */
- function cd($desiredPath) {
- $desiredPath = realpath($desiredPath);
- $newPath = $this->isAbsolute($desiredPath) ? $desiredPath : $this->addPathElement($this->path, $desiredPath);
- $isDir = (is_dir($newPath) && file_exists($newPath)) ? $this->path = $newPath : false;
- return $isDir;
- }
-/**
- * Returns an array of the contents of the current directory, or false on failure.
- * The returned array holds two arrays: one of dirs and one of files.
- *
- * @param boolean $sort
- * @param boolean $noDotFiles
- * @return array
- */
- function ls($sort = true, $noDotFiles = false) {
- $dirs = $files = array();
- $dir = opendir($this->path);
- if ($dir) {
- while (false !== ($n = readdir($dir))) {
- if ((!preg_match('#^\.+$#', $n) && $noDotFiles == false) || ($noDotFiles == true && !preg_match('#^\.(.*)$#', $n))) {
- if (is_dir($this->addPathElement($this->path, $n))) {
- $dirs[] = $n;
- } else {
- $files[] = $n;
- }
- }
- }
-
- if ($sort || $this->sort) {
- sort ($dirs);
- sort ($files);
- }
- closedir ($dir);
- }
- return array($dirs,$files);
- }
-/**
- * Returns an array of all matching files in current directory.
- *
- * @param string $pattern Preg_match pattern (Defaults to: .*)
- * @return array
- */
- function find($regexp_pattern = '.*') {
- $data = $this->ls();
-
- if (!is_array($data)) {
- return array();
- }
-
- list($dirs, $files) = $data;
- $found = array();
-
- foreach ($files as $file) {
- if (preg_match("/^{$regexp_pattern}$/i", $file)) {
- $found[] = $file;
- }
- }
- return $found;
- }
-/**
- * Returns an array of all matching files in and below current directory.
- *
- * @param string $pattern Preg_match pattern (Defaults to: .*)
- * @return array Files matching $pattern
- */
- function findRecursive($pattern = '.*') {
- $startsOn = $this->path;
- $out = $this->_findRecursive($pattern);
- $this->cd($startsOn);
- return $out;
- }
-/**
- * Private helper function for findRecursive.
- *
- * @param string $pattern
- * @return array Files matching pattern
- * @access private
- */
- function _findRecursive($pattern) {
- list($dirs, $files) = $this->ls();
-
- $found = array();
- foreach ($files as $file) {
- if (preg_match("/^{$pattern}$/i", $file)) {
- $found[] = $this->addPathElement($this->path, $file);
- }
- }
- $start = $this->path;
- foreach ($dirs as $dir) {
- $this->cd($this->addPathElement($start, $dir));
- $found = array_merge($found, $this->findRecursive($pattern));
- }
- return $found;
- }
-/**
- * Returns true if given $path is a Windows path.
- *
- * @param string $path Path to check
- * @return boolean
- * @static
- */
- function isWindowsPath($path) {
- $match = preg_match('#^[A-Z]:\\\#i', $path) ? true : false;
- return $match;
- }
-/**
- * Returns true if given $path is an absolute path.
- *
- * @param string $path Path to check
- * @return boolean
- * @static
- */
- function isAbsolute($path) {
- $match = preg_match('#^\/#', $path) || preg_match('#^[A-Z]:\\\#i', $path);
- return $match;
- }
-/**
- * Returns true if given $path ends in a slash (i.e. is slash-terminated).
- *
- * @param string $path Path to check
- * @return boolean
- * @static
- */
- function isSlashTerm($path) {
- $match = preg_match('#[\\\/]$#', $path) ? true : false;
- return $match;
- }
-/**
- * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
- *
- * @param string $path Path to check
- * @return string Set of slashes ("\\" or "/")
- * @static
- */
- function correctSlashFor($path) {
- return $this->isWindowsPath($path) ? '\\' : '/';
- }
-/**
- * Returns $path with added terminating slash (corrected for Windows or other OS).
- *
- * @param string $path Path to check
- * @return string
- * @static
- */
-function slashTerm($path) {
- return $path . ($this->isSlashTerm($path) ? null : $this->correctSlashFor($path));
- }
-/**
- * Returns $path with $element added, with correct slash in-between.
- *
- * @param string $path
- * @param string $element
- * @return string
- * @static
- */
- function addPathElement($path, $element) {
- return $this->slashTerm($path) . $element;
- }
-/**
- * Returns true if the File is in a given CakePath.
- *
- * @return boolean
- */
- function inCakePath($path = '') {
- $dir = substr($this->slashTerm(ROOT), 0, -1);
- $newdir = $this->slashTerm($dir . $path);
- return $this->inPath($newdir);
- }
-/**
- * Returns true if the File is in given path.
- *
- * @return boolean
- */
- function inPath($path = '') {
- $dir = substr($this->slashTerm($path), 0, -1);
- $return = preg_match('/^' . preg_quote($this->slashTerm($dir), '/') . '(.*)/', $this->slashTerm($this->pwd()));
- if ($return == 1) {
- return true;
- } else {
- return false;
- }
- }
-/**
- * Create a directory structure recursively.
- *
- * @param string $pathname The directory structure to create
- * @return bool Returns TRUE on success, FALSE on failure
- */
- function mkdirr($pathname, $mode = null) {
- if (is_dir($pathname) || empty($pathname)) {
- return true;
- }
-
- if (is_file($pathname)) {
- trigger_error('mkdirr() File exists', E_USER_WARNING);
- return false;
- }
- $nextPathname = substr($pathname, 0, strrpos($pathname, DIRECTORY_SEPARATOR));
-
- if ($this->mkdirr($nextPathname, $mode)) {
- if (!file_exists($pathname)) {
- umask (0);
- $mkdir = mkdir($pathname, $mode);
- return $mkdir;
- }
- }
- return false;
- }
-/**
- * Returns the size in bytes of this Folder.
- *
- * @param string $directory Path to directory
- */
- function dirsize() {
- $size = 0;
- $directory = $this->slashTerm($this->path);
- $stack = array($directory);
- $count = count($stack);
- for ($i = 0, $j = $count; $i < $j; ++$i) {
- if (is_file($stack[$i])) {
- $size += filesize($stack[$i]);
- } elseif (is_dir($stack[$i])) {
- $dir = dir($stack[$i]);
-
- while (false !== ($entry = $dir->read())) {
- if ($entry == '.' || $entry == '..') {
- continue;
- }
- $add = $stack[$i] . $entry;
-
- if (is_dir($stack[$i] . $entry)) {
- $add = $this->slashTerm($add);
- }
- $stack[ ]= $add;
- }
- $dir->close();
- }
- $j = count($stack);
- }
- return $size;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/inflector.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/inflector.php
deleted file mode 100644
index edf91c5..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/inflector.php
+++ /dev/null
@@ -1,437 +0,0 @@
-<?php
-/* SVN FILE: $Id: inflector.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Pluralize and singularize English words.
- *
- * Used by Cake's naming conventions throughout the framework.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
- if (!class_exists('Object')) {
- uses('object');
- }
- uses('Set');
-/**
- * Pluralize and singularize English words.
- *
- * Inflector pluralizes and singularizes English nouns.
- * Used by Cake's naming conventions throughout the framework.
- * Test with $i = new Inflector(); $i->test();
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Inflector extends Object {
-/**
- * Constructor.
- *
- */
- function __construct() {
- parent::__construct();
- }
-/**
- * Gets a reference to the Inflector object instance
- *
- * @return object
- * @access public
- */
- function &getInstance() {
- static $instance = array();
-
- if (!isset($instance[0]) || !$instance[0]) {
- $instance[0] =& new Inflector();
- }
-
- return $instance[0];
- }
-/**
- * Initializes plural inflection rules
- *
- * @access protected
- */
- function __initPluralRules() {
- $_this =& Inflector::getInstance();
- $corePluralRules = array('/(s)tatus$/i' => '\1\2tatuses',
- '/(quiz)$/i' => '\1zes',
- '/^(ox)$/i' => '\1\2en',
- '/([m|l])ouse$/i' => '\1ice',
- '/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
- '/(x|ch|ss|sh)$/i' => '\1es',
- '/([^aeiouy]|qu)y$/i' => '\1ies',
- '/(hive)$/i' => '\1s',
- '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
- '/sis$/i' => 'ses',
- '/([ti])um$/i' => '\1a',
- '/(p)erson$/i' => '\1eople',
- '/(m)an$/i' => '\1en',
- '/(c)hild$/i' => '\1hildren',
- '/(buffal|tomat)o$/i' => '\1\2oes',
- '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
- '/us$/' => 'uses',
- '/(alias)$/i' => '\1es',
- '/(ax|cri|test)is$/i' => '\1es',
- '/s$/' => 's',
- '/$/' => 's',);
-
- $coreUninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'Amoyese',
- 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
- 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
- 'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
- 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
- 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
- 'nexus', 'Niasese', 'Pekingese', 'People', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
- 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
- 'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
- 'whiting', 'wildebeest', 'Yengeese',);
-
- $coreIrregularPlural = array('atlas' => 'atlases',
- 'beef' => 'beefs',
- 'brother' => 'brothers',
- 'child' => 'children',
- 'corpus' => 'corpuses',
- 'cow' => 'cows',
- 'ganglion' => 'ganglions',
- 'genie' => 'genies',
- 'genus' => 'genera',
- 'graffito' => 'graffiti',
- 'hoof' => 'hoofs',
- 'loaf' => 'loaves',
- 'man' => 'men',
- 'money' => 'monies',
- 'mongoose' => 'mongooses',
- 'move' => 'moves',
- 'mythos' => 'mythoi',
- 'numen' => 'numina',
- 'occiput' => 'occiputs',
- 'octopus' => 'octopuses',
- 'opus' => 'opuses',
- 'ox' => 'oxen',
- 'penis' => 'penises',
- 'person' => 'people',
- 'sex' => 'sexes',
- 'soliloquy' => 'soliloquies',
- 'testis' => 'testes',
- 'trilby' => 'trilbys',
- 'turf' => 'turfs',);
-
- $pluralRules = $corePluralRules;
- $uninflected = $coreUninflectedPlural;
- $irregular = $coreIrregularPlural;
-
- if (file_exists(CONFIGS . 'inflections.php')) {
- include(CONFIGS.'inflections.php');
- $pluralRules = Set::pushDiff($pluralRules, $corePluralRules);
- $uninflected = Set::pushDiff($uninflectedPlural, $coreUninflectedPlural);
- $irregular = Set::pushDiff($irregularPlural, $coreIrregularPlural);
- }
- $_this->pluralRules = array('pluralRules' => $pluralRules, 'uninflected' => $uninflected, 'irregular' => $irregular);
- $_this->pluralized = array();
- }
-/**
- * Return $word in plural form.
- *
- * @param string $word Word in singular
- * @return string Word in plural
- * @access public
- * @static
- */
- function pluralize($word) {
-
- $_this =& Inflector::getInstance();
- if (!isset($_this->pluralRules) || empty($_this->pluralRules)) {
- $_this->__initPluralRules();
- }
-
- if (isset($_this->pluralized[$word])) {
- return $_this->pluralized[$word];
- }
-
- extract($_this->pluralRules);
- if (!isset($regexUninflected) || !isset($regexIrregular)) {
- $regexUninflected = __enclose(join( '|', $uninflected));
- $regexIrregular = __enclose(join( '|', array_keys($irregular)));
- $_this->pluralRules['regexUninflected'] = $regexUninflected;
- $_this->pluralRules['regexIrregular'] = $regexIrregular;
- }
-
- if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
- $_this->pluralized[$word] = $regs[1] . substr($word, 0, 1) . substr($irregular[strtolower($regs[2])], 1);
- return $_this->pluralized[$word];
- }
-
- if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
- $_this->pluralized[$word] = $word;
- return $word;
- }
-
- foreach ($pluralRules as $rule => $replacement) {
- if (preg_match($rule, $word)) {
- $_this->pluralized[$word] = preg_replace($rule, $replacement, $word);
- return $_this->pluralized[$word];
- }
- }
- $_this->pluralized[$word] = $word;
- return $word;
- }
-/**
- * Initializes singular inflection rules
- *
- * @access protected
- */
- function __initSingularRules() {
-
- $_this =& Inflector::getInstance();
- $coreSingularRules = array('/(s)tatuses$/i' => '\1\2tatus',
- '/^(.*)(menu)s$/i' => '\1\2',
- '/(quiz)zes$/i' => '\\1',
- '/(matr)ices$/i' => '\1ix',
- '/(vert|ind)ices$/i' => '\1ex',
- '/^(ox)en/i' => '\1',
- '/(alias)(es)*$/i' => '\1',
- '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
- '/(cris|ax|test)es$/i' => '\1is',
- '/(shoe)s$/i' => '\1',
- '/(o)es$/i' => '\1',
- '/ouses$/' => 'ouse',
- '/uses$/' => 'us',
- '/([m|l])ice$/i' => '\1ouse',
- '/(x|ch|ss|sh)es$/i' => '\1',
- '/(m)ovies$/i' => '\1\2ovie',
- '/(s)eries$/i' => '\1\2eries',
- '/([^aeiouy]|qu)ies$/i' => '\1y',
- '/([lr])ves$/i' => '\1f',
- '/(tive)s$/i' => '\1',
- '/(hive)s$/i' => '\1',
- '/(drive)s$/i' => '\1',
- '/([^f])ves$/i' => '\1fe',
- '/(^analy)ses$/i' => '\1sis',
- '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
- '/([ti])a$/i' => '\1um',
- '/(p)eople$/i' => '\1\2erson',
- '/(m)en$/i' => '\1an',
- '/(c)hildren$/i' => '\1\2hild',
- '/(n)ews$/i' => '\1\2ews',
- '/^(.*us)$/' => '\\1',
- '/s$/i' => '');
-
- $coreUninflectedSingular = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss', 'Amoyese',
- 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
- 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
- 'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
- 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
- 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
- 'nexus', 'Niasese', 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
- 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
- 'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
- 'whiting', 'wildebeest', 'Yengeese',);
-
- $coreIrregularSingular = array('atlases' => 'atlas',
- 'beefs' => 'beef',
- 'brothers' => 'brother',
- 'children' => 'child',
- 'corpuses' => 'corpus',
- 'cows' => 'cow',
- 'ganglions' => 'ganglion',
- 'genies' => 'genie',
- 'genera' => 'genus',
- 'graffiti' => 'graffito',
- 'hoofs' => 'hoof',
- 'loaves' => 'loaf',
- 'men' => 'man',
- 'monies' => 'money',
- 'mongooses' => 'mongoose',
- 'moves' => 'move',
- 'mythoi' => 'mythos',
- 'numina' => 'numen',
- 'occiputs' => 'occiput',
- 'octopuses' => 'octopus',
- 'opuses' => 'opus',
- 'oxen' => 'ox',
- 'penises' => 'penis',
- 'people' => 'person',
- 'sexes' => 'sex',
- 'soliloquies' => 'soliloquy',
- 'testes' => 'testis',
- 'trilbys' => 'trilby',
- 'turfs' => 'turf',);
-
- $singularRules = $coreSingularRules;
- $uninflected = $coreUninflectedSingular;
- $irregular = $coreIrregularSingular;
-
- if (file_exists(CONFIGS . 'inflections.php')) {
- include(CONFIGS.'inflections.php');
- $singularRules = Set::pushDiff($singularRules, $coreSingularRules);
- $uninflected = Set::pushDiff($uninflectedSingular, $coreUninflectedSingular);
- $irregular = Set::pushDiff($irregularSingular, $coreIrregularSingular);
- }
- $_this->singularRules = array('singularRules' => $singularRules, 'uninflected' => $uninflected, 'irregular' => $irregular);
- $_this->singularized = array();
- }
-/**
- * Return $word in singular form.
- *
- * @param string $word Word in plural
- * @return string Word in singular
- * @access public
- * @static
- */
- function singularize($word) {
- $_this =& Inflector::getInstance();
- if (!isset($_this->singularRules) || empty($_this->singularRules)) {
- $_this->__initSingularRules();
- }
-
- if (isset($_this->singularized[$word])) {
- return $_this->singularized[$word];
- }
-
- extract($_this->singularRules);
- if (!isset($regexUninflected) || !isset($regexIrregular)) {
- $regexUninflected = __enclose(join( '|', $uninflected));
- $regexIrregular = __enclose(join( '|', array_keys($irregular)));
- $_this->singularRules['regexUninflected'] = $regexUninflected;
- $_this->singularRules['regexIrregular'] = $regexIrregular;
- }
-
- if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
- $_this->singularized[$word] = $regs[1] . substr($word, 0, 1) . substr($irregular[strtolower($regs[2])], 1);
- return $_this->singularized[$word];
- }
-
- if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
- $_this->singularized[$word] = $word;
- return $word;
- }
-
- foreach ($singularRules as $rule => $replacement) {
- if (preg_match($rule, $word)) {
- $_this->singularized[$word] = preg_replace($rule, $replacement, $word);
- return $_this->singularized[$word];
- }
- }
- $_this->singularized[$word] = $word;
- return $word;
- }
-/**
- * Returns given $lower_case_and_underscored_word as a camelCased word.
- *
- * @param string $lower_case_and_underscored_word Word to camelize
- * @return string Camelized word. likeThis.
- * @access public
- * @static
- */
- function camelize($lowerCaseAndUnderscoredWord) {
- $replace = str_replace(" ", "", ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord)));
- return $replace;
- }
-/**
- * Returns an underscore-syntaxed ($like_this_dear_reader) version of the $camel_cased_word.
- *
- * @param string $camel_cased_word Camel-cased word to be "underscorized"
- * @return string Underscore-syntaxed version of the $camel_cased_word
- * @access public
- * @static
- */
- function underscore($camelCasedWord) {
- $replace = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
- return $replace;
- }
-/**
- * Returns a human-readable string from $lower_case_and_underscored_word,
- * by replacing underscores with a space, and by upper-casing the initial characters.
- *
- * @param string $lower_case_and_underscored_word String to be made more readable
- * @return string Human-readable string
- * @access public
- * @static
- */
- function humanize($lowerCaseAndUnderscoredWord) {
- $replace = ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord));
- return $replace;
- }
-/**
- * Returns corresponding table name for given $class_name. ("posts" for the model class "Post").
- *
- * @param string $class_name Name of class to get database table name for
- * @return string Name of the database table for given class
- * @access public
- * @static
- */
- function tableize($className) {
- $replace = Inflector::pluralize(Inflector::underscore($className));
- return $replace;
- }
-/**
- * Returns Cake model class name ("Post" for the database table "posts".) for given database table.
- *
- * @param string $tableName Name of database table to get class name for
- * @return string
- * @access public
- * @static
- */
- function classify($tableName) {
- $replace = Inflector::camelize(Inflector::singularize($tableName));
- return $replace;
- }
-/**
- * Returns camelBacked version of a string.
- *
- * @param string $string
- * @return string
- * @access public
- * @static
- */
- function variable($string) {
- $string = Inflector::camelize(Inflector::underscore($string));
- $replace = strtolower(substr($string, 0, 1));
- $variable = preg_replace('/\\w/', $replace, $string, 1);
- return $variable;
- }
-/**
- * Returns a string with all spaces converted to $replacement and non word characters removed.
- *
- * @param string $string
- * @param string $replacement
- * @return string
- * @access public
- * @static
- */
- function slug($string, $replacement = '_') {
- $string = preg_replace(array('/[^\w\s]/', '/\\s+/') , array(' ', $replacement), $string);
- return $string;
- }
-}
-/**
- * Enclose a string for preg matching.
- *
- * @param string $string String to enclose
- * @return string Enclosed string
- */
- function __enclose($string) {
- return '(?:' . $string . ')';
- }
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/legacy.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/legacy.php
deleted file mode 100644
index 3c89b8c..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/legacy.php
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-/* SVN FILE: $Id: legacy.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Backwards compatibility functions.
- *
- * With this hack you can use clone() in PHP4 code
- * use "clone($object)" not "clone $object"! the former works in both PHP4 and PHP5
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
- if (version_compare(phpversion(), '5.0') < 0) {
- if (!function_exists("clone")) {
- eval ('
- function clone($object) {
- return $object;
- }');
- }
- }
-/**
- * Replace file_get_contents()
- *
- * @internal resource_context is not supported
- * @since PHP 5
- * require PHP 4.0.0 (user_error)
- *
- * @param unknown_type $filename
- * @param unknown_type $incpath
- * @return unknown
- */
- if (!function_exists('file_get_contents')) {
- function file_get_contents($filename, $incpath = false) {
- if (false === $fh = fopen($filename, 'rb', $incpath)) {
- user_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
- return false;
- }
- clearstatcache();
-
- if ($fsize = @filesize($filename)) {
- $data = fread($fh, $fsize);
- } else {
- $data='';
-
- while (!feof($fh)) {
- $data .= fread($fh, 8192);
- }
- }
- fclose ($fh);
- return $data;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/connection_manager.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/connection_manager.php
deleted file mode 100644
index 946327e..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/connection_manager.php
+++ /dev/null
@@ -1,243 +0,0 @@
-<?php
-/* SVN FILE: $Id: connection_manager.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model
- * @since CakePHP(tm) v 0.10.x.1402
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Manages loaded instances of DataSource objects
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.model
- */
-
-uses ('model' . DS . 'datasources' . DS . 'datasource');
-config('database');
-
-class ConnectionManager extends Object {
-
-/**
- * Holds a loaded instance of the Connections object
- *
- * @var class:Connections
- * @access public
- */
- var $config = null;
-/**
- * Holds instances DataSource objects
- *
- * @var array
- * @access private
- */
- var $_dataSources = array();
-/**
- * Contains a list of all file and class names used in Connection settings
- *
- * @var array
- * @access private
- */
- var $_connectionsEnum = array();
-/**
- * Constructor.
- *
- */
- function __construct() {
- if (class_exists('DATABASE_CONFIG')) {
- $this->config = new DATABASE_CONFIG();
- }
- }
-/**
- * Gets a reference to the ConnectionManger object instance
- *
- * @return object
- */
- function &getInstance() {
- static $instance = array();
-
- if (!isset($instance[0]) || !$instance[0]) {
- $instance[0] = &new ConnectionManager();
- }
-
- return $instance[0];
- }
-/**
- * Gets a reference to a DataSource object
- *
- * @param string $name The name of the DataSource, as defined in app/config/connections
- * @return object
- */
- function &getDataSource($name) {
- $_this =& ConnectionManager::getInstance();
-
- if (in_array($name, array_keys($_this->_dataSources))) {
- return $_this->_dataSources[$name];
- }
-
- $connections = $_this->enumConnectionObjects();
- if (in_array($name, array_keys($connections))) {
- $conn = $connections[$name];
- $class = $conn['classname'];
- $_this->loadDataSource($name);
- $_this->_dataSources[$name] =& new $class($_this->config->{$name});
- $_this->_dataSources[$name]->configKeyName = $name;
- } else {
- trigger_error(sprintf(__("ConnectionManager::getDataSource - Non-existent data source %s", true), $name), E_USER_ERROR);
- return null;
- }
-
- return $_this->_dataSources[$name];
- }
-/**
- * Gets a DataSource name from an object reference
- *
- * @param object $source
- * @return string
- */
- function getSourceName(&$source) {
- $_this =& ConnectionManager::getInstance();
-
- $names = array_keys($_this->_dataSources);
- for ($i = 0; $i < count($names); $i++) {
- if ($_this->_dataSources[$names[$i]] === $source) {
- return $names[$i];
- }
- }
- return null;
- }
-/**
- * Loads the DataSource class for the given connection name
- *
- * @param mixed $connName A string name of the connection, as defined in Connections config,
- * or an array containing the file and class name of the object.
- * @return boolean True on success, null on failure or false if the class is already loaded
- */
- function loadDataSource($connName) {
- $_this =& ConnectionManager::getInstance();
-
- if (is_array($connName)) {
- $conn = $connName;
- } else {
- $connections = $_this->enumConnectionObjects();
- $conn = $connections[$connName];
- }
-
- if (isset($conn['parent']) && !empty($conn['parent'])) {
- $_this->loadDataSource($conn['parent']);
- }
-
- if (class_exists($conn['classname'])) {
- return false;
- }
-
- if (file_exists(MODELS . DS . $conn['filename'] . '.php')) {
- require (MODELS . DS . $conn['filename'] . '.php');
- } elseif (fileExistsInPath(LIBS . 'model' . DS . $conn['filename'] . '.php')) {
- require (LIBS . 'model' . DS . $conn['filename'] . '.php');
- } else {
- trigger_error(sprintf(__('Unable to load DataSource file %s.php', true), $conn['filename']), E_USER_ERROR);
- return null;
- }
- }
-/**
- * Gets a list of class and file names associated with the user-defined DataSource connections
- *
- * @return array An associative array of elements where the key is the connection name
- * (as defined in Connections), and the value is an array with keys 'filename' and 'classname'.
- */
- function enumConnectionObjects() {
- $_this =& ConnectionManager::getInstance();
-
- if (!empty($_this->_connectionsEnum)) {
- return $_this->_connectionsEnum;
- }
- $connections = get_object_vars($_this->config);
-
- if ($connections != null) {
- foreach ($connections as $name => $config) {
- $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
- }
- return $_this->_connectionsEnum;
- } else {
- $_this->cakeError('missingConnection', array(array('className' => 'ConnectionManager')));
- }
- }
-/**
- * Dynamically creates a DataSource object at runtime, with the given name and settings
- *
- * @param string $name The DataSource name
- * @param array $config The DataSource configuration settings
- * @return object A reference to the DataSource object, or null if creation failed
- */
- function &create($name = '', $config = array()) {
- $_this =& ConnectionManager::getInstance();
-
- if (empty($name) || empty($config) || array_key_exists($name, $_this->_connectionsEnum)) {
- $null = null;
- return $null;
- }
-
- $_this->config->{$name} = $config;
- $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
- return $_this->getDataSource($name);
- }
-/**
- * Private method
- *
- * Returns the file and class name for the given driver
- */
- function __getDriver($config) {
- $_this =& ConnectionManager::getInstance();
-
- if (!isset($config['datasource'])) {
- $config['datasource'] = 'dbo';
- }
-
- if (isset($config['driver']) && $config['driver'] != null && !empty($config['driver'])) {
- $filename = $config['datasource'] . DS . $config['datasource'] . '_' . $config['driver'];
- $classname = Inflector::camelize(strtolower($config['datasource'] . '_' . $config['driver']));
- $parent = $_this->__getDriver(array('datasource' => $config['datasource']));
- } else {
- $filename = 'datasources' . DS . $config['datasource'] . '_source';
- $classname = Inflector::camelize(strtolower($config['datasource'] . '_source'));
- $parent = null;
- }
- return array('filename' => $filename, 'classname' => $classname, 'parent' => $parent);
- }
-/**
- * Destructor.
- *
- */
- function __destruct() {
- if (CAKE_SESSION_SAVE == 'database' && function_exists('session_write_close')) {
- session_write_close();
- }
- }
-}
-
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/datasource.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/datasource.php
deleted file mode 100644
index a055577..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/datasource.php
+++ /dev/null
@@ -1,519 +0,0 @@
-<?php
-/* SVN FILE: $Id: datasource.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * DataSource base class
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.datasources
- * @since CakePHP(tm) v 0.10.5.1790
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * DataSource base class
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.model.datasources
- */
-class DataSource extends Object {
-/**
- * Are we connected to the DataSource?
- *
- * @var boolean
- * @access public
- */
- var $connected = false;
-/**
- * Print debug info?
- *
- * @var boolean
- * @access public
- */
- var $debug = false;
-/**
- * Print full query debug info?
- *
- * @var boolean
- * @access public
- */
- var $fullDebug = false;
-/**
- * Error description of last query
- *
- * @var unknown_type
- * @access public
- */
- var $error = null;
-/**
- * String to hold how many rows were affected by the last SQL operation.
- *
- * @var string
- * @access public
- */
- var $affected = null;
-/**
- * Number of rows in current resultset
- *
- * @var int
- * @access public
- */
- var $numRows = null;
-/**
- * Time the last query took
- *
- * @var int
- * @access public
- */
- var $took = null;
-/**
- * Enter description here...
- *
- * @var array
- * @access private
- */
- var $_result = null;
-/**
- * Queries count.
- *
- * @var int
- * @access private
- */
- var $_queriesCnt = 0;
-/**
- * Total duration of all queries.
- *
- * @var unknown_type
- * @access private
- */
- var $_queriesTime = null;
-/**
- * Log of queries executed by this DataSource
- *
- * @var unknown_type
- * @access private
- */
- var $_queriesLog = array();
-/**
- * Maximum number of items in query log, to prevent query log taking over
- * too much memory on large amounts of queries -- I we've had problems at
- * >6000 queries on one system.
- *
- * @var int Maximum number of queries in the queries log.
- * @access private
- */
- var $_queriesLogMax = 200;
-/**
- * Caches serialzed results of executed queries
- *
- * @var array Maximum number of queries in the queries log.
- * @access private
- */
- var $_queryCache = array();
-/**
- * The default configuration of a specific DataSource
- *
- * @var array
- * @access public
- */
- var $_baseConfig = array();
-/**
- * Holds references to descriptions loaded by the DataSource
- *
- * @var array
- * @access private
- */
- var $__descriptions = array();
-/**
- * Holds a list of sources (tables) contained in the DataSource
- *
- * @var array
- * @access protected
- */
- var $_sources = null;
-/**
- * A reference to the physical connection of this DataSource
- *
- * @var array
- * @access public
- */
- var $connection = null;
-/**
- * The DataSource configuration
- *
- * @var array
- * @access public
- */
- var $config = array();
-/**
- * The DataSource configuration key name
- *
- * @var string
- * @access public
- */
- var $configKeyName = null;
-/**
- * Whether or not this DataSource is in the middle of a transaction
- *
- * @var boolean
- * @access protected
- */
- var $_transactionStarted = false;
-/**
- * Enter description here...
- *
- * @var boolean
- */
- var $cacheSources = true;
-/**
- * Constructor.
- */
- function __construct() {
- parent::__construct();
- if (func_num_args() > 0) {
- $this->setConfig(func_get_arg(0));
- }
- }
-/**
- * Caches/returns cached results for child instances
- *
- * @return array
- */
- function listSources($data = null) {
- if ($this->cacheSources === false) {
- return null;
- }
- if ($this->_sources != null) {
- return $this->_sources;
- }
-
- if (Configure::read() > 0) {
- $expires = "+30 seconds";
- } else {
- $expires = "+999 days";
- }
-
- if ($data != null) {
- $data = serialize($data);
- }
- $filename = ConnectionManager::getSourceName($this) . '_' . preg_replace("/[^A-Za-z0-9_-]/", "_", $this->config['database']) . '_list';
- $new = cache('models' . DS . $filename, $data, $expires);
-
- if ($new != null) {
- $new = unserialize($new);
- $this->_sources = $new;
- }
- return $new;
- }
-/**
- * Convenience method for DboSource::listSources(). Returns source names in lowercase.
- *
- * @return array
- */
- function sources() {
- $return = array_map('strtolower', $this->listSources());
- return $return;
- }
-/**
- * Returns a Model description (metadata) or null if none found.
- *
- * @param Model $model
- * @return mixed
- */
- function describe($model) {
- if ($this->cacheSources === false) {
- return null;
- }
- if (isset($this->__descriptions[$model->tablePrefix . $model->table])) {
- return $this->__descriptions[$model->tablePrefix . $model->table];
- }
- $cache = $this->__cacheDescription($model->tablePrefix . $model->table);
-
- if ($cache !== null) {
- $this->__descriptions[$model->tablePrefix . $model->table] =& $cache;
- return $cache;
- }
- return null;
- }
-/**
- * Begin a transaction to be overridden in subclasses
- *
- * @param unknown_type $model
- * @return boolean True
- */
- function begin(&$model) {
- return true;
- }
-/**
- * Commit a transaction to be overridden in subclasses
- *
- * @param unknown_type $model
- * @return boolean True
- */
- function commit(&$model) {
- return true;
- }
-/**
- * Rollback a transaction to be overridden in subclasses
- *
- * @param unknown_type $model
- * @return boolean True
- */
- function rollback(&$model) {
- return true;
- }
-/**
- * Converts column types to basic types
- *
- * @param string $real Real column type (i.e. "varchar(255)")
- * @return string Abstract column type (i.e. "string")
- */
- function column($real) {
- return false;
- }
-/**
- * To-be-overridden in subclasses.
- *
- * @param unknown_type $model
- * @param unknown_type $fields
- * @param unknown_type $values
- * @return unknown
- */
- function create(&$model, $fields = null, $values = null) {
- return false;
- }
-/**
- * To-be-overridden in subclasses.
- *
- * @param unknown_type $model
- * @param unknown_type $queryData
- * @return unknown
- */
- function read(&$model, $queryData = array()) {
- return false;
- }
-/**
- * To-be-overridden in subclasses.
- *
- * @param unknown_type $model
- * @param unknown_type $fields
- * @param unknown_type $values
- * @return unknown
- */
- function update(&$model, $fields = null, $values = null) {
- return false;
- }
-/**
- * To-be-overridden in subclasses.
- *
- * @param unknown_type $model
- * @param unknown_type $id
- */
- function delete(&$model, $id = null) {
- if ($id == null) {
- $id = $model->id;
- }
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param unknown_type $source
- * @return in
- */
- function lastInsertId($source = null) {
- return false;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param unknown_type $source
- * @return in
- */
- function lastNumRows($source = null) {
- return false;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param unknown_type $source
- * @return in
- */
- function lastAffected($source = null) {
- return false;
- }
-/**
- * Returns true if the DataSource supports the given interface (method)
- *
- * @param string $interface The name of the interface (method)
- * @return boolean True on success
- */
- function isInterfaceSupported($interface) {
- $methods = get_class_methods(get_class($this));
- $methods = strtolower(implode('|', $methods));
- $methods = explode('|', $methods);
- $return = in_array(strtolower($interface), $methods);
- return $return;
- }
-/**
- * Sets the configuration for the DataSource
- *
- * @param array $config The configuration array
- * @return void
- */
- function setConfig($config) {
- if (is_array($this->_baseConfig)) {
- $this->config = $this->_baseConfig;
- foreach ($config as $key => $val) {
- $this->config[$key] = $val;
- }
- }
- }
-/**
- * Cache the DataSource description
- *
- * @param string $object The name of the object (model) to cache
- * @param mixed $data The description of the model, usually a string or array
- * @return void
- */
- function __cacheDescription($object, $data = null) {
- if ($this->cacheSources === false) {
- return null;
- }
- if (Configure::read() > 0) {
- $expires = "+15 seconds";
- } else {
- $expires = "+999 days";
- }
-
- if ($data !== null) {
- $this->__descriptions[$object] =& $data;
- $cache = serialize($data);
- } else {
- $cache = null;
- }
- $new = cache('models' . DS . ConnectionManager::getSourceName($this) . '_' . $object, $cache, $expires);
-
- if ($new != null) {
- $new = unserialize($new);
- }
- return $new;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $query
- * @param unknown_type $data
- * @param unknown_type $association
- * @param unknown_type $assocData
- * @param Model $model
- * @param Model $linkModel
- * @param array $stack
- * @return unknown
- */
- function insertQueryData($query, $data, $association, $assocData, &$model, &$linkModel, $stack) {
- $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}');
-
- foreach ($keys as $key) {
- $val = null;
-
- if (strpos($query, $key) !== false) {
- switch($key) {
- case '{$__cakeID__$}':
- if (isset($data[$model->name]) || isset($data[$association])) {
- if (isset($data[$model->name][$model->primaryKey])) {
- $val = $data[$model->name][$model->primaryKey];
- } elseif (isset($data[$association][$model->primaryKey])) {
- $val = $data[$association][$model->primaryKey];
- }
- } else {
- $found = false;
- foreach (array_reverse($stack) as $assoc) {
- if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
- $val = $data[$assoc][$model->primaryKey];
- $found = true;
- break;
- }
- }
- if (!$found) {
- $val = '';
- }
- }
- break;
- case '{$__cakeForeignKey__$}':
- foreach ($model->__associations as $id => $name) {
- foreach ($model->$name as $assocName => $assoc) {
- if ($assocName === $association) {
- if (isset($assoc['foreignKey'])) {
- $foreignKey = $assoc['foreignKey'];
-
- if (isset($data[$model->name][$foreignKey])) {
- $val = $data[$model->name][$foreignKey];
- } elseif (isset($data[$association][$foreignKey])) {
- $val = $data[$association][$foreignKey];
- } else {
- $found = false;
- foreach (array_reverse($stack) as $assoc) {
- if (isset($data[$assoc]) && isset($data[$assoc][$foreignKey])) {
- $val = $data[$assoc][$foreignKey];
- $found = true;
- break;
- }
- }
- if (!$found) {
- $val = '';
- }
- }
- }
- break 3;
- }
- }
- }
- break;
- }
- if (empty($val) && $val !== '0') {
- return false;
- }
- $query = r($key, $this->value($val, $model->getColumnType($model->primaryKey)), $query);
- }
- }
- return $query;
- }
-/**
- * To-be-overridden in subclasses.
- *
- * @param unknown_type $model
- * @param unknown_type $key
- * @return unknown
- */
- function resolveKey($model, $key) {
- return $model->name . $key;
- }
-/**
- * Closes the current datasource.
- *
- */
- function __destruct() {
- if ($this->connected) {
- $this->close();
- }
- }
-}
-?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/dbo_source.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/dbo_source.php
deleted file mode 100644
index 8d42ce0..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/datasources/dbo_source.php
+++ /dev/null
@@ -1,1967 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_source.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.datasources
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-uses('set');
-/**
- * DboSource
- *
- * Creates DBO-descendant objects from a given db connection configuration
- *
- * @package cake
- * @subpackage cake.cake.libs.model.datasources
- */
-class DboSource extends DataSource {
-/**
- * Description string for this Database Data Source.
- *
- * @var unknown_type
- */
- var $description = "Database Data Source";
-/**
- * index definition, standard cake, primary, index, unique
- *
- * @var array
- */
- var $index = array('PRI'=> 'primary', 'MUL'=> 'index', 'UNI'=>'unique');
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $startQuote = null;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $endQuote = null;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $alias = 'AS ';
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $goofyLimit = false;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $__bypass = false;
-/**
- * The set of valid SQL operations usable in a WHERE statement
- *
- * @var array
- */
- var $__sqlOps = array('like', 'ilike', 'or', 'not', 'in', 'between', 'regexp', 'similar to');
-/**
- * Constructor
- */
- function __construct($config = null, $autoConnect = true) {
- $this->debug = Configure::read() > 0;
- $this->fullDebug = Configure::read() > 1;
- parent::__construct($config);
-
- if ($autoConnect) {
- return $this->connect();
- } else {
- return true;
- }
- }
-/**
- * Reconnects to database server with optional new settings
- *
- * @param array $config An array defining the new configuration settings
- * @return boolean True on success, false on failure
- */
- function reconnect($config = null) {
- $this->disconnect();
- if ($config != null) {
- $this->config = array_merge($this->_baseConfig, $config);
- }
- return $this->connect();
- }
-/**
- * Prepares a value, or an array of values for database queries by quoting and escaping them.
- *
- * @param mixed $data A value or an array of values to prepare.
- * @return mixed Prepared value or array of values.
- */
- function value($data, $column = null) {
- if (is_array($data)) {
- $out = array();
- $keys = array_keys($data);
- $count = count($data);
- for ($i = 0; $i < $count; $i++) {
- $out[$keys[$i]] = $this->value($data[$keys[$i]]);
- }
- return $out;
- } elseif (in_array($data, array('{$__cakeID__$}', '{$__cakeForeignKey__$}'), true)) {
- return $data;
- }
- return null;
- }
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return unknown
- */
- function rawQuery($sql) {
- $this->took = $this->error = $this->numRows = false;
- return $this->execute($sql);
- }
-/**
- * Queries the database with given SQL statement, and obtains some metadata about the result
- * (rows affected, timing, any errors, number of rows in resultset). The query is also logged.
- * If DEBUG is set, the log is shown all the time, else it is only shown on errors.
- *
- * @param string $sql
- * @return unknown
- */
- function execute($sql) {
- $t = getMicrotime();
- $this->_result = $this->_execute($sql);
- $this->affected = $this->lastAffected();
- $this->took = round((getMicrotime() - $t) * 1000, 0);
- $this->error = $this->lastError();
- $this->numRows = $this->lastNumRows($this->_result);
-
- if ($this->fullDebug && Configure::read() > 1) {
- $this->logQuery($sql);
- }
-
- if ($this->error) {
- $this->showQuery($sql);
- return false;
- } else {
- return $this->_result;
- }
- }
-/**
- * DataSource Query abstraction
- *
- * @return resource Result resource identifier
- */
- function query() {
- $args = func_get_args();
- $fields = null;
- $order = null;
- $limit = null;
- $page = null;
- $recursive = null;
-
- if (count($args) == 1) {
- return $this->fetchAll($args[0]);
-
- } elseif (count($args) > 1 && (strpos(strtolower($args[0]), 'findby') === 0 || strpos(strtolower($args[0]), 'findallby') === 0)) {
- $params = $args[1];
-
- if (strpos(strtolower($args[0]), 'findby') === 0) {
- $all = false;
- $field = Inflector::underscore(preg_replace('/findBy/i', '', $args[0]));
- } else {
- $all = true;
- $field = Inflector::underscore(preg_replace('/findAllBy/i', '', $args[0]));
- }
-
- $or = (strpos($field, '_or_') !== false);
- if ($or) {
- $field = explode('_or_', $field);
- } else {
- $field = explode('_and_', $field);
- }
- $off = count($field) - 1;
-
- if (isset($params[1 + $off])) {
- $fields = $params[1 + $off];
- }
-
- if (isset($params[2 + $off])) {
- $order = $params[2 + $off];
- }
-
- if (!array_key_exists(0, $params)) {
- return false;
- }
-
- $c = 0;
- $query = array();
- foreach ($field as $f) {
- if (!is_array($params[$c]) && !empty($params[$c]) && $params[$c] !== true && $params[$c] !== false) {
- $query[$args[2]->alias . '.' . $f] = '= ' . $params[$c];
- } else {
- $query[$args[2]->alias . '.' . $f] = $params[$c];
- }
- $c++;
- }
-
- if ($or) {
- $query = array('OR' => $query);
- }
-
- if ($all) {
-
- if (isset($params[3 + $off])) {
- $limit = $params[3 + $off];
- }
-
- if (isset($params[4 + $off])) {
- $page = $params[4 + $off];
- }
-
- if (isset($params[5 + $off])) {
- $recursive = $params[5 + $off];
- }
- return $args[2]->findAll($query, $fields, $order, $limit, $page, $recursive);
- } else {
- if (isset($params[3 + $off])) {
- $recursive = $params[3 + $off];
- }
- return $args[2]->find($query, $fields, $order, $recursive);
- }
- } else {
- if (isset($args[1]) && $args[1] === true) {
- return $this->fetchAll($args[0], true);
- }
- return $this->fetchAll($args[0], false);
- }
- }
-/**
- * Returns a row from current resultset as an array .
- *
- * @return array The fetched row as an array
- */
- function fetchRow($sql = null) {
-
- if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
- if (!$this->execute($sql)) {
- return null;
- }
- }
-
- if (is_resource($this->_result) || is_object($this->_result)) {
- $this->resultSet($this->_result);
- $resultRow = $this->fetchResult();
- return $resultRow;
- } else {
- return null;
- }
- }
-/**
- * Returns an array of all result rows for a given SQL query.
- * Returns false if no rows matched.
- *
- * @param string $sql SQL statement
- * @param boolean $cache Enables returning/storing cached query results
- * @return array Array of resultset rows, or false if no rows matched
- */
- function fetchAll($sql, $cache = true, $modelName = null) {
- if ($cache && isset($this->_queryCache[$sql])) {
- if (preg_match('/^\s*select/i', $sql)) {
- return $this->_queryCache[$sql];
- }
- }
-
- if ($this->execute($sql)) {
- $out = array();
-
- while ($item = $this->fetchRow()) {
- $out[] = $item;
- }
-
- if ($cache) {
- if (strpos(trim(strtolower($sql)), 'select') !== false) {
- $this->_queryCache[$sql] = $out;
- }
- }
- return $out;
-
- } else {
- return false;
- }
- }
-/**
- * Returns a single field of the first of query results for a given SQL query, or false if empty.
- *
- * @param string $name Name of the field
- * @param string $sql SQL query
- * @return unknown
- */
- function field($name, $sql) {
- $data = $this->fetchRow($sql);
-
- if (!isset($data[$name]) || empty($data[$name])) {
- return false;
- } else {
- return $data[$name];
- }
- }
-/**
- * Returns a quoted name of $data for use in an SQL statement.
- * Strips fields out of SQL functions before quoting.
- *
- * @param string $data
- * @return string SQL field
- */
- function name($data) {
- if (preg_match_all('/([^(]*)\((.*)\)(.*)/', $data, $fields)) {
- $fields = Set::extract($fields, '{n}.0');
- if (!empty($fields[1])) {
- if (!empty($fields[2])) {
- return $fields[1] . '(' . $this->name($fields[2]) . ')' . $fields[3];
- } else {
- return $fields[1] . '()' . $fields[3];
- }
- }
- }
- if ($data == '*') {
- return '*';
- }
- $data = $this->startQuote . str_replace('.', $this->endQuote . '.' . $this->startQuote, $data) . $this->endQuote;
- $data = str_replace($this->startQuote . $this->startQuote, $this->startQuote, $data);
-
- if (!empty($this->endQuote) && $this->endQuote == $this->startQuote) {
- $oddMatches = substr_count($data, $this->endQuote);
- if ($oddMatches % 2 == 1) {
- $data = trim($data, $this->endQuote);
- }
- }
- return str_replace($this->endQuote . $this->endQuote, $this->endQuote, $data);
- }
-/**
- * Checks if it's connected to the database
- *
- * @return boolean True if the database is connected, else false
- */
- function isConnected() {
- return $this->connected;
- }
-/**
- * Outputs the contents of the queries log.
- *
- * @param boolean $sorted
- */
- function showLog($sorted = false) {
- if ($sorted) {
- $log = sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC);
- } else {
- $log = $this->_queriesLog;
- }
-
- if ($this->_queriesCnt > 1) {
- $text = 'queries';
- } else {
- $text = 'query';
- }
-
- if (php_sapi_name() != 'cli') {
- print ("<table class=\"cakeSqlLog\" id=\"cakeSqlLog_" . preg_replace('/[^A-Za-z0-9_]/', '_', uniqid(time(), true)) . "\" summary=\"Cake SQL Log\" cellspacing=\"0\" border = \"0\">\n<caption>{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms</caption>\n");
- print ("<thead>\n<tr><th>Nr</th><th>Query</th><th>Error</th><th>Affected</th><th>Num. rows</th><th>Took (ms)</th></tr>\n</thead>\n<tbody>\n");
-
- foreach ($log as $k => $i) {
- print ("<tr><td>" . ($k + 1) . "</td><td>" . h($i['query']) . "</td><td>{$i['error']}</td><td style = \"text-align: right\">{$i['affected']}</td><td style = \"text-align: right\">{$i['numRows']}</td><td style = \"text-align: right\">{$i['took']}</td></tr>\n");
- }
- print ("</tbody></table>\n");
- } else {
- foreach ($log as $k => $i) {
- print (($k + 1) . ". {$i['query']} {$i['error']}\n");
- }
- }
- }
-/**
- * Log given SQL query.
- *
- * @param string $sql SQL statement
- * @todo: Add hook to log errors instead of returning false
- */
- function logQuery($sql) {
- $this->_queriesCnt++;
- $this->_queriesTime += $this->took;
- $this->_queriesLog[] = array('query' => $sql,
- 'error' => $this->error,
- 'affected' => $this->affected,
- 'numRows' => $this->numRows,
- 'took' => $this->took
- );
- if (count($this->_queriesLog) > $this->_queriesLogMax) {
- array_pop($this->_queriesLog);
- }
- if ($this->error) {
- return false;
- }
- }
-/**
- * Output information about an SQL query. The SQL statement, number of rows in resultset,
- * and execution time in microseconds. If the query fails, an error is output instead.
- *
- * @param string $sql Query to show information on.
- */
- function showQuery($sql) {
- $error = $this->error;
- if (strlen($sql) > 200 && !$this->fullDebug && Configure::read() > 1) {
- $sql = substr($sql, 0, 200) . '[...]';
- }
-
- if (($this->debug || $error) && Configure::read() > 0) {
- e("<p style = \"text-align:left\"><b>Query:</b> {$sql} ");
- if ($error) {
- trigger_error("<span style = \"color:Red;text-align:left\"><b>SQL Error:</b> {$this->error}</span>", E_USER_WARNING);
- } else {
- e("<small>[Aff:{$this->affected} Num:{$this->numRows} Took:{$this->took}ms]</small>");
- }
- print ('</p>');
- }
- }
-/**
- * Gets full table name including prefix
- *
- * @param mixed $model
- * @param boolean $quote
- * @return string Full quoted table name
- */
- function fullTableName($model, $quote = true) {
- if (is_object($model)) {
- $table = $model->tablePrefix . $model->table;
- } elseif (isset($this->config['prefix'])) {
- $table = $this->config['prefix'] . strval($model);
- } else {
- $table = strval($model);
- }
- if ($quote) {
- return $this->name($table);
- }
- return $table;
- }
-/**
- * The "C" in CRUD
- *
- * @param Model $model
- * @param array $fields
- * @param array $values
- * @return boolean Success
- */
- function create(&$model, $fields = null, $values = null) {
- $fieldInsert = array();
- $valueInsert = array();
- $id = null;
-
- if ($fields == null) {
- unset($fields, $values);
- $fields = array_keys($model->data);
- $values = array_values($model->data);
- }
- $count = count($fields);
-
- for ($i = 0; $i < $count; $i++) {
- $fieldInsert[] = $this->name($fields[$i]);
- if ($fields[$i] == $model->primaryKey) {
- $id = $values[$i];
- }
- }
- $count = count($values);
-
- for ($i = 0; $i < $count; $i++) {
- $valueInsert[] = $this->value($values[$i], $model->getColumnType($fields[$i]));
- }
-
- if ($this->execute('INSERT INTO ' . $this->fullTableName($model) . ' (' . join(',', $fieldInsert). ') VALUES (' . join(',', $valueInsert) . ')')) {
- if (empty($id)) {
- $id = $this->lastInsertId($this->fullTableName($model, false), $model->primaryKey);
- }
- $model->setInsertID($id);
- $model->id = $id;
- return true;
- } else {
- $model->onError();
- return false;
- }
- }
-/**
- * The "R" in CRUD
- *
- * @param Model $model
- * @param array $queryData
- * @param integer $recursive Number of levels of association
- * @return unknown
- */
- function read(&$model, $queryData = array(), $recursive = null) {
-
- $this->__scrubQueryData($queryData);
- $null = null;
- $array = array();
- $linkedModels = array();
- $this->__bypass = false;
-
- if ($recursive === null && isset($queryData['recursive'])) {
- $recursive = $queryData['recursive'];
- }
-
- if (!is_null($recursive)) {
- $_recursive = $model->recursive;
- $model->recursive = $recursive;
- }
-
- if (!empty($queryData['fields'])) {
- $this->__bypass = true;
- $queryData['fields'] = $this->fields($model, null, $queryData['fields']);
- } else {
- $queryData['fields'] = $this->fields($model);
- }
-
- foreach ($model->__associations as $type) {
- foreach ($model->{$type} as $assoc => $assocData) {
- if ($model->recursive > -1) {
- $linkModel =& $model->{$assoc};
-
- $external = isset($assocData['external']);
- if ($model->alias == $linkModel->alias && $type != 'hasAndBelongsToMany' && $type != 'hasMany') {
- if (true === $this->generateSelfAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
- $linkedModels[] = $type . '/' . $assoc;
- }
- } else {
- if ($model->useDbConfig == $linkModel->useDbConfig) {
- if (true === $this->generateAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
- $linkedModels[] = $type . '/' . $assoc;
- }
- }
- }
- }
- }
- }
- // Build final query SQL
- $query = $this->generateAssociationQuery($model, $null, null, null, null, $queryData, false, $null);
- $resultSet = $this->fetchAll($query, $model->cacheQueries, $model->alias);
-
- if ($resultSet === false) {
- $model->onError();
- return false;
- }
-
- $filtered = $this->__filterResults($resultSet, $model);
-
- if ($model->recursive > 0) {
- foreach ($model->__associations as $type) {
- foreach ($model->{$type} as $assoc => $assocData) {
- $db = null;
- $linkModel =& $model->{$assoc};
-
- if (!in_array($type . '/' . $assoc, $linkedModels)) {
- if ($model->useDbConfig == $linkModel->useDbConfig) {
- $db =& $this;
- } else {
- $db =& ConnectionManager::getDataSource($linkModel->useDbConfig);
- }
- } elseif ($model->recursive > 1 && ($type == 'belongsTo' || $type == 'hasOne')) {
- // Do recursive joins on belongsTo and hasOne relationships
- $db =& $this;
- } else {
- unset ($db);
- }
-
- if (isset($db) && $db != null) {
- $stack = array($assoc);
- $db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1, $stack);
- unset($db);
- }
- }
- }
- $this->__filterResults($resultSet, $model, $filtered);
- }
-
- if (!is_null($recursive)) {
- $model->recursive = $_recursive;
- }
- return $resultSet;
- }
-/**
- * Private method. Passes association results thru afterFind filter of corresponding model
- *
- * @param unknown_type $results
- * @param unknown_type $model
- * @param unknown_type $filtered
- * @return unknown
- */
- function __filterResults(&$results, &$model, $filtered = array()) {
-
- $filtering = array();
- $associations = array_merge($model->belongsTo, $model->hasOne, $model->hasMany, $model->hasAndBelongsToMany);
- $count = count($results);
-
- for ($i = 0; $i < $count; $i++) {
- if (is_array($results[$i])) {
- $keys = array_keys($results[$i]);
- $count2 = count($keys);
-
- for ($j = 0; $j < $count2; $j++) {
- $className = $key = $keys[$j];
-
- if ($model->alias != $className && !in_array($key, $filtered)) {
- if (!in_array($key, $filtering)) {
- $filtering[] = $key;
- }
-
- if (isset($model->{$className}) && is_object($model->{$className})) {
- $data = $model->{$className}->afterFind(array(array($key => $results[$i][$key])), false);
- }
- if (isset($data[0][$key])) {
- $results[$i][$key] = $data[0][$key];
- }
- }
- }
- }
- }
- return $filtering;
- }
-/**
- * Enter description here...
- *
- * @param Model $model
- * @param unknown_type $linkModel
- * @param string $type Association type
- * @param unknown_type $association
- * @param unknown_type $assocData
- * @param unknown_type $queryData
- * @param unknown_type $external
- * @param unknown_type $resultSet
- * @param integer $recursive Number of levels of association
- * @param array $stack
- */
- function queryAssociation(&$model, &$linkModel, $type, $association, $assocData, &$queryData, $external = false, &$resultSet, $recursive, $stack) {
-
- if ($query = $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet)) {
- if (!isset($resultSet) || !is_array($resultSet)) {
- if (Configure::read() > 0) {
- e('<div style = "font: Verdana bold 12px; color: #FF0000">SQL Error in model ' . $model->alias . ': ');
- if (isset($this->error) && $this->error != null) {
- e($this->error);
- }
- e('</div>');
- }
- return null;
- }
- $count = count($resultSet);
-
- if ($type === 'hasMany' && (!isset($assocData['limit']) || empty($assocData['limit']))) {
- $ins = $fetch = array();
- for ($i = 0; $i < $count; $i++) {
- if ($in = $this->insertQueryData('{$__cakeID__$}', $resultSet[$i], $association, $assocData, $model, $linkModel, $stack)) {
- $ins[] = $in;
- }
- }
-
- if (!empty($ins)) {
- $query = r('{$__cakeID__$}', join(', ', $ins), $query);
- $fetch = $this->fetchAll($query, $model->cacheQueries, $model->alias);
- }
-
- if (!empty($fetch) && is_array($fetch)) {
- if ($recursive > 0) {
-
- foreach ($linkModel->__associations as $type1) {
- foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
-
- $deepModel =& $linkModel->{$assocData1['className']};
- if ($deepModel->alias != $model->alias) {
- $tmpStack = $stack;
- $tmpStack[] = $assoc1;
- if ($linkModel->useDbConfig == $deepModel->useDbConfig) {
- $db =& $this;
- } else {
- $db =& ConnectionManager::getDataSource($deepModel->useDbConfig);
- }
- $db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
- }
- }
- }
- }
- }
- return $this->__mergeHasMany($resultSet, $fetch, $association, $model, $linkModel, $recursive);
- }
- for ($i = 0; $i < $count; $i++) {
-
- $row =& $resultSet[$i];
- $q = $this->insertQueryData($query, $resultSet[$i], $association, $assocData, $model, $linkModel, $stack);
-
- if ($q != false) {
- $fetch = $this->fetchAll($q, $model->cacheQueries, $model->alias);
- } else {
- $fetch = null;
- }
-
- if (!empty($fetch) && is_array($fetch)) {
- if ($recursive > 0) {
-
- foreach ($linkModel->__associations as $type1) {
- foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
-
- $deepModel =& $linkModel->{$assocData1['className']};
- if ($deepModel->alias != $model->alias) {
- $tmpStack = $stack;
- $tmpStack[] = $assoc1;
- if ($linkModel->useDbConfig == $deepModel->useDbConfig) {
- $db =& $this;
- } else {
- $db =& ConnectionManager::getDataSource($deepModel->useDbConfig);
- }
- $db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
- }
- }
- }
- }
- $this->__mergeAssociation($resultSet[$i], $fetch, $association, $type);
- $resultSet[$i][$association] = $linkModel->afterfind($resultSet[$i][$association]);
-
- } else {
- $tempArray[0][$association] = false;
- $this->__mergeAssociation($resultSet[$i], $tempArray, $association, $type);
- }
- }
- }
- }
-
- function __mergeHasMany(&$resultSet, $merge, $association, &$model, &$linkModel) {
- foreach ($resultSet as $i => $value) {
- $count = 0;
- $merged[$association] = array();
- foreach ($merge as $j => $data) {
- if (isset($value[$model->alias]) && $value[$model->alias][$model->primaryKey] === $data[$association][$model->hasMany[$association]['foreignKey']]) {
- if (count($data) > 1) {
- $data = array_merge($data[$association], $data);
- unset($data[$association]);
- foreach ($data as $key => $name) {
- if (is_numeric($key)) {
- $data[$association][] = $name;
- unset($data[$key]);
- }
- }
- $merged[$association][] = $data;
- } else {
- $merged[$association][] = $data[$association];
- }
- }
- $count++;
- }
- if (isset($value[$model->alias])) {
- $resultSet[$i] = Set::pushDiff($resultSet[$i], $merged);
- unset($merged);
- }
- }
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $data
- * @param unknown_type $merge
- * @param unknown_type $association
- * @param unknown_type $type
- */
- function __mergeAssociation(&$data, $merge, $association, $type) {
-
- if (isset($merge[0]) && !isset($merge[0][$association])) {
- $association = Inflector::pluralize($association);
- }
-
- if ($type == 'belongsTo' || $type == 'hasOne') {
- if (isset($merge[$association])) {
- $data[$association] = $merge[$association][0];
- } else {
- if (count($merge[0][$association]) > 1) {
- foreach ($merge[0] as $assoc => $data2) {
- if ($assoc != $association) {
- $merge[0][$association][$assoc] = $data2;
- }
- }
- }
- if (!isset($data[$association])) {
- if ($merge[0][$association] != null) {
- $data[$association] = $merge[0][$association];
- } else {
- $data[$association] = array();
- }
- } else {
- if (is_array($merge[0][$association])) {
- foreach ($data[$association] as $k => $v) {
- if (!is_array($v)) {
- $dataAssocTmp[$k] = $v;
- }
- }
-
- foreach ($merge[0][$association] as $k => $v) {
- if (!is_array($v)) {
- $mergeAssocTmp[$k] = $v;
- }
- }
-
- if (array_keys($merge[0]) === array_keys($data)) {
- $data[$association][$association] = $merge[0][$association];
- } else {
- $diff = Set::diff($dataAssocTmp, $mergeAssocTmp);
- $data[$association] = array_merge($merge[0][$association], $diff);
- }
- }
- }
- }
- } else {
- if ($merge[0][$association] === false) {
- if (!isset($data[$association])) {
- $data[$association] = array();
- }
- } else {
- foreach ($merge as $i => $row) {
- if (count($row) == 1) {
- $data[$association][] = $row[$association];
- } else {
- $tmp = array_merge($row[$association], $row);
- unset($tmp[$association]);
- $data[$association][] = $tmp;
- }
- }
- }
- }
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $model
- * @param unknown_type $linkModel
- * @param unknown_type $type
- * @param unknown_type $association
- * @param unknown_type $assocData
- * @param unknown_type $queryData
- * @param unknown_type $external
- * @param unknown_type $resultSet
- * @return unknown
- */
- function generateSelfAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) {
- $alias = $association;
- if (empty($alias) && !empty($linkModel)) {
- $alias = $linkModel->alias;
- }
-
- if (!isset($queryData['selfJoin'])) {
- $queryData['selfJoin'] = array();
-
- $self = array(
- 'fields' => $this->fields($model, null, $queryData['fields']),
- 'joins' => array(array(
- 'table' => $this->fullTableName($linkModel),
- 'alias' => $alias,
- 'type' => 'LEFT',
- 'conditions' => array(
- $model->escapeField($assocData['foreignKey']) => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}'))
- ),
- 'table' => $this->fullTableName($model),
- 'alias' => $model->alias,
- 'limit' => $queryData['limit'],
- 'offset' => $queryData['offset'],
- 'conditions'=> $queryData['conditions'],
- 'order' => $queryData['order']
- );
-
- if (!empty($assocData['conditions'])) {
- $self['joins'][0]['conditions'] = trim($this->conditions(array_merge($self['joins'][0]['conditions'], (array)$assocData['conditions']), true, false));
- }
-
- if (!empty($queryData['joins'])) {
- foreach ($queryData['joins'] as $join) {
- $self['joins'][] = $join;
- }
- }
-
- if ($this->__bypass === false) {
- $self['fields'] = array_merge($self['fields'], $this->fields($linkModel, $alias, (isset($assocData['fields']) ? $assocData['fields'] : '')));
- }
-
- if (!in_array($self, $queryData['selfJoin'])) {
- $queryData['selfJoin'][] = $self;
- return true;
- }
-
- } elseif (isset($linkModel)) {
- return $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
-
- } else {
- $result = $queryData['selfJoin'][0];
- if (!empty($queryData['joins'])) {
- foreach ($queryData['joins'] as $join) {
- if (!in_array($join, $result['joins'])) {
- $result['joins'][] = $join;
- }
- }
- }
- if (!empty($queryData['conditions'])) {
- $result['conditions'] = trim($this->conditions(array_merge((array)$result['conditions'], $assocData['conditions']), true, false));
- }
- if (!empty($queryData['fields'])) {
- $result['fields'] = array_unique(array_merge($result['fields'], $queryData['fields']));
- }
- $sql = $this->buildStatement($result, $model);
- return $sql;
- }
- }
-/**
- * Enter description here...
- *
- * @param Model $model
- * @param unknown_type $linkModel
- * @param unknown_type $type
- * @param unknown_type $association
- * @param unknown_type $assocData
- * @param unknown_type $queryData
- * @param unknown_type $external
- * @param unknown_type $resultSet
- * @return unknown
- */
- function generateAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) {
- $this->__scrubQueryData($queryData);
- $this->__scrubQueryData($assocData);
- $joinedOnSelf = false;
-
- if (empty($queryData['fields'])) {
- $queryData['fields'] = $this->fields($model, $model->alias);
- } elseif (!empty($model->hasMany) && $model->recursive > -1) {
- $assocFields = $this->fields($model, $model->alias, array("{$model->alias}.{$model->primaryKey}"));
- $passedFields = $this->fields($model, $model->alias, $queryData['fields']);
-
- if (count($passedFields) === 1) {
- $match = strpos($passedFields[0], $assocFields[0]);
- $match1 = strpos($passedFields[0], 'COUNT(');
- if ($match === false && $match1 === false) {
- $queryData['fields'] = array_unique(array_merge($passedFields, $assocFields));
- } else {
- $queryData['fields'] = $passedFields;
- }
- } else {
- $queryData['fields'] = array_unique(array_merge($passedFields, $assocFields));
- }
- unset($assocFields, $passedFields);
- }
-
- if ($linkModel == null) {
- if (array_key_exists('selfJoin', $queryData)) {
- return $this->generateSelfAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
- } else {
- return $this->buildStatement(array(
- 'fields' => array_unique($queryData['fields']),
- 'table' => $this->fullTableName($model),
- 'alias' => $model->alias,
- 'limit' => $queryData['limit'],
- 'offset' => $queryData['offset'],
- 'joins' => $queryData['joins'],
- 'conditions' => $queryData['conditions'],
- 'order' => $queryData['order']), $model
- );
- }
- }
- $alias = $association;
-
- if ($model->alias == $linkModel->alias) {
- $joinedOnSelf = true;
- }
-
- if ($external && isset($assocData['finderQuery'])) {
- if (!empty($assocData['finderQuery'])) {
- return $assocData['finderQuery'];
- }
- }
-
- if ((!$external && in_array($type, array('hasOne', 'belongsTo')) && $this->__bypass === false) || $external) {
- $fields = $this->fields($linkModel, $alias, $assocData['fields']);
- } else {
- $fields = array();
- }
- $limit = '';
-
- if (isset($assocData['limit'])) {
- if ((!isset($assocData['offset']) || (empty($assocData['offset']))) && isset($assocData['page'])) {
- $assocData['offset'] = ($assocData['page'] - 1) * $assocData['limit'];
- } elseif (!isset($assocData['offset'])) {
- $assocData['offset'] = null;
- }
- $limit = $this->limit($assocData['limit'], $assocData['offset']);
- }
-
- switch($type) {
- case 'hasOne':
- case 'belongsTo':
- if ($external) {
- if ($type == 'hasOne') {
- $conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$assocData['foreignKey']}" => '{$__cakeID__$}'));
- } elseif ($type == 'belongsTo') {
- $conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$linkModel->primaryKey}" => '{$__cakeForeignKey__$}'));
- }
- $query = array_merge($assocData, array(
- 'conditions' => $conditions,
- 'table' => $this->fullTableName($linkModel),
- 'fields' => $fields,
- 'alias' => $alias
- ));
-
- if ($type == 'belongsTo') {
- // Dunno if we should be doing this for hasOne also...?
- // Or maybe not doing it at all...?
- $query = array_merge($query, array('order' => $assocData['order'], 'limit' => $limit));
- }
- } else {
- if ($type == 'hasOne') {
- $conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$assocData['foreignKey']}" => '{$__cakeIdentifier[' . "{$model->alias}.{$model->primaryKey}" . ']__$}'));
- } elseif ($type == 'belongsTo') {
- $conditions = $this->__mergeConditions($assocData['conditions'], array("{$model->alias}.{$assocData['foreignKey']}" => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}'));
- }
-
- $join = array(
- 'table' => $this->fullTableName($linkModel),
- 'alias' => $alias,
- 'type' => 'LEFT',
- 'conditions' => trim($this->conditions($conditions, true, false))
- );
-
- $queryData['fields'] = array_merge($queryData['fields'], $fields);
-
- if (!empty($assocData['order'])) {
- $hasCount = false;
- foreach ($queryData['fields'] as $field) {
- if (stripos($field, 'COUNT(*)') !== false) {
- $hasCount = true;
- break;
- }
- }
-
- $putOrderByFields = true;
- if ($hasCount) {
- $orders = spliti(' ASC| DESC|,', $assocData['order']);
- foreach ($orders as $order) {
- $order = trim($order);
- if (!empty($order) && !in_array($order, $queryData['fields'])) {
- $putOrderByFields = false;
- break;
- }
- }
- }
-
- if ($putOrderByFields) {
- $queryData['order'][] = $assocData['order'];
- }
- }
-
- if (!in_array($join, $queryData['joins'])) {
- $queryData['joins'][] = $join;
- }
- return true;
- }
- break;
- case 'hasMany':
- $assocData['fields'] = array_unique(array_merge(
- $this->fields($linkModel, $alias, $assocData['fields']),
- $this->fields($linkModel, $alias, array("{$alias}.{$assocData['foreignKey']}"))
- ));
-
- $query = array(
- 'conditions' => $this->__mergeConditions(array("{$alias}.{$assocData['foreignKey']}" => array('{$__cakeID__$}')), $assocData['conditions']),
- 'fields' => $assocData['fields'],
- 'table' => $this->fullTableName($linkModel),
- 'alias' => $alias,
- 'order' => $assocData['order'],
- 'limit' => $limit
- );
- break;
- case 'hasAndBelongsToMany':
- $joinTbl = $this->fullTableName($assocData['joinTable']);
- $joinFields = array();
- $joinAssoc = null;
- $joinAlias = $joinTbl;
-
- if (isset($assocData['with']) && !empty($assocData['with'])) {
- $joinAssoc = $joinAlias = $model->{$assocData['with']}->name;
- $joinFields = $model->{$assocData['with']}->loadInfo();
- $joinFields = $joinFields->extract('{n}.name');
-
- if (is_array($joinFields) && !empty($joinFields) && count($joinFields) > 2) {
- $joinFields = $this->fields($model->{$assocData['with']}, $model->{$assocData['with']}->name, $joinFields);
- } else {
- $joinFields = array();
- $joinAssoc = null;
- $joinAlias = $joinTbl;
- }
- }
-
- $query = array(
- 'conditions' => $assocData['conditions'],
- 'limit' => $limit,
- 'table' => $this->fullTableName($linkModel),
- 'alias' => $alias,
- 'fields' => array_merge($this->fields($linkModel, $alias, $assocData['fields']), $joinFields),
- 'order' => $assocData['order'],
- 'joins' => array(array(
- 'table' => $joinTbl,
- 'alias' => $joinAssoc,
- 'conditions' => array(
- array("{$joinAlias}.{$assocData['foreignKey']}" => '{$__cakeID__$}'),
- array("{$joinAlias}.{$assocData['associationForeignKey']}" => '{$__cakeIdentifier['."{$alias}.{$linkModel->primaryKey}".']__$}')
- ))
- )
- );
- break;
- }
- if (isset($query)) {
- return $this->buildStatement($query, $model);
- }
- return null;
- }
-
- function buildJoinStatement($join) {
- $data = array_merge(array(
- 'type' => null,
- 'alias' => null,
- 'table' => 'join_table',
- 'conditions' => array()
- ), $join);
-
- if (!empty($data['alias'])) {
- $data['alias'] = $this->alias . $this->name($data['alias']);
- }
- if (!empty($data['conditions'])) {
- $data['conditions'] = trim($this->conditions($data['conditions'], true, false));
- }
- return $this->renderJoinStatement($data);
- }
-
- function buildStatement($query, $model) {
- $query = array_merge(array('offset' => null, 'joins' => array()), $query);
- if (!empty($query['joins'])) {
- for ($i = 0; $i < count($query['joins']); $i++) {
- if (is_array($query['joins'][$i])) {
- $query['joins'][$i] = $this->buildJoinStatement($query['joins'][$i]);
- }
- }
- }
- return $this->renderStatement(array(
- 'conditions' => $this->conditions($query['conditions']),
- 'fields' => join(', ', $query['fields']),
- 'table' => $query['table'],
- 'alias' => $this->alias . $this->name($query['alias']),
- 'order' => $this->order($query['order']),
- 'limit' => $this->limit($query['limit'], $query['offset']),
- 'joins' => join(' ', $query['joins'])
- ));
- }
-
- function renderJoinStatement($data) {
- extract($data);
- return trim("{$type} JOIN {$table} {$alias} ON ({$conditions})");
- }
-
- function renderStatement($data) {
- extract($data);
- return "SELECT {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order} {$limit}";
- }
-/**
- * Private method
- *
- * @return array
- */
- function __mergeConditions($query, $assoc) {
- if (!empty($assoc)) {
- if (is_array($query)) {
- return array_merge((array)$assoc, $query);
- } else {
- if (!empty($query)) {
- $query = array($query);
- if (is_array($assoc)) {
- $query = array_merge($query, $assoc);
- } else {
- $query[] = $assoc;
- }
- return $query;
- } else {
- return $assoc;
- }
- }
- }
- return $query;
- }
-/**
- * Generates and executes an SQL UPDATE statement for given model, fields, and values.
- *
- * @param Model $model
- * @param array $fields
- * @param array $values
- * @param mixed $conditions
- * @return array
- */
- function update(&$model, $fields = array(), $values = null, $conditions = null) {
- $updates = array();
-
- if ($values == null) {
- $combined = $fields;
- } else {
- $combined = array_combine($fields, $values);
- }
-
- foreach ($combined as $field => $value) {
- if ($value === null) {
- $updates[] = $this->name($field) . ' = NULL';
- } else {
- $update = $this->name($field) . ' = ';
- if ($conditions == null) {
- $update .= $this->value($value, $model->getColumnType($field));
- } else {
- $update .= $value;
- }
- $updates[] = $update;
- }
- }
- $conditions = $this->defaultConditions($model, $conditions);
-
- if ($conditions === false) {
- return false;
- }
-
- $fields = join(',', $updates);
- $table = $this->fullTableName($model);
-
- $conditions = $this->conditions($conditions);
-
- if (!$this->execute("UPDATE {$table} SET {$fields} {$conditions}")) {
- $model->onError();
- return false;
- }
- return true;
- }
-/**
- * Generates and executes an SQL DELETE statement for given id on given model.
- *
- * @param Model $model
- * @param mixed $conditions
- * @return boolean Success
- */
- function delete(&$model, $conditions = null) {
- $query = $this->defaultConditions($model, $conditions);
-
- if ($query === false) {
- return false;
- }
-
- $table = $this->fullTableName($model);
- $conditions = $this->conditions($query);
-
- if ($this->execute("DELETE FROM {$table} {$conditions}") === false) {
- $model->onError();
- return false;
- }
- return true;
- }
-/**
- * Creates a default set of conditions from the model if $conditions is null/empty.
- *
- * @param object $model
- * @param mixed $conditions
- * @return mixed
- */
- function defaultConditions(&$model, $conditions) {
- if (!empty($conditions)) {
- return $conditions;
- }
- if (!$model->exists()) {
- return false;
- }
- return array($model->primaryKey => (array)$model->getID());
- }
-/**
- * Returns a key formatted like a string Model.fieldname(i.e. Post.title, or Country.name)
- *
- * @param unknown_type $model
- * @param unknown_type $key
- * @param unknown_type $assoc
- * @return string
- */
- function resolveKey($model, $key, $assoc = null) {
- if (empty($assoc)) {
- $assoc = $model->alias;
- }
- if (!strpos('.', $key)) {
- return $this->name($model->alias) . '.' . $this->name($key);
- }
- return $key;
- }
-/**
- * Returns the column type of a given
- *
- * @param Model $model
- * @param string $field
- */
- function getColumnType(&$model, $field) {
- return $model->getColumnType($field);
- }
-/**
- * Private helper method to remove query metadata in given data array.
- *
- * @param array $data
- */
- function __scrubQueryData(&$data) {
- foreach (array('conditions', 'fields', 'joins', 'order', 'limit', 'offset') as $key) {
- if (!isset($data[$key]) || empty($data[$key])) {
- $data[$key] = array();
- }
- }
- }
-/**
- * Generates the fields list of an SQL query.
- *
- * @param Model $model
- * @param string $alias Alias tablename
- * @param mixed $fields
- * @param boolean $quote If false, returns fields array unquoted
- * @return array
- */
- function fields(&$model, $alias = null, $fields = array(), $quote = true) {
- if (empty($alias)) {
- $alias = $model->alias;
- }
-
- if (!is_array($fields)) {
- if (!empty($fields)) {
- $depth = 0;
- $offset = 0;
- $buffer = '';
- $results = array();
- $length = strlen($fields);
-
- while ($offset <= $length) {
- $tmpOffset = -1;
- $offsets = array(strpos($fields, ',', $offset), strpos($fields, '(', $offset), strpos($fields, ')', $offset));
- for ($i = 0; $i < 3; $i++) {
- if ($offsets[$i] !== false && ($offsets[$i] < $tmpOffset || $tmpOffset == -1)) {
- $tmpOffset = $offsets[$i];
- }
- }
- if ($tmpOffset !== -1) {
- $buffer .= substr($fields, $offset, ($tmpOffset - $offset));
- if ($fields{$tmpOffset} == ',' && $depth == 0) {
- $results[] = $buffer;
- $buffer = '';
- } else {
- $buffer .= $fields{$tmpOffset};
- }
- if ($fields{$tmpOffset} == '(') {
- $depth++;
- }
- if ($fields{$tmpOffset} == ')') {
- $depth--;
- }
- $offset = ++$tmpOffset;
- } else {
- $results[] = $buffer . substr($fields, $offset);
- $offset = $length + 1;
- }
- }
- if (empty($results) && !empty($buffer)) {
- $results[] = $buffer;
- }
-
- if (!empty($results)) {
- $fields = array_map('trim', $results);
- } else {
- $fields = array();
- }
- }
- }
- if (empty($fields)) {
- $fieldData = $model->loadInfo();
- $fields = $fieldData->extract('{n}.name');
- } else {
- $fields = array_filter($fields);
- }
-
- if (!$quote) {
- return $fields;
- }
- $count = count($fields);
-
- if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) {
- for ($i = 0; $i < $count; $i++) {
- if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
- $prepend = '';
-
- if (strpos($fields[$i], 'DISTINCT') !== false) {
- $prepend = 'DISTINCT ';
- $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
- }
- $dot = strpos($fields[$i], '.');
-
- if ($dot === false) {
- $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]);
- } else {
- $comma = strpos($fields[$i], ',');
- if ($comma === false) {
- $build = explode('.', $fields[$i]);
- if (!Set::numeric($build)) {
- $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]);
- }
- } else {
- $comma = explode(',', $fields[$i]);
- foreach ($comma as $string) {
- $build = explode('.', $string);
- if (!Set::numeric($build)) {
- $value[] = $prepend . $this->name(trim($build[0])) . '.' . $this->name(trim($build[1]));
- }
- }
- $fields[$i] = implode(', ', $value);
- }
- }
- } elseif (preg_match('/\(([\.\w]+)\)/', $fields[$i], $field)) {
- if (isset($field[1])) {
- if (strpos($field[1], '.') === false) {
- $field[1] = $this->name($alias) . '.' . $this->name($field[1]);
- } else {
- $field[0] = explode('.', $field[1]);
- if (!Set::numeric($field[0])) {
- $field[0] = join('.', array_map(array($this, 'name'), $field[0]));
- $fields[$i] = preg_replace('/\(' . $field[1] . '\)/', '(' . $field[0] . ')', $fields[$i], 1);
- }
- }
- }
- }
- }
- }
- return $fields;
- }
-/**
- * Creates a WHERE clause by parsing given conditions data.
- *
- * @param mixed $conditions Array or string of conditions
- * @return string SQL fragment
- */
- function conditions($conditions, $quoteValues = true, $where = true) {
- $clause = $out = '';
- if (is_string($conditions) || empty($conditions) || $conditions === true) {
- if (empty($conditions) || trim($conditions) == '' || $conditions === true) {
- if ($where) {
- return ' WHERE 1 = 1';
- }
- return '1 = 1';
- }
- if (!preg_match('/^WHERE\\x20|^GROUP\\x20BY\\x20|^HAVING\\x20|^ORDER\\x20BY\\x20/i', $conditions, $match)) {
- if ($where) {
- $clause = ' WHERE ';
- }
- }
- if (trim($conditions) == '') {
- $conditions = ' 1 = 1';
- } else {
- $conditions = $this->__quoteFields($conditions);
- }
- return $clause . $conditions;
- } else {
- if ($where) {
- $clause = ' WHERE ';
- }
- if (!empty($conditions)) {
- $out = $this->conditionKeysToString($conditions, $quoteValues);
- }
- if (empty($out) || empty($conditions)) {
- return $clause . ' 1 = 1';
- }
- return $clause . join(' AND ', $out);
- }
- }
-/**
- * Creates a WHERE clause by parsing given conditions array. Used by DboSource::conditions().
- *
- * @param array $conditions Array or string of conditions
- * @return string SQL fragment
- */
- function conditionKeysToString($conditions, $quoteValues = true) {
- $c = 0;
- $data = $not = null;
- $out = array();
- $bool = array('and', 'or', 'not', 'and not', 'or not', 'xor', '||', '&&');
- $join = ' AND ';
-
- foreach ($conditions as $key => $value) {
- if (is_numeric($key) && empty($value)) {
- continue;
- } elseif (is_numeric($key) && is_string($value)) {
- $out[] = $not . $this->__quoteFields($value);
- } elseif (in_array(strtolower(trim($key)), $bool)) {
- $join = ' ' . strtoupper($key) . ' ';
- $value = $this->conditionKeysToString($value, $quoteValues);
- if (strpos($join, 'NOT') !== false) {
- if (strtoupper(trim($key)) == 'NOT') {
- $key = 'AND ' . $key;
- }
- $not = 'NOT ';
- } else {
- $not = null;
- }
- $out[] = $not . '((' . join(') ' . strtoupper($key) . ' (', $value) . '))';
- } else {
- if (is_string($value) && preg_match('/^\{\$__cakeIdentifier\[(.*)\]__\$}$/', $value, $identifier) && isset($identifier[1])) {
- $data .= $this->name($key) . ' = ' . $this->name($identifier[1]);
- } elseif (is_array($value) && !empty($value)) {
- $keys = array_keys($value);
- if ($keys[0] === 0) {
- $data = $this->name($key) . ' IN (';
- if (strpos($value[0], '-!') === 0) {
- $value[0] = str_replace('-!', '', $value[0]);
- $data .= $value[0];
- $data .= ')';
- } else {
- if ($quoteValues) {
- foreach ($value as $valElement) {
- $data .= $this->value($valElement) . ', ';
- }
- }
- $data[strlen($data) - 2] = ')';
- }
- } else {
- $ret = $this->conditionKeysToString($value, $quoteValues);
- if (count($ret) > 1) {
- $out[] = '(' . join(') AND (', $ret) . ')';
- } elseif (isset($ret[0])) {
- $out[] = $ret[0];
- }
- }
- } elseif (is_numeric($key) && !empty($value)) {
- $data = $this->__quoteFields($value);
- } elseif ($value === null || (is_array($value) && empty($value))) {
- $data = $this->name($key) . ' IS NULL';
- } elseif ($value === false || $value === true) {
- $data = $this->name($key) . " = " . $this->value($value, 'boolean');
- } elseif ($value === '') {
- $data = $this->name($key) . " = ''";
- } elseif (preg_match('/^([a-z]+\\([a-z0-9]*\\)\\x20+|(?:' . join('\\x20)|(?:', $this->__sqlOps) . '\\x20)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)?(.*)/is', $value, $match)) {
- if (preg_match('/(\\x20[\\w]*\\x20)/', $key, $regs)) {
- $clause = $regs['1'];
- $key = preg_replace('/' . $regs['1'] . '/', '', $key);
- }
-
- $not = false;
- $mValue = trim($match['1']);
- if (empty($match['1'])) {
- $match['1'] = ' = ';
- } elseif (empty($mValue)) {
- $match['1'] = ' = ';
- $match['2'] = $match['0'];
- } elseif (!isset($match['2'])) {
- $match['1'] = ' = ';
- $match['2'] = $match['0'];
- } elseif (strtolower($mValue) == 'not') {
- $not = $this->conditionKeysToString(array($mValue => array($key => $match[2])), $quoteValues);
- }
-
- if ($not) {
- $data = $not[0];
- } elseif (strpos($match['2'], '-!') === 0) {
- $match['2'] = str_replace('-!', '', $match['2']);
- $data = $this->name($key) . ' ' . $match['1'] . ' ' . $match['2'];
- } else {
- if (!empty($match['2']) && $quoteValues) {
- if (!preg_match('/[A-Za-z]+\\([a-z0-9]*\\),?\\x20+/', $match['2'])) {
- $match['2'] = $this->value($match['2']);
- }
- $match['2'] = str_replace(' AND ', "' AND '", $match['2']);
- }
- $data = $this->__quoteFields($key);
- if ($data === $key) {
- $data = $this->name($key) . ' ' . $match['1'] . ' ' . $match['2'];
- } else {
- $data = $data . ' ' . $match['1'] . ' ' . $match['2'];
- }
- }
- }
-
- if ($data != null) {
- $out[] = $data;
- $data = null;
- }
- }
- $c++;
- }
- return $out;
- }
-/**
- * Quotes Model.fields
- *
- * @param string $conditions
- * @return string or false if no match
- * @access private
- */
- function __quoteFields($conditions) {
- $start = null;
- $end = null;
- $original = $conditions;
-
- if (!empty($this->startQuote)) {
- $start = preg_quote($this->startQuote);
- }
-
- if (!empty($this->endQuote)) {
- $end = preg_quote($this->endQuote);
- }
- $conditions = str_replace(array($start, $end), '', $conditions);
- preg_match_all('/(?:[\'\"][^\'\"\\\]*(?:\\\.[^\'\"\\\]*)*[\'\"])|([a-z0-9_' . $start . $end . ']*\\.[a-z0-9_' . $start . $end . ']*)/i', $conditions, $replace, PREG_PATTERN_ORDER);
-
- if (isset($replace['1']['0'])) {
- $pregCount = count($replace['1']);
-
- for ($i = 0; $i < $pregCount; $i++) {
- if (!empty($replace['1'][$i]) && !is_numeric($replace['1'][$i])) {
- $conditions = preg_replace('/\b' . preg_quote($replace['1'][$i]) . '\b/', $this->name($replace['1'][$i]), $conditions);
- }
- }
- return $conditions;
- }
- return $original;
- }
-/**
- * Returns a limit statement in the correct format for the particular database.
- *
- * @param integer $limit Limit of results returned
- * @param integer $offset Offset from which to start results
- * @return string SQL limit/offset statement
- */
- function limit($limit, $offset = null) {
- if ($limit) {
- $rt = '';
- if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
- $rt = ' LIMIT';
- }
-
- if ($offset) {
- $rt .= ' ' . $offset . ',';
- }
-
- $rt .= ' ' . $limit;
- return $rt;
- }
- return null;
- }
-/**
- * Returns an ORDER BY clause as a string.
- *
- * @param string $key Field reference, as a key (i.e. Post.title)
- * @param string $direction Direction (ASC or DESC)
- * @return string ORDER BY clause
- */
- function order($keys, $direction = 'ASC') {
- if (is_string($keys) && strpos($keys, ',') && !preg_match('/\(.+\,.+\)/', $keys)) {
- $keys = explode(',', $keys);
- array_map('trim', $keys);
- }
-
- if (is_array($keys)) {
- foreach ($keys as $key => $val) {
- if (is_numeric($key) && empty($val)) {
- unset ($keys[$key]);
- }
- }
- }
-
- if (empty($keys) || (is_array($keys) && count($keys) && isset($keys[0]) && empty($keys[0]))) {
- return '';
- }
-
- if (is_array($keys)) {
- if (Set::countDim($keys) > 1) {
- $new = array();
-
- foreach ($keys as $val) {
- $val = $this->order($val);
- $new[] = $val;
- }
-
- $keys = $new;
- }
-
- foreach ($keys as $key => $value) {
- if (is_numeric($key)) {
- $value = ltrim(str_replace('ORDER BY ', '', $this->order($value)));
- $key = $value;
-
- if (!preg_match('/\\x20ASC|\\x20DESC/i', $key)) {
- $value = ' ' . $direction;
- } else {
- $value = '';
- }
- } else {
- $value = ' ' . $value;
- }
-
- if (!preg_match('/^.+\\(.*\\)/', $key) && !strpos($key, ',')) {
- $dir = '';
- $hasDir = preg_match('/\\x20ASC|\\x20DESC/i', $key, $dir);
-
- if ($hasDir) {
- $dir = $dir[0];
- $key = preg_replace('/\\x20ASC|\\x20DESC/i', '', $key);
- } else {
- $dir = '';
- }
- $key = trim($this->name(trim($key)) . ' ' . trim($dir));
- }
- $order[] = $this->order($key . $value);
- }
-
- return ' ORDER BY ' . trim(str_replace('ORDER BY', '', join(',', $order)));
- } else {
- $keys = preg_replace('/ORDER\\x20BY/i', '', $keys);
-
- if (strpos($keys, '.')) {
- preg_match_all('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', $keys, $result,
- PREG_PATTERN_ORDER);
- $pregCount = count($result['0']);
-
- for ($i = 0; $i < $pregCount; $i++) {
- $keys = preg_replace('/' . $result['0'][$i] . '/', $this->name($result['0'][$i]), $keys);
- }
-
- if (preg_match('/\\x20ASC|\\x20DESC/i', $keys)) {
- return ' ORDER BY ' . $keys;
- } else {
- return ' ORDER BY ' . $keys . ' ' . $direction;
- }
- } elseif (preg_match('/(\\x20ASC|\\x20DESC)/i', $keys, $match)) {
- $direction = $match['1'];
- $keys = preg_replace('/' . $match['1'] . '/', '', $keys);
- return ' ORDER BY ' . $keys . $direction;
- } else {
- $direction = ' ' . $direction;
- }
- return ' ORDER BY ' . $keys . $direction;
- }
- }
-/**
- * Disconnects database, kills the connection and says the connection is closed,
- * and if DEBUG is turned on, the log for this object is shown.
- *
- */
- function close() {
- if (Configure::read() > 1) {
- $this->showLog();
- }
- $this->disconnect();
- }
-/**
- * Checks if the specified table contains any record matching specified SQL
- *
- * @param Model $model Model to search
- * @param string $sql SQL WHERE clause (condition only, not the "WHERE" part)
- * @return boolean True if the table has a matching record, else false
- */
- function hasAny($model, $sql) {
- $sql = $this->conditions($sql);
- $out = $this->fetchRow("SELECT COUNT(" . $model->primaryKey . ") " . $this->alias . "count FROM " . $this->fullTableName($model) . ' ' . ($sql ? ' ' . $sql : 'WHERE 1 = 1'));
-
- if (is_array($out)) {
- return $out[0]['count'];
- }
- return false;
- }
-/**
- * Gets the length of a database-native column description, or null if no length
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return integer An integer representing the length of the column
- */
- function length($real) {
- $col = str_replace(array(')', 'unsigned'), '', $real);
- $limit = null;
-
- if (strpos($col, '(') !== false) {
- list($col, $limit) = explode('(', $col);
- }
-
- if ($limit != null) {
- return intval($limit);
- }
- return null;
- }
-/**
- * Translates between PHP boolean values and Database (faked) boolean values
- *
- * @param mixed $data Value to be translated
- * @return mixed Converted boolean value
- */
- function boolean($data) {
- if ($data === true || $data === false) {
- if ($data === true) {
- return 1;
- }
- return 0;
- }
-
- if (!empty($data)) {
- return true;
- }
- return false;
- }
-/**
- * Destructor. Closes connection to the database.
- *
- */
- function __destruct() {
- if ($this->_transactionStarted) {
- $null = null;
- $this->rollback($null);
- }
- parent::__destruct();
- }
-/**
- * Inserts multiple values into a join table
- *
- * @param string $table
- * @param string $fields
- * @param array $values
- */
- function insertMulti($table, $fields, $values) {
- $values = implode(', ', $values);
- $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values}");
- }
-/**
- * Returns an array of the indexes in given datasource name.
- *
- * @param string $model Name of model to inspect
- * @return array Fields in table. Keys are column and unique
- */
- function index($model) {
- return false;
- }
-/**
- * Generate a create syntax from CakeSchema
- *
- * @param object $schema An instance of a subclass of CakeSchema
- * @param string $table Optional. If specified only the table name given will be generated.
- * Otherwise, all tables defined in the schema are generated.
- * @return string
- */
- function createSchema($schema, $table = null) {
- return false;
- }
-/**
- * Generate a alter syntax from CakeSchema::compare()
- *
- * @param unknown_type $schema
- * @return unknown
- */
- function alterSchema($compare, $table = null) {
- return false;
- }
-/**
- * Generate a drop syntax from CakeSchema
- *
- * @param object $schema An instance of a subclass of CakeSchema
- * @param string $table Optional. If specified only the table name given will be generated.
- * Otherwise, all tables defined in the schema are generated.
- * @return string
- */
- function dropSchema($schema, $table = null) {
- return false;
- }
-/**
- * Generate a column schema string
- *
- * @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
- * where options can be 'default', 'length', or 'key'.
- * @return string
- */
- function buildColumn($column) {
- return false;
- }
-/**
- * Format indexes for create table
- *
- * @param array $indexes
- * @return string
- */
- function buildIndex($indexes) {
- return false;
- }
-/**
- * Guesses the data type of an array
- *
- * @param string $value
- * @return void
- * @access public
- */
- function introspectType($value) {
- if (!is_array($value)) {
- if ($value === true || $value === false) {
- return 'boolean';
- }
- if (is_float($value) && floatval($value) === $value) {
- return 'float';
- }
- if (is_int($value) && intval($value) === $value) {
- return 'integer';
- }
- if (is_string($value) && strlen($value) > 255) {
- return 'text';
- }
- return 'string';
- }
-
- $isAllFloat = $isAllInt = true;
- $containsFloat = $containsInt = $containsString = false;
- foreach ($value as $key => $valElement) {
- $valElement = trim($valElement);
- if (!is_float($valElement) && !preg_match('/^[\d]+\.[\d]+$/', $valElement)) {
- $isAllFloat = false;
- } else {
- $containsFloat = true;
- continue;
- }
- if (!is_int($valElement) && !preg_match('/^[\d]+$/', $valElement)) {
- $isAllInt = false;
- } else {
- $containsInt = true;
- continue;
- }
- $containsString = true;
- }
-
- if ($isAllFloat) {
- return 'float';
- }
- if ($isAllInt) {
- return 'integer';
- }
-
- if ($containsInt && !$containsString) {
- return 'integer';
- }
- return 'string';
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_adodb.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_adodb.php
deleted file mode 100644
index f9d58d7..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_adodb.php
+++ /dev/null
@@ -1,437 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_adodb.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * AdoDB layer for DBO.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Include AdoDB files.
- */
-vendor ('adodb' . DS . 'adodb.inc');
-
-/**
- * AdoDB DBO implementation.
- *
- * Database abstraction implementation for the AdoDB library.
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboAdodb extends DboSource {
-/**
- * Enter description here...
- *
- * @var string
- */
- var $description = "ADOdb DBO Driver";
-
-/**
- * ADOConnection object with which we connect.
- *
- * @var ADOConnection The connection object.
- * @access private
- */
- var $_adodb = null;
-
-/**
- * Array translating ADOdb column MetaTypes to cake-supported metatypes
- *
- * @var array
- * @access private
- */
- var $_adodb_column_types = array(
- 'C' => 'string',
- 'X' => 'text',
- 'D' => 'date',
- 'T' => 'timestamp',
- 'L' => 'boolean',
- 'N' => 'float',
- 'I' => 'integer',
- 'R' => 'integer', // denotes auto-increment or counter field
- 'B' => 'binary'
- );
-
-/**
- * Connects to the database using options in the given configuration array.
- *
- * @param array $config Configuration array for connecting
- */
- function connect() {
- $config = $this->config;
- $persistent = strrpos($config['connect'], '|p');
-
- if ($persistent === false) {
- $adodb_driver = $config['connect'];
- $connect = 'Connect';
- } else {
- $adodb_driver = substr($config['connect'], 0, $persistent);
- $connect = 'PConnect';
- }
-
- $this->_adodb = NewADOConnection($adodb_driver);
-
- $this->startQuote = $this->_adodb->nameQuote;
- $this->endQuote = $this->_adodb->nameQuote;
-
- $this->connected = $this->_adodb->$connect($config['host'], $config['login'], $config['password'], $config['database']);
- return $this->connected;
- }
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- return $this->_adodb->Close();
- }
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- */
- function _execute($sql) {
- global $ADODB_FETCH_MODE;
- $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
- return $this->_adodb->execute($sql);
- }
-/**
- * Returns a row from given resultset as an array .
- *
- * @return array The fetched row as an array
- */
-/**
- * Returns a row from current resultset as an array .
- *
- * @return array The fetched row as an array
- */
- function fetchRow($sql = null) {
-
- if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
- if (!$this->execute($sql)) {
- return null;
- }
- }
-
- if (!is_object($this->_result) || $this->_result->EOF) {
- return null;
- } else {
- $resultRow = $this->_result->FetchRow();
- $this->resultSet($resultRow);
- return $this->fetchResult();
- }
- }
-/**
- * Begin a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions).
- */
- function begin(&$model) {
- if (parent::begin($model)) {
- if ($this->_adodb->BeginTrans()) {
- $this->_transactionStarted = true;
- return true;
- }
- }
- return false;
- }
-/**
- * Commit a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function commit(&$model) {
- if (parent::commit($model)) {
- $this->_transactionStarted = false;
- return $this->_adodb->CommitTrans();
- }
- return false;
- }
-/**
- * Rollback a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function rollback(&$model) {
- if (parent::rollback($model)) {
- return $this->_adodb->RollbackTrans();
- }
- return false;
- }
-/**
- * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
- *
- * @return array Array of tablenames in the database
- */
- function listSources() {
- $tables = $this->_adodb->MetaTables('TABLES');
-
- if (!sizeof($tables) > 0) {
- trigger_error(ERROR_NO_TABLE_LIST, E_USER_NOTICE);
- exit;
- }
-
- return $tables;
- }
-/**
- * Returns an array of the fields in the table used by the given model.
- *
- * @param AppModel $model Model object
- * @return array Fields in table. Keys are name and type
- */
- function describe(&$model) {
- $cache = parent::describe($model);
- if ($cache != null) {
- return $cache;
- }
-
- $fields = false;
- $cols = $this->_adodb->MetaColumns($this->fullTableName($model, false));
-
- foreach ($cols as $column) {
- $fields[$column->name] = array(
- 'type' => $this->column($column->type)
- );
- }
-
- $this->__cacheDescription($this->fullTableName($model, false), $fields);
- return $fields;
- }
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message
- */
- function lastError() {
- return $this->_adodb->ErrorMsg();
- }
-/**
- * Returns number of affected rows in previous database operation, or false if no previous operation exists.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- return $this->_adodb->Affected_Rows();
- }
-/**
- * Returns number of rows in previous resultset, or false if no previous resultset exists.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- return $this->_result ? $this->_result->RecordCount() : false;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @return int
- *
- * @Returns the last autonumbering ID inserted. Returns false if function not supported.
- */
- function lastInsertId() {
- return $this->_adodb->Insert_ID();
- }
-
-/**
- * Returns a LIMIT statement in the correct format for the particular database.
- *
- * @param int $limit Limit of results returned
- * @param int $offset Offset from which to start results
- * @return string SQL limit/offset statement
- * @todo Please change output string to whatever select your database accepts. adodb doesn't allow us to get the correct limit string out of it.
- */
- function limit($limit, $offset = null) {
- if (empty($limit)) {
- return null;
- }
- return " LIMIT {$limit}" . ($offset ? "{$offset}" : null);
- // please change to whatever select your database accepts
- // adodb doesn't allow us to get the correct limit string out of it
- }
-
-/**
- * Converts database-layer column types to basic types
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return string Abstract column type (i.e. "string")
- */
- function column($real) {
- if (isset($this->_result)) {
- $adodb_metatyper = &$this->_result;
- } else {
- $adodb_metatyper = &$this->_adodb->execute('Select 1');
- }
-
- $interpreted_type = $adodb_metatyper->MetaType($real);
- if (!isset($this->_adodb_column_types[$interpreted_type])) {
- return 'text';
- }
-
- return $this->_adodb_column_types[$interpreted_type];
- }
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @param string $column_type The type of the column into which this data will be inserted
- * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
- * @return string Quoted and escaped data
- */
- function value($data, $column = null, $safe = false) {
- $parent = parent::value($data, $column, $safe);
- if ($parent != null) {
- return $parent;
- }
-
- if ($data === null) {
- return 'NULL';
- }
-
- if ($data === '') {
- return "''";
- }
- return $this->_adodb->qstr($data);
- }
-/**
- * Generates the fields list of an SQL query.
- *
- * @param Model $model
- * @param string $alias Alias tablename
- * @param mixed $fields
- * @return array
- */
- function fields(&$model, $alias = null, $fields = null, $quote = true) {
- if (empty($alias)) {
- $alias = $model->name;
- }
-
- if (!is_array($fields)) {
- if ($fields != null) {
- if (strpos($fields, ',')) {
- $fields = explode(',', $fields);
- } else {
- $fields = array($fields);
- }
- $fields = array_map('trim', $fields);
- } else {
- foreach ($model->_tableInfo->value as $field) {
- $fields[] = $field['name'];
- }
- }
- }
-
- $count = count($fields);
-
- if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
- for ($i = 0; $i < $count; $i++) {
- if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
- $prepend = '';
- if (strpos($fields[$i], 'DISTINCT') !== false) {
- $prepend = 'DISTINCT ';
- $fields[$i] = trim(r('DISTINCT', '', $fields[$i]));
- }
-
- $dot = strrpos($fields[$i], '.');
- if ($dot === false) {
- $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fields[$i]);
- } else {
- $build = explode('.', $fields[$i]);
- $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $build[1]);
- }
- }
- }
- }
- return $fields;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $results
- */
- function resultSet(&$results) {
- $num_fields = count($results);
- $fields = array_keys($results);
- $this->results =& $results;
- $this->map = array();
- $index = 0;
- $j = 0;
-
- while ($j < $num_fields) {
- $columnName = $fields[$j];
-
- if (strpos($columnName, '__')) {
- $parts = explode('__', $columnName);
- $this->map[$index++] = array($parts[0], $parts[1]);
- } else {
- $this->map[$index++] = array(0, $columnName);
- }
- $j++;
- }
- }
-/**
- * Fetches the next row from the current result set
- *
- * @return unknown
- */
- function fetchResult() {
- if (!empty($this->results) && $row = $this->results) {
- $resultRow = array();
- $fields = array_keys($row);
- $count = count($fields);
- $i = 0;
- for ($i = 0; $i < $count; $i++) { //$row as $index => $field) {
- list($table, $column) = $this->map[$i];
- $resultRow[$table][$column] = $row[$fields[$i]];
- }
- return $resultRow;
- } else {
- return false;
- }
- }
-/**
- * Inserts multiple values into a join table
- *
- * @param string $table
- * @param string $fields
- * @param array $values
- */
- function insertMulti($table, $fields, $values) {
- $count = count($values);
- for ($x = 0; $x < $count; $x++) {
- $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mssql.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mssql.php
deleted file mode 100644
index accff58..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mssql.php
+++ /dev/null
@@ -1,604 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_mssql.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * MS SQL layer for DBO
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 0.10.5.1790
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Short description for class.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboMssql extends DboSource {
-/**
- * Driver description
- *
- * @var string
- */
- var $description = "MS SQL DBO Driver";
-/**
- * Starting quote character for quoted identifiers
- *
- * @var string
- */
- var $startQuote = "[";
-/**
- * Ending quote character for quoted identifiers
- *
- * @var string
- */
- var $endQuote = "]";
- /**
- * Creates a map between field aliases and numeric indexes. Workaround for the
- * SQL Server driver's 30-character column name limitation.
- *
- * @var array
- */
- var $__fieldMappings = array();
-/**
- * Base configuration settings for MS SQL driver
- *
- * @var array
- */
- var $_baseConfig = array(
- 'persistent' => true,
- 'host' => 'localhost',
- 'login' => 'root',
- 'password' => '',
- 'database' => 'cake',
- 'port' => '1433',
- 'connect' => 'mssql_pconnect'
- );
-/**
- * MS SQL column definition
- *
- * @var array
- */
- var $columns = array(
- 'primary_key' => array('name' => 'int IDENTITY (1, 1) NOT NULL'),
- 'string' => array('name' => 'varchar', 'limit' => '255'),
- 'text' => array('name' => 'text'),
- 'integer' => array('name' => 'int', 'formatter' => 'intval'),
- 'float' => array('name' => 'float', 'formatter' => 'floatval'),
- 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'time' => array('name' => 'datetime', 'format' => 'H:i:s', 'formatter' => 'date'),
- 'date' => array('name' => 'datetime', 'format' => 'Y-m-d', 'formatter' => 'date'),
- 'binary' => array('name' => 'image'),
- 'boolean' => array('name' => 'bit')
- );
-/**
- * MS SQL DBO driver constructor; sets SQL Server error reporting defaults
- *
- * @param array $config Configuration data from app/config/databases.php
- * @return boolean True if connected successfully, false on error
- */
- function __construct($config, $autoConnect = true) {
- if ($autoConnect) {
- if (!function_exists('mssql_min_message_severity')) {
- trigger_error("PHP SQL Server interface is not installed, cannot continue. For troubleshooting information, see http://php.net/mssql/", E_USER_WARNING);
- }
- mssql_min_message_severity(15);
- mssql_min_error_severity(2);
- }
- return parent::__construct($config, $autoConnect);
- }
-/**
- * Connects to the database using options in the given configuration array.
- *
- * @return boolean True if the database could be connected, else false
- */
- function connect() {
- $config = $this->config;
-
- $os = env('OS');
- if (!empty($os) && strpos($os, 'Windows') !== false) {
- $sep = ',';
- } else {
- $sep = ':';
- }
- $connect = 'mssql_connect';
- if ($config['persistent']) {
- $connect = 'mssql_pconnect';
- }
- $this->connected = false;
-
- if (is_numeric($config['port'])) {
- $port = $sep . $config['port']; // Port number
- } elseif ($config['port'] === null) {
- $port = ''; // No port - SQL Server 2005
- } else {
- $port = '\\' . $config['port']; // Named pipe
- }
- $this->connection = $connect($config['host'] . $port, $config['login'], $config['password']);
-
- if (mssql_select_db($config['database'], $this->connection)) {
- $this->connected = true;
- }
- }
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- @mssql_free_result($this->results);
- $this->connected = !@mssql_close($this->connection);
- return !$this->connected;
- }
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- * @access protected
- */
- function _execute($sql) {
- return mssql_query($sql, $this->connection);
- }
-/**
- * Returns an array of sources (tables) in the database.
- *
- * @return array Array of tablenames in the database
- */
- function listSources() {
- $cache = parent::listSources();
-
- if ($cache != null) {
- return $cache;
- }
-
- $result = $this->fetchAll('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES');
-
- if (!$result || empty($result)) {
- return array();
- } else {
- $tables = array();
-
- foreach ($result as $table) {
- $tables[] = $table[0]['TABLE_NAME'];
- }
-
- parent::listSources($tables);
- return $tables;
- }
- }
-/**
- * Returns an array of the fields in given table name.
- *
- * @param Model $model Model object to describe
- * @return array Fields in table. Keys are name and type
- */
- function describe(&$model) {
- $cache = parent::describe($model);
-
- if ($cache != null) {
- return $cache;
- }
-
- $fields = false;
- $cols = $this->fetchAll("SELECT COLUMN_NAME as Field, DATA_TYPE as Type, COL_LENGTH('" . $this->fullTableName($model, false) . "', COLUMN_NAME) as Length, IS_NULLABLE As [Null], COLUMN_DEFAULT as [Default], COLUMNPROPERTY(OBJECT_ID('" . $this->fullTableName($model, false) . "'), COLUMN_NAME, 'IsIdentity') as [Key], NUMERIC_SCALE as Size FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" . $this->fullTableName($model, false) . "'", false);
-
- foreach ($cols as $column) {
- $fields[$column[0]['Field']] = array(
- 'type' => $this->column($column[0]['Type']),
- 'null' => (strtoupper($column[0]['Null']) == 'YES'),
- 'default' => $column[0]['Default'],
- 'length' => $this->length($column[0]['Type']),
- );
- }
- $this->__cacheDescription($this->fullTableName($model, false), $fields);
- return $fields;
- }
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @param string $column The column into which this data will be inserted
- * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
- * @return string Quoted and escaped data
- */
- function value($data, $column = null, $safe = false) {
- $parent = parent::value($data, $column, $safe);
-
- if ($parent != null) {
- return $parent;
- }
- if ($data === null) {
- return 'NULL';
- }
- if ($data === '') {
- return "''";
- }
-
- switch($column) {
- case 'boolean':
- $data = $this->boolean((bool)$data);
- break;
- case 'datetime':
- if ($data && (($timestamp = strtotime($data)) !== false)) {
- $data = date('Y-m-d\TH:i:s', $timestamp);
- }
- break;
- default:
- if (get_magic_quotes_gpc()) {
- $data = stripslashes(str_replace("'", "''", $data));
- } else {
- $data = str_replace("'", "''", $data);
- }
- break;
- }
-
- if (in_array($column, array('integer', 'float')) && is_numeric($data)) {
- return $data;
- }
- return "'" . $data . "'";
- }
-/**
- * Generates the fields list of an SQL query.
- *
- * @param Model $model
- * @param string $alias Alias tablename
- * @param mixed $fields
- * @return array
- */
- function fields(&$model, $alias = null, $fields = array(), $quote = true) {
- if (empty($alias)) {
- $alias = $model->name;
- }
- $fields = parent::fields($model, $alias, $fields, false);
- $count = count($fields);
-
- if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
- for ($i = 0; $i < $count; $i++) {
- $dot = strrpos($fields[$i], '.');
- $fieldAlias = count($this->__fieldMappings);
-
- if ($dot === false && !preg_match('/\s+AS\s+/i', $fields[$i])) {
- $this->__fieldMappings[$alias . '__' . $fieldAlias] = $alias . '.' . $fields[$i];
- $fields[$i] = $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fieldAlias);
- } elseif (!preg_match('/\s+AS\s+/i', $fields[$i])) {
- $build = explode('.', $fields[$i]);
- $this->__fieldMappings[$build[0] . '__' . $fieldAlias] = $build[0] . '.' . $build[1];
- $fields[$i] = $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $fieldAlias);
- }
- }
- }
- return $fields;
- }
-/**
- * Begin a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions).
- */
- function begin(&$model) {
- if (parent::begin($model)) {
- if ($this->execute('BEGIN TRANSACTION')) {
- $this->_transactionStarted = true;
- return true;
- }
- }
- return false;
- }
-/**
- * Commit a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function commit(&$model) {
- if (parent::commit($model)) {
- $this->_transactionStarted = false;
- return $this->execute('COMMIT');
- }
- return false;
- }
-/**
- * Rollback a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function rollback(&$model) {
- if (parent::rollback($model)) {
- return $this->execute('ROLLBACK');
- }
- return false;
- }
-/**
- * Removes Identity (primary key) column from update data before returning to parent
- *
- * @param Model $model
- * @param array $fields
- * @param array $values
- * @return array
- */
- function update(&$model, $fields = array(), $values = array()) {
- foreach ($fields as $i => $field) {
- if ($field == $model->primaryKey) {
- unset ($fields[$i]);
- unset ($values[$i]);
- break;
- }
- }
- return parent::update($model, $fields, $values);
- }
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message with error number
- */
- function lastError() {
- $error = mssql_get_last_message($this->connection);
-
- if ($error) {
- if (strpos(strtolower($error), 'changed database') === false) {
- return $error;
- }
- }
- return null;
- }
-/**
- * Returns number of affected rows in previous database operation. If no previous operation exists,
- * this returns false.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- if ($this->_result) {
- return mssql_rows_affected($this->connection);
- }
- return null;
- }
-/**
- * Returns number of rows in previous resultset. If no previous resultset exists,
- * this returns false.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- if ($this->_result) {
- return @mssql_num_rows($this->_result);
- }
- return null;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param unknown_type $source
- * @return in
- */
- function lastInsertId($source = null) {
- $id = $this->fetchRow('SELECT SCOPE_IDENTITY() AS insertID', false);
- return $id[0]['insertID'];
- }
-/**
- * Returns a limit statement in the correct format for the particular database.
- *
- * @param int $limit Limit of results returned
- * @param int $offset Offset from which to start results
- * @return string SQL limit/offset statement
- */
- function limit($limit, $offset = null) {
- if ($limit) {
- $rt = '';
- if (!strpos(strtolower($limit), 'top') || strpos(strtolower($limit), 'top') === 0) {
- $rt = ' TOP';
- }
- $rt .= ' ' . $limit;
- if (is_int($offset) && $offset > 0) {
- $rt .= ' OFFSET ' . $offset;
- }
- return $rt;
- }
- return null;
- }
-/**
- * Converts database-layer column types to basic types
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return string Abstract column type (i.e. "string")
- */
- function column($real) {
- if (is_array($real)) {
- $col = $real['name'];
-
- if (isset($real['limit'])) {
- $col .= '(' . $real['limit'] . ')';
- }
- return $col;
- }
- $col = str_replace(')', '', $real);
- $limit = null;
- @list($col, $limit) = explode('(', $col);
-
- if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
- return $col;
- }
-
- if ($col == 'bit') {
- return 'boolean';
- }
-
- if (strpos($col, 'int') !== false || $col == 'numeric') {
- return 'integer';
- }
-
- if (strpos($col, 'char') !== false) {
- return 'string';
- }
-
- if (strpos($col, 'text') !== false) {
- return 'text';
- }
-
- if (strpos($col, 'binary') !== false || $col == 'image') {
- return 'binary';
- }
-
- if (in_array($col, array('float', 'real', 'decimal'))) {
- return 'float';
- }
- return 'text';
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $results
- */
- function resultSet(&$results) {
- $this->results =& $results;
- $this->map = array();
- $num_fields = mssql_num_fields($results);
- $index = 0;
- $j = 0;
-
- while ($j < $num_fields) {
- $column = mssql_field_name($results, $j);
-
- if (strpos($column, '__')) {
- if (isset($this->__fieldMappings[$column]) && strpos($this->__fieldMappings[$column], '.')) {
- $map = explode('.', $this->__fieldMappings[$column]);
- } elseif (isset($this->__fieldMappings[$column])) {
- $map = array(0, $this->__fieldMappings[$column]);
- } else {
- $map = array(0, $column);
- }
- $this->map[$index++] = $map;
- } else {
- $this->map[$index++] = array(0, $column);
- }
- $j++;
- }
- }
-/**
- * Builds final SQL statement
- *
- * @param array $data Query data
- * @return string
- */
- function renderStatement($data) {
- extract($data);
- if (preg_match('/offset\s+([0-9]+)/i', $limit, $offset)) {
- $limit = preg_replace('/\s*offset.*$/i', '', $limit);
- preg_match('/top\s+([0-9]+)/i', $limit, $limitVal);
- $offset = intval($offset[1]) + intval($limitVal[1]);
- $rOrder = $this->__switchSort($order);
- list($order2, $rOrder) = array($this->__mapFields($order), $this->__mapFields($rOrder));
- return "SELECT * FROM (SELECT {$limit} * FROM (SELECT TOP {$offset} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order}) AS Set1 {$rOrder}) AS Set2 {$order2}";
- } else {
- return "SELECT {$limit} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order}";
- }
- }
-/**
- * Reverses the sort direction of ORDER statements to get paging offsets to work correctly
- *
- * @param string $order
- * @return string
- * @access private
- */
- function __switchSort($order) {
- $order = preg_replace('/\s+ASC/i', '__tmp_asc__', $order);
- $order = preg_replace('/\s+DESC/i', ' ASC', $order);
- return preg_replace('/__tmp_asc__/', ' DESC', $order);
- }
-/**
- * Translates field names used for filtering and sorting to shortened names using the field map
- *
- * @param string $sql A snippet of SQL representing an ORDER or WHERE statement
- * @return string The value of $sql with field names replaced
- * @access private
- */
- function __mapFields($sql) {
- if (empty($sql) || empty($this->__fieldMappings)) {
- return $sql;
- }
- foreach ($this->__fieldMappings as $key => $val) {
- $sql = preg_replace('/' . preg_quote($val) . '/', $this->name($key), $sql);
- $sql = preg_replace('/' . preg_quote($this->name($val)) . '/', $this->name($key), $sql);
- }
- return $sql;
- }
-/**
- * Returns an array of all result rows for a given SQL query.
- * Returns false if no rows matched.
- *
- * @param string $sql SQL statement
- * @param boolean $cache Enables returning/storing cached query results
- * @return array Array of resultset rows, or false if no rows matched
- */
- function read(&$model, $queryData = array(), $recursive = null) {
- $results = parent::read($model, $queryData, $recursive);
- $this->__fieldMappings = array();
- $this->__fieldMapBase = null;
- return $results;
- }
-/**
- * Fetches the next row from the current result set
- *
- * @return unknown
- */
- function fetchResult() {
- if ($row = mssql_fetch_row($this->results)) {
- $resultRow = array();
- $i = 0;
-
- foreach ($row as $index => $field) {
- list($table, $column) = $this->map[$index];
- $resultRow[$table][$column] = $row[$index];
- $i++;
- }
- return $resultRow;
- } else {
- return false;
- }
- }
-/**
- * Inserts multiple values into a join table
- *
- * @param string $table
- * @param string $fields
- * @param array $values
- */
- function insertMulti($table, $fields, $values) {
- $count = count($values);
- for ($x = 0; $x < $count; $x++) {
- $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
- }
- }
-
-}
-?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysql.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysql.php
deleted file mode 100644
index 5774563..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysql.php
+++ /dev/null
@@ -1,681 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_mysql.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * MySQL layer for DBO
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 0.10.5.1790
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Short description for class.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboMysql extends DboSource {
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $description = "MySQL DBO Driver";
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $startQuote = "`";
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $endQuote = "`";
-/**
- * Base configuration settings for MySQL driver
- *
- * @var array
- */
- var $_baseConfig = array(
- 'persistent' => true,
- 'host' => 'localhost',
- 'login' => 'root',
- 'password' => '',
- 'database' => 'cake',
- 'port' => '3306',
- 'connect' => 'mysql_pconnect'
- );
-/**
- * MySQL column definition
- *
- * @var array
- */
- var $columns = array(
- 'primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
- 'string' => array('name' => 'varchar', 'limit' => '255'),
- 'text' => array('name' => 'text'),
- 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
- 'float' => array('name' => 'float', 'formatter' => 'floatval'),
- 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
- 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
- 'binary' => array('name' => 'blob'),
- 'boolean' => array('name' => 'tinyint', 'limit' => '1')
- );
-/**
- * Connects to the database using options in the given configuration array.
- *
- * @return boolean True if the database could be connected, else false
- */
- function connect() {
- $config = $this->config;
- $connect = $config['connect'];
- $this->connected = false;
-
- if (!$config['persistent'] || $config['connect'] === 'mysql_connect') {
- $this->connection = mysql_connect($config['host'] . ':' . $config['port'], $config['login'], $config['password'], true);
- } else {
- $this->connection = $connect($config['host'] . ':' . $config['port'], $config['login'], $config['password']);
- }
-
- if (mysql_select_db($config['database'], $this->connection)) {
- $this->connected = true;
- }
-
- if (isset($config['encoding']) && !empty($config['encoding'])) {
- $this->setEncoding($config['encoding']);
- }
-
- return $this->connected;
- }
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- @mysql_free_result($this->results);
- $this->connected = !@mysql_close($this->connection);
- return !$this->connected;
- }
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- * @access protected
- */
- function _execute($sql) {
- return mysql_query($sql, $this->connection);
- }
-/**
- * Returns an array of sources (tables) in the database.
- *
- * @return array Array of tablenames in the database
- */
- function listSources() {
- $cache = parent::listSources();
- if ($cache != null) {
- return $cache;
- }
- $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
-
- if (!$result) {
- return array();
- } else {
- $tables = array();
-
- while ($line = mysql_fetch_array($result)) {
- $tables[] = $line[0];
- }
- parent::listSources($tables);
- return $tables;
- }
- }
-/**
- * Returns an array of the fields in given table name.
- *
- * @param string $tableName Name of database table to inspect
- * @return array Fields in table. Keys are name and type
- */
- function describe(&$model) {
- $cache = parent::describe($model);
- if ($cache != null) {
- return $cache;
- }
- $fields = false;
- $cols = $this->query('DESCRIBE ' . $this->fullTableName($model));
-
- foreach ($cols as $column) {
- $colKey = array_keys($column);
- if (isset($column[$colKey[0]]) && !isset($column[0])) {
- $column[0] = $column[$colKey[0]];
- }
- if (isset($column[0])) {
- $fields[$column[0]['Field']] = array(
- 'type' => $this->column($column[0]['Type']),
- 'null' => ($column[0]['Null'] == 'YES' ? true : false),
- 'default' => $column[0]['Default'],
- 'length' => $this->length($column[0]['Type']),
- );
- if(!empty($column[0]['Key']) && isset($this->index[$column[0]['Key']])) {
- $fields[$column[0]['Field']]['key'] = $this->index[$column[0]['Key']];
- }
- if(!empty($column[0]['Extra'])) {
- $fields[$column[0]['Field']]['extra'] = $column[0]['Extra'];
- }
- }
- }
- $this->__cacheDescription($this->fullTableName($model, false), $fields);
- return $fields;
- }
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @param string $column The column into which this data will be inserted
- * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
- * @return string Quoted and escaped data
- */
- function value($data, $column = null, $safe = false) {
- $parent = parent::value($data, $column, $safe);
-
- if ($parent != null) {
- return $parent;
- } elseif ($data === null || (is_array($data) && empty($data))) {
- return 'NULL';
- } elseif ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') {
- return "''";
- }
- if (empty($column)) {
- $column = $this->introspectType($data);
- }
-
- switch ($column) {
- case 'boolean':
- return $this->boolean((bool)$data);
- break;
- case 'integer':
- case 'float':
- if ($data === '') {
- return 'NULL';
- }
- if ((is_int($data) || is_float($data) || $data === '0') || (
- is_numeric($data) && strpos($data, ',') === false &&
- $data[0] != '0' && strpos($data, 'e') === false)) {
- return $data;
- }
- default:
- $data = "'" . mysql_real_escape_string($data, $this->connection) . "'";
- break;
- }
- return $data;
- }
-/**
- * Begin a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions).
- */
- function begin(&$model) {
- if (parent::begin($model)) {
- if ($this->execute('START TRANSACTION')) {
- $this->_transactionStarted = true;
- return true;
- }
- }
- return false;
- }
-/**
- * Commit a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function commit(&$model) {
- if (parent::commit($model)) {
- $this->_transactionStarted = false;
- return $this->execute('COMMIT');
- }
- return false;
- }
-/**
- * Rollback a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function rollback(&$model) {
- if (parent::rollback($model)) {
- return $this->execute('ROLLBACK');
- }
- return false;
- }
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message with error number
- */
- function lastError() {
- if (mysql_errno($this->connection)) {
- return mysql_errno($this->connection).': '.mysql_error($this->connection);
- }
- return null;
- }
-/**
- * Returns number of affected rows in previous database operation. If no previous operation exists,
- * this returns false.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- if ($this->_result) {
- return mysql_affected_rows($this->connection);
- }
- return null;
- }
-/**
- * Returns number of rows in previous resultset. If no previous resultset exists,
- * this returns false.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- if ($this->_result and is_resource($this->_result)) {
- return @mysql_num_rows($this->_result);
- }
- return null;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param unknown_type $source
- * @return in
- */
- function lastInsertId($source = null) {
- $id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
- if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
- return $id[0]['insertID'];
- }
-
- return null;
- }
-/**
- * Converts database-layer column types to basic types
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return string Abstract column type (i.e. "string")
- */
- function column($real) {
- if (is_array($real)) {
- $col = $real['name'];
- if (isset($real['limit'])) {
- $col .= '('.$real['limit'].')';
- }
- return $col;
- }
-
- $col = r(')', '', $real);
- $limit = $this->length($real);
- @list($col,$vals) = explode('(', $col);
-
- if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
- return $col;
- }
- if ($col == 'tinyint' && $limit == 1) {
- return 'boolean';
- }
- if (strpos($col, 'int') !== false) {
- return 'integer';
- }
- if (strpos($col, 'char') !== false || $col == 'tinytext') {
- return 'string';
- }
- if (strpos($col, 'text') !== false) {
- return 'text';
- }
- if (strpos($col, 'blob') !== false) {
- return 'binary';
- }
- if (in_array($col, array('float', 'double', 'decimal'))) {
- return 'float';
- }
- if (strpos($col, 'enum') !== false) {
- return "enum($vals)";
- }
- if ($col == 'boolean') {
- return $col;
- }
- return 'text';
- }
-/**
- * Gets the length of a database-native column description, or null if no length
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return int An integer representing the length of the column
- */
- function length($real) {
- $col = r(array(')', 'unsigned'), '', $real);
- $limit = null;
-
- if (strpos($col, '(') !== false) {
- list($col, $limit) = explode('(', $col);
- }
-
- if ($limit != null) {
- return intval($limit);
- }
- return null;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $results
- */
- function resultSet(&$results) {
- $this->results =& $results;
- $this->map = array();
- $num_fields = mysql_num_fields($results);
- $index = 0;
- $j = 0;
-
- while ($j < $num_fields) {
-
- $column = mysql_fetch_field($results,$j);
- if (!empty($column->table)) {
- $this->map[$index++] = array($column->table, $column->name);
- } else {
- $this->map[$index++] = array(0, $column->name);
- }
- $j++;
- }
- }
-/**
- * Fetches the next row from the current result set
- *
- * @return unknown
- */
- function fetchResult() {
- if ($row = mysql_fetch_row($this->results)) {
- $resultRow = array();
- $i = 0;
- foreach ($row as $index => $field) {
- list($table, $column) = $this->map[$index];
- $resultRow[$table][$column] = $row[$index];
- $i++;
- }
- return $resultRow;
- } else {
- return false;
- }
- }
-/**
- * Sets the database encoding
- *
- * @param string $enc Database encoding
- * @return void
- */
- function setEncoding($enc) {
- return $this->_execute('SET NAMES ' . $enc) != false;
- }
-/**
- * Gets the database encoding
- *
- * @return string The database encoding
- */
- function getEncoding() {
- return mysql_client_encoding($this->connection);
- }
-/**
- * Returns an array of the indexes in given table name.
- *
- * @param string $model Name of model to inspect
- * @return array Fields in table. Keys are column and unique
- */
- function index($model) {
- $index = array();
- $table = $this->fullTableName($model, false);
- if($table) {
- $indexes = $this->query('SHOW INDEX FROM ' . $table);
- $keys = Set::extract($indexes, '{n}.STATISTICS');
- foreach ($keys as $i => $key) {
- if(!isset($index[$key['Key_name']])) {
- $index[$key['Key_name']]['column'] = $key['Column_name'];
- $index[$key['Key_name']]['unique'] = ife($key['Non_unique'] == 0, 1, 0);
- } else {
- if(!is_array($index[$key['Key_name']]['column'])) {
- $col[] = $index[$key['Key_name']]['column'];
- }
- $col[] = $key['Column_name'];
- $index[$key['Key_name']]['column'] = $col;
- }
- }
- }
- return $index;
- }
-/**
- * Generate a MySQL schema for the given Schema object
- *
- * @param object $schema An instance of a subclass of CakeSchema
- * @param string $table Optional. If specified only the table name given will be generated.
- * Otherwise, all tables defined in the schema are generated.
- * @return string
- */
- function createSchema($schema, $table = null) {
- if (!is_a($schema, 'CakeSchema')) {
- trigger_error(__('Invalid schema object', true), E_USER_WARNING);
- return null;
- }
- $out = '';
- foreach ($schema->tables as $curTable => $columns) {
- if (!$table || $table == $curTable) {
- $out .= 'CREATE TABLE ' . $this->fullTableName($curTable) . " (\n";
- $cols = $colList = $index = array();
- $primary = null;
- foreach ($columns as $name => $col) {
- if (is_string($col)) {
- $col = array('type' => $col);
- }
- if (isset($col['key']) && $col['key'] == 'primary') {
- $primary = $name;
- }
- if($name !== 'indexes') {
- $col['name'] = $name;
- if(!isset($col['type'])) {
- $col['type'] = 'string';
- }
- $cols[] = $this->buildColumn($col);
- } else {
- $index[] = $this->buildIndex($col);
- }
-
- }
- if(empty($index) && !empty($primary)) {
- $col = array('PRIMARY' => array('column'=> $primary, 'unique' => 1));
- $index[] = $this->buildIndex($col);
- }
- $out .= "\t" . join(",\n\t", $cols) . ",\n\t". join(",\n\t", $index) . "\n);\n\n";
- }
- }
- return $out;
- }
-/**
- * Generate a MySQL Alter Table syntax for the given Schema comparison
- *
- * @param unknown_type $schema
- * @return unknown
- */
- function alterSchema($compare, $table = null) {
- if(!is_array($compare)) {
- return false;
- }
- $out = '';
- $colList = array();
- foreach($compare as $curTable => $types) {
- if (!$table || $table == $curTable) {
- $out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n";
- foreach($types as $type => $column) {
- switch($type) {
- case 'add':
- foreach($column as $field => $col) {
- $col['name'] = $field;
- $alter = 'ADD '.$this->buildColumn($col);
- if(isset($col['after'])) {
- $alter .= ' AFTER '. $this->name($col['after']);
- }
- $colList[] = $alter;
- }
- break;
- case 'drop':
- foreach($column as $field => $col) {
- $col['name'] = $field;
- $colList[] = 'DROP '.$this->name($field);
- }
- break;
- case 'change':
- foreach($column as $field => $col) {
- if(!isset($col['name'])) {
- $col['name'] = $field;
- }
- $colList[] = 'CHANGE '. $this->name($field).' '.$this->buildColumn($col);
- }
- break;
- }
- }
- $out .= "\t" . join(",\n\t", $colList) . ";\n\n";
- }
- }
- return $out;
- }
-/**
- * Generate a MySQL Drop table for the given Schema object
- *
- * @param object $schema An instance of a subclass of CakeSchema
- * @param string $table Optional. If specified only the table name given will be generated.
- * Otherwise, all tables defined in the schema are generated.
- * @return string
- */
- function dropSchema($schema, $table = null) {
- if (!is_a($schema, 'CakeSchema')) {
- trigger_error(__('Invalid schema object', true), E_USER_WARNING);
- return null;
- }
- $out = '';
- foreach ($schema->tables as $curTable => $columns) {
- if (!$table || $table == $curTable) {
- $out .= 'DROP TABLE IF EXISTS ' . $this->fullTableName($curTable) . ";\n";
- }
- }
- return $out;
- }
-/**
- * Generate a MySQL-native column schema string
- *
- * @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
- * where options can be 'default', 'length', or 'key'.
- * @return string
- */
- function buildColumn($column) {
- $name = $type = null;
- $column = am(array('null' => true), $column);
- extract($column);
-
- if (empty($name) || empty($type)) {
- trigger_error('Column name or type not defined in schema', E_USER_WARNING);
- return null;
- }
-
- if (!isset($this->columns[$type])) {
- trigger_error("Column type {$type} does not exist", E_USER_WARNING);
- return null;
- }
-
- $real = $this->columns[$type];
- $out = $this->name($name) . ' ' . $real['name'];
-
- if (isset($real['limit']) || isset($real['length']) || isset($column['limit']) || isset($column['length'])) {
- if (isset($column['length'])) {
- $length = $column['length'];
- } elseif (isset($column['limit'])) {
- $length = $column['limit'];
- } elseif (isset($real['length'])) {
- $length = $real['length'];
- } else {
- $length = $real['limit'];
- }
- $out .= '(' . $length . ')';
- }
- if (isset($column['key']) && $column['key'] == 'primary' && (isset($column['extra']) && $column['extra'] == 'auto_increment')) {
- $out .= ' NOT NULL AUTO_INCREMENT';
- } elseif (isset($column['key']) && $column['key'] == 'primary') {
- $out .= ' NOT NULL';
- } elseif (isset($column['default']) && isset($column['null']) && $column['null'] == false) {
- $out .= ' DEFAULT ' . $this->value($column['default'], $type) . ' NOT NULL';
- } elseif (isset($column['default'])) {
- $out .= ' DEFAULT ' . $this->value($column['default'], $type);
- } elseif (isset($column['null']) && $column['null'] == true) {
- $out .= ' DEFAULT NULL';
- } elseif (isset($column['null']) && $column['null'] == false) {
- $out .= ' NOT NULL';
- }
-
- return $out;
- }
-/**
- * Format indexes for create table
- *
- * @param array $indexes
- * @return string
- */
- function buildIndex($indexes) {
- $join = array();
- foreach ($indexes as $name => $value) {
- $out = '';
- if ($name == 'PRIMARY') {
- $out .= 'PRIMARY ';
- $name = null;
- } else {
- if (!empty($value['unique'])) {
- $out .= 'UNIQUE ';
- }
- }
- if (is_array($value['column'])) {
- $out .= 'KEY '. $name .' (' . join(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
- } else {
- $out .= 'KEY '. $name .' (' . $this->name($value['column']) . ')';
- }
- $join[] = $out;
- }
- return join(",\n\t", $join);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysqli.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysqli.php
deleted file mode 100644
index e1156b8..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_mysqli.php
+++ /dev/null
@@ -1,441 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_mysqli.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * MySQLi layer for DBO
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 1.1.4.2974
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Short description for class.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboMysqli extends DboSource {
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $description = "Mysqli DBO Driver";
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $startQuote = "`";
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $endQuote = "`";
-/**
- * Base configuration settings for Mysqli driver
- *
- * @var array
- */
- var $_baseConfig = array('persistent' => true,
- 'host' => 'localhost',
- 'login' => 'root',
- 'password' => '',
- 'database' => 'cake',
- 'port' => '3306',
- 'connect' => 'mysqli_connect');
-/**
- * Mysqli column definition
- *
- * @var array
- */
- var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
- 'string' => array('name' => 'varchar', 'limit' => '255'),
- 'text' => array('name' => 'text'),
- 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
- 'float' => array('name' => 'float', 'formatter' => 'floatval'),
- 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
- 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
- 'binary' => array('name' => 'blob'),
- 'boolean' => array('name' => 'tinyint', 'limit' => '1'));
-/**
- * Connects to the database using options in the given configuration array.
- *
- * @return boolean True if the database could be connected, else false
- */
- function connect() {
- $config = $this->config;
- $this->connected = false;
- $this->connection = mysqli_connect($config['host'], $config['login'], $config['password'], $config['database'], $config['port']);
-
- if ($this->connection !== false) {
- $this->connected = true;
- }
-
- if (!empty($config['encoding'])) {
- $this->setEncoding($config['encoding']);
- }
- return $this->connected;
- }
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- @mysqli_free_result($this->results);
- $this->connected = !@mysqli_close($this->connection);
- return !$this->connected;
- }
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- * @access protected
- */
- function _execute($sql) {
- return mysqli_query($this->connection, $sql);
- }
-/**
- * Returns an array of sources (tables) in the database.
- *
- * @return array Array of tablenames in the database
- */
- function listSources() {
- $cache = parent::listSources();
- if ($cache != null) {
- return $cache;
- }
- $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
-
- if (!$result) {
- return array();
- } else {
- $tables = array();
-
- while ($line = mysqli_fetch_array($result)) {
- $tables[] = $line[0];
- }
- parent::listSources($tables);
- return $tables;
- }
- }
-/**
- * Returns an array of the fields in given table name.
- *
- * @param string $tableName Name of database table to inspect
- * @return array Fields in table. Keys are name and type
- */
- function describe(&$model) {
-
- $cache = parent::describe($model);
- if ($cache != null) {
- return $cache;
- }
-
- $fields = false;
- $cols = $this->query('DESCRIBE ' . $this->fullTableName($model));
-
- foreach ($cols as $column) {
- $colKey = array_keys($column);
- if (isset($column[$colKey[0]]) && !isset($column[0])) {
- $column[0] = $column[$colKey[0]];
- }
- if (isset($column[0])) {
- $fields[$column[0]['Field']] = array(
- 'type' => $this->column($column[0]['Type']),
- 'null' => ($column[0]['Null'] == 'YES' ? true : false),
- 'default' => $column[0]['Default'],
- 'length' => $this->length($column[0]['Type'])
- );
- }
- }
-
- $this->__cacheDescription($this->fullTableName($model, false), $fields);
- return $fields;
- }
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @param string $column The column into which this data will be inserted
- * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
- * @return string Quoted and escaped data
- */
- function value($data, $column = null, $safe = false) {
- $parent = parent::value($data, $column, $safe);
-
- if ($parent != null) {
- return $parent;
- }
-
- if ($data === null) {
- return 'NULL';
- }
-
- if ($data === '') {
- return "''";
- }
-
- switch ($column) {
- case 'boolean':
- $data = $this->boolean((bool)$data);
- break;
- case 'integer' :
- case 'float' :
- case null :
- if (is_numeric($data) && strpos($data, ',') === false && $data[0] != '0' && strpos($data, 'e') === false) {
- break;
- }
- default:
- $data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";
- break;
- }
-
- return $data;
- }
-/**
- * Begin a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions).
- */
- function begin(&$model) {
- if (parent::begin($model)) {
- if ($this->execute('START TRANSACTION')) {
- $this->_transactionStarted = true;
- return true;
- }
- }
- return false;
- }
-/**
- * Commit a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function commit(&$model) {
- if (parent::commit($model)) {
- $this->_transactionStarted = false;
- return $this->execute('COMMIT');
- }
- return false;
- }
-/**
- * Rollback a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function rollback(&$model) {
- if (parent::rollback($model)) {
- return $this->execute('ROLLBACK');
- }
- return false;
- }
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message with error number
- */
- function lastError() {
- if (mysqli_errno($this->connection)) {
- return mysqli_errno($this->connection).': '.mysqli_error($this->connection);
- }
- return null;
- }
-/**
- * Returns number of affected rows in previous database operation. If no previous operation exists,
- * this returns false.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- if ($this->_result) {
- return mysqli_affected_rows($this->connection);
- }
- return null;
- }
-/**
- * Returns number of rows in previous resultset. If no previous resultset exists,
- * this returns false.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- if ($this->_result and is_object($this->_result)) {
- return @mysqli_num_rows($this->_result);
- }
- return null;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param unknown_type $source
- * @return in
- */
- function lastInsertId($source = null) {
- $id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
- if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
- return $id[0]['insertID'];
- }
-
- return null;
- }
-/**
- * Converts database-layer column types to basic types
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return string Abstract column type (i.e. "string")
- */
- function column($real) {
- if (is_array($real)) {
- $col = $real['name'];
- if (isset($real['limit'])) {
- $col .= '('.$real['limit'].')';
- }
- return $col;
- }
-
- $col = r(')', '', $real);
- $limit = $this->length($real);
- @list($col,$vals) = explode('(', $col);
-
- if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
- return $col;
- }
- if ($col == 'tinyint' && $limit == 1) {
- return 'boolean';
- }
- if (strpos($col, 'int') !== false) {
- return 'integer';
- }
- if (strpos($col, 'char') !== false || $col == 'tinytext') {
- return 'string';
- }
- if (strpos($col, 'text') !== false) {
- return 'text';
- }
- if (strpos($col, 'blob') !== false) {
- return 'binary';
- }
- if (in_array($col, array('float', 'double', 'decimal'))) {
- return 'float';
- }
- if (strpos($col, 'enum') !== false) {
- return "enum($vals)";
- }
- if ($col == 'boolean') {
- return $col;
- }
- return 'text';
- }
-/**
- * Gets the length of a database-native column description, or null if no length
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return int An integer representing the length of the column
- */
- function length($real) {
- $col = r(array(')', 'unsigned'), '', $real);
- $limit = null;
-
- if (strpos($col, '(') !== false) {
- list($col, $limit) = explode('(', $col);
- }
-
- if ($limit != null) {
- return intval($limit);
- }
- return null;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $results
- */
- function resultSet(&$results) {
- $this->results =& $results;
- $this->map = array();
- $num_fields = mysqli_num_fields($results);
- $index = 0;
- $j = 0;
- while ($j < $num_fields) {
- $column = mysqli_fetch_field_direct($results, $j);
- if (!empty($column->table)) {
- $this->map[$index++] = array($column->table, $column->name);
- } else {
- $this->map[$index++] = array(0, $column->name);
- }
- $j++;
- }
- }
-/**
- * Fetches the next row from the current result set
- *
- * @return unknown
- */
- function fetchResult() {
- if ($row = mysqli_fetch_row($this->results)) {
- $resultRow = array();
- $i = 0;
- foreach ($row as $index => $field) {
- @list($table, $column) = $this->map[$index];
- $resultRow[$table][$column] = $row[$index];
- $i++;
- }
- return $resultRow;
- } else {
- return false;
- }
- }
-/**
- * Sets the database encoding
- *
- * @param string $enc Database encoding
- * @return void
- */
- function setEncoding($enc) {
- return $this->_execute('SET NAMES ' . $enc) != false;
- }
-/**
- * Gets the database encoding
- *
- * @return string The database encoding
- */
- function getEncoding() {
- return mysqli_client_encoding($this->connection);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_odbc.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_odbc.php
deleted file mode 100644
index 563627b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_odbc.php
+++ /dev/null
@@ -1,437 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_odbc.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * ODBC for DBO
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 0.10.5.1790
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Short description for class.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboOdbc extends DboSource{
-
-/**
- * Driver description
- *
- * @var string
- */
- var $description = "ODBC DBO Driver";
-
-/**
- * Table/column starting quote
- *
- * @var string
- */
- var $startQuote = "`";
-
-/**
- * Table/column end quote
- *
- * @var string
- */
- var $endQuote = "`";
-
-/**
- * Driver base configuration
- *
- * @var array
- */
- var $_baseConfig = array('persistent' => true,
- 'login' => 'root',
- 'password' => '',
- 'database' => 'cake',
- 'connect' => 'odbc_pconnect'
- );
-
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
-
- var $columns = array();
-
- // var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
- // 'string' => array('name' => 'varchar', 'limit' => '255'),
- // 'text' => array('name' => 'text'),
- // 'integer' => array('name' => 'int', 'limit' => '11'),
- // 'float' => array('name' => 'float'),
- // 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
- // 'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
- // 'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'),
- // 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
- // 'binary' => array('name' => 'blob'),
- // 'boolean' => array('name' => 'tinyint', 'limit' => '1'));
-
-/**
- * Connects to the database using options in the given configuration array.
- *
- * @return boolean True if the database could be connected, else false
- */
- function connect() {
- $config = $this->config;
- $connect = $config['connect'];
-
- $this->connected = false;
- $this->connection = $connect($config['database'], $config['login'], $config['password']);
-
- if ($this->connection) {
- $this->connected = true;
- }
-
- return $this->connected;
- }
-
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- return @odbc_close($this->connection);
- }
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- * @access protected
- */
- function _execute($sql) {
- return odbc_exec($this->connection, $sql);
- }
-/**
- * Returns an array of sources (tables) in the database.
- *
- * @return array Array of tablenames in the database
- */
- function listSources() {
-
- $cache = parent::listSources();
- if ($cache != null) {
- return $cache;
- }
-
- /*$result = odbc_tables($this->connection);
- if (function_exists('odbc_fetch_row')) {
- echo 'GOOD';
- } else {
- echo 'BAD';
- }*/
-
- $result = odbc_tables($this->connection);
-
- $tables = array();
- while (odbc_fetch_row($result)) {
- array_push($tables, odbc_result($result, "TABLE_NAME"));
- }
-
- parent::listSources($tables);
- return $tables;
- }
-/**
- * Returns an array of the fields in given table name.
- *
- * @param Model $model Model object to describe
- * @return array Fields in table. Keys are name and type
- */
- function &describe(&$model) {
- $cache=parent::describe($model);
-
- if ($cache != null) {
- return $cache;
- }
-
- $fields = array();
- $sql = 'SELECT * FROM ' . $this->fullTableName($model);
- $result = odbc_exec($this->connection, $sql);
-
- $count = odbc_num_fields($result);
-
- for ($i = 1; $i <= $count; $i++) {
- $cols[$i - 1] = odbc_field_name($result, $i);
- }
-
- foreach ($cols as $column) {
- $type = odbc_field_type(odbc_exec($this->connection, "SELECT " . $column . " FROM " . $this->fullTableName($model)), 1);
- $fields[$column] = array('type' => $type);
- }
-
- $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
- return $fields;
- }
-
- function name($data) {
- if ($data == '*') {
- return '*';
- }
-
- $pos = strpos($data, '`');
-
- if ($pos === false) {
- $data = '' . str_replace('.', '.', $data) . '';
- //$data = '`'. str_replace('.', '`.`', $data) .'`';
- }
-
- return $data;
- }
-
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @param string $column The column into which this data will be inserted
- * @return string Quoted and escaped
- * @todo Add logic that formats/escapes data based on column type
- */
- function value($data, $column = null) {
- $parent=parent::value($data, $column);
-
- if ($parent != null) {
- return $parent;
- }
-
- if ($data === null) {
- return 'NULL';
- }
-
- // $data = mysql_real_escape_string($data, $this->connection);
-
- if (!is_numeric($data)) {
- $return = "'" . $data . "'";
- } else {
- $return = $data;
- }
-
- return $return;
- }
-
-/**
- * Not sure about this one, MySQL needs it but does ODBC? Safer just to leave it
- * Translates between PHP boolean values and MySQL (faked) boolean values
- *
- * @param mixed $data Value to be translated
- * @return mixed Converted boolean value
- */
- function boolean($data) {
- if ($data === true || $data === false) {
- if ($data === true) {
- return 1;
- }
-
- return 0;
- } else {
- if (intval($data !== 0)) {
- return true;
- }
-
- return false;
- }
- }
-
-/**
- * Begin a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions).
- */
- function begin(&$model) {
- if (parent::begin($model)) {
- if (odbc_autocommit($this->connection, false)) {
- $this->_transactionStarted = true;
- return true;
- }
- }
-
- return false;
- }
-
-/**
- * Commit a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function commit(&$model) {
- if (parent::commit($model)) {
- if (odbc_commit($this->connection)) {
- $this->_transactionStarted = false;
- return true;
- }
- }
-
- return false;
- }
-
-/**
- * Rollback a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function rollback(&$model) {
- if (parent::rollback($model)) {
- $this->_transactionStarted=false;
- return odbc_rollback($this->connection);
- }
-
- return false;
- }
-
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message with error number
- */
- function lastError() {
- if (odbc_error($this->connection)) {
- return odbc_error($this->connection) . ': ' . odbc_errormsg($this->connection);
- }
-
- return null;
- }
-
-/**
- * Returns number of affected rows in previous database operation. If no previous operation exists,
- * this returns false.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- if ($this->_result) {
- return null;
- }
-
- return null;
- }
-
-/**
- * Returns number of rows in previous resultset. If no previous resultset exists,
- * this returns false.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- if ($this->_result) {
- return@odbc_num_rows($this->_result);
- }
-
- return null;
- }
-
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param unknown_type $source
- * @return int
- */
- function lastInsertId($source = null) {
- $result=$this->fetchRow('SELECT @@IDENTITY');
- return $result[0];
- }
-
-/**
- * Enter description here...
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- */
- function column($real) {
- if (is_array($real)) {
- $col=$real['name'];
-
- if (isset($real['limit'])) {
- $col .= '(' . $real['limit'] . ')';
- }
-
- return $col;
- }
-
- return $real;
- }
-
-/**
- * Enter description here...
- *
- * @param unknown_type $results
- */
- function resultSet(&$results) {
- $this->results=&$results;
- $this->map=array();
- $num_fields =odbc_num_fields($results);
- $index =0;
- $j =0;
-
- while ($j < $num_fields) {
- $column = odbc_fetch_array($results, $j);
-
- if (!empty($column->table)) {
- $this->map[$index++] = array($column->table,
- $column->name);
- } else {
- echo array(0,
- $column->name);
-
- $this->map[$index++]=array(0,
- $column->name);
- }
-
- $j++;
- }
- }
-
-/**
- * Fetches the next row from the current result set
- *
- * @return unknown
- */
- function fetchResult() {
- if ($row = odbc_fetch_row($this->results)) {
- $resultRow=array();
- $i=0;
-
- foreach ($row as $index => $field) {
- list($table, $column) = $this->map[$index];
- $resultRow[$table][$column]=$row[$index];
- $i++;
- }
-
- return $resultRow;
- } else {
- return false;
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_pear.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_pear.php
deleted file mode 100644
index f5e57eb..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_pear.php
+++ /dev/null
@@ -1,241 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_pear.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * {@link http://pear.php.net/package/DB PEAR::DB} layer for DBO.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Create an include path required PEAR libraries.
- */
-ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . PEAR);
-vendor ('Pear/DB');
-
-/**
- * {@link http://pear.php.net/package/DB PEAR::DB} layer for DBO.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboPear extends DboSource{
-
-/**
- * PEAR::DB object with which we connect.
- *
- * @var DB The connection object.
- * @access private
- */
- var $_pear = null;
-
-/**
- * Connects to the database using options in the given configuration array.
- *
- * @param array $config Configuration array for connecting
- * @return boolean True if the database could be connected, else false
- */
- function connect($config) {
- $this->config =$config;
- $dsn =$config['driver'] . '://' . $config['login'] . ':' . $config['password'] . '@'
- . $config['host'] . '/' . $config['database'];
- $options=array('debug' => Configure::read() - 1,
- 'portability' => DB_PORTABILITY_ALL,);
-
- $this->_pear =&DB::connect($dsn, $options);
- $this->connected=$this->_pear ? true : false;
- return !(PEAR::isError($this->_pear));
- }
-
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- die (__('Please implement DBO::disconnect() first.'));
- }
-
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- */
- function execute($sql) {
- return $this->_pear->query($sql);
- }
-
-/**
- * Returns a row from given resultset as an array .
- *
- * @return array The fetched row as an array
- */
- function fetchRow($sql = null) {
- if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
- if (!$this->execute($sql)) {
- return null;
- }
- }
- return $this->_result->fetchRow(DB_FETCHMODE_ASSOC);
- }
-
-/**
- * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
- * :WARNING: :TODO: POSTGRESQL & MYSQL ONLY! PEAR::DB doesn't support universal table listing.
- *
- * @return array Array of tablenames in the database
- */
- function tablesList() {
- $driver=$this->config['driver'];
- $tables=array();
-
- if ('postgres' == $driver) {
- $sql ="SELECT a.relname AS name
- FROM pg_class a, pg_user b
- WHERE ( relkind = 'r') and relname !~ '^pg_' AND relname !~ '^sql_'
- AND relname !~ '^xin[vx][0-9]+' AND b.usesysid = a.relowner
- AND NOT (EXISTS (SELECT viewname FROM pg_views WHERE viewname=a.relname));";
-
- $result=$this->all($sql);
-
- foreach ($result as $item) {
- $tables[] = $item['name'];
- }
- } elseif ('mysql' == $driver) {
- $result=array();
- $result=mysql_list_tables($this->config['database']);
-
- while ($item = mysql_fetch_array($result)) {
- $tables[] = $item[0];
- }
- } else {
- die (__('Please implement DBO_Pear::tablesList() for your database driver.'));
- }
-
- if (!$result) {
- trigger_error(ERROR_NO_TABLE_LIST, E_USER_ERROR);
- exit;
- } else {
- return $tables;
- }
- }
-
-/**
- * Returns an array of the fields in given table name.
- *
- * @param string $tableName Name of database table to inspect
- * @return array Fields in table. Keys are name and type
- */
- function fields($tableName) {
- $data =$this->_pear->tableInfo($tableName);
- $fields=false;
-
- foreach ($data as $item) {
- $fields[] = array('name' => $item['name'],
- 'type' => $item['type']);
- }
-
- return $fields;
- }
-
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @return string Quoted and escaped
- */
- function prepareValue($data) {
- return $this->_pear->quoteSmart($data);
- }
-
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message
- */
- function lastError() {
- return PEAR::isError($this->_result) ? $this->_result->getMessage() : null;
- }
-
-/**
- * Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- return $this->_pear->affectedRows();
- }
-
-/**
- * Returns number of rows in previous resultset. If no previous resultset exists,
- * this returns false.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- if (method_exists($this->_result, 'numRows')) {
- return $this->_result->numRows();
- } else {
- return false;
- }
- }
-
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param string $table Name of the database table
- * @return int
- */
- function lastInsertId($table) {
- return $this->field('id', "SELECT MAX(id) FROM {$table}");
- }
-
-/**
- * Returns a limit statement in the correct format for the particular database.
- *
- * @param int $limit Limit of results returned
- * @param int $offset Offset from which to start results
- * @return string SQL limit/offset statement
- */
- function selectLimit($limit, $offset = '0') {
- return ' ' . $this->_pear->modifyLimitQuery('', $offset, $limit);
- }
-/**
- * Inserts multiple values into a join table
- *
- * @param string $table
- * @param string $fields
- * @param array $values
- */
- function insertMulti($table, $fields, $values) {
- $count = count($values);
- for ($x = 0; $x < $count; $x++) {
- $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_postgres.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_postgres.php
deleted file mode 100644
index f77942c..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_postgres.php
+++ /dev/null
@@ -1,595 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_postgres.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * PostgreSQL layer for DBO.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 0.9.1.114
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * PostgreSQL layer for DBO.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboPostgres extends DboSource {
-
- var $description = "PostgreSQL DBO Driver";
-
- var $_baseConfig = array(
- 'connect' => 'pg_pconnect',
- 'persistent' => true,
- 'host' => 'localhost',
- 'login' => 'root',
- 'password' => '',
- 'database' => 'cake',
- 'schema' => 'public',
- 'port' => 5432,
- 'encoding' => ''
- );
-
- var $columns = array(
- 'primary_key' => array('name' => 'serial NOT NULL'),
- 'string' => array('name' => 'varchar', 'limit' => '255'),
- 'text' => array('name' => 'text'),
- 'integer' => array('name' => 'integer', 'formatter' => 'intval'),
- 'float' => array('name' => 'float', 'formatter' => 'floatval'),
- 'datetime' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
- 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
- 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
- 'binary' => array('name' => 'bytea'),
- 'boolean' => array('name' => 'boolean'),
- 'number' => array('name' => 'numeric'),
- 'inet' => array('name' => 'inet')
- );
-
- var $startQuote = '"';
-
- var $endQuote = '"';
-/**
- * Contains mappings of custom auto-increment sequences, if a table uses a sequence name
- * other than what is dictated by convention.
- *
- * @var array
- */
- var $_sequenceMap = array();
-/**
- * Connects to the database using options in the given configuration array.
- *
- * @return True if successfully connected.
- */
- function connect() {
-
- $config = $this->config;
- $connect = $config['connect'];
- $this->connection = $connect("host='{$config['host']}' port='{$config['port']}' dbname='{$config['database']}' user='{$config['login']}' password='{$config['password']}'");
-
- if ($this->connection) {
- $this->connected = true;
- $this->_execute("SET search_path TO " . $config['schema']);
- } else {
- $this->connected = false;
- }
- if (!empty($config['encoding'])) {
- $this->setEncoding($config['encoding']);
- }
-
- return $this->connected;
- }
-
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- @pg_free_result($this->results);
- $this->connected = !@pg_close($this->connection);
- return !$this->connected;
- }
-
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- */
- function _execute($sql) {
- return pg_query($this->connection, $sql);
- }
-/**
- * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
- *
- * @return array Array of tablenames in the database
- */
- function listSources() {
- $cache = parent::listSources();
-
- if ($cache != null) {
- return $cache;
- }
-
- $schema = $this->config['schema'];
- $sql = "SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = '{$schema}';";
- $result = $this->fetchAll($sql);
-
- if (!$result) {
- return array();
- } else {
- $tables = array();
-
- foreach ($result as $item) {
- $tables[] = $item[0]['name'];
- }
-
- parent::listSources($tables);
- return $tables;
- }
- }
-
-/**
- * Returns an array of the fields in given table name.
- *
- * @param string $tableName Name of database table to inspect
- * @return array Fields in table. Keys are name and type
- */
- function &describe(&$model) {
- if (isset($model->sequence)) {
- $this->_sequenceMap[$this->fullTableName($model, false)] = $model->sequence;
- }
-
- $cache = parent::describe($model);
- if ($cache != null) {
- return $cache;
- }
-
- $fields = false;
- $cols = $this->fetchAll("SELECT DISTINCT column_name AS name, data_type AS type, is_nullable AS null, column_default AS default, ordinal_position AS position, character_maximum_length AS char_length, character_octet_length AS oct_length FROM information_schema.columns WHERE table_name =" . $this->value($model->tablePrefix . $model->table) . " ORDER BY position");
-
- foreach ($cols as $column) {
- $colKey = array_keys($column);
-
- if (isset($column[$colKey[0]]) && !isset($column[0])) {
- $column[0] = $column[$colKey[0]];
- }
-
- if (isset($column[0])) {
- $c = $column[0];
- if (strpos($c['default'], 'nextval(') === 0) {
- $c['default'] = null;
- }
- if (!empty($c['char_length'])) {
- $length = intval($c['char_length']);
- } elseif (!empty($c['oct_length'])) {
- $length = intval($c['oct_length']);
- } else {
- $length = $this->length($c['type']);
- }
- $fields[$c['name']] = array(
- 'type' => $this->column($c['type']),
- 'null' => ($c['null'] == 'NO' ? false : true),
- 'default' => $c['default'],
- 'length' => $length
- );
- }
- }
- $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
- return $fields;
- }
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @param string $column The column into which this data will be inserted
- * @return string Quoted and escaped
- * @todo Add logic that formats/escapes data based on column type
- */
- function value($data, $column = null) {
-
- $parent = parent::value($data, $column);
- if ($parent != null) {
- return $parent;
- }
-
- if ($data === null) {
- return 'NULL';
- }
-
- switch($column) {
- case 'inet':
- if (!strlen($data)) {
- return 'DEFAULT';
- } else {
- $data = pg_escape_string($data);
- }
- break;
- case 'integer':
- if ($data === '') {
- return 'DEFAULT';
- } else {
- $data = pg_escape_string($data);
- }
- break;
- case 'binary':
- $data = pg_escape_bytea($data);
-
- break;
- case 'boolean':
- default:
- if ($data === true) {
- return 'TRUE';
- } elseif ($data === false) {
- return 'FALSE';
- }
- $data = pg_escape_string($data);
- break;
- }
- return "'" . $data . "'";
- }
-
-/**
- * Begin a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions).
- */
- function begin(&$model) {
- if (parent::begin($model)) {
- if ($this->execute('BEGIN')) {
- $this->_transactionStarted = true;
- return true;
- }
- }
- return false;
- }
-
-/**
- * Commit a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function commit(&$model) {
- if (parent::commit($model)) {
- $this->_transactionStarted = false;
- return $this->execute('COMMIT');
- }
- return false;
- }
-
-/**
- * Rollback a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function rollback(&$model) {
- if (parent::rollback($model)) {
- return $this->execute('ROLLBACK');
- }
- return false;
- }
-
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message
- */
- function lastError() {
- $last_error = pg_last_error($this->connection);
- if ($last_error) {
- return $last_error;
- }
- return null;
- }
-
-/**
- * Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- if ($this->_result) {
- $return = pg_affected_rows($this->_result);
- return $return;
- }
- return false;
- }
-/**
- * Returns number of rows in previous resultset. If no previous resultset exists,
- * this returns false.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- if ($this->_result) {
- $return = pg_num_rows($this->_result);
- return $return;
- }
- return false;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @param string $source Name of the database table
- * @param string $field Name of the ID database field. Defaults to "id"
- * @return int
- */
- function lastInsertId($source, $field = 'id') {
- foreach ($this->__descriptions[$source] as $name => $sourceinfo) {
- if (strcasecmp($name, $field) == 0) {
- break;
- }
- }
-
- if (isset($this->_sequenceMap[$source])) {
- $seq = $this->_sequenceMap[$source];
- } elseif (preg_match('/^nextval\(\'(\w+)\'/', $sourceinfo['default'], $matches)) {
- $seq = $matches[1];
- } else {
- $seq = "{$source}_{$field}_seq";
- }
-
- $res = $this->rawQuery("SELECT last_value AS max FROM \"{$seq}\"");
- $data = $this->fetchRow($res);
- return $data[0]['max'];
- }
-/**
- * Generates the fields list of an SQL query.
- *
- * @param Model $model
- * @param string $alias Alias tablename
- * @param mixed $fields
- * @return array
- */
- function fields(&$model, $alias = null, $fields = array(), $quote = true) {
- if (empty($alias)) {
- $alias = $model->name;
- }
- $fields = parent::fields($model, $alias, $fields, false);
-
- if (!$quote) {
- return $fields;
- }
- $count = count($fields);
-
- if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
- for ($i = 0; $i < $count; $i++) {
- if (!preg_match('/^.+\\(.*\\)/', $fields[$i]) && !preg_match('/\s+AS\s+/', $fields[$i])) {
- $prepend = '';
- if (strpos($fields[$i], 'DISTINCT') !== false) {
- $prepend = 'DISTINCT ';
- $fields[$i] = trim(r('DISTINCT', '', $fields[$i]));
- }
-
- $dot = strrpos($fields[$i], '.');
- if ($dot === false) {
- $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fields[$i]);
- } else {
- $build = explode('.', $fields[$i]);
- $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $build[1]);
- }
- }
- }
- }
- return $fields;
- }
-/**
- * Returns a limit statement in the correct format for the particular database.
- *
- * @param int $limit Limit of results returned
- * @param int $offset Offset from which to start results
- * @return string SQL limit/offset statement
- */
- function limit($limit, $offset = null) {
- if ($limit) {
- $rt = '';
- if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
- $rt = ' LIMIT';
- }
-
- $rt .= ' ' . $limit;
- if ($offset) {
- $rt .= ' OFFSET ' . $offset;
- }
-
- return $rt;
- }
- return null;
- }
-/**
- * Converts database-layer column types to basic types
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return string Abstract column type (i.e. "string")
- */
- function column($real) {
- if (is_array($real)) {
- $col = $real['name'];
- if (isset($real['limit'])) {
- $col .= '(' . $real['limit'] . ')';
- }
- return $col;
- }
-
- $col = r(')', '', $real);
- $limit = null;
- @list($col, $limit) = explode('(', $col);
-
- if (in_array($col, array('date', 'time'))) {
- return $col;
- }
- if (strpos($col, 'timestamp') !== false) {
- return 'datetime';
- }
- if ($col == 'inet') {
- return('inet');
- }
- if ($col == 'boolean') {
- return 'boolean';
- }
- if (strpos($col, 'int') !== false && $col != 'interval') {
- return 'integer';
- }
- if (strpos($col, 'char') !== false) {
- return 'string';
- }
- if (strpos($col, 'text') !== false) {
- return 'text';
- }
- if (strpos($col, 'bytea') !== false) {
- return 'binary';
- }
- if (in_array($col, array('float', 'float4', 'float8', 'double', 'double precision', 'decimal', 'real', 'numeric'))) {
- return 'float';
- }
- return 'text';
- }
-/**
- * Gets the length of a database-native column description, or null if no length
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return int An integer representing the length of the column
- */
- function length($real) {
- $col = r(array(')', 'unsigned'), '', $real);
- $limit = null;
-
- if (strpos($col, '(') !== false) {
- list($col, $limit) = explode('(', $col);
- }
-
- if ($limit != null) {
- return intval($limit);
- }
- return null;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $results
- */
- function resultSet(&$results) {
- $this->results =& $results;
- $this->map = array();
- $num_fields = pg_num_fields($results);
- $index = 0;
- $j = 0;
-
- while ($j < $num_fields) {
- $columnName = pg_field_name($results, $j);
-
- if (strpos($columnName, '__')) {
- $parts = explode('__', $columnName);
- $this->map[$index++] = array($parts[0], $parts[1]);
- } else {
- $this->map[$index++] = array(0, $columnName);
- }
- $j++;
- }
- }
-/**
- * Fetches the next row from the current result set
- *
- * @return unknown
- */
- function fetchResult() {
- if ($row = pg_fetch_row($this->results)) {
- $resultRow = array();
- $i = 0;
-
- foreach ($row as $index => $field) {
- list($table, $column) = $this->map[$index];
- $resultRow[$table][$column] = $row[$index];
- $i++;
- }
- return $resultRow;
- } else {
- return false;
- }
- }
-/**
- * Translates between PHP boolean values and PostgreSQL boolean values
- *
- * @param mixed $data Value to be translated
- * @param boolean $quote True to quote value, false otherwise
- * @return mixed Converted boolean value
- */
- function boolean($data, $quote = true) {
- $result = null;
-
- if ($data === true || $data === false) {
- $result = $data;
- } elseif (is_string($data) && !is_numeric($data)) {
- if (strpos(low($data), 't') !== false) {
- $result = true;
- } else {
- $result = false;
- }
- } else {
- $result = (bool)$data;
- }
- return $result;
- }
-/**
- * Sets the database encoding
- *
- * @param mixed $enc Database encoding
- * @return boolean True on success, false on failure
- */
- function setEncoding($enc) {
- return pg_set_client_encoding($this->connection, $enc) == 0;
- }
-/**
- * Gets the database encoding
- *
- * @return string The database encoding
- */
- function getEncoding() {
- return pg_client_encoding($this->connection);
- }
-/**
- * Inserts multiple values into a join table
- *
- * @param string $table
- * @param string $fields
- * @param array $values
- */
- function insertMulti($table, $fields, $values) {
- $count = count($values);
- for ($x = 0; $x < $count; $x++) {
- $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_sqlite.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_sqlite.php
deleted file mode 100644
index 26e6b1b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/dbo/dbo_sqlite.php
+++ /dev/null
@@ -1,409 +0,0 @@
-<?php
-/* SVN FILE: $Id: dbo_sqlite.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * SQLite layer for DBO
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- * @since CakePHP(tm) v 0.9.0
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * DBO implementation for the SQLite DBMS.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.model.dbo
- */
-class DboSqlite extends DboSource {
-
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $description = "SQLite DBO Driver";
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $startQuote = '"';
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $endQuote = '"';
-/**
- * Base configuration settings for SQLite driver
- *
- * @var array
- */
- var $_baseConfig = array(
- 'persistent' => true,
- 'database' => null,
- 'connect' => 'sqlite_popen'
- );
-/**
- * SQLite column definition
- *
- * @var array
- */
- var $columns = array(
- 'primary_key' => array('name' => 'integer primary key'),
- 'string' => array('name' => 'varchar', 'limit' => '255'),
- 'text' => array('name' => 'text'),
- 'integer' => array('name' => 'integer', 'limit' => '11', 'formatter' => 'intval'),
- 'float' => array('name' => 'float', 'formatter' => 'floatval'),
- 'datetime' => array('name' => 'timestamp', 'format' => 'YmdHis', 'formatter' => 'date'),
- 'timestamp' => array('name' => 'timestamp', 'format' => 'YmdHis', 'formatter' => 'date'),
- 'time' => array('name' => 'timestamp', 'format' => 'His', 'formatter' => 'date'),
- 'date' => array('name' => 'date', 'format' => 'Ymd', 'formatter' => 'date'),
- 'binary' => array('name' => 'blob'),
- 'boolean' => array('name' => 'integer', 'limit' => '1')
- );
-/**
- * Connects to the database using config['database'] as a filename.
- *
- * @param array $config Configuration array for connecting
- * @return mixed
- */
- function connect() {
- $config = $this->config;
- $this->connection = $config['connect']($config['database']);
- $this->connected = is_resource($this->connection);
- return $this->connected;
- }
-/**
- * Disconnects from database.
- *
- * @return boolean True if the database could be disconnected, else false
- */
- function disconnect() {
- @sqlite_close($this->connection);
- $this->connected = false;
- return $this->connected;
- }
-/**
- * Executes given SQL statement.
- *
- * @param string $sql SQL statement
- * @return resource Result resource identifier
- */
- function _execute($sql) {
- return sqlite_query($this->connection, $sql);
- }
-/**
- * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
- *
- * @return array Array of tablenames in the database
- */
- function listSources() {
- $db = $this->config['database'];
- $this->config['database'] = basename($this->config['database']);
-
- $cache = parent::listSources();
- if ($cache != null) {
- return $cache;
- }
-
- $result = $this->fetchAll("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;");
-
- if (!$result || empty($result)) {
- return array();
- } else {
- $tables = array();
- foreach ($result as $table) {
- $tables[] = $table[0]['name'];
- }
- parent::listSources($tables);
-
- $this->config['database'] = $db;
- return $tables;
- }
- $this->config['database'] = $db;
- return array();
- }
-/**
- * Returns an array of the fields in given table name.
- *
- * @param string $tableName Name of database table to inspect
- * @return array Fields in table. Keys are name and type
- */
- function describe(&$model) {
- $cache = parent::describe($model);
- if ($cache != null) {
- return $cache;
- }
- $fields = array();
- $result = $this->fetchAll('PRAGMA table_info(' . $model->tablePrefix . $model->table . ')');
-
- foreach ($result as $column) {
- $fields[$column[0]['name']] = array(
- 'type' => $this->column($column[0]['type']),
- 'null' => ! $column[0]['notnull'],
- 'default' => $column[0]['dflt_value']
- );
- }
-
- $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
- return $fields;
- }
-/**
- * Returns a quoted and escaped string of $data for use in an SQL statement.
- *
- * @param string $data String to be prepared for use in an SQL statement
- * @return string Quoted and escaped
- */
- function value ($data, $column = null, $safe = false) {
- $parent = parent::value($data, $column, $safe);
-
- if ($parent != null) {
- return $parent;
- }
-
- if ($data === null) {
- return 'NULL';
- }
-
- if ($data === '') {
- return "''";
- }
-
- switch ($column) {
- case 'boolean':
- $data = $this->boolean((bool)$data);
- break;
- default:
- $data = sqlite_escape_string($data);
- break;
- }
- return "'" . $data . "'";
- }
-/**
- * Begin a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions).
- */
- function begin (&$model) {
- if (parent::begin($model)) {
- if ($this->execute('BEGIN')) {
- $this->_transactionStarted = true;
- return true;
- }
- }
- return false;
- }
-/**
- * Commit a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function commit (&$model) {
- if (parent::commit($model)) {
- $this->_transactionStarted = false;
- return $this->execute('COMMIT');
- }
- return false;
- }
-/**
- * Rollback a transaction
- *
- * @param unknown_type $model
- * @return boolean True on success, false on fail
- * (i.e. if the database/model does not support transactions,
- * or a transaction has not started).
- */
- function rollback (&$model) {
- if (parent::rollback($model)) {
- return $this->execute('ROLLBACK');
- }
- return false;
- }
-/**
- * Returns a formatted error message from previous database operation.
- *
- * @return string Error message
- */
- function lastError() {
- $error = sqlite_last_error($this->connection);
- if ($error) {
- return $error.': '.sqlite_error_string($error);
- }
- return null;
- }
-/**
- * Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
- *
- * @return int Number of affected rows
- */
- function lastAffected() {
- if ($this->_result) {
- return sqlite_changes($this->connection);
- }
- return false;
- }
-/**
- * Returns number of rows in previous resultset. If no previous resultset exists,
- * this returns false.
- *
- * @return int Number of rows in resultset
- */
- function lastNumRows() {
- if ($this->_result) {
- sqlite_num_rows($this->_result);
- }
- return false;
- }
-/**
- * Returns the ID generated from the previous INSERT operation.
- *
- * @return int
- */
- function lastInsertId() {
- return sqlite_last_insert_rowid($this->connection);
- }
-/**
- * Converts database-layer column types to basic types
- *
- * @param string $real Real database-layer column type (i.e. "varchar(255)")
- * @return string Abstract column type (i.e. "string")
- */
- function column($real) {
- if (is_array($real)) {
- $col = $real['name'];
- if (isset($real['limit'])) {
- $col .= '('.$real['limit'].')';
- }
- return $col;
- }
-
- $col = low(r(')', '', $real));
- $limit = null;
- @list($col, $limit) = explode('(', $col);
-
- if (in_array($col, array('text', 'integer', 'float', 'boolean', 'timestamp', 'datetime'))) {
- return $col;
- }
- if (strpos($col, 'varchar') !== false) {
- return 'string';
- }
- if (in_array($col, array('blob', 'clob'))) {
- return 'binary';
- }
- if (strpos($col, 'numeric') !== false) {
- return 'float';
- }
-
- return 'text';
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $results
- */
- function resultSet(&$results) {
- $this->results =& $results;
- $this->map = array();
- $num_fields = sqlite_num_fields($results);
- $index = 0;
- $j = 0;
-
- while ($j < $num_fields) {
- $columnName = str_replace('"', '', sqlite_field_name($results, $j));
-
- if (strpos($columnName, '.')) {
- $parts = explode('.', $columnName);
- $this->map[$index++] = array($parts[0], $parts[1]);
- } else {
- $this->map[$index++] = array(0, $columnName);
- }
- $j++;
- }
- }
-/**
- * Fetches the next row from the current result set
- *
- * @return unknown
- */
- function fetchResult() {
- if ($row = sqlite_fetch_array($this->results, SQLITE_ASSOC)) {
- $resultRow = array();
- $i = 0;
-
- foreach ($row as $index => $field) {
- if (strpos($index, '.')) {
- list($table, $column) = explode('.', str_replace('"', '', $index));
- $resultRow[$table][$column] = $row[$index];
- } else {
- $resultRow[0][str_replace('"', '', $index)] = $row[$index];
- }
- $i++;
- }
- return $resultRow;
- } else {
- return false;
- }
- }
-/**
- * Returns a limit statement in the correct format for the particular database.
- *
- * @param int $limit Limit of results returned
- * @param int $offset Offset from which to start results
- * @return string SQL limit/offset statement
- */
- function limit ($limit, $offset = null) {
- if ($limit) {
- $rt = '';
- if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
- $rt = ' LIMIT';
- }
- $rt .= ' ' . $limit;
- if ($offset) {
- $rt .= ' OFFSET ' . $offset;
- }
- return $rt;
- }
- return null;
- }
-/**
- * Inserts multiple values into a join table
- *
- * @param string $table
- * @param string $fields
- * @param array $values
- */
- function insertMulti($table, $fields, $values) {
- $count = count($values);
- for ($x = 0; $x < $count; $x++) {
- $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model.php
deleted file mode 100644
index 8e40eb5..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-/* SVN FILE: $Id: model.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Object-relational mapper.
- *
- * DBO-backed object data model, for mapping database tables to Cake objects.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model
- * @since CakePHP(tm) v 0.10.0.0
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Load the model class based on the version of PHP.
- *
- */
-if (phpversion() < 5) {
- require(LIBS . 'model' . DS . 'model_php4.php');
-
- if (function_exists("overload")) {
- overload("Model");
- }
-} else {
- require(LIBS . 'model' . DS . 'model_php5.php');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php4.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php4.php
deleted file mode 100644
index 9a24eee..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php4.php
+++ /dev/null
@@ -1,1719 +0,0 @@
-<?php
-/* SVN FILE: $Id: model_php4.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Object-relational mapper.
- *
- * DBO-backed object data model, for mapping database tables to Cake objects.
- *
- * PHP versions 4
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model
- * @since CakePHP(tm) v 0.10.0.0
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libs
- */
-uses('class_registry', 'validators', 'model' . DS . 'connection_manager', 'set');
-/**
- * Object-relational mapper.
- *
- * DBO-backed object data model.
- * Automatically selects a database table name based on a pluralized lowercase object class name
- * (i.e. class 'User' => table 'users'; class 'Man' => table 'men')
- * The table is required to have at least 'id auto_increment', 'created datetime',
- * and 'modified datetime' fields.
- *
- * @package cake
- * @subpackage cake.cake.libs.model
- */
-class Model extends Object{
-/**
- * The name of the DataSource connection that this Model uses
- *
- * @var string
- * @access public
- */
- var $useDbConfig = 'default';
-/**
- * Custom database table name.
- *
- * @var string
- * @access public
- */
- var $useTable = null;
-/**
- * Custom display field name. Display fields are used by Scaffold, in SELECT boxes' OPTION elements.
- *
- * @var string
- * @access public
- */
- var $displayField = null;
-
-/**
- * Value of the primary key ID of the record that this model is currently pointing to
- *
- * @var string
- * @access public
- */
- var $id = false;
-/**
- * Container for the data that this model gets from persistent storage (the database).
- *
- * @var array
- * @access public
- */
- var $data = array();
-/**
- * Table name for this Model.
- *
- * @var string
- * @access public
- */
- var $table = false;
-/**
- * The name of the ID field for this Model.
- *
- * @var string
- * @access public
- */
- var $primaryKey = null;
-/**
- * Table metadata
- *
- * @var array
- * @access protected
- */
- var $_tableInfo = null;
-/**
- * List of validation rules. Append entries for validation as ('field_name' => '/^perl_compat_regexp$/')
- * that have to match with preg_match(). Use these rules with Model::validate()
- *
- * @var array
- * @access public
- */
- var $validate = array();
-/**
- * Errors in validation
- * @var array
- * @access public
- */
- var $validationErrors = array();
-/**
- * Database table prefix for tables in model.
- *
- * @var string
- * @access public
- */
- var $tablePrefix = null;
-/**
- * Name of the model.
- *
- * @var string
- * @access public
- */
- var $name = null;
-/**
- * Name of the current model.
- *
- * @var string
- * @access public
- */
- var $currentModel = null;
-/**
- * List of table names included in the Model description. Used for associations.
- *
- * @var array
- * @access public
- */
- var $tableToModel = array();
-/**
- * List of Model names by used tables. Used for associations.
- *
- * @var array
- * @access public
- */
- var $modelToTable = array();
-/**
- * List of Foreign Key names to used tables. Used for associations.
- *
- * @var array
- * @access public
- */
- var $keyToTable = array();
-/**
- * Alias name for model.
- *
- * @var array
- * @access public
- */
- var $alias = null;
-/**
- * Whether or not transactions for this model should be logged
- *
- * @var boolean
- * @access public
- */
- var $logTransactions = false;
-/**
- * Whether or not to enable transactions for this model (i.e. BEGIN/COMMIT/ROLLBACK)
- *
- * @var boolean
- * @access public
- */
- var $transactional = false;
-/**
- * Whether or not to cache queries for this model. This enables in-memory
- * caching only, the results are not stored beyond this execution.
- *
- * @var boolean
- * @access public
- */
- var $cacheQueries = true;
-/**
- * belongsTo association
- *
- * @var array
- * @access public
- */
- var $belongsTo = array();
-/**
- * hasOne association
- *
- * @var array
- * @access public
- */
- var $hasOne = array();
-/**
- * hasMany association
- *
- * @var array
- * @access public
- */
- var $hasMany = array();
-/**
- * hasAndBelongsToMany association
- *
- * @var array
- * @access public
- */
- var $hasAndBelongsToMany = array();
-/**
- * Depth of recursive association
- *
- * @var int
- * @access public
- */
- var $recursive = 1;
-/**
- * Whitelist of fields allowed to be saved
- *
- * @var array
- */
- var $whitelist = array();
-/**
- * Enter description here...
- *
- * @var boolean
- */
- var $cacheSources = true;
-/**
- * Default association keys
- *
- * @var array
- * @access private
- */
- var $__associationKeys = array('belongsTo' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'counterCache'),
- 'hasOne' => array('className', 'foreignKey','conditions', 'fields','order', 'dependent'),
- 'hasMany' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'),
- 'hasAndBelongsToMany' => array('className', 'joinTable', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery'));
-/**
- * Holds provided/generated association key names and other data for all associations
- *
- * @var array
- * @access private
- */
- var $__associations = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
-/**
- * The last inserted ID of the data that this model created
- *
- * @var int
- * @access private
- */
- var $__insertID = null;
-/**
- * The number of records returned by the last query
- *
- * @var int
- * @access private
- */
- var $__numRows = null;
-/**
- * The number of records affected by the last query
- *
- * @var int
- * @access private
- */
- var $__affectedRows = null;
-/**
- * Holds model associations temporarily to allow for dynamic (un)binding
- *
- * @var array
- * @access private
- */
- var $__backAssociation = array();
-/**
- * Constructor. Binds the Model's database table to the object.
- *
- * @param integer $id
- * @param string $table Name of database table to use.
- * @param DataSource $ds DataSource connection object.
- */
- function __construct($id = false, $table = null, $ds = null) {
- parent::__construct();
-
- if (is_array($id) && isset($id['name'])) {
- $options = array_merge(array('id' => false, 'table' => null, 'ds' => null, 'alias' => null), $id);
- list($id, $table, $ds) = array($options['id'], $options['table'], $options['ds']);
- $this->name = $options['name'];
- }
-
- if ($this->name === null) {
- $this->name = get_class($this);
- }
-
- if ($this->primaryKey === null) {
- $this->primaryKey = 'id';
- }
-
- if (isset($options['alias']) || !empty($options['alias'])) {
- $this->alias = $options['alias'];
- unset($options);
- } else {
- $this->alias = $this->name;
- }
- ClassRegistry::addObject($this->alias, $this);
-
- $this->id = $id;
- unset($id);
-
- if ($table === false) {
- $this->useTable = false;
- } elseif ($table) {
- $this->useTable = $table;
- }
-
- if ($this->useTable !== false) {
- $this->setDataSource($ds);
-
- if ($this->useTable === null) {
- $this->useTable = Inflector::tableize($this->name);
- }
-
- if (in_array('settableprefix', get_class_methods($this))) {
- $this->setTablePrefix();
- }
-
- $this->setSource($this->useTable);
- $this->__createLinks();
-
- if ($this->displayField == null) {
- if ($this->hasField('title')) {
- $this->displayField = 'title';
- }
-
- if ($this->hasField('name')) {
- $this->displayField = 'name';
- }
-
- if ($this->displayField == null) {
- $this->displayField = $this->primaryKey;
- }
- }
- }
- }
-
-/**
- * PHP4 Only
- *
- * Handles custom method calls, like findBy<field> for DB models,
- * and custom RPC calls for remote data sources
- *
- * @param unknown_type $method
- * @param unknown_type $params
- * @param unknown_type $return
- * @return unknown
- * @access protected
- */
- function __call($method, $params, &$return) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $return = $db->query($method, $params, $this);
- if (isset($this->__backAssociation)) {
- $this->__resetAssociations();
- }
- return true;
- }
-/**
- * Bind model associations on the fly.
- *
- * @param array $params
- * @return true
- * @access public
- */
- function bindModel($params) {
- foreach ($params as $assoc => $model) {
- if(!isset($this->__backAssociation[$assoc])) {
- $this->__backAssociation[$assoc] = $this->{$assoc};
- }
-
- foreach ($model as $key => $value) {
- $assocName = $key;
-
- if (is_numeric($key)) {
- $assocName = $value;
- $value = array();
- }
- $modelName = $assocName;
- $this->{$assoc}[$assocName] = $value;
- }
- }
- $this->__createLinks();
- return true;
- }
-/**
- * Turn off associations on the fly.
- *
- * @param array $params
- * @return true
- * @access public
- */
- function unbindModel($params) {
- foreach ($params as $assoc => $models) {
- if(!isset($this->__backAssociation[$assoc])) {
- $this->__backAssociation[$assoc] = $this->{$assoc};
- }
-
- foreach ($models as $model) {
- $this->__backAssociation = array_merge($this->__backAssociation, $this->{$assoc});
- unset ($this->{$assoc}[$model]);
- }
- }
- return true;
- }
-/**
- * Private helper method to create a set of associations.
- *
- * @access private
- */
- function __createLinks() {
-
- foreach ($this->__associations as $type) {
- if (!is_array($this->{$type})) {
- $this->{$type} = explode(',', $this->{$type});
-
- foreach ($this->{$type} as $i => $className) {
- $className = trim($className);
- unset ($this->{$type}[$i]);
- $this->{$type}[$className] = array();
- }
- }
-
- foreach ($this->{$type} as $assoc => $value) {
- if (is_numeric($assoc)) {
- unset ($this->{$type}[$assoc]);
- $assoc = $value;
- $value = array();
- $this->{$type}[$assoc] = $value;
- }
-
- $className = $assoc;
-
- if (isset($value['className']) && !empty($value['className'])) {
- $className = $value['className'];
- }
- $this->__constructLinkedModel($assoc, $className);
- }
- }
-
- foreach ($this->__associations as $type) {
- $this->__generateAssociation($type);
- }
- }
-
-/**
- * Private helper method to create associated models of given class.
- * @param string $assoc
- * @param string $className Class name
- * @param string $type Type of assocation
- * @access private
- */
- function __constructLinkedModel($assoc, $className) {
- if(empty($className)) {
- $className = $assoc;
- }
-
- if (!class_exists($className)) {
- loadModel($className);
- }
- $colKey = Inflector::underscore($className);
- $model = array('name' => $className, 'alias' => $assoc);
-
- if (ClassRegistry::isKeySet($colKey)) {
- $this->{$assoc} =& ClassRegistry::getObject($colKey);
- $this->{$className} =& $this->{$assoc};
- } else {
- $this->{$assoc} =& new $className($model);
- $this->{$className} =& $this->{$assoc};
- }
- $this->tableToModel[$this->{$assoc}->table] = $className;
- $this->modelToTable[$assoc] = $this->{$assoc}->table;
- }
-/**
- * Build array-based association from string.
- *
- * @param string $type "Belongs", "One", "Many", "ManyTo"
- * @access private
- */
- function __generateAssociation($type) {
- foreach ($this->{$type}as $assocKey => $assocData) {
- $class = $assocKey;
-
- foreach ($this->__associationKeys[$type] as $key) {
- if (!isset($this->{$type}[$assocKey][$key]) || $this->{$type}[$assocKey][$key] == null) {
- $data = '';
-
- switch($key) {
- case 'fields':
- $data = '';
- break;
-
- case 'foreignKey':
- $data = Inflector::singularize($this->table) . '_id';
-
- if ($type == 'belongsTo') {
- $data = Inflector::singularize($this->{$class}->table) . '_id';
- }
- break;
-
- case 'associationForeignKey':
- $data = Inflector::singularize($this->{$class}->table) . '_id';
- break;
-
- case 'joinTable':
- $tables = array($this->table, $this->{$class}->table);
- sort ($tables);
- $data = $tables[0] . '_' . $tables[1];
- break;
-
- case 'className':
- $data = $class;
- break;
- }
-
- $this->{$type}[$assocKey][$key] = $data;
- }
-
- if ($key == 'foreignKey' && !isset($this->keyToTable[$this->{$type}[$assocKey][$key]])) {
- $this->keyToTable[$this->{$type}[$assocKey][$key]][0] = $this->{$class}->table;
- $this->keyToTable[$this->{$type}[$assocKey][$key]][1] = $this->{$class}->alias;
- }
- }
- }
- }
-/**
- * Sets a custom table for your controller class. Used by your controller to select a database table.
- *
- * @param string $tableName Name of the custom table
- * @access public
- */
- function setSource($tableName) {
- $this->setDataSource($this->useDbConfig);
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $db->cacheSources = $this->cacheSources;
-
- if ($db->isInterfaceSupported('listSources')) {
- $sources = $db->listSources();
- if (is_array($sources) && !in_array(low($this->tablePrefix . $tableName), array_map('low', $sources))) {
- return $this->cakeError('missingTable', array(array(
- 'className' => $this->alias,
- 'table' => $this->tablePrefix . $tableName)));
-
- }
- $this->_tableInfo = null;
- }
- $this->table = $this->useTable = $tableName;
- $this->tableToModel[$this->table] = $this->alias;
- $this->loadInfo();
- }
-/**
- * This function does two things: 1) it scans the array $one for the primary key,
- * and if that's found, it sets the current id to the value of $one[id].
- * For all other keys than 'id' the keys and values of $one are copied to the 'data' property of this object.
- * 2) Returns an array with all of $one's keys and values.
- * (Alternative indata: two strings, which are mangled to
- * a one-item, two-dimensional array using $one for a key and $two as its value.)
- *
- * @param mixed $one Array or string of data
- * @param string $two Value string for the alternative indata method
- * @return array
- * @access public
- */
- function set($one, $two = null) {
- if (is_array($one)) {
- if (countdim($one) == 1) {
- $data = array($this->alias => $one);
- } else {
- $data = $one;
- }
- } else {
- $data = array($this->alias => array($one => $two));
- }
-
- foreach ($data as $n => $v) {
- if (is_array($v)) {
-
- foreach ($v as $x => $y) {
- if (empty($this->whitelist) || (in_array($x, $this->whitelist) || $n !== $this->alias)) {
- if (isset($this->validationErrors[$x])) {
- unset ($this->validationErrors[$x]);
- }
-
- if ($n == $this->name || is_array($y)) {
- if ($x === $this->primaryKey) {
- $this->id = $y;
- }
- $this->data[$n][$x] = $y;
- }
- }
- }
- }
- }
- return $data;
- }
-/**
- * Returns an array of table metadata (column names and types) from the database.
- *
- * @return array Array of table metadata
- * @access public
- */
- function loadInfo() {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $db->cacheSources = $this->cacheSources;
-
- if (!is_object($this->_tableInfo) && $db->isInterfaceSupported('describe') && $this->useTable !== false) {
- $info = new Set($db->describe($this));
-
- foreach($info->value as $field => $value) {
- $fields[] = am(array('name'=> $field), $value);
- }
- unset($info);
- $this->_tableInfo = new Set($fields);
- } elseif ($this->useTable === false) {
- $this->_tableInfo = new Set();
- }
- return $this->_tableInfo;
- }
-/**
- * Returns an associative array of field names and column types.
- *
- * @return array
- * @access public
- */
- function getColumnTypes() {
- $columns = $this->loadInfo();
- $columns = $columns->value;
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $cols = array();
-
- foreach ($columns as $col) {
- $cols[$col['name']] = $col['type'];
- }
- return $cols;
- }
-/**
- * Returns the column type of a column in the model
- *
- * @param string $column The name of the model column
- * @return string
- * @access public
- */
- function getColumnType($column) {
- $columns = $this->loadInfo();
- $columns = $columns->value;
- $cols = array();
-
- foreach ($columns as $col) {
- if ($col['name'] == $column) {
- return $col['type'];
- }
- }
- return null;
- }
-/**
- * Returns true if this Model has given field in its database table.
- *
- * @param string $name Name of field to look for
- * @return boolean
- * @access public
- */
- function hasField($name) {
- if (is_array($name)) {
- foreach ($name as $n) {
- if ($this->hasField($n)) {
- return $n;
- }
- }
- return false;
- }
-
- if (empty($this->_tableInfo)) {
- $this->loadInfo();
- }
-
- if ($this->_tableInfo != null) {
- return in_array($name, $this->_tableInfo->extract('{n}.name'));
- }
- return false;
- }
-/**
- * Initializes the model for writing a new record.
- *
- * @return boolean True
- * @access public
- */
- function create() {
- $this->id = false;
- unset ($this->data);
- $this->data = $this->validationErrors = array();
- return true;
- }
-/**
- * @deprecated
- */
- function setId($id) {
- $this->id = $id;
- }
-/**
- * Use query() instead.
- * @deprecated
- */
- function findBySql($sql) {
- return $this->query($sql);
- }
-/**
- * Returns a list of fields from the database
- *
- * @param mixed $id The ID of the record to read
- * @param mixed $fields String of single fieldname, or an array of fieldnames.
- * @return array Array of database fields
- * @access public
- */
- function read($fields = null, $id = null) {
- $this->validationErrors = array();
-
- if ($id != null) {
- $this->id = $id;
- }
-
- $id = $this->id;
-
- if (is_array($this->id)) {
- $id = $this->id[0];
- }
-
- if ($this->id !== null && $this->id !== false) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $field = $db->name($this->alias) . '.' . $db->name($this->primaryKey);
- return $this->find($field . ' = ' . $db->value($id, $this->getColumnType($this->primaryKey)), $fields);
- } else {
- return false;
- }
- }
-/**
- * Returns contents of a field in a query matching given conditions.
- *
- * @param string $name Name of field to get
- * @param array $conditions SQL conditions (defaults to NULL)
- * @param string $order SQL ORDER BY fragment
- * @return field contents
- * @access public
- */
- function field($name, $conditions = null, $order = null) {
- if ($conditions === null && $this->id !== false) {
- $conditions = array($this->alias . '.' . $this->primaryKey => $this->id);
- }
-
- if ($data = $this->find($conditions, $name, $order, 0)) {
-
- if (strpos($name, '.') === false) {
- if (isset($data[$this->alias][$name])) {
- return $data[$this->alias][$name];
- } else {
- return false;
- }
- } else {
- $name = explode('.', $name);
-
- if (isset($data[$name[0]][$name[1]])) {
- return $data[$name[0]][$name[1]];
- } else {
- return false;
- }
- }
- } else {
- return false;
- }
- }
-/**
- * Saves a single field to the database.
- *
- * @param string $name Name of the table field
- * @param mixed $value Value of the field
- * @param boolean $validate Whether or not this model should validate before saving (defaults to false)
- * @return boolean True on success save
- * @access public
- */
- function saveField($name, $value, $validate = false) {
- return $this->save(array($this->alias => array($name => $value)), $validate);
- }
-/**
- * Saves model data to the database.
- * By default, validation occurs before save.
- *
- * @param array $data Data to save.
- * @param boolean $validate If set, validation will be done before the save
- * @param array $fieldList List of fields to allow to be written
- * @return boolean success
- * @access public
- */
- function save($data = null, $validate = true, $fieldList = array()) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $_whitelist = $this->whitelist;
-
- if (!empty($fieldList)) {
- $this->whitelist = $fieldList;
- } elseif ($fieldList === null) {
- $this->whitelist = array();
- }
-
- if ($data) {
- if (countdim($data) == 1) {
- $this->set(array($this->alias => $data));
- } else {
- $this->set($data);
- }
- }
-
- if ($validate && !$this->validates()) {
- $this->whitelist = $_whitelist;
- return false;
- }
-
- if (!$this->beforeSave()) {
- $this->whitelist = $_whitelist;
- return false;
- }
- $fields = $values = array();
-
- if (isset($this->data[$this->alias][$this->primaryKey]) && empty($this->data[$this->alias][$this->primaryKey])) {
- unset($this->data[$this->alias][$this->primaryKey]);
- }
-
- if (count($this->data) > 1) {
- $weHaveMulti = true;
- $joined = false;
- } else {
- $weHaveMulti = false;
- }
-
- foreach ($this->data as $n => $v) {
- if (isset($weHaveMulti) && isset($v[$n]) && in_array($n, array_keys($this->hasAndBelongsToMany))) {
- $joined[] = $v;
- } else {
- if ($n === $this->alias) {
- foreach (array('created', 'updated', 'modified') as $field) {
- if (array_key_exists($field, $v) && (empty($v[$field]) || $v[$field] === null)) {
- unset($v[$field]);
- }
- }
-
- foreach ($v as $x => $y) {
- if ($this->hasField($x)) {
- $fields[] = $x;
- $values[] = $y;
- }
- }
- }
- }
- }
- $exists = $this->exists();
-
- if (!$exists && $this->hasField('created') && !in_array('created', $fields)) {
- $fields[] = 'created';
- $values[] = date('Y-m-d H:i:s');
- }
-
- if ($this->hasField('modified') && !in_array('modified', $fields)) {
- $fields[] = 'modified';
- $values[] = date('Y-m-d H:i:s');
- }
-
- if ($this->hasField('updated') && !in_array('updated', $fields)) {
- $fields[] = 'updated';
- $values[] = date('Y-m-d H:i:s');
- }
-
- if (!$exists) {
- $this->id = false;
- }
- $this->whitelist = $_whitelist;
-
- if (count($fields)) {
- if (!empty($this->id)) {
- if ($db->update($this, $fields, $values)) {
- if (!empty($joined)) {
- $this->__saveMulti($joined, $this->id);
- }
-
- $this->afterSave();
- $this->data = false;
- $this->_clearCache();
- return true;
- } else {
- return false;
- }
- } else {
- if ($db->create($this, $fields, $values)) {
- if (!empty($joined)) {
- $this->__saveMulti($joined, $this->id);
- }
-
- $this->afterSave();
- $this->data = false;
- $this->_clearCache();
- $this->validationErrors = array();
- return true;
- } else {
- return false;
- }
- }
- } else {
- return false;
- }
- }
-/**
- * Saves model hasAndBelongsToMany data to the database.
- *
- * @param array $joined Data to save.
- * @param string $id
- * @return void
- * @access private
- */
- function __saveMulti($joined, $id) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- foreach ($joined as $x => $y) {
- foreach ($y as $assoc => $value) {
- if (isset($this->hasAndBelongsToMany[$assoc])) {
- $joinTable[$assoc] = $this->hasAndBelongsToMany[$assoc]['joinTable'];
- $mainKey[$assoc] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
- $keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
- $keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
- $fields[$assoc] = join(',', $keys);
- unset($keys);
-
- foreach ($value as $update) {
- if (!empty($update)) {
- $values[] = $db->value($id, $this->getColumnType($this->primaryKey));
- $values[] = $db->value($update);
- $values = join(',', $values);
- $newValues[] = "({$values})";
- unset ($values);
- }
- }
-
- if (!empty($newValues)) {
- $newValue[$assoc] = $newValues;
- unset($newValues);
- } else {
- $newValue[$assoc] = array();
- }
- }
- }
- }
-
- if (isset($joinTable)) {
- $total = count($joinTable);
-
- if (is_array($newValue)) {
- foreach ($newValue as $loopAssoc => $val) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $table = $db->name($db->fullTableName($joinTable[$loopAssoc]));
- $db->query("DELETE FROM {$table} WHERE {$mainKey[$loopAssoc]} = '{$id}'");
-
- if (!empty($newValue[$loopAssoc])) {
- $secondCount = count($newValue[$loopAssoc]);
- for ($x = 0; $x < $secondCount; $x++) {
- $db->query("INSERT INTO {$table} ({$fields[$loopAssoc]}) VALUES {$newValue[$loopAssoc][$x]}");
- }
- }
- }
- }
- }
- }
-/**
- * Synonym for del().
- *
- * @param mixed $id
- * @see function del
- * @return boolean True on success
- * @access public
- */
- function remove($id = null, $cascade = true) {
- return $this->del($id, $cascade);
- }
-/**
- * Removes record for given id. If no id is given, the current id is used. Returns true on success.
- *
- * @param mixed $id Id of record to delete
- * @return boolean True on success
- * @access public
- */
- function del($id = null, $cascade = true) {
- if ($id) {
- $this->id = $id;
- }
- $id = $this->id;
-
- if ($this->exists() && $this->beforeDelete()) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- $this->_deleteMulti($id);
- $this->_deleteHasMany($id, $cascade);
- $this->_deleteHasOne($id, $cascade);
- $this->id = $id;
-
- if ($db->delete($this)) {
- $this->afterDelete();
- $this->_clearCache();
- $this->id = false;
- return true;
- }
- }
-
- return false;
- }
-/**
- * Alias for del()
- *
- * @param mixed $id Id of record to delete
- * @return boolean True on success
- * @access public
- */
- function delete($id = null, $cascade = true) {
- return $this->del($id, $cascade);
- }
-/**
- * Cascades model deletes to hasMany relationships.
- *
- * @param string $id
- * @return null
- * @access protected
- */
- function _deleteHasMany($id, $cascade) {
- if (!empty($this->__backAssociation)) {
- $savedAssociatons = $this->__backAssociation;
- $this->__backAssociation = array();
- }
- foreach ($this->hasMany as $assoc => $data) {
- if ($data['dependent'] === true && $cascade === true) {
- $model =& $this->{$data['className']};
- $field = $model->escapeField($data['foreignKey']);
- $model->recursive = 0;
- $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
-
- if ($records != false) {
- foreach ($records as $record) {
- $model->del($record[$data['className']][$model->primaryKey]);
- }
- }
- }
- }
- if (isset($savedAssociatons)) {
- $this->__backAssociation = $savedAssociatons;
- }
- }
-/**
- * Cascades model deletes to hasOne relationships.
- *
- * @param string $id
- * @return null
- * @access protected
- */
- function _deleteHasOne($id, $cascade) {
- if (!empty($this->__backAssociation)) {
- $savedAssociatons = $this->__backAssociation;
- $this->__backAssociation = array();
- }
- foreach ($this->hasOne as $assoc => $data) {
- if ($data['dependent'] === true && $cascade === true) {
- $model =& $this->{$data['className']};
- $field = $model->escapeField($data['foreignKey']);
- $model->recursive = 0;
- $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
-
- if ($records != false) {
- foreach ($records as $record) {
- $model->del($record[$data['className']][$model->primaryKey]);
- }
- }
- }
- }
- if (isset($savedAssociatons)) {
- $this->__backAssociation = $savedAssociatons;
- }
- }
-/**
- * Cascades model deletes to HABTM join keys.
- *
- * @param string $id
- * @return null
- * @access protected
- */
- function _deleteMulti($id) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- foreach ($this->hasAndBelongsToMany as $assoc => $data) {
- $db->execute("DELETE FROM " . $db->name($db->fullTableName($data['joinTable'])) . " WHERE " . $db->name($data['foreignKey']) . " = '{$id}'");
- }
- }
-/**
- * Returns true if a record with set id exists.
- *
- * @return boolean True if such a record exists
- * @access public
- */
- function exists() {
- if ($this->id) {
- $id = $this->id;
-
- if (is_array($id)) {
- $id = $id[0];
- }
-
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->hasAny($this, array($this->primaryKey => $id));
- }
- return false;
- }
-/**
- * Returns true if a record that meets given conditions exists
- *
- * @param array $conditions SQL conditions array
- * @return boolean True if such a record exists
- * @access public
- */
- function hasAny($conditions = null) {
- return ($this->findCount($conditions) != false);
- }
-/**
- * Return a single row as a resultset array.
- * By using the $recursive parameter, the call can access further "levels of association" than
- * the ones this model is directly associated to.
- *
- * @param array $conditions SQL conditions array
- * @param mixed $fields Either a single string of a field name, or an array of field names
- * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
- * @param int $recursive The number of levels deep to fetch associated records
- * @return array Array of records
- * @access public
- */
- function find($conditions = null, $fields = null, $order = null, $recursive = null) {
- $data = $this->findAll($conditions, $fields, $order, 1, null, $recursive);
-
- if (empty($data[0])) {
- return false;
- }
-
- return $data[0];
- }
-/**
- * Returns a resultset array with specified fields from database matching given conditions.
- * By using the $recursive parameter, the call can access further "levels of association" than
- * the ones this model is directly associated to.
- *
- * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
- * @param mixed $fields Either a single string of a field name, or an array of field names
- * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
- * @param int $limit SQL LIMIT clause, for calculating items per page.
- * @param int $page Page number, for accessing paged data
- * @param int $recursive The number of levels deep to fetch associated records
- * @return array Array of records
- * @access public
- */
- function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
-
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $this->id = $this->getID();
- $offset = null;
-
- if ($page > 1 && $limit != null) {
- $offset = ($page - 1) * $limit;
- }
-
- if ($order == null) {
- $order = array();
- } else {
- $order = array($order);
- }
-
- $queryData = array('conditions' => $conditions,
- 'fields' => $fields,
- 'joins' => array(),
- 'limit' => $limit,
- 'offset' => $offset,
- 'order' => $order
- );
-
- $ret = $this->beforeFind($queryData);
- if (is_array($ret)) {
- $queryData = $ret;
- } elseif ($ret === false) {
- return null;
- }
-
- $return = $this->afterFind($db->read($this, $queryData, $recursive));
-
- if (!empty($this->__backAssociation)) {
- $this->__resetAssociations();
- }
-
- return $return;
- }
-/**
- * Method is called only when bindTo<ModelName>() is used.
- * This resets the association arrays for the model back
- * to the original as set in the model.
- *
- * @return boolean
- * @access private
- */
- function __resetAssociations() {
- foreach ($this->__associations as $type) {
- if (isset($this->__backAssociation[$type])) {
- $this->{$type} = $this->__backAssociation[$type];
- }
- }
-
- $this->__backAssociation = array();
- return true;
- }
-/**
- * Runs a direct query against the bound DataSource, and returns the result.
- *
- * @param string $data Query data
- * @return array
- * @access public
- */
- function execute($data) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $data = $db->fetchAll($data, $this->cacheQueries);
-
- foreach ($data as $key => $value) {
- foreach ($this->tableToModel as $key1 => $value1) {
- if (isset($data[$key][$key1])) {
- $newData[$key][$value1] = $data[$key][$key1];
- }
- }
- }
-
- if (!empty($newData)) {
- return $newData;
- }
-
- return $data;
- }
-/**
- * Returns number of rows matching given SQL condition.
- *
- * @param array $conditions SQL conditions array for findAll
- * @param int $recursize The number of levels deep to fetch associated records
- * @return int Number of matching rows
- * @see Model::findAll
- * @access public
- */
- function findCount($conditions = null, $recursive = 0) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- list($data) = $this->findAll($conditions, 'COUNT(*) AS ' . $db->name('count'), null, null, 1, $recursive);
-
- if (isset($data[0]['count'])) {
- return $data[0]['count'];
- } elseif (isset($data[$this->alias]['count'])) {
- return $data[$this->alias]['count'];
- }
-
- return false;
- }
-/**
- * Special findAll variation for tables joined to themselves.
- * The table needs the fields id and parent_id to work.
- *
- * @param array $conditions Conditions for the findAll() call
- * @param array $fields Fields for the findAll() call
- * @param string $sort SQL ORDER BY statement
- * @return array
- * @access public
- * @todo Perhaps create a Component with this logic
- */
- function findAllThreaded($conditions = null, $fields = null, $sort = null) {
- return $this->__doThread(Model::findAll($conditions, $fields, $sort), null);
- }
-/**
- * Private, recursive helper method for findAllThreaded.
- *
- * @param array $data
- * @param string $root NULL or id for root node of operation
- * @return array
- * @access private
- * @see findAllThreaded
- */
- function __doThread($data, $root) {
- $out = array();
- $sizeOf = sizeof($data);
-
- for ($ii = 0; $ii < $sizeOf; $ii++) {
- if (($data[$ii][$this->alias]['parent_id'] == $root) || (($root === null) && ($data[$ii][$this->alias]['parent_id'] == '0'))) {
- $tmp = $data[$ii];
-
- if (isset($data[$ii][$this->alias][$this->primaryKey])) {
- $tmp['children'] = $this->__doThread($data, $data[$ii][$this->alias][$this->primaryKey]);
- } else {
- $tmp['children'] = null;
- }
-
- $out[] = $tmp;
- }
- }
-
- return $out;
- }
-/**
- * Returns an array with keys "prev" and "next" that holds the id's of neighbouring data,
- * which is useful when creating paged lists.
- *
- * @param string $conditions SQL conditions for matching rows
- * @param string $field Field name (parameter for findAll)
- * @param unknown_type $value
- * @return array Array with keys "prev" and "next" that holds the id's
- * @access public
- */
- function findNeighbours($conditions = null, $field, $value) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- if (!is_null($conditions)) {
- $conditions = $conditions . ' AND ';
- }
-
- @list($prev) = Model::findAll($conditions . $field . ' < ' . $db->value($value), $field, $field . ' DESC', 1, null, 0);
- @list($next) = Model::findAll($conditions . $field . ' > ' . $db->value($value), $field, $field . ' ASC', 1, null, 0);
-
- if (!isset($prev)) {
- $prev = null;
- }
-
- if (!isset($next)) {
- $next = null;
- }
-
- return array('prev' => $prev, 'next' => $next);
- }
-/**
- * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method.
- *
- * @param string $sql SQL statement
- * @return array Resultset
- * @access public
- */
- function query() {
- $params = func_get_args();
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return call_user_func_array(array(&$db, 'query'), $params);
- }
-/**
- * Returns true if all fields pass validation, otherwise false.
- *
- * @param array $data POST data
- * @return boolean True if there are no errors
- * @access public
- */
- function validates($data = array()) {
- $errors = $this->invalidFields($data);
- return count($errors) == 0;
- }
-/**
- * Returns an array of invalid fields.
- *
- * @param array $data
- * @return array Array of invalid fields or boolean case any error occurs
- * @access public
- */
- function invalidFields($data = array()) {
- if (empty($data)) {
- $data = $this->data;
- }
-
- if (!$this->beforeValidate()) {
- return $this->validationErrors;
- }
-
- if (!isset($this->validate)) {
- return $this->validationErrors;
- }
-
- if (!empty($data)) {
- $data = $data;
- } elseif (isset($this->data)) {
- $data = $this->data;
- }
-
- if (isset($data[$this->alias])) {
- $data = $data[$this->alias];
- }
-
- foreach ($this->validate as $field_name => $validator) {
- if (isset($data[$field_name]) && !preg_match($validator, $data[$field_name])) {
- $this->invalidate($field_name);
- }
- }
- return $this->validationErrors;
- }
-/**
- * Sets a field as invalid
- *
- * @param string $field The name of the field to invalidate
- * @return void
- * @access public
- */
- function invalidate($field) {
- if (!is_array($this->validationErrors)) {
- $this->validationErrors = array();
- }
- $this->validationErrors[$field] = 1;
- }
-/**
- * Returns true if given field name is a foreign key in this Model.
- *
- * @param string $field Returns true if the input string ends in "_id"
- * @return True if the field is a foreign key listed in the belongsTo array.
- * @access public
- */
- function isForeignKey($field) {
- $foreignKeys = array();
-
- if (count($this->belongsTo)) {
- foreach ($this->belongsTo as $assoc => $data) {
- $foreignKeys[] = $data['foreignKey'];
- }
- }
- return (bool)(in_array($field, $foreignKeys));
- }
-/**
- * Gets the display field for this model
- *
- * @return string The name of the display field for this Model (i.e. 'name', 'title').
- * @access public
- */
- function getDisplayField() {
- return $this->displayField;
- }
-/**
- * Returns a resultset array with specified fields from database matching given conditions.
- * Method can be used to generate option lists for SELECT elements.
- *
- * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
- * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
- * @param int $limit SQL LIMIT clause, for calculating items per page
- * @param string $keyPath A string path to the key, i.e. "{n}.Post.id"
- * @param string $valuePath A string path to the value, i.e. "{n}.Post.title"
- * @return array An associative array of records, where the id is the key, and the display field is the value
- * @access public
- */
- function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) {
- if ($keyPath == null && $valuePath == null && $this->hasField($this->displayField)) {
- $fields = array($this->primaryKey, $this->displayField);
- } else {
- $fields = null;
- }
- $recursive = $this->recursive;
-
- if ($recursive >= 1) {
- $this->recursive = -1;
- }
- $result = $this->findAll($conditions, $fields, $order, $limit);
- $this->recursive = $recursive;
-
- if (!$result) {
- return false;
- }
-
- if ($keyPath == null) {
- $keyPath = '{n}.' . $this->alias . '.' . $this->primaryKey;
- }
-
- if ($valuePath == null) {
- $valuePath = '{n}.' . $this->alias . '.' . $this->displayField;
- }
-
- $keys = Set::extract($result, $keyPath);
- $vals = Set::extract($result, $valuePath);
-
- if (!empty($keys) && !empty($vals)) {
- $return = array_combine($keys, $vals);
- return $return;
- }
- return null;
- }
-/**
- * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules.
- *
- * @param unknown_type $field
- * @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`).
- * @access public
- */
- function escapeField($field) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->name($this->alias) . '.' . $db->name($field);
- }
-/**
- * Returns the current record's ID
- *
- * @param unknown_type $list
- * @return mixed The ID of the current record
- * @access public
- */
- function getID($list = 0) {
- if (!is_array($this->id)) {
- return $this->id;
- }
-
- if (count($this->id) == 0) {
- return false;
- }
-
- if (isset($this->id[$list])) {
- return $this->id[$list];
- }
-
- foreach ($this->id as $id) {
- return $id;
- }
-
- return false;
- }
-/**
- * Returns the ID of the last record this Model inserted
- *
- * @return mixed
- * @access public
- */
- function getLastInsertID() {
- return $this->getInsertID();
- }
-/**
- * Returns the ID of the last record this Model inserted
- *
- * @return mixed
- * @access public
- */
- function getInsertID() {
- return $this->__insertID;
- }
-/**
- * Sets the ID of the last record this Model inserted
- *
- * @param mixed $id
- * @return void
- */
- function setInsertID($id) {
- $this->__insertID = $id;
- }
-/**
- * Returns the number of rows returned from the last query
- *
- * @return int
- * @access public
- */
- function getNumRows() {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->lastNumRows();
- }
-/**
- * Returns the number of rows affected by the last query
- *
- * @return int
- * @access public
- */
- function getAffectedRows() {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->lastAffected();
- }
-/**
- * Sets the DataSource to which this model is bound
- *
- * @param string $dataSource The name of the DataSource, as defined in Connections.php
- * @return boolean True on success
- * @access public
- */
- function setDataSource($dataSource = null) {
- if ($dataSource != null) {
- $this->useDbConfig = $dataSource;
- }
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- if (!empty($db->config['prefix']) && $this->tablePrefix === null) {
- $this->tablePrefix = $db->config['prefix'];
- }
-
- if (empty($db) || $db == null || !is_object($db)) {
- return $this->cakeError('missingConnection', array(array('className' => $this->alias)));
- }
- }
-/**
- * Before find callback
- *
- * @param array $queryData Data used to execute this query, i.e. conditions, order, etc.
- * @return boolean True if the operation should continue, false if it should abort
- * @access public
- */
- function beforeFind(&$queryData) {
- return true;
- }
-/**
- * After find callback. Can be used to modify any results returned by find and findAll.
- *
- * @param mixed $results The results of the find operation
- * @return mixed Result of the find operation
- * @access public
- */
- function afterFind($results) {
- return $results;
- }
-/**
- * Before save callback
- *
- * @return boolean True if the operation should continue, false if it should abort
- * @access public
- */
- function beforeSave() {
- return true;
- }
-/**
- * After save callback
- *
- * @return boolean
- * @access public
- */
- function afterSave() {
- return true;
- }
-/**
- * Before delete callback
- *
- * @return boolean True if the operation should continue, false if it should abort
- * @access public
- */
- function beforeDelete() {
- return true;
- }
-/**
- * After delete callback
- *
- * @return boolean
- * @access public
- */
- function afterDelete() {
- return true;
- }
-/**
- * Before validate callback
- *
- * @return boolean
- * @access public
- */
- function beforeValidate() {
- return true;
- }
-/**
- * DataSource error callback
- *
- * @return void
- */
- function onError() {
- }
-/**
- * Private method. Clears cache for this model
- *
- * @param string $type If null this deletes cached views if CACHE_CHECK is true
- * Will be used to allow deleting query cache also
- * @return boolean true on delete
- * @access protected
- */
- function _clearCache($type = null) {
- if ($type === null) {
- if (defined('CACHE_CHECK') && CACHE_CHECK === true) {
- $assoc[] = strtolower(Inflector::pluralize($this->alias));
-
- foreach ($this->__associations as $key => $association) {
- foreach ($this->$association as $key => $className) {
- $check = strtolower(Inflector::pluralize($className['className']));
-
- if (!in_array($check, $assoc)) {
- $assoc[] = strtolower(Inflector::pluralize($className['className']));
- }
- }
- }
- clearCache($assoc);
- return true;
- }
- } else {
- //Will use for query cache deleting
- }
- }
-/**
- * Called when serializing a model
- *
- * @return array
- * @access public
- */
- function __sleep() {
- $return = array_keys(get_object_vars($this));
- return $return;
- }
-/**
- * Called when unserializing a model
- *
- * @return void
- * @access public
- */
- function __wakeup() {
- }
-}
-// --- PHP4 Only
-overload ('Model');
-// --- PHP4 Only
-
-?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php5.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php5.php
deleted file mode 100644
index 55a4594..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/model/model_php5.php
+++ /dev/null
@@ -1,1716 +0,0 @@
-<?php
-/* SVN FILE: $Id: model_php5.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Object-relational mapper.
- *
- * DBO-backed object data model, for mapping database tables to Cake objects.
- *
- * PHP versions 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.model
- * @since CakePHP(tm) v 0.10.0.0
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libs
- */
-uses('class_registry', 'validators', 'model' . DS . 'connection_manager', 'set');
-/**
- * Object-relational mapper.
- *
- * DBO-backed object data model.
- * Automatically selects a database table name based on a pluralized lowercase object class name
- * (i.e. class 'User' => table 'users'; class 'Man' => table 'men')
- * The table is required to have at least 'id auto_increment', 'created datetime',
- * and 'modified datetime' fields.
- *
- * @package cake
- * @subpackage cake.cake.libs.model
- */
-class Model extends Object{
-/**
- * The name of the DataSource connection that this Model uses
- *
- * @var string
- * @access public
- */
- var $useDbConfig = 'default';
-/**
- * Custom database table name.
- *
- * @var string
- * @access public
- */
- var $useTable = null;
-/**
- * Custom display field name. Display fields are used by Scaffold, in SELECT boxes' OPTION elements.
- *
- * @var string
- * @access public
- */
- var $displayField = null;
-
-/**
- * Value of the primary key ID of the record that this model is currently pointing to
- *
- * @var string
- * @access public
- */
- var $id = false;
-/**
- * Container for the data that this model gets from persistent storage (the database).
- *
- * @var array
- * @access public
- */
- var $data = array();
-/**
- * Table name for this Model.
- *
- * @var string
- * @access public
- */
- var $table = false;
-/**
- * The name of the ID field for this Model.
- *
- * @var string
- * @access public
- */
- var $primaryKey = null;
-/**
- * Table metadata
- *
- * @var array
- * @access protected
- */
- var $_tableInfo = null;
-/**
- * List of validation rules. Append entries for validation as ('field_name' => '/^perl_compat_regexp$/')
- * that have to match with preg_match(). Use these rules with Model::validate()
- *
- * @var array
- * @access public
- */
- var $validate = array();
-/**
- * Errors in validation
- * @var array
- * @access public
- */
- var $validationErrors = array();
-/**
- * Database table prefix for tables in model.
- *
- * @var string
- * @access public
- */
- var $tablePrefix = null;
-/**
- * Name of the model.
- *
- * @var string
- * @access public
- */
- var $name = null;
-/**
- * Name of the current model.
- *
- * @var string
- * @access public
- */
- var $currentModel = null;
-/**
- * List of table names included in the Model description. Used for associations.
- *
- * @var array
- * @access public
- */
- var $tableToModel = array();
-/**
- * List of Model names by used tables. Used for associations.
- *
- * @var array
- * @access public
- */
- var $modelToTable = array();
-/**
- * List of Foreign Key names to used tables. Used for associations.
- *
- * @var array
- * @access public
- */
- var $keyToTable = array();
-/**
- * Alias name for model.
- *
- * @var array
- * @access public
- */
- var $alias = null;
-/**
- * Whether or not transactions for this model should be logged
- *
- * @var boolean
- * @access public
- */
- var $logTransactions = false;
-/**
- * Whether or not to enable transactions for this model (i.e. BEGIN/COMMIT/ROLLBACK)
- *
- * @var boolean
- * @access public
- */
- var $transactional = false;
-/**
- * Whether or not to cache queries for this model. This enables in-memory
- * caching only, the results are not stored beyond this execution.
- *
- * @var boolean
- * @access public
- */
- var $cacheQueries = true;
-/**
- * belongsTo association
- *
- * @var array
- * @access public
- */
- var $belongsTo = array();
-/**
- * hasOne association
- *
- * @var array
- * @access public
- */
- var $hasOne = array();
-/**
- * hasMany association
- *
- * @var array
- * @access public
- */
- var $hasMany = array();
-/**
- * hasAndBelongsToMany association
- *
- * @var array
- * @access public
- */
- var $hasAndBelongsToMany = array();
-/**
- * Depth of recursive association
- *
- * @var int
- * @access public
- */
- var $recursive = 1;
-/**
- * Whitelist of fields allowed to be saved
- *
- * @var array
- */
- var $whitelist = array();
-/**
- * Enter description here...
- *
- * @var boolean
- */
- var $cacheSources = true;
-/**
- * Default association keys
- *
- * @var array
- * @access private
- */
- var $__associationKeys = array('belongsTo' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'counterCache'),
- 'hasOne' => array('className', 'foreignKey','conditions', 'fields','order', 'dependent'),
- 'hasMany' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'),
- 'hasAndBelongsToMany' => array('className', 'joinTable', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery'));
-/**
- * Holds provided/generated association key names and other data for all associations
- *
- * @var array
- * @access private
- */
- var $__associations = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
-/**
- * The last inserted ID of the data that this model created
- *
- * @var int
- * @access private
- */
- var $__insertID = null;
-/**
- * The number of records returned by the last query
- *
- * @var int
- * @access private
- */
- var $__numRows = null;
-/**
- * The number of records affected by the last query
- *
- * @var int
- * @access private
- */
- var $__affectedRows = null;
-/**
- * Holds model associations temporarily to allow for dynamic (un)binding
- *
- * @var array
- * @access private
- */
- var $__backAssociation = array();
-/**
- * Constructor. Binds the Model's database table to the object.
- *
- * @param integer $id
- * @param string $table Name of database table to use.
- * @param DataSource $ds DataSource connection object.
- */
- function __construct($id = false, $table = null, $ds = null) {
- parent::__construct();
-
- if (is_array($id) && isset($id['name'])) {
- $options = array_merge(array('id' => false, 'table' => null, 'ds' => null, 'alias' => null), $id);
- list($id, $table, $ds) = array($options['id'], $options['table'], $options['ds']);
- $this->name = $options['name'];
- }
-
- if ($this->name === null) {
- $this->name = get_class($this);
- }
-
- if ($this->primaryKey === null) {
- $this->primaryKey = 'id';
- }
-
- if (isset($options['alias']) || !empty($options['alias'])) {
- $this->alias = $options['alias'];
- unset($options);
- } else {
- $this->alias = $this->name;
- }
- ClassRegistry::addObject($this->alias, $this);
-
- $this->id = $id;
- unset($id);
-
- if ($table === false) {
- $this->useTable = false;
- } elseif ($table) {
- $this->useTable = $table;
- }
-
- if ($this->useTable !== false) {
- $this->setDataSource($ds);
-
- if ($this->useTable === null) {
- $this->useTable = Inflector::tableize($this->name);
- }
-
- if (in_array('settableprefix', get_class_methods($this))) {
- $this->setTablePrefix();
- }
-
- $this->setSource($this->useTable);
- $this->__createLinks();
-
- if ($this->displayField == null) {
- if ($this->hasField('title')) {
- $this->displayField = 'title';
- }
-
- if ($this->hasField('name')) {
- $this->displayField = 'name';
- }
-
- if ($this->displayField == null) {
- $this->displayField = $this->primaryKey;
- }
- }
- }
- }
-
-/**
- * Handles custom method calls, like findBy<field> for DB models,
- * and custom RPC calls for remote data sources
- *
- * @param unknown_type $method
- * @param array $params
- * @return unknown
- * @access protected
- */
- function __call($method, $params) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->query($method, $params, $this);
- }
-/**
- * Bind model associations on the fly.
- *
- * @param array $params
- * @return true
- * @access public
- */
- function bindModel($params) {
- foreach ($params as $assoc => $model) {
- if(!isset($this->__backAssociation[$assoc])) {
- $this->__backAssociation[$assoc] = $this->{$assoc};
- }
-
- foreach ($model as $key => $value) {
- $assocName = $key;
-
- if (is_numeric($key)) {
- $assocName = $value;
- $value = array();
- }
- $modelName = $assocName;
- $this->{$assoc}[$assocName] = $value;
- }
- }
- $this->__createLinks();
- return true;
- }
-/**
- * Turn off associations on the fly.
- *
- * @param array $params
- * @return true
- * @access public
- */
- function unbindModel($params) {
- foreach ($params as $assoc => $models) {
- if(!isset($this->__backAssociation[$assoc])) {
- $this->__backAssociation[$assoc] = $this->{$assoc};
- }
-
- foreach ($models as $model) {
- $this->__backAssociation = array_merge($this->__backAssociation, $this->{$assoc});
- unset ($this->{$assoc}[$model]);
- }
- }
- return true;
- }
-/**
- * Private helper method to create a set of associations.
- *
- * @access private
- */
- function __createLinks() {
-
- foreach ($this->__associations as $type) {
- if (!is_array($this->{$type})) {
- $this->{$type} = explode(',', $this->{$type});
-
- foreach ($this->{$type} as $i => $className) {
- $className = trim($className);
- unset ($this->{$type}[$i]);
- $this->{$type}[$className] = array();
- }
- }
-
- foreach ($this->{$type} as $assoc => $value) {
- if (is_numeric($assoc)) {
- unset ($this->{$type}[$assoc]);
- $assoc = $value;
- $value = array();
- $this->{$type}[$assoc] = $value;
- }
-
- $className = $assoc;
-
- if (isset($value['className']) && !empty($value['className'])) {
- $className = $value['className'];
- }
- $this->__constructLinkedModel($assoc, $className);
- }
- }
-
- foreach ($this->__associations as $type) {
- $this->__generateAssociation($type);
- }
- }
-
-/**
- * Private helper method to create associated models of given class.
- * @param string $assoc
- * @param string $className Class name
- * @param string $type Type of assocation
- * @access private
- */
- function __constructLinkedModel($assoc, $className) {
- if(empty($className)) {
- $className = $assoc;
- }
-
- if (!class_exists($className)) {
- loadModel($className);
- }
- $colKey = Inflector::underscore($className);
- $model = array('name' => $className, 'alias' => $assoc);
-
- if (ClassRegistry::isKeySet($colKey)) {
- $this->{$assoc} = ClassRegistry::getObject($colKey);
- $this->{$className} = $this->{$assoc};
- } else {
- $this->{$assoc} = new $className($model);
- $this->{$className} = $this->{$assoc};
- }
- $this->tableToModel[$this->{$assoc}->table] = $className;
- $this->modelToTable[$assoc] = $this->{$assoc}->table;
- }
-/**
- * Build array-based association from string.
- *
- * @param string $type "Belongs", "One", "Many", "ManyTo"
- * @access private
- */
- function __generateAssociation($type) {
- foreach ($this->{$type}as $assocKey => $assocData) {
- $class = $assocKey;
-
- foreach ($this->__associationKeys[$type] as $key) {
- if (!isset($this->{$type}[$assocKey][$key]) || $this->{$type}[$assocKey][$key] == null) {
- $data = '';
-
- switch($key) {
- case 'fields':
- $data = '';
- break;
-
- case 'foreignKey':
- $data = Inflector::singularize($this->table) . '_id';
-
- if ($type == 'belongsTo') {
- $data = Inflector::singularize($this->{$class}->table) . '_id';
- }
- break;
-
- case 'associationForeignKey':
- $data = Inflector::singularize($this->{$class}->table) . '_id';
- break;
-
- case 'joinTable':
- $tables = array($this->table, $this->{$class}->table);
- sort ($tables);
- $data = $tables[0] . '_' . $tables[1];
- break;
-
- case 'className':
- $data = $class;
- break;
- }
-
- $this->{$type}[$assocKey][$key] = $data;
- }
-
- if ($key == 'foreignKey' && !isset($this->keyToTable[$this->{$type}[$assocKey][$key]])) {
- $this->keyToTable[$this->{$type}[$assocKey][$key]][0] = $this->{$class}->table;
- $this->keyToTable[$this->{$type}[$assocKey][$key]][1] = $this->{$class}->alias;
- }
- }
- }
- }
-/**
- * Sets a custom table for your controller class. Used by your controller to select a database table.
- *
- * @param string $tableName Name of the custom table
- * @access public
- */
- function setSource($tableName) {
- $this->setDataSource($this->useDbConfig);
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $db->cacheSources = $this->cacheSources;
-
- if ($db->isInterfaceSupported('listSources')) {
- $sources = $db->listSources();
- if (is_array($sources) && !in_array(low($this->tablePrefix . $tableName), array_map('low', $sources))) {
- return $this->cakeError('missingTable', array(array(
- 'className' => $this->alias,
- 'table' => $this->tablePrefix . $tableName)));
-
- }
- $this->_tableInfo = null;
- }
- $this->table = $this->useTable = $tableName;
- $this->tableToModel[$this->table] = $this->alias;
- $this->loadInfo();
- }
-/**
- * This function does two things: 1) it scans the array $one for the primary key,
- * and if that's found, it sets the current id to the value of $one[id].
- * For all other keys than 'id' the keys and values of $one are copied to the 'data' property of this object.
- * 2) Returns an array with all of $one's keys and values.
- * (Alternative indata: two strings, which are mangled to
- * a one-item, two-dimensional array using $one for a key and $two as its value.)
- *
- * @param mixed $one Array or string of data
- * @param string $two Value string for the alternative indata method
- * @return array
- * @access public
- */
- function set($one, $two = null) {
- if (is_array($one)) {
- if (countdim($one) == 1) {
- $data = array($this->alias => $one);
- } else {
- $data = $one;
- }
- } else {
- $data = array($this->alias => array($one => $two));
- }
-
- foreach ($data as $n => $v) {
- if (is_array($v)) {
-
- foreach ($v as $x => $y) {
- if (empty($this->whitelist) || (in_array($x, $this->whitelist) || $n !== $this->alias)) {
- if (isset($this->validationErrors[$x])) {
- unset ($this->validationErrors[$x]);
- }
-
- if ($n == $this->name || is_array($y)) {
- if ($x === $this->primaryKey) {
- $this->id = $y;
- }
- $this->data[$n][$x] = $y;
- }
- }
- }
- }
- }
- return $data;
- }
-/**
- * Returns an array of table metadata (column names and types) from the database.
- *
- * @return array Array of table metadata
- * @access public
- */
- function loadInfo() {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $db->cacheSources = $this->cacheSources;
-
- if (!is_object($this->_tableInfo) && $db->isInterfaceSupported('describe') && $this->useTable !== false) {
- $info = new Set($db->describe($this));
-
- foreach($info->value as $field => $value) {
- $fields[] = am(array('name'=> $field), $value);
- }
- unset($info);
- $this->_tableInfo = new Set($fields);
- } elseif ($this->useTable === false) {
- $this->_tableInfo = new Set();
- }
- return $this->_tableInfo;
- }
-/**
- * Returns an associative array of field names and column types.
- *
- * @return array
- * @access public
- */
- function getColumnTypes() {
- $columns = $this->loadInfo();
- $columns = $columns->value;
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $cols = array();
-
- foreach ($columns as $col) {
- $cols[$col['name']] = $col['type'];
- }
- return $cols;
- }
-/**
- * Returns the column type of a column in the model
- *
- * @param string $column The name of the model column
- * @return string
- * @access public
- */
- function getColumnType($column) {
- $columns = $this->loadInfo();
- $columns = $columns->value;
- $cols = array();
-
- foreach ($columns as $col) {
- if ($col['name'] == $column) {
- return $col['type'];
- }
- }
- return null;
- }
-/**
- * Returns true if this Model has given field in its database table.
- *
- * @param string $name Name of field to look for
- * @return boolean
- * @access public
- */
- function hasField($name) {
- if (is_array($name)) {
- foreach ($name as $n) {
- if ($this->hasField($n)) {
- return $n;
- }
- }
- return false;
- }
-
- if (empty($this->_tableInfo)) {
- $this->loadInfo();
- }
-
- if ($this->_tableInfo != null) {
- return in_array($name, $this->_tableInfo->extract('{n}.name'));
- }
- return false;
- }
-/**
- * Initializes the model for writing a new record.
- *
- * @return boolean True
- * @access public
- */
- function create() {
- $this->id = false;
- unset ($this->data);
- $this->data = $this->validationErrors = array();
- return true;
- }
-/**
- * @deprecated
- */
- function setId($id) {
- $this->id = $id;
- }
-/**
- * Use query() instead.
- * @deprecated
- */
- function findBySql($sql) {
- return $this->query($sql);
- }
-/**
- * Returns a list of fields from the database
- *
- * @param mixed $id The ID of the record to read
- * @param mixed $fields String of single fieldname, or an array of fieldnames.
- * @return array Array of database fields
- * @access public
- */
- function read($fields = null, $id = null) {
- $this->validationErrors = array();
-
- if ($id != null) {
- $this->id = $id;
- }
-
- $id = $this->id;
-
- if (is_array($this->id)) {
- $id = $this->id[0];
- }
-
- if ($this->id !== null && $this->id !== false) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $field = $db->name($this->alias) . '.' . $db->name($this->primaryKey);
- return $this->find($field . ' = ' . $db->value($id, $this->getColumnType($this->primaryKey)), $fields);
- } else {
- return false;
- }
- }
-/**
- * Returns contents of a field in a query matching given conditions.
- *
- * @param string $name Name of field to get
- * @param array $conditions SQL conditions (defaults to NULL)
- * @param string $order SQL ORDER BY fragment
- * @return field contents
- * @access public
- */
- function field($name, $conditions = null, $order = null) {
- if ($conditions === null && $this->id !== false) {
- $conditions = array($this->alias . '.' . $this->primaryKey => $this->id);
- }
-
- if ($data = $this->find($conditions, $name, $order, 0)) {
-
- if (strpos($name, '.') === false) {
- if (isset($data[$this->alias][$name])) {
- return $data[$this->alias][$name];
- } else {
- return false;
- }
- } else {
- $name = explode('.', $name);
-
- if (isset($data[$name[0]][$name[1]])) {
- return $data[$name[0]][$name[1]];
- } else {
- return false;
- }
- }
- } else {
- return false;
- }
- }
-/**
- * Saves a single field to the database.
- *
- * @param string $name Name of the table field
- * @param mixed $value Value of the field
- * @param array $validate See $options param in Model::save(). Does not respect 'fieldList' key if passed
- * @return boolean See Model::save()
- * @access public
- * @see Model::save()
- */
- function saveField($name, $value, $validate = false) {
- $id = $this->id;
- $this->create();
-
- if (is_array($validate)) {
- $options = array_merge(array('validate' => false, 'fieldList' => array($name)), $validate);
- } else {
- $options = array('validate' => $validate, 'fieldList' => array($name));
- }
-
- return $this->save(array($this->alias => array($this->primaryKey => $id, $name => $value)), $options);
- }
-/**
- * Saves model data to the database.
- * By default, validation occurs before save.
- *
- * @param array $data Data to save.
- * @param boolean $validate If set, validation will be done before the save
- * @param array $fieldList List of fields to allow to be written
- * @return boolean success
- * @access public
- */
- function save($data = null, $validate = true, $fieldList = array()) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $_whitelist = $this->whitelist;
-
- if (!empty($fieldList)) {
- $this->whitelist = $fieldList;
- } elseif ($fieldList === null) {
- $this->whitelist = array();
- }
-
- if ($data) {
- if (countdim($data) == 1) {
- $this->set(array($this->alias => $data));
- } else {
- $this->set($data);
- }
- }
-
- if ($validate && !$this->validates()) {
- $this->whitelist = $_whitelist;
- return false;
- }
-
- if (!$this->beforeSave()) {
- $this->whitelist = $_whitelist;
- return false;
- }
- $fields = $values = array();
-
- if (isset($this->data[$this->alias][$this->primaryKey]) && empty($this->data[$this->alias][$this->primaryKey])) {
- unset($this->data[$this->alias][$this->primaryKey]);
- }
-
- if (count($this->data) > 1) {
- $weHaveMulti = true;
- $joined = false;
- } else {
- $weHaveMulti = false;
- }
-
- foreach ($this->data as $n => $v) {
- if (isset($weHaveMulti) && isset($v[$n]) && in_array($n, array_keys($this->hasAndBelongsToMany))) {
- $joined[] = $v;
- } else {
- if ($n === $this->alias) {
- foreach (array('created', 'updated', 'modified') as $field) {
- if (array_key_exists($field, $v) && (empty($v[$field]) || $v[$field] === null)) {
- unset($v[$field]);
- }
- }
-
- foreach ($v as $x => $y) {
- if ($this->hasField($x)) {
- $fields[] = $x;
- $values[] = $y;
- }
- }
- }
- }
- }
- $exists = $this->exists();
-
- if (!$exists && $this->hasField('created') && !in_array('created', $fields)) {
- $fields[] = 'created';
- $values[] = date('Y-m-d H:i:s');
- }
-
- if ($this->hasField('modified') && !in_array('modified', $fields)) {
- $fields[] = 'modified';
- $values[] = date('Y-m-d H:i:s');
- }
-
- if ($this->hasField('updated') && !in_array('updated', $fields)) {
- $fields[] = 'updated';
- $values[] = date('Y-m-d H:i:s');
- }
-
- if (!$exists) {
- $this->id = false;
- }
- $this->whitelist = $_whitelist;
-
-
- if (count($fields)) {
- if (!empty($this->id)) {
- if ($db->update($this, $fields, $values)) {
- if (!empty($joined)) {
- $this->__saveMulti($joined, $this->id);
- }
-
- $this->afterSave();
- $this->data = false;
- $this->_clearCache();
- return true;
- }
- return false;
- }
-
- if ($db->create($this, $fields, $values)) {
- if (!empty($joined)) {
- $this->__saveMulti($joined, $this->id);
- }
-
- $this->afterSave();
- $this->data = false;
- $this->_clearCache();
- $this->validationErrors = array();
- return true;
- }
- return false;
- }
- return false;
- }
-/**
- * Saves model hasAndBelongsToMany data to the database.
- *
- * @param array $joined Data to save.
- * @param string $id
- * @return void
- * @access private
- */
- function __saveMulti($joined, $id) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- foreach ($joined as $x => $y) {
- foreach ($y as $assoc => $value) {
- if (isset($this->hasAndBelongsToMany[$assoc])) {
- $joinTable[$assoc] = $this->hasAndBelongsToMany[$assoc]['joinTable'];
- $mainKey[$assoc] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
- $keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
- $keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
- $fields[$assoc] = join(',', $keys);
- unset($keys);
-
- foreach ($value as $update) {
- if (!empty($update)) {
- $values[] = $db->value($id, $this->getColumnType($this->primaryKey));
- $values[] = $db->value($update);
- $values = join(',', $values);
- $newValues[] = "({$values})";
- unset ($values);
- }
- }
-
- if (!empty($newValues)) {
- $newValue[$assoc] = $newValues;
- unset($newValues);
- } else {
- $newValue[$assoc] = array();
- }
- }
- }
- }
-
- if (isset($joinTable)) {
- $total = count($joinTable);
-
- if (is_array($newValue)) {
- foreach ($newValue as $loopAssoc => $val) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $table = $db->name($db->fullTableName($joinTable[$loopAssoc]));
- $db->query("DELETE FROM {$table} WHERE {$mainKey[$loopAssoc]} = '{$id}'");
-
- if (!empty($newValue[$loopAssoc])) {
- $secondCount = count($newValue[$loopAssoc]);
- for ($x = 0; $x < $secondCount; $x++) {
- $db->query("INSERT INTO {$table} ({$fields[$loopAssoc]}) VALUES {$newValue[$loopAssoc][$x]}");
- }
- }
- }
- }
- }
- }
-/**
- * Synonym for del().
- *
- * @param mixed $id
- * @see function del
- * @return boolean True on success
- * @access public
- */
- function remove($id = null, $cascade = true) {
- return $this->del($id, $cascade);
- }
-/**
- * Removes record for given id. If no id is given, the current id is used. Returns true on success.
- *
- * @param mixed $id Id of record to delete
- * @return boolean True on success
- * @access public
- */
- function del($id = null, $cascade = true) {
- if ($id) {
- $this->id = $id;
- }
- $id = $this->id;
-
- if ($this->exists() && $this->beforeDelete()) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- $this->_deleteMulti($id);
- $this->_deleteHasMany($id, $cascade);
- $this->_deleteHasOne($id, $cascade);
- $this->id = $id;
-
- if ($db->delete($this)) {
- $this->afterDelete();
- $this->_clearCache();
- $this->id = false;
- return true;
- }
- }
-
- return false;
- }
-/**
- * Alias for del()
- *
- * @param mixed $id Id of record to delete
- * @return boolean True on success
- * @access public
- */
- function delete($id = null, $cascade = true) {
- return $this->del($id, $cascade);
- }
-/**
- * Cascades model deletes to hasMany relationships.
- *
- * @param string $id
- * @return null
- * @access protected
- */
- function _deleteHasMany($id, $cascade) {
- if (!empty($this->__backAssociation)) {
- $savedAssociatons = $this->__backAssociation;
- $this->__backAssociation = array();
- }
- foreach ($this->hasMany as $assoc => $data) {
- if ($data['dependent'] === true && $cascade === true) {
- $model =& $this->{$data['className']};
- $field = $model->escapeField($data['foreignKey']);
- $model->recursive = 0;
- $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
-
- if ($records != false) {
- foreach ($records as $record) {
- $model->del($record[$data['className']][$model->primaryKey]);
- }
- }
- }
- }
- if (isset($savedAssociatons)) {
- $this->__backAssociation = $savedAssociatons;
- }
- }
-/**
- * Cascades model deletes to hasOne relationships.
- *
- * @param string $id
- * @return null
- * @access protected
- */
- function _deleteHasOne($id, $cascade) {
- if (!empty($this->__backAssociation)) {
- $savedAssociatons = $this->__backAssociation;
- $this->__backAssociation = array();
- }
- foreach ($this->hasOne as $assoc => $data) {
- if ($data['dependent'] === true && $cascade === true) {
- $model =& $this->{$data['className']};
- $field = $model->escapeField($data['foreignKey']);
- $model->recursive = 0;
- $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
-
- if ($records != false) {
- foreach ($records as $record) {
- $model->del($record[$data['className']][$model->primaryKey]);
- }
- }
- }
- }
- if (isset($savedAssociatons)) {
- $this->__backAssociation = $savedAssociatons;
- }
- }
-/**
- * Cascades model deletes to HABTM join keys.
- *
- * @param string $id
- * @return null
- * @access protected
- */
- function _deleteMulti($id) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- foreach ($this->hasAndBelongsToMany as $assoc => $data) {
- $db->execute("DELETE FROM " . $db->name($db->fullTableName($data['joinTable'])) . " WHERE " . $db->name($data['foreignKey']) . " = '{$id}'");
- }
- }
-/**
- * Returns true if a record with set id exists.
- *
- * @return boolean True if such a record exists
- * @access public
- */
- function exists() {
- if ($this->id) {
- $id = $this->id;
-
- if (is_array($id)) {
- $id = $id[0];
- }
-
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->hasAny($this, array($this->primaryKey => $id));
- }
- return false;
- }
-/**
- * Returns true if a record that meets given conditions exists
- *
- * @param array $conditions SQL conditions array
- * @return boolean True if such a record exists
- * @access public
- */
- function hasAny($conditions = null) {
- return ($this->findCount($conditions) != false);
- }
-/**
- * Return a single row as a resultset array.
- * By using the $recursive parameter, the call can access further "levels of association" than
- * the ones this model is directly associated to.
- *
- * @param array $conditions SQL conditions array
- * @param mixed $fields Either a single string of a field name, or an array of field names
- * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
- * @param int $recursive The number of levels deep to fetch associated records
- * @return array Array of records
- * @access public
- */
- function find($conditions = null, $fields = null, $order = null, $recursive = null) {
- $data = $this->findAll($conditions, $fields, $order, 1, null, $recursive);
-
- if (empty($data[0])) {
- return false;
- }
-
- return $data[0];
- }
-/**
- * Returns a resultset array with specified fields from database matching given conditions.
- * By using the $recursive parameter, the call can access further "levels of association" than
- * the ones this model is directly associated to.
- *
- * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
- * @param mixed $fields Either a single string of a field name, or an array of field names
- * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
- * @param int $limit SQL LIMIT clause, for calculating items per page.
- * @param int $page Page number, for accessing paged data
- * @param int $recursive The number of levels deep to fetch associated records
- * @return array Array of records
- * @access public
- */
- function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
-
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $this->id = $this->getID();
- $offset = null;
-
- if ($page > 1 && $limit != null) {
- $offset = ($page - 1) * $limit;
- }
-
- if ($order == null) {
- $order = array();
- } else {
- $order = array($order);
- }
-
- $queryData = array('conditions' => $conditions,
- 'fields' => $fields,
- 'joins' => array(),
- 'limit' => $limit,
- 'offset' => $offset,
- 'order' => $order
- );
-
- $ret = $this->beforeFind($queryData);
- if (is_array($ret)) {
- $queryData = $ret;
- } elseif ($ret === false) {
- return null;
- }
-
- $return = $this->afterFind($db->read($this, $queryData, $recursive));
-
- if (!empty($this->__backAssociation)) {
- $this->__resetAssociations();
- }
-
- return $return;
- }
-/**
- * Method is called only when bindTo<ModelName>() is used.
- * This resets the association arrays for the model back
- * to the original as set in the model.
- *
- * @return boolean
- * @access private
- */
- function __resetAssociations() {
- foreach ($this->__associations as $type) {
- if (isset($this->__backAssociation[$type])) {
- $this->{$type} = $this->__backAssociation[$type];
- }
- }
-
- $this->__backAssociation = array();
- return true;
- }
-/**
- * Runs a direct query against the bound DataSource, and returns the result.
- *
- * @param string $data Query data
- * @return array
- * @access public
- */
- function execute($data) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- $data = $db->fetchAll($data, $this->cacheQueries);
-
- foreach ($data as $key => $value) {
- foreach ($this->tableToModel as $key1 => $value1) {
- if (isset($data[$key][$key1])) {
- $newData[$key][$value1] = $data[$key][$key1];
- }
- }
- }
-
- if (!empty($newData)) {
- return $newData;
- }
-
- return $data;
- }
-/**
- * Returns number of rows matching given SQL condition.
- *
- * @param array $conditions SQL conditions array for findAll
- * @param int $recursize The number of levels deep to fetch associated records
- * @return int Number of matching rows
- * @see Model::findAll
- * @access public
- */
- function findCount($conditions = null, $recursive = 0) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- list($data) = $this->findAll($conditions, 'COUNT(*) AS ' . $db->name('count'), null, null, 1, $recursive);
-
- if (isset($data[0]['count'])) {
- return $data[0]['count'];
- } elseif (isset($data[$this->alias]['count'])) {
- return $data[$this->alias]['count'];
- }
-
- return false;
- }
-/**
- * Special findAll variation for tables joined to themselves.
- * The table needs the fields id and parent_id to work.
- *
- * @param array $conditions Conditions for the findAll() call
- * @param array $fields Fields for the findAll() call
- * @param string $sort SQL ORDER BY statement
- * @return array
- * @access public
- * @todo Perhaps create a Component with this logic
- */
- function findAllThreaded($conditions = null, $fields = null, $sort = null) {
- return $this->__doThread(Model::findAll($conditions, $fields, $sort), null);
- }
-/**
- * Private, recursive helper method for findAllThreaded.
- *
- * @param array $data
- * @param string $root NULL or id for root node of operation
- * @return array
- * @access private
- * @see findAllThreaded
- */
- function __doThread($data, $root) {
- $out = array();
- $sizeOf = sizeof($data);
-
- for ($ii = 0; $ii < $sizeOf; $ii++) {
- if (($data[$ii][$this->alias]['parent_id'] == $root) || (($root === null) && ($data[$ii][$this->alias]['parent_id'] == '0'))) {
- $tmp = $data[$ii];
-
- if (isset($data[$ii][$this->alias][$this->primaryKey])) {
- $tmp['children'] = $this->__doThread($data, $data[$ii][$this->alias][$this->primaryKey]);
- } else {
- $tmp['children'] = null;
- }
-
- $out[] = $tmp;
- }
- }
-
- return $out;
- }
-/**
- * Returns an array with keys "prev" and "next" that holds the id's of neighbouring data,
- * which is useful when creating paged lists.
- *
- * @param string $conditions SQL conditions for matching rows
- * @param string $field Field name (parameter for findAll)
- * @param unknown_type $value
- * @return array Array with keys "prev" and "next" that holds the id's
- * @access public
- */
- function findNeighbours($conditions = null, $field, $value) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- if (!is_null($conditions)) {
- $conditions = $conditions . ' AND ';
- }
-
- @list($prev) = Model::findAll($conditions . $field . ' < ' . $db->value($value), $field, $field . ' DESC', 1, null, 0);
- @list($next) = Model::findAll($conditions . $field . ' > ' . $db->value($value), $field, $field . ' ASC', 1, null, 0);
-
- if (!isset($prev)) {
- $prev = null;
- }
-
- if (!isset($next)) {
- $next = null;
- }
-
- return array('prev' => $prev, 'next' => $next);
- }
-/**
- * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method.
- *
- * @param string $sql SQL statement
- * @return array Resultset
- * @access public
- */
- function query() {
- $params = func_get_args();
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return call_user_func_array(array(&$db, 'query'), $params);
- }
-/**
- * Returns true if all fields pass validation, otherwise false.
- *
- * @param array $data POST data
- * @return boolean True if there are no errors
- * @access public
- */
- function validates($data = array()) {
- $errors = $this->invalidFields($data);
- return count($errors) == 0;
- }
-/**
- * Returns an array of invalid fields.
- *
- * @param array $data
- * @return array Array of invalid fields or boolean case any error occurs
- * @access public
- */
- function invalidFields($data = array()) {
- if (empty($data)) {
- $data = $this->data;
- }
-
- if (!$this->beforeValidate()) {
- return $this->validationErrors;
- }
-
- if (!isset($this->validate)) {
- return $this->validationErrors;
- }
-
- if (!empty($data)) {
- $data = $data;
- } elseif (isset($this->data)) {
- $data = $this->data;
- }
-
- if (isset($data[$this->alias])) {
- $data = $data[$this->alias];
- }
-
- foreach ($this->validate as $field_name => $validator) {
- if (isset($data[$field_name]) && !preg_match($validator, $data[$field_name])) {
- $this->invalidate($field_name);
- }
- }
- return $this->validationErrors;
- }
-/**
- * Sets a field as invalid
- *
- * @param string $field The name of the field to invalidate
- * @return void
- * @access public
- */
- function invalidate($field) {
- if (!is_array($this->validationErrors)) {
- $this->validationErrors = array();
- }
- $this->validationErrors[$field] = 1;
- }
-/**
- * Returns true if given field name is a foreign key in this Model.
- *
- * @param string $field Returns true if the input string ends in "_id"
- * @return True if the field is a foreign key listed in the belongsTo array.
- * @access public
- */
- function isForeignKey($field) {
- $foreignKeys = array();
-
- if (count($this->belongsTo)) {
- foreach ($this->belongsTo as $assoc => $data) {
- $foreignKeys[] = $data['foreignKey'];
- }
- }
- return (bool)(in_array($field, $foreignKeys));
- }
-/**
- * Gets the display field for this model
- *
- * @return string The name of the display field for this Model (i.e. 'name', 'title').
- * @access public
- */
- function getDisplayField() {
- return $this->displayField;
- }
-/**
- * Returns a resultset array with specified fields from database matching given conditions.
- * Method can be used to generate option lists for SELECT elements.
- *
- * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
- * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
- * @param int $limit SQL LIMIT clause, for calculating items per page
- * @param string $keyPath A string path to the key, i.e. "{n}.Post.id"
- * @param string $valuePath A string path to the value, i.e. "{n}.Post.title"
- * @return array An associative array of records, where the id is the key, and the display field is the value
- * @access public
- */
- function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) {
- if ($keyPath == null && $valuePath == null && $this->hasField($this->displayField)) {
- $fields = array($this->primaryKey, $this->displayField);
- } else {
- $fields = null;
- }
- $recursive = $this->recursive;
-
- if ($recursive >= 1) {
- $this->recursive = -1;
- }
- $result = $this->findAll($conditions, $fields, $order, $limit);
- $this->recursive = $recursive;
-
- if (!$result) {
- return false;
- }
-
- if ($keyPath == null) {
- $keyPath = '{n}.' . $this->alias . '.' . $this->primaryKey;
- }
-
- if ($valuePath == null) {
- $valuePath = '{n}.' . $this->alias . '.' . $this->displayField;
- }
-
- $keys = Set::extract($result, $keyPath);
- $vals = Set::extract($result, $valuePath);
-
- if (!empty($keys) && !empty($vals)) {
- $return = array_combine($keys, $vals);
- return $return;
- }
- return null;
- }
-/**
- * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules.
- *
- * @param unknown_type $field
- * @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`).
- * @access public
- */
- function escapeField($field) {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->name($this->alias) . '.' . $db->name($field);
- }
-/**
- * Returns the current record's ID
- *
- * @param unknown_type $list
- * @return mixed The ID of the current record
- * @access public
- */
- function getID($list = 0) {
- if (!is_array($this->id)) {
- return $this->id;
- }
-
- if (count($this->id) == 0) {
- return false;
- }
-
- if (isset($this->id[$list])) {
- return $this->id[$list];
- }
-
- foreach ($this->id as $id) {
- return $id;
- }
-
- return false;
- }
-/**
- * Returns the ID of the last record this Model inserted
- *
- * @return mixed
- * @access public
- */
- function getLastInsertID() {
- return $this->getInsertID();
- }
-/**
- * Returns the ID of the last record this Model inserted
- *
- * @return mixed
- * @access public
- */
- function getInsertID() {
- return $this->__insertID;
- }
-/**
- * Sets the ID of the last record this Model inserted
- *
- * @param mixed $id
- * @return void
- */
- function setInsertID($id) {
- $this->__insertID = $id;
- }
-/**
- * Returns the number of rows returned from the last query
- *
- * @return int
- * @access public
- */
- function getNumRows() {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->lastNumRows();
- }
-/**
- * Returns the number of rows affected by the last query
- *
- * @return int
- * @access public
- */
- function getAffectedRows() {
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
- return $db->lastAffected();
- }
-/**
- * Sets the DataSource to which this model is bound
- *
- * @param string $dataSource The name of the DataSource, as defined in Connections.php
- * @return boolean True on success
- * @access public
- */
- function setDataSource($dataSource = null) {
- if ($dataSource != null) {
- $this->useDbConfig = $dataSource;
- }
- $db =& ConnectionManager::getDataSource($this->useDbConfig);
-
- if (!empty($db->config['prefix']) && $this->tablePrefix === null) {
- $this->tablePrefix = $db->config['prefix'];
- }
-
- if (empty($db) || $db == null || !is_object($db)) {
- return $this->cakeError('missingConnection', array(array('className' => $this->alias)));
- }
- }
-/**
- * Before find callback
- *
- * @param array $queryData Data used to execute this query, i.e. conditions, order, etc.
- * @return boolean True if the operation should continue, false if it should abort
- * @access public
- */
- function beforeFind(&$queryData) {
- return true;
- }
-/**
- * After find callback. Can be used to modify any results returned by find and findAll.
- *
- * @param mixed $results The results of the find operation
- * @return mixed Result of the find operation
- * @access public
- */
- function afterFind($results) {
- return $results;
- }
-/**
- * Before save callback
- *
- * @return boolean True if the operation should continue, false if it should abort
- * @access public
- */
- function beforeSave() {
- return true;
- }
-/**
- * After save callback
- *
- * @return boolean
- * @access public
- */
- function afterSave() {
- return true;
- }
-/**
- * Before delete callback
- *
- * @return boolean True if the operation should continue, false if it should abort
- * @access public
- */
- function beforeDelete() {
- return true;
- }
-/**
- * After delete callback
- *
- * @return boolean
- * @access public
- */
- function afterDelete() {
- return true;
- }
-/**
- * Before validate callback
- *
- * @return boolean
- * @access public
- */
- function beforeValidate() {
- return true;
- }
-/**
- * DataSource error callback
- *
- * @return void
- */
- function onError() {
- }
-/**
- * Private method. Clears cache for this model
- *
- * @param string $type If null this deletes cached views if CACHE_CHECK is true
- * Will be used to allow deleting query cache also
- * @return boolean true on delete
- * @access protected
- */
- function _clearCache($type = null) {
- if ($type === null) {
- if (defined('CACHE_CHECK') && CACHE_CHECK === true) {
- $assoc[] = strtolower(Inflector::pluralize($this->alias));
-
- foreach ($this->__associations as $key => $association) {
- foreach ($this->$association as $key => $className) {
- $check = strtolower(Inflector::pluralize($className['className']));
-
- if (!in_array($check, $assoc)) {
- $assoc[] = strtolower(Inflector::pluralize($className['className']));
- }
- }
- }
- clearCache($assoc);
- return true;
- }
- } else {
- //Will use for query cache deleting
- }
- }
-/**
- * Called when serializing a model
- *
- * @return array
- * @access public
- */
- function __sleep() {
- $return = array_keys(get_object_vars($this));
- return $return;
- }
-/**
- * Called when unserializing a model
- *
- * @return void
- * @access public
- */
- function __wakeup() {
- }
-}
-?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_array.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_array.php
deleted file mode 100644
index fd04a6b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_array.php
+++ /dev/null
@@ -1,318 +0,0 @@
-<?php
-/* SVN FILE: $Id: neat_array.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Library of array functions for Cake.
- *
- * Internal use only.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Class used for internal manipulation of multi-dimensional arrays (arrays of arrays).
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class NeatArray{
-/**
- * Value of NeatArray.
- *
- * @var array
- * @access public
- */
- var $value;
-/**
- * Constructor. Defaults to an empty array.
- *
- * @param array $value
- * @access public
- * @uses NeatArray::value
- */
- function NeatArray($value = array()) {
- $this->value = $value;
- }
-/**
- * Finds and returns records with $fieldName equal to $value from this NeatArray.
- *
- * @param string $fieldName
- * @param string $value
- * @return mixed
- * @access public
- * @uses NeatArray::value
- */
- function findIn($fieldName, $value) {
- if (!is_array($this->value)) {
- return false;
- }
- $out = false;
- $keys = array_keys($this->value);
- $count = sizeof($keys);
-
- for ($i = 0; $i < $count; $i++) {
- if (isset($this->value[$keys[$i]][$fieldName]) && ($this->value[$keys[$i]][$fieldName] == $value))
- {
- $out[$keys[$i]] = $this->value[$keys[$i]];
- }
- }
- return $out;
- }
-/**
- * Checks if $this->value is an array, and removes all empty elements.
- *
- * @access public
- * @uses NeatArray::value
- */
- function cleanup() {
- $out = is_array($this->value) ? array(): null;
- foreach ($this->value as $k => $v) {
- if ($v == "0") {
- $out[$k] = $v;
- } elseif ($v) {
- $out[$k] = $v;
- }
- }
- $this->value=$out;
- }
-/**
- * Adds elements from given array to itself.
- *
- * @param string $value
- * @return bool
- * @access public
- * @uses NeatArray::value
- */
- function add($value) {
- return ($this->value = $this->plus($value)) ? true : false;
- }
-/**
- * Returns itself merged with given array.
- *
- * @param array $value Array to add to NeatArray.
- * @return array
- * @access public
- * @uses NeatArray::value
- */
- function plus($value) {
- $merge = array_merge($this->value, (is_array($value) ? $value : array($value)));
- return $merge;
- }
-/**
- * Counts repeating strings and returns an array of totals.
- *
- * @param int $sortedBy A value of 1 sorts by values, a value of 2 sorts by keys. Defaults to null (no sorting).
- * @return array
- * @access public
- * @uses NeatArray::value
- */
- function totals($sortedBy = 1, $reverse = true) {
- $out = array();
- foreach ($this->value as $val) {
- isset($out[$val]) ? $out[$val]++ : $out[$val] = 1;
- }
-
- if ($sortedBy == 1) {
- $reverse ? arsort($out, SORT_NUMERIC) : asort($out, SORT_NUMERIC);
- }
-
- if ($sortedBy == 2) {
- $reverse ? krsort($out, SORT_STRING) : ksort($out, SORT_STRING);
- }
- return $out;
- }
-/**
- * Performs an array_filter() on the contents of this NeatArray.
- *
- * @param string $with Name of callback function to perform on each element of this NeatArray.
- * @return array
- */
- function filter($with) {
- return $this->value = array_filter($this->value, $with);
- }
-/**
- * Passes each of its values through a specified function or method.
- * Think of PHP's {@link http://php.net/array_walk array_walk()}.
- *
- * @param string $with Name of callback function
- * @return array Returns value of NeatArray::value
- * @access public
- * @uses NeatArray::value
- */
- function walk($with) {
- array_walk($this->value, $with);
- return $this->value;
- }
-/**
- * Apply $template to all elements of this NeatArray, and return the array itself.
- *
- * @param string $template {@link http://php.net/sprintf sprintf()}-compatible string to be applied to all values of this NeatArray.
- * @return array
- */
- function sprintf($template) {
- $count = count($this->value);
- for ($ii = 0; $ii < $count; $ii++) {
- $this->value[$ii] = sprintf($template, $this->value[$ii]);
- }
- return $this->value;
- }
-/**
- * Extracts a value from all array items.
- *
- * @return array
- * @access public
- * @uses NeatArray::value
- */
- function extract($name) {
- $out = array();
- foreach ($this->value as $val) {
- if (isset($val[$name]))
- $out[]=$val[$name];
- }
- return $out;
- }
-/**
- * Returns a list of unique elements.
- *
- * @return array
- */
- function unique() {
- $unique = array_unique($this->value);
- return $unique;
- }
-/**
- * Removes duplicate elements from the value and returns it.
- *
- * @return array
- */
- function makeUnique() {
- return $this->value = array_unique($this->value);
- }
-/**
- * Joins an array with myself using a key (like a join between database tables).
- *
- * Example:
- *
- * $alice = array('id'=>'1', 'name'=>'Alice');
- * $bob = array('id'=>'2', 'name'=>'Bob');
- *
- * $users = new NeatArray(array($alice, $bob));
- *
- * $born = array
- * (
- * array('user_id'=>'1', 'born'=>'1980'),
- * array('user_id'=>'2', 'born'=>'1976')
- * );
- *
- * $users->joinWith($born, 'id', 'user_id');
- *
- * Result:
- *
- * $users->value == array
- * (
- * array('id'=>'1', 'name'=>'Alice', 'born'=>'1980'),
- * array('id'=>'2', 'name'=>'Bob', 'born'=>'1976')
- * );
- *
- * @param array $his The array to join with myself.
- * @param string $onMine Key to use on myself.
- * @param string $onHis Key to use on him.
- * @return array
- */
- function joinWith($his, $onMine, $onHis = null) {
- if (empty($onHis)) {
- $onHis = $onMine;
- }
- $his = new NeatArray($his);
- $out = array();
-
- foreach ($this->value as $key => $val) {
- if ($fromHis = $his->findIn($onHis, $val[$onMine])) {
- list($fromHis) = array_values($fromHis);
- $out[$key] = array_merge($val, $fromHis);
- } else {
- $out[$key] = $val;
- }
- }
- return $this->value = $out;
- }
-/**
- * Enter description here...
- * @todo Explain this function. almost looks like it creates a tree
- *
- * @param string $root
- * @param string $idKey
- * @param string $parentIdKey
- * @param string $childrenKey
- * @return array
- */
- function threaded($root = null, $idKey = 'id', $parentIdKey = 'parent_id', $childrenKey = 'children') {
- $out = array();
- $sizeof = sizeof($this->value);
-
- for ($ii = 0; $ii < $sizeof; $ii++) {
- if ($this->value[$ii][$parentIdKey] == $root) {
- $tmp = $this->value[$ii];
- $tmp[$childrenKey]=isset($this->value[$ii][$idKey])
- ? $this->threaded($this->value[$ii][$idKey], $idKey, $parentIdKey, $childrenKey) : null;
- $out[] = $tmp;
- }
- }
- return $out;
- }
-/**
- * Array multi search
- *
- * @param string $search_value
- * @param array $the_array
- * @return array
- * @link http://php.net/array_search#47116
- */
- function multi_search($search_value, $the_array = null) {
- if ($the_array == null) {
- $the_array = $this->value;
- }
-
- if (is_array($the_array)) {
- foreach ($the_array as $key => $value) {
- $result = $this->multi_search($search_value, $value);
-
- if (is_array($result)) {
- $return = $result;
- array_unshift($return, $key);
- return $return;
- } elseif ($result == true) {
- $return[]=$key;
- return $return;
- }
- }
- return false;
- } else {
- if ($search_value == $the_array) {
- return true;
- } else {
- return false;
- }
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_string.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_string.php
deleted file mode 100644
index 620e60b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/neat_string.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/* SVN FILE: $Id: neat_string.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * String handling methods.
- *
- * Random passwords, splitting strings into arrays, removing Cyrillic characters, stripping whitespace.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * String handling methods.
- *
- * Random passwords, splitting strings into arrays, removing Cyrillic characters, stripping whitespace.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class NeatString{
-/**
- * Returns an array with each of the non-empty characters in $string as an element.
- *
- * @param string $string
- * @return array
- */
- function toArray($string) {
- $split = preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY);
- return $split;
- }
-/**
- * Returns string with Cyrillic characters translated to Roman ones.
- *
- * @param string $string
- * @return string
- */
- function toRoman($string) {
- $pl = array('ą','ć','ę','ł','ń','ó','ś','ź','ż','Ą','Ć','Ę','�?','Ń','Ó','Ś','Ź','Ż');
- $ro = array('a','c','e','l','n','o','s','z','z','A','C','E','L','N','O','S','Z','Z');
- $replace = str_replace($pl, $ro, $string);
- return $replace;
- }
-/**
- * Returns string as lowercase with whitespace removed.
- *
- * @param string $string
- * @return string
- */
- function toCompressed($string) {
- $whitespace = array("\n", " ", "\r", "\0", "\x0B", " ");
- $replace = strtolower(str_replace($whitespace, '', $string));
- return $replace;
- }
-/**
- * Returns a random password.
- *
- * @param integer $length Length of generated password
- * @param string $available_chars List of characters to use in password
- * @return string Generated password
- */
- function randomPassword($length, $available_chars = 'ABDEFHKMNPRTWXYABDEFHKMNPRTWXY23456789') {
- $chars = preg_split('//', $available_chars, -1, PREG_SPLIT_NO_EMPTY);
- $char_count = count($chars);
- $out = '';
- for ($ii = 0; $ii < $length; $ii++) {
- $out .= $chars[rand(1, $char_count)-1];
- }
- return $out;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/object.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/object.php
deleted file mode 100644
index a23afc9..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/object.php
+++ /dev/null
@@ -1,259 +0,0 @@
-<?php
-/* SVN FILE: $Id: object.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Object class, allowing __construct and __destruct in PHP4.
- *
- * Also includes methods for logging and the special method RequestAction,
- * to call other Controllers' Actions from anywhere.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Object class, allowing __construct and __destruct in PHP4.
- *
- * Also includes methods for logging and the special method RequestAction,
- * to call other Controllers' Actions from anywhere.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Object{
-/**
- * Log object
- *
- * @var object
- * @access protected
- */
- var $_log = null;
-/**
- * A hack to support __construct() on PHP 4
- * Hint: descendant classes have no PHP4 class_name() constructors,
- * so this constructor gets called first and calls the top-layer __construct()
- * which (if present) should call parent::__construct()
- *
- * @return Object
- * @access public
- */
- function Object() {
- $args = func_get_args();
- if (method_exists($this, '__destruct')) {
- register_shutdown_function (array(&$this, '__destruct'));
- }
- call_user_func_array(array(&$this, '__construct'), $args);
- }
-/**
- * Class constructor, overridden in descendant classes.
- *
- * @abstract
- * @access public
- */
- function __construct() {
- }
-
-/**
- * Object-to-string conversion.
- * Each class can override this method as necessary.
- *
- * @return string The name of this class
- * @access public
- */
- function toString() {
- $class = get_class($this);
- return $class;
- }
-/**
- * Calls a controller's method from any location. Allows for
- * controllers to communicate with each other.
- *
- * @param string $url URL in the form of Cake URL ("/controller/method/parameter")
- * @param array $extra If array includes the key "return" it sets the AutoRender to true.
- * @return boolean Success
- * @access public
- */
- function requestAction($url, $extra = array()) {
- if (!empty($url)) {
- $dispatcher =& new Dispatcher();
- if (isset($this->plugin)) {
- $extra['plugin'] = $this->plugin;
- }
- if (in_array('return', $extra, true)) {
- $extra['return'] = 0;
- $extra['bare'] = 1;
- $extra['requested'] = 1;
- ob_start();
- $out = $dispatcher->dispatch($url, $extra);
- $out = ob_get_clean();
- return $out;
- } else {
- $extra['return'] = 1;
- $extra['bare'] = 1;
- $extra['requested'] = 1;
- return $dispatcher->dispatch($url, $extra);
- }
- } else {
- return false;
- }
- }
-/**
- * API for logging events.
- *
- * @param string $msg Log message
- * @param int $type Error type constant. Defined in app/config/core.php.
- * @access
- */
- function log($msg, $type = LOG_ERROR) {
- if (!class_exists('CakeLog')) {
- uses('cake_log');
- }
-
- if (is_null($this->_log)) {
- $this->_log = new CakeLog();
- }
-
- if (!is_string($msg)) {
- ob_start();
- print_r ($msg);
- $msg=ob_get_contents();
- ob_end_clean();
- }
-
- switch($type) {
- case LOG_DEBUG:
- return $this->_log->write('debug', $msg);
- break;
- default:
- return $this->_log->write('error', $msg);
- break;
- }
- }
-/**
- * Used to report user friendly errors.
- * If there is a file app/error.php this file will be loaded
- * error.php is the AppError class it should extend ErrorHandler class.
- *
- * @param string $method Method to be called in the error class (AppError or ErrorHandler classes)
- * @param array $messages Message that is to be displayed by the error class
- * @return error message
- * @access public
- */
- function cakeError($method, $messages) {
- if (!class_exists('ErrorHandler')) {
- uses('error');
- if (file_exists(APP . 'error.php')) {
- include_once (APP . 'error.php');
- }
- }
-
- if (class_exists('AppError')) {
- $error = new AppError($method, $messages);
- } else {
- $error = new ErrorHandler($method, $messages);
- }
- return $error;
- }
-/**
- * Checks for a persistent class file, if found file is opened and true returned
- * If file is not found a file is created and false returned
- *
- * There are many uses for this method, see manual for examples also art of
- * the cache system
- *
- * @param string $name name of class to persist
- * @param boolean $return
- * @param object $object
- * @param string $type
- * @return boolean
- * @todo add examples to manual
- * @access protected
- */
- function _persist($name, $return = null, &$object, $type = null) {
- $file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
- if ($return === null) {
- if (!file_exists($file)) {
- return false;
- } else {
- return true;
- }
- }
-
- if (!file_exists($file)) {
- $this->_savePersistent($name, $object);
- return false;
- } else {
- $this->__openPersistent($name, $type);
- return true;
- }
- }
-/**
- * You should choose a unique name for the persistent file
- *
- * There are many uses for this method, see manual for examples also part of
- * the cache system
- *
- * @param string $name name used for object to cache
- * @param object $object the object to persist
- * @return true on save, throws error if file can not be created
- * @access protected
- */
- function _savePersistent($name, &$object) {
- $file = 'persistent' . DS . strtolower($name) . '.php';
- $objectArray = array(&$object);
- $data = str_replace('\\', '\\\\', serialize($objectArray));
- $data = '<?php $' . $name . ' = \'' . str_replace('\'', '\\\'', $data) . '\' ?>';
- cache($file, $data, '+1 day');
- }
-/**
- * Open the persistent class file for reading
- * Used by Object::_persist(), part of the cache
- * system
- *
- * @param string $name Name of the persistant file
- * @param string $type
- * @access private
- */
- function __openPersistent($name, $type = null) {
- $file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
- include($file);
-
- switch($type) {
- case 'registry':
- $vars = unserialize(${$name});
- foreach ($vars['0'] as $key => $value) {
- loadModel(Inflector::classify($key));
- }
- unset($vars);
- $vars = unserialize(${$name});
- foreach ($vars['0'] as $key => $value) {
- ClassRegistry::addObject($key, $value);
- unset ($value);
- }
- unset($vars);
- break;
- default:
- $vars = unserialize(${$name});
- $this->{$name} = $vars['0'];
- unset($vars);
- break;
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/router.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/router.php
deleted file mode 100644
index bf32954..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/router.php
+++ /dev/null
@@ -1,230 +0,0 @@
-<?php
-/* SVN FILE: $Id: router.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Parses the request URL into controller, action, and parameters.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
- if (!class_exists('Object')) {
- uses ('object');
- }
-/**
- * Parses the request URL into controller, action, and parameters.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Router extends Object {
-/**
- * Array of routes
- *
- * @var array
- * @access public
- */
- var $routes = array();
-/**
- * CAKE_ADMIN route
- *
- * @var array
- * @access private
- */
- var $__admin = null;
-/**
- * Constructor
- *
- * @access public
- */
- function __construct() {
- if (defined('CAKE_ADMIN')) {
- $admin = CAKE_ADMIN;
- if (!empty($admin)) {
- $this->__admin = array('/:' . $admin . '/:controller/:action/* (default)',
- '/^(?:\/(?:(' . $admin . ')(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:[\\/\\?](.*))?)?)?))[\/]*$/',
- array($admin, 'controller', 'action'), array());
- }
- }
- }
-/**
- * Returns this object's routes array. Returns false if there are no routes available.
- *
- * @param string $route An empty string, or a route string "/"
- * @param array $default NULL or an array describing the default route
- * @return array Array of routes
- */
- function connect($route, $default = null) {
- $parsed = $names = array();
-
- if (defined('CAKE_ADMIN') && $default == null) {
- if ($route == CAKE_ADMIN) {
- $this->routes[] = $this->__admin;
- $this->__admin = null;
- }
- }
- $r = null;
- if (($route == '') || ($route == '/')) {
- $regexp='/^[\/]*$/';
- $this->routes[] = array($route, $regexp, array(), $default);
- } else {
- $elements = array();
-
- foreach (explode('/', $route)as $element) {
- if (trim($element))
- $elements[] = $element;
- }
-
- if (!count($elements)) {
- return false;
- }
-
- foreach ($elements as $element) {
-
- if (preg_match('/^:(.+)$/', $element, $r)) {
- $parsed[]='(?:\/([^\/]+))?';
- $names[] =$r[1];
- } elseif (preg_match('/^\*$/', $element, $r)) {
- $parsed[] = '(?:\/(.*))?';
- } else {
- $parsed[] = '/' . $element;
- }
- }
-
- $regexp='#^' . join('', $parsed) . '[\/]*$#';
- $this->routes[] = array($route, $regexp, $names, $default);
- }
- return $this->routes;
- }
-/**
- * Parses given URL and returns an array of controllers, action and parameters
- * taken from that URL.
- *
- * @param string $url URL to be parsed
- * @return array
- * @access public
- */
- function parse($url) {
- if (ini_get('magic_quotes_gpc') == 1) {
- $url = stripslashes_deep($url);
- }
-
- if ($url && ('/' != $url[0])) {
- if (!defined('SERVER_IIS')) {
- $url = '/' . $url;
- }
- }
- $out = array('pass'=>array());
- $r = null;
- $default_route = array('/:controller/:action/* (default)',
- '/^(?:\/(?:([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:[\\/\\?](.*))?)?))[\\/]*$/',
- array('controller', 'action'), array());
-
- if (defined('CAKE_ADMIN') && $this->__admin != null) {
- $this->routes[]=$this->__admin;
- $this->__admin =null;
- }
- $this->connect('/bare/:controller/:action/*', array('bare' => '1'));
- $this->connect('/ajax/:controller/:action/*', array('bare' => '1'));
-
- if (defined('WEBSERVICES') && WEBSERVICES == 'on') {
- $this->connect('/rest/:controller/:action/*', array('webservices' => 'Rest'));
- $this->connect('/rss/:controller/:action/*', array('webservices' => 'Rss'));
- $this->connect('/soap/:controller/:action/*', array('webservices' => 'Soap'));
- $this->connect('/xml/:controller/:action/*', array('webservices' => 'Xml'));
- $this->connect('/xmlrpc/:controller/:action/*', array('webservices' => 'XmlRpc'));
- }
- $this->routes[] = $default_route;
-
- if (strpos($url, '?') !== false) {
- $url = substr($url, 0, strpos($url, '?'));
- }
-
- foreach ($this->routes as $route) {
- list($route, $regexp, $names, $defaults) = $route;
-
- if (preg_match($regexp, $url, $r)) {
- // remove the first element, which is the url
- array_shift ($r);
- // hack, pre-fill the default route names
- foreach ($names as $name) {
- $out[$name] = null;
- }
- $ii=0;
-
- if (is_array($defaults)) {
- foreach ($defaults as $name => $value) {
- if (preg_match('#[a-zA-Z_\-]#i', $name)) {
- $out[$name] = $this->stripEscape($value);
- } else {
- $out['pass'][] = $this->stripEscape($value);
- }
- }
- }
-
- foreach ($r as $found) {
- // if $found is a named url element (i.e. ':action')
- if (isset($names[$ii])) {
- $out[$names[$ii]] = $found;
- } else {
- // unnamed elements go in as 'pass'
- $found = explode('/', $found);
- $pass = array();
- foreach ($found as $key => $value) {
- if ($value == "0") {
- $pass[$key] = $this->stripEscape($value);
- } elseif ($value) {
- $pass[$key] = $this->stripEscape($value);
- }
- }
- $out['pass'] = am($out['pass'], $pass);
- }
- $ii++;
- }
- break;
- }
- }
- return $out;
- }
- function stripEscape($param) {
- if (!is_array($param) || empty($param)) {
- if (is_bool($param)) {
- return $param;
- }
-
- $return = preg_replace('/^[\\t ]*(?:-!)+/', '', $param);
- return $return;
- }
- foreach ($param as $key => $value) {
- if (is_string($value)) {
- $return[$key] = preg_replace('/^[\\t ]*(?:-!)+/', '', $value);
- } else {
- foreach ($value as $array => $string) {
- $return[$key][$array] = $this->stripEscape($string);
- }
- }
- }
- return $return;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/sanitize.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/sanitize.php
deleted file mode 100644
index ef818b0..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/sanitize.php
+++ /dev/null
@@ -1,245 +0,0 @@
-<?php
-/* SVN FILE: $Id: sanitize.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Washes strings from unwanted noise.
- *
- * Helpful methods to make unsafe strings usable.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Data Sanitization.
- *
- * Removal of alpahnumeric characters, SQL-safe slash-added strings, HTML-friendly strings,
- * and all of the above on arrays.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Sanitize{
-/**
- * Removes any non-alphanumeric characters.
- *
- * @param string $string
- * @return string
- * @access public
- */
- function paranoid($string, $allowed = array()) {
- $allow = null;
- if (!empty($allowed)) {
- foreach ($allowed as $value) {
- $allow .= "\\$value";
- }
- }
-
- if (is_array($string)) {
- foreach ($string as $key => $clean) {
- $cleaned[$key] = preg_replace("/[^{$allow}a-zA-Z0-9]/", "", $clean);
- }
- } else {
- $cleaned = preg_replace("/[^{$allow}a-zA-Z0-9]/", "", $string);
- }
- return $cleaned;
- }
-/**
- * Makes a string SQL-safe by adding slashes (if needed).
- *
- * @param string $string
- * @return string
- * @access public
- */
- function sql($string) {
- if (!ini_get('magic_quotes_gpc')) {
- $string = addslashes($string);
- }
- return $string;
- }
-/**
- * Returns given string safe for display as HTML. Renders entities.
- *
- * @param string $string
- * @param boolean $remove If true, the string is stripped of all HTML tags
- * @return string
- * @access public
- */
- function html($string, $remove = false) {
- if ($remove) {
- $string = strip_tags($string);
- } else {
- $patterns = array("/\&/", "/%/", "/</", "/>/", '/"/', "/'/", "/\(/", "/\)/", "/\+/", "/-/");
- $replacements = array("&amp;", "&#37;", "&lt;", "&gt;", "&quot;", "&#39;", "&#40;", "&#41;", "&#43;", "&#45;");
- $string = preg_replace($patterns, $replacements, $string);
- }
- return $string;
- }
-/**
- * Recursively sanitizes given array of data for safe input.
- *
- * @param mixed $toClean
- * @return mixed
- * @access public
- */
- function cleanArray(&$toClean) {
- return $this->cleanArrayR($toClean);
- }
-/**
- * Method used for recursively sanitizing arrays of data
- * for safe input
- *
- * @param array $toClean
- * @return array The clean array
- * @access public
- */
- function cleanArrayR(&$toClean) {
- if (is_array($toClean)) {
- while (list($k, $v) = each($toClean)) {
- if (is_array($toClean[$k])) {
- $this->cleanArray($toClean[$k]);
- } else {
- $toClean[$k] = $this->cleanValue($v);
- }
- }
- } else {
- return null;
- }
- }
-/**
- * Do we really need to sanitize array keys? If so, we can use this code...
- function cleanKey($key) {
- if ($key == "")
- {
- return "";
- }
- //URL decode and convert chars to HTML entities
- $key = htmlspecialchars(urldecode($key));
- //Remove ..
- $key = preg_replace( "/\.\./", "", $key );
- //Remove __FILE__, etc.
- $key = preg_replace( "/\_\_(.+?)\_\_/", "", $key );
- //Trim word chars, '.', '-', '_'
- $key = preg_replace( "/^([\w\.\-\_]+)$/", "$1", $key );
- return $key;
- }
- */
-
-/**
- * Method used by cleanArray() to sanitize array nodes.
- *
- * @param string $val
- * @return string
- * @access public
- */
- function cleanValue($val) {
- if ($val == "") {
- return "";
- }
- //Replace odd spaces with safe ones
- $val = str_replace(" ", " ", $val);
- $val = str_replace(chr(0xCA), "", $val);
- //Encode any HTML to entities.
- $val = $this->html($val);
- //Double-check special chars and replace carriage returns with new lines
- $val = preg_replace("/\\\$/", "$", $val);
- $val = preg_replace("/\r\n/", "\n", $val);
- $val = str_replace("!", "!", $val);
- $val = str_replace("'", "'", $val);
- //Allow unicode (?)
- $val = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $val);
- //Add slashes for SQL
- $val = $this->sql($val);
- //Swap user-inputted backslashes (?)
- $val = preg_replace("/\\\(?!&amp;#|\?#)/", "\\", $val);
- return $val;
- }
-
-/**
- * Formats column data from definition in DBO's $columns array
- *
- * @param Model $model The model containing the data to be formatted
- * @return void
- * @access public
- */
- function formatColumns(&$model) {
- foreach ($model->data as $name => $values) {
- if ($name == $model->name) {
- $curModel =& $model;
- } elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) {
- $curModel =& $model->{$name};
- } else {
- $curModel = null;
- }
-
- if ($curModel != null) {
- foreach ($values as $column => $data) {
- $colType = $curModel->getColumnType($column);
-
- if ($colType != null) {
- $db =& ConnectionManager::getDataSource($curModel->useDbConfig);
- $colData = $db->columns[$colType];
-
- if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) {
- $data = substr(strval($data), 0, $colData['limit']);
- }
-
- if (isset($colData['formatter']) || isset($colData['format'])) {
-
- switch(strtolower($colData['formatter'])) {
- case 'date':
- $data = date($colData['format'], strtotime($data));
- break;
- case 'sprintf':
- $data = sprintf($colData['format'], $data);
- break;
- case 'intval':
- $data = intval($data);
- break;
- case 'floatval':
- $data = floatval($data);
- break;
- }
- }
- $model->data[$name][$column]=$data;
- /*
- switch($colType) {
- case 'integer':
- case 'int':
- return $data;
- break;
- case 'string':
- case 'text':
- case 'binary':
- case 'date':
- case 'time':
- case 'datetime':
- case 'timestamp':
- case 'date':
- return "'" . $data . "'";
- break;
- }
- */
- }
- }
- }
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/security.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/security.php
deleted file mode 100644
index c3a59b2..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/security.php
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-/* SVN FILE: $Id: security.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Security Class
- *
- * This class is a singleton class that contains
- * functions for hasing and security.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v .0.10.0.1233
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Security Class
- *
- * This class is a singleton class that contains functions for hasing and security.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Security extends Object {
-/**
- * Singleton method to retrieve the instance of the Security class
- *
- * @return object Security
- * @access public
- */
- function &getInstance() {
- static $instance = array();
- if (!$instance) {
- $instance[0] = &new Security;
- }
- return $instance[0];
- }
-/**
- * Returns inactive minutes constant based on cake the security level
- *
- * @return integer
- * @access public
- */
- function inactiveMins() {
- switch(CAKE_SECURITY) {
- case 'high':
- return 10;
- break;
- case 'medium':
- return 100;
- break;
- case 'low':
- default:
- return 300;
- break;
- }
- }
-/**
- * Generates a unique authkey
- *
- * @return mixed
- * @access public
- */
- function generateAuthKey() {
- $_this =& Security::getInstance();
- return $_this->hash(uniqid(rand(), true));
- }
-/**
- * Validates the authkey
- *
- * @param mixed $authKey
- * @return boolean
- * @access public
- */
- function validateAuthKey($authKey) {
- return true;
- }
-/**
- * Generates a hash of a string using a php built in hashing function
- *
- * @param string $string The string to be hashed
- * @param string $type The hashing algorithm
- * @return string
- * @access public
- */
- function hash($string, $type = 'sha1') {
- $type = strtolower($type);
- if ($type == 'sha1') {
- if (function_exists('sha1')) {
- $return = sha1($string);
- return $return;
- } else {
- $type = 'sha256';
- }
- }
-
- if ($type == 'sha256') {
- if (function_exists('mhash')) {
- $return = bin2hex(mhash(MHASH_SHA256, $string));
- return $return;
- } else {
- $type = 'md5';
- }
- }
-
- if ($type == 'md5') {
- $return = md5($string);
- return $return;
- }
- }
-/**
- * Function that ciphers a text using a key
- *
- * @param string $text
- * @param string $key
- * @return string
- * @access public
- */
- function cipher($text, $key) {
- if (!defined('CIPHER_SEED')) {
- //This is temporary will change later
- define('CIPHER_SEED', '76859309657453542496749683645');
- }
- srand (CIPHER_SEED);
- $out = '';
-
- for ($i = 0; $i < strlen($text); $i++) {
- for ($j = 0; $j < ord(substr($key, $i % strlen($key), 1)); $j++) {
- $toss = rand(0, 255);
- }
- $mask = rand(0, 255);
- $out .= chr(ord(substr($text, $i, 1)) ^ $mask);
- }
- return $out;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/session.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/session.php
deleted file mode 100644
index 924b931..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/session.php
+++ /dev/null
@@ -1,757 +0,0 @@
-<?php
-/* SVN FILE: $Id: session.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Session class for Cake.
- *
- * Cake abstracts the handling of sessions.
- * There are several convenient methods to access session information.
- * This class is the implementation of those methods.
- * They are mostly used by the Session Component.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v .0.10.0.1222
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Database name for cake sessions.
- *
- */
- if (!defined('CAKE_SESSION_TABLE')) {
- define('CAKE_SESSION_TABLE', 'cake_sessions');
- }
-
- if (CAKE_SESSION_SAVE === 'database') {
- uses('model' . DS . 'connection_manager');
- }
- uses('set');
-/**
- * Session class for Cake.
- *
- * Cake abstracts the handling of sessions. There are several convenient methods to access session information.
- * This class is the implementation of those methods. They are mostly used by the Session Component.
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class CakeSession extends Object {
-/**
- * True if the Session is still valid
- *
- * @var boolean
- * @access public
- */
- var $valid = false;
-/**
- * Error messages for this session
- *
- * @var array
- * @access public
- */
- var $error = false;
-/**
- * User agent string
- *
- * @var string
- * @access protected
- */
- var $_userAgent = '';
-/**
- * Path to where the session is active.
- *
- * @var string
- * @access public
- */
- var $path = '/';
-/**
- * Error number of last occurred error
- *
- * @var integer
- * @access public
- */
- var $lastError = null;
-/**
- * CAKE_SECURITY setting, "high", "medium", or "low".
- *
- * @var string
- * @access public
- */
- var $security = null;
-/**
- * Start time for this session.
- *
- * @var integer
- * @access public
- */
- var $time = false;
-/**
- * Time when this session becomes invalid.
- *
- * @var integer
- * @access public
- */
- var $sessionTime = false;
-/**
- * Keeps track of keys to watch for writes on
- *
- * @var array
- * @access public
- */
- var $watchKeys = array();
-/**
- * Current Session id
- *
- * @var string
- * @access public
- */
- var $id = null;
-/**
- * Constructor.
- *
- * @param string $base The base path for the Session
- * @param boolean $start Should session be started right now
- * @access public
- */
- function __construct($base = null, $start = true) {
- if (Configure::read('Session.checkAgent') === true) {
- if (env('HTTP_USER_AGENT') != null) {
- $this->_userAgent = md5(env('HTTP_USER_AGENT') . CAKE_SESSION_STRING);
- }
- }
- $this->time = time();
-
- if ($start === true) {
- $this->host = env('HTTP_HOST');
-
- if (empty($base) || strpos($base, '?') === 0 || strpos($base, 'index.php') === 0) {
- $this->path = '/';
- } else {
- $this->path = $base;
- }
-
- if (strpos($this->host, ':') !== false) {
- $this->host = substr($this->host, 0, strpos($this->host, ':'));
- }
-
- $this->sessionTime = $this->time + (Security::inactiveMins() * CAKE_SESSION_TIMEOUT);
- $this->security = CAKE_SECURITY;
- }
- parent::__construct();
- }
-/**
- * Starts the Session.
- *
- * @param string $name Variable name to check for
- * @return boolean True if variable is there
- * @access public
- */
- function start() {
- if (function_exists('session_write_close')) {
- session_write_close();
- }
- $this->__initSession();
- return $this->__startSession();
- }
-/**
- * Determine if Session has been started.
- *
- * @access public
- */
- function started(){
- if (isset($_SESSION)) {
- return true;
- }
- return false;
- }
-/**
- * Returns true if given variable is set in session.
- *
- * @param string $name Variable name to check for
- * @return boolean True if variable is there
- * @access public
- */
- function check($name) {
- $var = $this->__validateKeys($name);
- if (empty($var)) {
- return false;
- }
- $result = Set::extract($_SESSION, $var);
- return isset($result);
- }
-/**
- *
- * @param id $name string
- * @return string Session id
- * @access public
- */
- function id($id = null) {
- if ($id) {
- $this->id = $id;
- session_id($this->id);
- }
- if (isset($_SESSION)) {
- return session_id();
- } else {
- return $this->id;
- }
- }
-/**
- * Temp method until we are able to remove the last eval().
- * Builds an expression to fetch a session variable with specified name.
- *
- * @param string $name Name of variable (in dot notation)
- * @access private
- */
- function __sessionVarNames($name) {
- if (is_string($name) && preg_match("/^[ 0-9a-zA-Z._-]*$/", $name)) {
- if (strpos($name, ".")) {
- $names = explode(".", $name);
- } else {
- $names = array($name);
- }
- $expression = "\$_SESSION";
- foreach ($names as $item) {
- $expression .= is_numeric($item) ? "[$item]" : "['$item']";
- }
- return $expression;
- }
- $this->__setError(3, "$name is not a string");
- return false;
- }
-/**
- * Removes a variable from session.
- *
- * @param string $name Session variable to remove
- * @return boolean Success
- * @access public
- */
- function del($name) {
- if ($this->check($name)) {
- if ($var = $this->__validateKeys($name)) {
- if (in_array($var, $this->watchKeys)) {
- trigger_error('Deleting session key {' . $var . '}', E_USER_NOTICE);
- }
- $this->__overwrite($_SESSION, Set::remove($_SESSION, $var));
- return ($this->check($var) == false);
- }
- }
- $this->__setError(2, "$name doesn't exist");
- return false;
- }
-/**
- * Used to write new data to _SESSION, since PHP doesn't like us setting the _SESSION var itself
- *
- * @param array $old Set of old variables => values
- * @param array $new New set of variable => value
- * @access private
- */
- function __overwrite(&$old, $new) {
- if(!empty($old)) {
- foreach ($old as $key => $var) {
- if (!isset($new[$key])) {
- unset($old[$key]);
- }
- }
- }
- foreach ($new as $key => $var) {
- $old[$key] = $var;
- }
- }
-/**
- * Return error description for given error number.
- *
- * @param integer $errorNumber Error to set
- * @return string Error as string
- * @access private
- */
- function __error($errorNumber) {
- if (!is_array($this->error) || !array_key_exists($errorNumber, $this->error)) {
- return false;
- } else {
- return $this->error[$errorNumber];
- }
- }
-/**
- * Returns last occurred error as a string, if any.
- *
- * @return mixed Error description as a string, or false.
- * @access public
- */
- function error() {
- if ($this->lastError) {
- return $this->__error($this->lastError);
- } else {
- return false;
- }
- }
-/**
- * Returns true if session is valid.
- *
- * @return boolean Success
- * @access public
- */
- function valid() {
- if ($this->read('Config')) {
- if (Configure::read('Session.checkAgent') === false || $this->_userAgent == $this->read("Config.userAgent") && $this->time <= $this->read("Config.time")) {
- if ($this->error === false) {
- $this->valid = true;
- }
- } else {
- $this->valid = false;
- $this->__setError(1, "Session Highjacking Attempted !!!");
- }
- }
- return $this->valid;
- }
-/**
- * Returns given session variable, or all of them, if no parameters given.
- *
- * @param mixed $name The name of the session variable (or a path as sent to Set.extract)
- * @return mixed The value of the session variable
- * @access public
- */
- function read($name = null) {
- if (is_null($name)) {
- return $this->__returnSessionVars();
- }
- if (empty($name)) {
- return false;
- }
- $result = Set::extract($_SESSION, $name);
-
- if (!is_null($result)) {
- return $result;
- }
- $this->__setError(2, "$name doesn't exist");
- return null;
- }
-/**
- * Returns all session variables.
- *
- * @return mixed Full $_SESSION array, or false on error.
- * @access private
- */
- function __returnSessionVars() {
- if (!empty($_SESSION)) {
- return $_SESSION;
- }
- $this->__setError(2, "No Session vars set");
- return false;
- }
-/**
- * Tells Session to write a notification when a certain session path or subpath is written to
- *
- * @param mixed $var The variable path to watch
- * @access public
- */
- function watch($var) {
- $var = $this->__validateKeys($var);
- if (empty($var)) {
- return false;
- }
- $this->watchKeys[] = $var;
- }
-/**
- * Tells Session to stop watching a given key path
- *
- * @param mixed $var The variable path to watch
- * @access public
- */
- function ignore($var) {
- $var = $this->__validateKeys($var);
- if (!in_array($var, $this->watchKeys)) {
- return;
- }
- foreach ($this->watchKeys as $i => $key) {
- if ($key == $var) {
- unset($this->watchKeys[$i]);
- $this->watchKeys = array_values($this->watchKeys);
- return;
- }
- }
- }
-/**
- * Writes value to given session variable name.
- *
- * @param mixed $name Name of variable
- * @param string $value Value to write
- * @return boolean True if the write was successful, false if the write failed
- * @access public
- */
- function write($name, $value) {
- $var = $this->__validateKeys($name);
-
- if (empty($var)) {
- return false;
- }
- if (in_array($var, $this->watchKeys)) {
- trigger_error('Writing session key {' . $var . '}: ' . print_r($value), E_USER_NOTICE);
- }
- $this->__overwrite($_SESSION, Set::insert($_SESSION, $var, $value));
- return (Set::extract($_SESSION, $var) === $value);
- }
-/**
- * Helper method to destroy invalid sessions.
- *
- * @access public
- */
- function destroy() {
- $sessionpath = session_save_path();
- if (empty($sessionpath)) {
- $sessionpath = "/tmp";
- }
-
- if (isset($_COOKIE[session_name()])) {
- setcookie(CAKE_SESSION_COOKIE, '', time() - 42000, $this->path);
- }
-
- $_SESSION = array();
- $file = $sessionpath . DS . "sess_" . session_id();
- @session_destroy();
- @unlink ($file);
- $this->__construct($this->path);
- $this->renew();
- }
-/**
- * Helper method to initialize a session, based on Cake core settings.
- *
- * @access private
- */
- function __initSession() {
- switch($this->security) {
- case 'high':
- $this->cookieLifeTime = 0;
- if (function_exists('ini_set')) {
- ini_set('session.referer_check', $this->host);
- }
- break;
- case 'medium':
- $this->cookieLifeTime = 7 * 86400;
- if (function_exists('ini_set')) {
- ini_set('session.referer_check', $this->host);
- }
- break;
- case 'low':
- default:
- $this->cookieLifeTime = 788940000;
- break;
- }
-
- switch(CAKE_SESSION_SAVE) {
- case 'cake':
- if (!isset($_SESSION)) {
- if (function_exists('ini_set')) {
- ini_set('session.use_trans_sid', 0);
- ini_set('url_rewriter.tags', '');
- ini_set('session.serialize_handler', 'php');
- ini_set('session.use_cookies', 1);
- ini_set('session.name', CAKE_SESSION_COOKIE);
- ini_set('session.cookie_lifetime', $this->cookieLifeTime);
- ini_set('session.cookie_path', $this->path);
- ini_set('session.auto_start', 0);
- ini_set('session.save_path', TMP . 'sessions');
- }
- }
- break;
- case 'database':
- if (!isset($_SESSION)) {
- if (function_exists('ini_set')) {
- ini_set('session.use_trans_sid', 0);
- ini_set('url_rewriter.tags', '');
- ini_set('session.save_handler', 'user');
- ini_set('session.serialize_handler', 'php');
- ini_set('session.use_cookies', 1);
- ini_set('session.name', CAKE_SESSION_COOKIE);
- ini_set('session.cookie_lifetime', $this->cookieLifeTime);
- ini_set('session.cookie_path', $this->path);
- ini_set('session.auto_start', 0);
- }
- }
- session_set_save_handler(array('CakeSession','__open'),
- array('CakeSession', '__close'),
- array('CakeSession', '__read'),
- array('CakeSession', '__write'),
- array('CakeSession', '__destroy'),
- array('CakeSession', '__gc'));
- break;
- case 'php':
- if (!isset($_SESSION)) {
- if (function_exists('ini_set')) {
- ini_set('session.use_trans_sid', 0);
- ini_set('session.name', CAKE_SESSION_COOKIE);
- ini_set('session.cookie_lifetime', $this->cookieLifeTime);
- ini_set('session.cookie_path', $this->path);
- }
- }
- break;
- default:
- if (!isset($_SESSION)) {
- $config = CONFIGS . CAKE_SESSION_SAVE . '.php';
-
- if (is_file($config)) {
- require_once ($config);
- }
- }
- break;
- }
- }
-/**
- * Helper method to start a session
- *
- * @access private
- */
- function __startSession() {
- if (headers_sent()) {
- if (!isset($_SESSION)) {
- $_SESSION = array();
- }
- return false;
- } elseif (!isset($_SESSION)) {
- session_cache_limiter ("must-revalidate");
- session_start();
- header ('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');
- return true;
- } else {
- session_start();
- return true;
- }
- }
-/**
- * Helper method to create a new session.
- *
- * @access protected
- */
- function _checkValid() {
- if ($this->read('Config')) {
- if (Configure::read('Session.checkAgent') === false || $this->_userAgent == $this->read("Config.userAgent") && $this->time <= $this->read("Config.time")) {
- $time = $this->read("Config.time");
- $this->write("Config.time", $this->sessionTime);
-
- if ($this->security === 'high') {
- $check = $this->read("Config.timeout");
- $check = $check - 1;
- $this->write("Config.timeout", $check);
-
- if (time() > ($time - (Security::inactiveMins() * CAKE_SESSION_TIMEOUT) + 2) || $check < 1) {
- $this->renew();
- $this->write('Config.timeout', 10);
- }
- }
- $this->valid = true;
- } else {
- $this->destroy();
- $this->valid = false;
- $this->__setError(1, "Session Highjacking Attempted !!!");
- }
- } else {
- srand ((double)microtime() * 1000000);
- $this->write("Config.userAgent", $this->_userAgent);
- $this->write("Config.time", $this->sessionTime);
- $this->write('Config.rand', rand());
- $this->write('Config.timeout', 10);
- $this->valid = true;
- $this->__setError(1, "Session is valid");
- }
- }
-/**
- * Helper method to restart a session.
- *
- * @access private
- */
- function __regenerateId() {
- $oldSessionId = session_id();
- if ($oldSessionId) {
- $sessionpath = session_save_path();
- if (empty($sessionpath)) {
- $sessionpath = "/tmp";
- }
-
- if (isset($_COOKIE[session_name()])) {
- setcookie(CAKE_SESSION_COOKIE, '', time() - 42000, $this->path);
- }
- session_regenerate_id();
- $newSessid = session_id();
-
- if (function_exists('session_write_close')) {
- session_write_close();
- }
- $this->__initSession();
- session_id($oldSessionId);
- session_start();
- session_destroy();
- $file = $sessionpath . DS . "sess_$oldSessionId";
- @unlink($file);
- $this->__initSession();
- session_id($newSessid);
- session_start();
- }
- }
-/**
- * Restarts this session.
- *
- * @access public
- */
- function renew() {
- $this->__regenerateId();
- }
-/**
- * Validate that the $name is in correct dot notation
- * example: $name = 'ControllerName.key';
- *
- * @param string $name Session key names as string.
- * @return mixed false is $name is not correct format, or $name if it is correct
- * @access private
- */
- function __validateKeys($name) {
- if (is_string($name) && preg_match("/^[ 0-9a-zA-Z._-]*$/", $name)) {
- return $name;
- }
- $this->__setError(3, "$name is not a string");
- return false;
- }
-/**
- * Helper method to set an internal error message.
- *
- * @param integer $errorNumber Number of the error
- * @param string $errorMessage Description of the error
- * @access private
- */
- function __setError($errorNumber, $errorMessage) {
- if ($this->error === false) {
- $this->error = array();
- }
- $this->error[$errorNumber] = $errorMessage;
- $this->lastError = $errorNumber;
- }
-/**
- * Method called on open of a database session.
- *
- * @return boolean Success
- * @access private
- */
- function __open() {
- return true;
- }
-/**
- * Method called on close of a database session.
- *
- * @return boolean Success
- * @access private
- */
- function __close() {
- $probability = mt_rand(1, 150);
- if ($probability <= 3) {
- CakeSession::__gc();
- }
- return true;
- }
-/**
- * Method used to read from a database session.
- *
- * @param mixed $key The key of the value to read
- * @return mixed The value of the key or false if it does not exist
- * @access private
- */
- function __read($key) {
- $db =& ConnectionManager::getDataSource('default');
- $table = $db->fullTableName(CAKE_SESSION_TABLE, false);
- $row = $db->query("SELECT " . $db->name($table.'.data') . " FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key), false);
-
- if ($row && !isset($row[0][$table]) && isset($row[0][0])) {
- $table = 0;
- }
-
- if ($row && $row[0][$table]['data']) {
- return $row[0][$table]['data'];
- } else {
- return false;
- }
- }
-/**
- * Helper function called on write for database sessions.
- *
- * @param mixed $key The name of the var
- * @param mixed $value The value of the var
- * @return boolean Success
- * @access private
- */
- function __write($key, $value) {
- $db =& ConnectionManager::getDataSource('default');
- $table = $db->fullTableName(CAKE_SESSION_TABLE);
-
- switch(CAKE_SECURITY) {
- case 'high':
- $factor = 10;
- break;
- case 'medium':
- $factor = 100;
- break;
- case 'low':
- $factor = 300;
- break;
- default:
- $factor = 10;
- break;
- }
- $expires = time() + CAKE_SESSION_TIMEOUT * $factor;
- $row = $db->query("SELECT COUNT(id) AS count FROM " . $db->name($table) . " WHERE "
- . $db->name('id') . " = "
- . $db->value($key), false);
-
- if ($row[0][0]['count'] > 0) {
- $db->execute("UPDATE " . $db->name($table) . " SET " . $db->name('data') . " = "
- . $db->value($value) . ", " . $db->name('expires') . " = "
- . $db->value($expires) . " WHERE " . $db->name('id') . " = "
- . $db->value($key));
- } else {
- $db->execute("INSERT INTO " . $db->name($table) . " (" . $db->name('data') . ","
- . $db->name('expires') . "," . $db->name('id')
- . ") VALUES (" . $db->value($value) . ", " . $db->value($expires) . ", "
- . $db->value($key) . ")");
- }
- return true;
- }
-/**
- * Method called on the destruction of a database session.
- *
- * @param int $key Key that uniquely identifies session in database
- * @return boolean Success
- * @access private
- */
- function __destroy($key) {
- $db =& ConnectionManager::getDataSource('default');
- $table = $db->fullTableName(CAKE_SESSION_TABLE);
- $db->execute("DELETE FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key, 'integer'));
- return true;
- }
-/**
- * Helper function called on gc for database sessions.
- *
- * @param int $expires Timestamp (defaults to current time)
- * @return boolean Success
- * @access private
- */
- function __gc($expires = null) {
- $db =& ConnectionManager::getDataSource('default');
- $table = $db->fullTableName(CAKE_SESSION_TABLE);
- $db->execute("DELETE FROM " . $db->name($table) . " WHERE " . $db->name($table.'.expires') . " < ". $db->value(time()));
- return true;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/set.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/set.php
deleted file mode 100644
index 44147b9..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/set.php
+++ /dev/null
@@ -1,805 +0,0 @@
-<?php
-/* SVN FILE: $Id: set.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Library of array functions for Cake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 1.2.0
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Class used for manipulation of arrays.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs
- */
-class Set extends Object {
-/**
- * Value of the Set object.
- *
- * @var array
- * @access public
- */
- var $value = array();
-/**
- * Constructor. Defaults to an empty array.
- *
- * @access public
- */
- function __construct() {
- if (func_num_args() == 1 && is_array(func_get_arg(0))) {
- $this->value = func_get_arg(0);
- } else {
- $this->value = func_get_args();
- }
- }
-/**
- * Returns the contents of the Set object
- *
- * @return array
- * @access public
- */
- function &get() {
- return $this->value;
- }
-/**
- * This function can be thought of as a hybrid between PHP's array_merge and array_merge_recursive. The difference
- * to the two is that if an array key contains another array then the function behaves recursive (unlike array_merge)
- * but does not do if for keys containing strings (unlike array_merge_recursive). See the unit test for more information.
- *
- * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.
- *
- * @param array $arr1 Array to be merged
- * @param array $arr2 Array to merge with
- * @return array Merged array
- * @access public
- */
- function merge($arr1, $arr2 = null) {
- $args = func_get_args();
-
- if (is_a($this, 'set')) {
- $backtrace = debug_backtrace();
- $previousCall = strtolower($backtrace[1]['class'].'::'.$backtrace[1]['function']);
- if ($previousCall != 'set::merge') {
- $r =& $this->value;
- array_unshift($args, null);
- }
- }
- if (!isset($r)) {
- $r = (array)current($args);
- }
-
- while (($arg = next($args)) !== false) {
- if (is_a($arg, 'set')) {
- $arg = $arg->get();
- }
-
- foreach ((array)$arg as $key => $val) {
- if (is_array($val) && isset($r[$key]) && is_array($r[$key])) {
- $r[$key] = Set::merge($r[$key], $val);
- } elseif (is_int($key)) {
- $r[] = $val;
- } else {
- $r[$key] = $val;
- }
- }
- }
- return $r;
- }
-/**
- * Filters empty elements out of a route array, excluding '0'.
- *
- * @param mixed $var Either an array to filter, or value when in callback
- * @param boolean $isArray Force to tell $var is an array when $var is empty
- * @return mixed Either filtered array, or true/false when in callback
- * @access public
- */
- function filter($var, $isArray = false) {
- if (is_array($var) && (!empty($var) || $isArray)) {
- return array_filter($var, array('Set', 'filter'));
- } else {
- if ($var === 0 || $var === '0' || !empty($var)) {
- return true;
- } else {
- return false;
- }
- }
- }
-/**
- * Pushes the differences in $array2 onto the end of $array
- *
- * @param mixed $array Original array
- * @param mixed $array2 Differences to push
- * @return array Combined array
- * @access public
- */
- function pushDiff($array = null, $array2 = null) {
- if ($array2 !== null && is_array($array2)) {
- foreach ($array2 as $key => $value) {
- if (!array_key_exists($key, $array)) {
- $array[$key] = $value;
- } else {
- if (is_array($value)) {
- $array[$key] = Set::pushDiff($array[$key], $array2[$key]);
- }
- }
- }
- return $array;
- }
-
- if (!isset($this->value)) {
- $this->value = array();
- }
- $this->value = Set::pushDiff($this->value, Set::__array($array));
- return $this->value;
- }
-/**
- * Maps the contents of the Set object to an object hierarchy.
- * Maintains numeric keys as arrays of objects
- *
- * @param string $class A class name of the type of object to map to
- * @param string $tmp A temporary class name used as $class if $class is an array
- * @return object Hierarchical object
- * @access public
- */
- function map($class = 'stdClass', $tmp = 'stdClass') {
- if (is_array($class)) {
- $val = $class;
- $class = $tmp;
- } elseif (is_a($this, 'set')) {
- $val = $this->get();
- }
-
- if (empty($val) || $val == null) {
- return null;
- }
- return Set::__map($val, $class);
- }
-
-/**
- * Get the array value of $array. If $array is null, it will return
- * the current array Set holds. If it is an object of type Set, it
- * will return its value. If it is another object, its object variables.
- * If it is anything else but an array, it will return an array whose first
- * element is $array.
- *
- * @param mixed $array Data from where to get the array.
- * @return array Array from $array.
- * @access private
- */
- function __array($array) {
- if ($array == null) {
- $array = $this->value;
- } elseif (is_object($array) && (is_a($array, 'set'))) {
- $array = $array->get();
- } elseif (is_object($array)) {
- $array = get_object_vars($array);
- } elseif (!is_array($array)) {
- $array = array($array);
- }
- return $array;
- }
-
-/**
- * Maps the given value as an object. If $value is an object,
- * it returns $value. Otherwise it maps $value as an object of
- * type $class, and if primary assign _name_ $key on first array.
- * If $value is not empty, it will be used to set properties of
- * returned object (recursively). If $key is numeric will maintain array
- * structure
- *
- * @param mixed $value Value to map
- * @param string $class Class name
- * @param boolean $primary whether to assign first array key as the _name_
- * @return mixed Mapped object
- * @access private
- */
- function __map(&$array, $class, $primary = false) {
- if ($class === true) {
- $out = new stdClass;
- } else {
- $out = new $class;
- }
- if (is_array($array)) {
- $keys = array_keys($array);
- foreach ($array as $key => $value) {
- if($keys[0] === $key && $class !== true) {
- $primary = true;
- }
- if (is_numeric($key)) {
- if (is_object($out) && is_array($value)) {
- $out = get_object_vars($out);
- }
- $out[$key] = Set::__map($value, $class, true);
- } elseif ($primary === true && is_array($value)) {
- $out->_name_ = $key;
- $primary = false;
- foreach($value as $key2 => $value2) {
- $out->{$key2} = Set::__map($value2, $class);
- }
- } else {
- $out->{$key} = Set::__map($value, $class);
- }
- }
- } else {
- $out = $array;
- }
- return $out;
- }
-/**
- * Checks to see if all the values in the array are numeric
- *
- * @param array $array The array to check. If null, the value of the current Set object
- * @return boolean true if values are numeric, false otherwise
- * @access public
- */
- function numeric($array = null) {
- if ($array == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
- $array = $this->get();
- }
-
- $numeric = true;
- $keys = array_keys($array);
- $count = count($keys);
- for ($i = 0; $i < $count; $i++) {
- if (!is_numeric($array[$keys[$i]])) {
- $numeric = false;
- break;
- }
- }
- return $numeric;
- }
-/**
- * Return a value from an array list if the key exists.
- *
- * If a comma separated $list is passed arrays are numeric with the key of the first being 0
- * $list = 'no, yes' would translate to $list = array(0 => 'no', 1 => 'yes');
- *
- * If an array is used, keys can be strings example: array('no' => 0, 'yes' => 1);
- *
- * $list defaults to 0 = no 1 = yes if param is not passed
- *
- * @param mixed $select Key in $list to return
- * @param mixed $list can be an array or a comma-separated list.
- * @return string the value of the array key or null if no match
- * @access public
- */
- function enum($select, $list = null) {
- if (empty($list) && is_a($this, 'Set')) {
- $list = $this->get();
- } elseif (empty($list)) {
- $list = array('no', 'yes');
- }
-
- $return = null;
- $list = Set::normalize($list, false);
-
- if (array_key_exists($select, $list)) {
- $return = $list[$select];
- }
- return $return;
- }
-/**
- * Returns a series of values extracted from an array, formatted in a format string.
- *
- * @param array $data Source array from which to extract the data
- * @param string $format Format string into which values will be inserted, see sprintf()
- * @param array $keys An array containing one or more Set::extract()-style key paths
- * @return array An array of strings extracted from $keys and formatted with $format
- * @access public
- */
- function format($data, $format, $keys) {
-
- $extracted = array();
- $count = count($keys);
-
- if (!$count) {
- return;
- }
-
- for ($i = 0; $i < $count; $i++) {
- $extracted[] = Set::extract($data, $keys[$i]);
- }
- $out = array();
- $data = $extracted;
- $count = count($data[0]);
-
- if (preg_match_all('/\{([0-9]+)\}/msi', $format, $keys2) && isset($keys2[1])) {
- $keys = $keys2[1];
- $format = preg_split('/\{([0-9]+)\}/msi', $format);
- $count2 = count($format);
-
- for ($j = 0; $j < $count; $j++) {
- $formatted = '';
- for ($i = 0; $i <= $count2; $i++) {
- if (isset($format[$i])) {
- $formatted .= $format[$i];
- }
- if (isset($keys[$i]) && isset($data[$keys[$i]][$j])) {
- $formatted .= $data[$keys[$i]][$j];
- }
- }
- $out[] = $formatted;
- }
- } else {
- $count2 = count($data);
- for ($j = 0; $j < $count; $j++) {
- $args = array();
- for ($i = 0; $i < $count2; $i++) {
- if (isset($data[$i][$j])) {
- $args[] = $data[$i][$j];
- }
- }
- $out[] = vsprintf($format, $args);
- }
- }
- return $out;
- }
-/**
- * Gets a value from an array or object that maps a given path.
- * The special {n}, as seen in the Model::generateList method, is taken care of here.
- *
- * @param array $data Array from where to extract
- * @param mixed $path As an array, or as a dot-separated string.
- * @return array Extracted data
- * @access public
- */
- function extract($data, $path = null) {
- if ($path === null && is_a($this, 'set')) {
- $path = $data;
- $data = $this->get();
- }
- if (is_object($data)) {
- $data = get_object_vars($data);
- }
-
- if (!is_array($path)) {
- if (strpos($path, '/') !== 0 && strpos($path, './') === false) {
- $path = explode('.', $path);
- } else {
- }
- }
- $tmp = array();
- if (!is_array($path) || empty($path)) {
- return null;
- }
-
- foreach ($path as $i => $key) {
- if (is_numeric($key) && intval($key) > 0 || $key == '0') {
- if (isset($data[intval($key)])) {
- $data = $data[intval($key)];
- } else {
- return null;
- }
- } elseif ($key == '{n}') {
- foreach ($data as $j => $val) {
- if (is_int($j)) {
- $tmpPath = array_slice($path, $i + 1);
- if (empty($tmpPath)) {
- $tmp[] = $val;
- } else {
- $tmp[] = Set::extract($val, $tmpPath);
- }
- }
- }
- return $tmp;
- } else {
- if (isset($data[$key])) {
- $data = $data[$key];
- } else {
- return null;
- }
- }
- }
- return $data;
- }
-/**
- * Inserts $data into an array as defined by $path.
- *
- * @param mixed $list Where to insert into
- * @param mixed $path A dot-separated string.
- * @param array $data Data to insert
- * @return array
- * @access public
- */
- function insert($list, $path, $data = null) {
- if (empty($data) && is_a($this, 'Set')) {
- $data = $path;
- $path = $list;
- $list =& $this->get();
- }
- if (!is_array($path)) {
- $path = explode('.', $path);
- }
- $_list =& $list;
-
- foreach ($path as $i => $key) {
- if (is_numeric($key) && intval($key) > 0 || $key == '0') {
- $key = intval($key);
- }
- if ($i == count($path) - 1) {
- $_list[$key] = $data;
- } else {
- if (!isset($_list[$key])) {
- $_list[$key] = array();
- }
- $_list =& $_list[$key];
- }
- }
- return $list;
- }
-/**
- * Removes an element from a Set or array as defined by $path.
- *
- * @param mixed $list From where to remove
- * @param mixed $path A dot-separated string.
- * @return array Array with $path removed from its value
- * @access public
- */
- function remove($list, $path = null) {
- if (empty($path) && is_a($this, 'Set')) {
- $path = $list;
- $list =& $this->get();
- }
- if (!is_array($path)) {
- $path = explode('.', $path);
- }
- $_list =& $list;
-
- foreach ($path as $i => $key) {
- if (is_numeric($key) && intval($key) > 0 || $key == '0') {
- $key = intval($key);
- }
- if ($i == count($path) - 1) {
- unset($_list[$key]);
- } else {
- if (!isset($_list[$key])) {
- return $list;
- }
- $_list =& $_list[$key];
- }
- }
-
- if (is_a($this, 'Set')) {
- $this->value = $list;
- return $this;
- } else {
- return $list;
- }
- }
-/**
- * Checks if a particular path is set in an array
- *
- * @param mixed $data Data to check on
- * @param mixed $path A dot-separated string.
- * @return boolean true if path is found, false otherwise
- * @access public
- */
- function check($data, $path = null) {
- if (empty($path) && is_a($this, 'Set')) {
- $path = $data;
- $data = $this->get();
- }
- if (!is_array($path)) {
- $path = explode('.', $path);
- }
-
- foreach ($path as $i => $key) {
- if (is_numeric($key) && intval($key) > 0 || $key == '0') {
- $key = intval($key);
- }
- if ($i == count($path) - 1) {
- return isset($data[$key]);
- } else {
- if (!isset($data[$key])) {
- return false;
- }
- $data =& $data[$key];
- }
- }
- return true;
- }
-/**
- * Computes the difference between a Set and an array, two Sets, or two arrays
- *
- * @param mixed $val1 First value
- * @param mixed $val2 Second value
- * @return array Computed difference
- * @access public
- */
- function diff($val1, $val2 = null) {
- if ($val2 == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
- $val2 = $val1;
- $val1 = $this->get();
- }
-
- if (is_object($val2) && (is_a($val2, 'set') || is_a($val2, 'Set'))) {
- $val2 = $val2->get();
- }
- $out = array();
-
- if (empty($val1)) {
- return (array)$val2;
- } elseif (empty($val2)) {
- return (array)$val1;
- }
-
- foreach ($val1 as $key => $val) {
- if (array_key_exists($key, $val2) && $val2[$key] != $val) {
- $out[$key] = $val;
- } elseif (!array_key_exists($key, $val2)) {
- $out[$key] = $val;
- }
- unset($val2[$key]);
- }
-
- foreach ($val2 as $key => $val) {
- if (!array_key_exists($key, $out)) {
- $out[$key] = $val;
- }
- }
- return $out;
- }
-/**
- * Determines if two Sets or arrays are equal
- *
- * @param array $val1 First value
- * @param array $val2 Second value
- * @return boolean true if they are equal, false otherwise
- * @access public
- */
- function isEqual($val1, $val2 = null) {
- if ($val2 == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
- $val2 = $val1;
- $val1 = $this->get();
- }
-
- return ($val1 == $val2);
- }
-/**
- * Determines if one Set or array contains the exact keys and values of another.
- *
- * @param array $val1 First value
- * @param array $val2 Second value
- * @return boolean true if $val1 contains $val2, false otherwise
- * @access public
- */
- function contains($val1, $val2 = null) {
- if ($val2 == null && is_a($this, 'set')) {
- $val2 = $val1;
- $val1 = $this->get();
- } elseif ($val2 != null && is_object($val2) && is_a($val2, 'set')) {
- $val2 = $val2->get();
- }
-
- foreach ($val2 as $key => $val) {
- if (is_numeric($key)) {
- if (!in_array($val, $val1)) {
- return false;
- }
- } else {
- if (!isset($val1[$key]) || $val1[$key] != $val) {
- return false;
- }
- }
- }
- return true;
- }
-/**
- * Counts the dimensions of an array. If $all is set to false (which is the default) it will
- * only consider the dimension of the first element in the array.
- *
- * @param array $array Array to count dimensions on
- * @param boolean $all Set to true to count the dimension considering all elements in array
- * @param integer $count Start the dimension count at this number
- * @return integer The number of dimensions in $array
- * @access public
- */
- function countDim($array = null, $all = false, $count = 0) {
- if ($array === null) {
- $array = $this->get();
- } elseif (is_object($array) && is_a($array, 'set')) {
- $array = $array->get();
- }
- if ($all) {
- $depth = array($count);
- if (is_array($array) && reset($array) !== false) {
- foreach ($array as $value) {
- $depth[] = Set::countDim($value, true, $count + 1);
- }
- }
- $return = max($depth);
- } else {
- if (is_array(reset($array))) {
- $return = Set::countDim(reset($array)) + 1;
- } else {
- $return = 1;
- }
- }
- return $return;
- }
-/**
- * Normalizes a string or array list.
- *
- * @param mixed $list List to normalize
- * @param boolean $assoc If true, $list will be converted to an associative array
- * @param string $sep If $list is a string, it will be split into an array with $sep
- * @param boolean $trim If true, separated strings will be trimmed
- * @return array
- * @access public
- */
- function normalize($list, $assoc = true, $sep = ',', $trim = true) {
- if (is_string($list)) {
- $list = explode($sep, $list);
- if ($trim) {
- $list = array_map('trim', $list);
- }
- if ($assoc) {
- return Set::normalize($list);
- }
- } elseif (is_array($list)) {
- $keys = array_keys($list);
- $count = count($keys);
- $numeric = true;
-
- if (!$assoc) {
- for ($i = 0; $i < $count; $i++) {
- if (!is_int($keys[$i])) {
- $numeric = false;
- break;
- }
- }
- }
- if (!$numeric || $assoc) {
- $newList = array();
- for ($i = 0; $i < $count; $i++) {
- if (is_int($keys[$i])) {
- $newList[$list[$keys[$i]]] = null;
- } else {
- $newList[$keys[$i]] = $list[$keys[$i]];
- }
- }
- $list = $newList;
- }
- }
- return $list;
- }
-/**
- * Creates an associative array using a $path1 as the path to build its keys, and optionally
- * $path2 as path to get the values. If $path2 is not specified, all values will be initialized
- * to null (useful for Set::merge). You can optionally group the values by what is obtained when
- * following the path specified in $groupPath.
- *
- * @param array $data Array from where to extract keys and values
- * @param mixed $path1 As an array, or as a dot-separated string.
- * @param mixed $path2 As an array, or as a dot-separated string.
- * @param string $groupPath As an array, or as a dot-separated string.
- * @return array Combined array
- * @access public
- */
- function combine($data, $path1 = null, $path2 = null, $groupPath = null) {
- if (is_a($this, 'set') && is_string($data) && is_string($path1) && is_string($path2)) {
- $groupPath = $path2;
- $path2 = $path1;
- $path1 = $data;
- $data = $this->get();
-
- } elseif (is_a($this, 'set') && is_string($data) && empty($path2)) {
- $path2 = $path1;
- $path1 = $data;
- $data = $this->get();
- }
-
- if (is_object($data)) {
- $data = get_object_vars($data);
- }
-
- if (is_array($path1)) {
- $format = array_shift($path1);
- $keys = Set::format($data, $format, $path1);
- } else {
- $keys = Set::extract($data, $path1);
- }
-
- if (!empty($path2) && is_array($path2)) {
- $format = array_shift($path2);
- $vals = Set::format($data, $format, $path2);
-
- } elseif (!empty($path2)) {
- $vals = Set::extract($data, $path2);
-
- } else {
- $count = count($keys);
- for ($i = 0; $i < $count; $i++) {
- $vals[$i] = null;
- }
- }
-
- if ($groupPath != null) {
- $group = Set::extract($data, $groupPath);
- if (!empty($group)) {
- $c = count($keys);
- for ($i = 0; $i < $c; $i++) {
- if (!isset($group[$i])) {
- $group[$i] = 0;
- }
- if (!isset($out[$group[$i]])) {
- $out[$group[$i]] = array();
- }
- $out[$group[$i]][$keys[$i]] = $vals[$i];
- }
- return $out;
- }
- }
-
- return array_combine($keys, $vals);
- }
-/**
- * Converts an object into an array
- *
- * @param object $object
- * @return array
- */
- function reverse($object) {
- if (is_a($object, 'xmlnode') || is_a($object, 'XMLNode')) {
- if ($object->name != Inflector::underscore($this->name)) {
- if (is_object($object->child(Inflector::underscore($this->name)))) {
- $object = $object->child(Inflector::underscore($this->name));
- $object = $object->attributes;
- } else {
- return null;
- }
- }
- } else {
- $out = array();
- if (is_object($object)) {
- $keys = get_object_vars($object);
- if (isset($keys['_name_'])) {
- $identity = $keys['_name_'];
- unset($keys['_name_']);
- }
- $new = array();
- foreach ($keys as $key => $value) {
- if (is_array($value)) {
- $new[$key] = (array)Set::reverse($value);
- } else {
- $new[$key] = Set::reverse($value);
- }
- }
- if (isset($identity)) {
- $out[$identity] = $new;
- } else {
- $out = $new;
- }
- } elseif (is_array($object)) {
- foreach ($object as $key => $value) {
- $out[$key] = Set::reverse($value);
- }
- } else {
- $out = $object;
- }
- return $out;
- }
- return $object;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/validators.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/validators.php
deleted file mode 100644
index cbd7c03..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/validators.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/* SVN FILE: $Id: validators.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Tort Validators
- *
- * Used to validate data in Models.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Not empty.
- */
- define('VALID_NOT_EMPTY', '/.+/');
-/**
- * Numbers [0-9] only.
- */
- define('VALID_NUMBER', '/^[-+]?\\b[0-9]*\\.?[0-9]+\\b$/');
-/**
- * A valid email address.
- */
- define('VALID_EMAIL', '/\\A(?:^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$)\\z/i');
-/**
- * A valid year (1000-2999).
- */
- define('VALID_YEAR', '/^[12][0-9]{3}$/');
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helper.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helper.php
deleted file mode 100644
index 99ec582..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helper.php
+++ /dev/null
@@ -1,167 +0,0 @@
-<?php
-/* SVN FILE: $Id: helper.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Backend for helpers.
- *
- * Internal methods for the Helpers.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Backend for helpers.
- *
- * Long description for class
- *
- * @package cake
- * @subpackage cake.cake.libs.view
- */
-class Helper extends Object {
-/**
- * Holds tag templates.
- *
- * @access public
- * @var array
- */
- var $tags = array('link' => '<a href="%s" %s>%s</a>',
- 'mailto' => '<a href="mailto:%s" %s>%s</a>',
- 'form' => '<form %s>',
- 'input' => '<input name="data[%s][%s]" %s/>',
- 'textarea' => '<textarea name="data[%s][%s]" %s>%s</textarea>',
- 'hidden' => '<input type="hidden" name="data[%s][%s]" %s/>',
- 'textarea' => '<textarea name="data[%s][%s]" %s>%s</textarea>',
- 'checkbox' => '<input type="checkbox" name="data[%s][%s]" %s/>',
- 'radio' => '<input type="radio" name="data[%s][%s]" id="%s" %s />%s',
- 'selectstart' => '<select name="data[%s][%s]" %s>',
- 'selectmultiplestart' => '<select name="data[%s][%s][]" %s>',
- 'selectempty' => '<option value="" %s>&nbsp;</option>',
- 'selectoption' => '<option value="%s" %s>%s</option>',
- 'selectend' => '</select>',
- 'password' => '<input type="password" name="data[%s][%s]" %s/>',
- 'file' => '<input type="file" name="data[%s][%s]" %s/>',
- 'file_no_model' => '<input type="file" name="%s" %s/>',
- 'submit' => '<input type="submit" %s/>',
- 'image' => '<img src="%s" %s/>',
- 'tableheader' => '<th%s>%s</th>',
- 'tableheaderrow' => '<tr%s>%s</tr>',
- 'tablecell' => '<td%s>%s</td>',
- 'tablerow' => '<tr%s>%s</tr>',
- 'block' => '<div%s>%s</div>',
- 'blockstart' => '<div%s>',
- 'blockend' => '</div>',
- 'css' => '<link rel="%s" type="text/css" href="%s" %s/>',
- 'style' => '<style type="text/css"%s>%s</style>',
- 'charset' => '<meta http-equiv="Content-Type" content="text/html; charset=%s" />',
- 'javascriptblock' => '<script type="text/javascript">%s</script>',
- 'javascriptlink' => '<script type="text/javascript" src="%s"></script>');
-/**
- * Parses custom config/tags.ini.php and merges with $this->tags.
- *
- * @return html tags used by helpers
- */
- function loadConfig() {
-
- if (file_exists(APP . 'config' . DS . 'tags.ini.php')) {
- $tags = $this->readConfigFile(APP . 'config' . DS . 'tags.ini.php');
- $this->tags = am($this->tags, $tags);
- }
- return $this->tags;
- }
-/**
- * Decides whether to output or return a string.
- *
- * Based on AUTO_OUTPUT and $return's value, this method decides whether to
- * output a string, or return it.
- *
- * @param string $str String to be output or returned.
- * @param boolean $return Whether this method should return a value or output it.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- */
- function output($str, $return = false) {
- if (AUTO_OUTPUT && $return === false) {
- echo $str;
- } else {
- return $str;
- }
- }
-/**
- * Assigns values to tag templates.
- *
- * Finds a tag template by $keyName, and replaces $values's keys with
- * $values's keys.
- *
- * @param string $keyName Name of the key in the tag array.
- * @param array $values Values to be inserted into tag.
- * @return string Tag with inserted values.
- */
- function assign($keyName, $values) {
- return str_replace('%%' . array_keys($values) . '%%', array_values($values), $this->tags[$keyName]);
- }
-/**
- * Returns an array of settings in given INI file.
- *
- * @param string $fileName ini file to read
- * @return array of lines from the $fileName
- */
- function readConfigFile($fileName) {
- $fileLineArray = file($fileName);
-
- foreach ($fileLineArray as $fileLine) {
- $dataLine = trim($fileLine);
- $firstChar = substr($dataLine, 0, 1);
-
- if ($firstChar != ';' && $dataLine != '') {
- if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
- // [section block] we might use this later do not know for sure
- // this could be used to add a key with the section block name
- // but it adds another array level
- } else {
- $delimiter = strpos($dataLine, '=');
-
- if ($delimiter > 0) {
- $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
- $value = trim(stripcslashes(substr($dataLine, $delimiter + 1)));
-
- if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
- $value = substr($value, 1, -1);
- }
-
- $iniSetting[$key] = $value;
-
- } else {
- $iniSetting[strtolower(trim($dataLine))] = '';
- }
- }
- } else {
- }
- }
-
- return $iniSetting;
- }
-/**
- * After render callback. Overridden in subclasses.
- *
- * @return void
- */
- function afterRender() {
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/ajax.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/ajax.php
deleted file mode 100644
index 9e14931..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/ajax.php
+++ /dev/null
@@ -1,853 +0,0 @@
-<?php
-/* SVN FILE: $Id: ajax.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Helper for AJAX operations.
- *
- * Helps doing AJAX using the Prototype library.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * AjaxHelper library.
- *
- * Helps doing AJAX using the Prototype library.
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class AjaxHelper extends Helper {
-/**
- * Included helpers.
- *
- * @var array
- * @access public
- */
- var $helpers = array('Html', 'Javascript');
-/**
- * Names of Javascript callback functions.
- *
- * @var array
- * @access public
- */
- var $callbacks = array('uninitialized', 'loading', 'loaded', 'interactive', 'complete', 'success', 'failure');
-/**
- * Names of AJAX options.
- *
- * @var array
- * @access public
- */
- var $ajaxOptions = array('type', 'confirm', 'condition', 'before', 'after', 'fallback', 'update', 'loading', 'loaded', 'interactive', 'complete', 'with', 'url', 'method', 'position', 'form', 'parameters', 'evalScripts', 'asynchronous', 'onComplete', 'onUninitialized', 'onLoading', 'onLoaded', 'onInteractive', 'success', 'failure', 'onSuccess', 'onFailure', 'insertion', 'requestHeaders');
-/**
- * Options for draggable.
- *
- * @var array
- * @access public
- */
- var $dragOptions = array('handle', 'revert', 'constraint', 'change', 'ghosting');
-/**
- * Options for droppable.
- *
- * @var array
- * @access public
- */
- var $dropOptions = array('accept', 'containment', 'overlap', 'greedy', 'hoverclass', 'onHover', 'onDrop');
-/**
- * Options for sortable.
- *
- * @var array
- * @access public
- */
- var $sortOptions = array('tag', 'only', 'overlap', 'constraint', 'containment', 'handle', 'hoverclass', 'ghosting', 'dropOnEmpty', 'onUpdate', 'onChange');
-/**
- * Options for slider.
- *
- * @var array
- * @access public
- */
- var $sliderOptions = array('axis', 'increment', 'maximum', 'minimum', 'alignX', 'alignY', 'sliderValue', 'disabled', 'handleImage', 'handleDisabled', 'values', 'onSlide', 'onChange');
-/**
- * Options for in-place editor.
- *
- * @var array
- * @access public
- */
- var $editorOptions = array('okText', 'cancelText', 'savingText', 'formId', 'externalControl', 'rows', 'cols', 'size', 'highlightcolor', 'highlightendcolor', 'savingClassName', 'formClassName', 'loadTextURL', 'loadingText', 'callback', 'ajaxOptions', 'clickToEditText');
-/**
- * Options for auto-complete editor.
- *
- * @var array
- * @access public
- */
- var $autoCompleteOptions = array('paramName', 'tokens', 'frequency', 'minChars', 'indicator', 'updateElement', 'afterUpdateElement', 'onShow', 'onHide');
-/**
- * Output buffer for Ajax update content
- *
- * @var array
- * @access private
- */
- var $__ajaxBuffer = array();
-/**
- * Returns link to remote action
- *
- * Returns a link to a remote action defined by <i>options[url]</i>
- * (using the urlFor format) that's called in the background using
- * XMLHttpRequest. The result of that request can then be inserted into a
- * DOM object whose id can be specified with <i>options[update]</i>.
- *
- * Examples:
- * <code>
- * $ajax->link("Delete this post", "/posts/delete/{$post['Post']['id']}"
- * array("update" => "posts", "loading"=>"Element.show('loading');", "complete"=>"Element.hide('loading');"),
- * "Are you sure you want to delte this post?");
- * $ajax->link($html->img("refresh"), '/emails/refresh',
- * array("update" => "posts", "loading"=>"Element.show('loading');", "complete"=>"Element.hide('loading');"),
- * null, false);
- * </code>
- *
- * By default, these remote requests are processed asynchronous during
- * which various callbacks can be triggered (for progress indicators and
- * the likes).
- *
- * The callbacks that may be specified are:
- *
- * - <i>loading</i>:: Called when the remote document is being
- * loaded with data by the browser.
- * - <i>loaded</i>:: Called when the browser has finished loading
- * the remote document.
- * - <i>interactive</i>:: Called when the user can interact with the
- * remote document, even though it has not
- * finished loading.
- * - <i>complete</i>:: Called when the request is complete.
- *
- * If you for some reason or another need synchronous processing (that'll
- * block the browser while the request is happening), you can specify
- * <i>$options['type'] = synchronous</i>.
- *
- * You can customize further browser side call logic by passing
- * in Javascript code snippets via some optional parameters. In
- * their order of use these are:
- *
- * - <i>confirm</i> :: Adds confirmation dialog.
- * - <i>condition</i> :: Perform remote request conditionally
- * by this expression. Use this to
- * describe browser-side conditions when
- * request should not be initiated.
- * - <i>before</i> :: Called before request is initiated.
- * - <i>after</i> :: Called immediately after request was
- * initiated and before <i>loading</i>.
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Updater
- * @param string $title Title of link
- * @param string $href href string "/products/view/12"
- * @param array $options Options for JavaScript function
- * @param string $confirm Confirmation message. Calls up a JavaScript confirm() message.
- * @param boolean $escapeTitle Escaping the title string to HTML entities
- * @return HTML code for link to remote action
- * @access public
- */
- function link($title, $href = null, $options = array(), $confirm = null, $escapeTitle = true) {
- if (!isset($href)) {
- $href = $title;
- }
-
- if (!isset($options['url'])) {
- $options['url'] = $href;
- }
-
- if (isset($confirm)) {
- $options['confirm'] = $confirm;
- unset($confirm);
- }
- $htmlOptions = $this->__getHtmlOptions($options);
-
- if (empty($options['fallback']) || !isset($options['fallback'])) {
- $options['fallback'] = $href;
- }
-
- if (!isset($htmlOptions['id'])) {
- $htmlOptions['id'] = 'link' . intval(rand());
- }
-
- if (!isset($htmlOptions['onclick'])) {
- $htmlOptions['onclick'] = '';
- }
- $htmlOptions['onclick'] .= ' event.returnValue = false; return false;';
- $return = $this->Html->link($title, $href, $htmlOptions, null, $escapeTitle);
- $script = $this->Javascript->event("'{$htmlOptions['id']}'", "click", $this->remoteFunction($options));
-
- if (is_string($script)) {
- $return .= $script;
- }
- return $return;
- }
-/**
- * Creates JavaScript function for remote AJAX call
- *
- * This function creates the javascript needed to make a remote call
- * it is primarily used as a helper for link.
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Updater
- * @see link() for docs on options parameter.
- * @param array $options options for javascript
- * @return string html code for link to remote action
- * @access public
- */
- function remoteFunction($options = null) {
- if (isset($options['update'])) {
- if (!is_array($options['update'])) {
- $func = "new Ajax.Updater('{$options['update']}',";
- } else {
- $func = "new Ajax.Updater(document.createElement('div'),";
- }
- if (!isset($options['requestHeaders'])) {
- $options['requestHeaders'] = array();
- }
- if (is_array($options['update'])) {
- $options['update'] = join(' ', $options['update']);
- }
- $options['requestHeaders']['X-Update'] = $options['update'];
- } else {
- $func = "new Ajax.Request(";
- }
-
- $func .= "'" . $this->Html->url(isset($options['url']) ? $options['url'] : "") . "'";
- $func .= ", " . $this->__optionsForAjax($options) . ")";
-
- if (isset($options['before'])) {
- $func = "{$options['before']}; $func";
- }
-
- if (isset($options['after'])) {
- $func = "$func; {$options['after']};";
- }
-
- if (isset($options['condition'])) {
- $func = "if ({$options['condition']}) { $func; }";
- }
-
- if (isset($options['confirm'])) {
- $func = "if (confirm('" . $this->Javascript->escapeString($options['confirm'])
- . "')) { $func; } else { event.returnValue = false; return false; }";
- }
- return $func;
- }
-/**
- * Periodically call remote url via AJAX.
- *
- * Periodically calls the specified url (<i>options['url']</i>) every <i>options['frequency']</i> seconds (default is 10).
- * Usually used to update a specified div (<i>options['update']</i>) with the results of the remote call.
- * The options for specifying the target with url and defining callbacks is the same as link.
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Updater
- * @param array $options Callback options
- * @return string Javascript codeblock
- * @access public
- */
- function remoteTimer($options = null) {
- $frequency=(isset($options['frequency'])) ? $options['frequency'] : 10;
- $code="new PeriodicalExecuter(function() {" . $this->remoteFunction($options) . "}, $frequency)";
- return $this->Javascript->codeBlock($code);
- }
-/**
- * Returns form tag that will submit using Ajax.
- *
- * Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular
- * reloading POST arrangement. Even though it's using Javascript to serialize the form elements, the form submission
- * will work just like a regular submission as viewed by the receiving side (all elements available in params).
- * The options for defining callbacks is the same as link().
- *
- * @param array $params Form target
- * @param array $type How form data is posted: 'get' or 'post'
- * @param array $options Callback/HTML options
- * @return string JavaScript/HTML code
- * @access public
- */
- function form($params = null, $type = 'post', $options = array()) {
- if (is_array($params)) {
- extract($params, EXTR_OVERWRITE);
-
- if (!isset($action)) {
- $action = null;
- }
-
- if (!isset($type)) {
- $type = 'post';
- }
-
- if (!isset($options)) {
- $options = array();
- }
- } else {
- $action = $params;
- }
- $htmlOptions = $this->__getHtmlOptions($options);
- $htmlOptions['action'] = $action;
-
- if (!isset($htmlOptions['id'])) {
- $htmlOptions['id'] = 'form' . intval(rand());
- }
- $htmlOptions['onsubmit']="event.returnValue = false; return false;";
-
- if (!isset($options['with'])) {
- $options['with'] = "Form.serialize('{$htmlOptions['id']}')";
- }
- $options['url']=$action;
-
- return $this->Html->formTag($htmlOptions['action'], $type, $htmlOptions)
- . $this->Javascript->event("'" . $htmlOptions['id']. "'", "submit", $this->remoteFunction($options));
- }
-/**
- * Returns a button input tag that will submit using Ajax
- *
- * Returns a button input tag that will submit form using XMLHttpRequest in the background instead of regular
- * reloading POST arrangement. <i>options</i> argument is the same as in <i>form_remote_tag</i>
- *
- * @param string $title Input button title
- * @param array $options Callback options
- * @return string Ajaxed input button
- * @access public
- */
- function submit($title = 'Submit', $options = array()) {
- $htmlOptions =$this->__getHtmlOptions($options);
- $htmlOptions['value']=$title;
-
- if (!isset($options['with'])) {
- $options['with'] = 'Form.serialize(Event.element(event).form)';
- }
-
- if (!isset($htmlOptions['id'])) {
- $htmlOptions['id'] = 'submit' . intval(rand());
- }
- $htmlOptions['onclick']="event.returnValue = false; return false;";
- return $this->Html->submit($title, $htmlOptions)
- . $this->Javascript->event('"' . $htmlOptions['id'] . '"', 'click', $this->remoteFunction($options));
- }
-/**
- * Observe field and call ajax on change.
- *
- * Observes the field with the DOM ID specified by <i>field_id</i> and makes
- * an Ajax when its contents have changed.
- *
- * Required +options+ are:
- * - <i>frequency</i>:: The frequency (in seconds) at which changes to
- * this field will be detected.
- * - <i>url</i>:: @see urlFor() -style options for the action to call
- * when the field has changed.
- *
- * Additional options are:
- * - <i>update</i>:: Specifies the DOM ID of the element whose
- * innerHTML should be updated with the
- * XMLHttpRequest response text.
- * - <i>with</i>:: A Javascript expression specifying the
- * parameters for the XMLHttpRequest. This defaults
- * to Form.Element.serialize('$field_id'), which can be
- * accessed from params['form']['field_id'].
- *
- * @see link().
- * @param string $field_id DOM ID of field to observe
- * @param array $options ajax options
- * @return string ajax script
- * @access public
- */
- function observeField($field_id, $options = array()) {
- if (!isset($options['with'])) {
- $options['with'] = "Form.Element.serialize('$field_id')";
- }
- return $this->Javascript->codeBlock($this->_buildObserver('Form.Element.Observer', $field_id, $options));
- }
-/**
- * Observe entire form and call ajax on change.
- *
- * Like @see observeField(), but operates on an entire form identified by the
- * DOM ID <b>form_id</b>. <b>options</b> are the same as <b>observe_field</b>, except
- * the default value of the <i>with</i> option evaluates to the
- * serialized (request string) value of the form.
- *
- * @param string $field_id DOM ID of field to observe
- * @param array $options ajax options
- * @return string ajax script
- * @access public
- */
- function observeForm($field_id, $options = array()) {
- if (!isset($options['with'])) {
- $options['with'] = 'Form.serialize("' . $field_id . '")';
- }
- return $this->Javascript->codeBlock($this->_buildObserver('Form.Observer', $field_id, $options));
- }
-/**
- * Create a text field with Autocomplete.
- *
- * Creates an autocomplete field with the given ID and options.
- *
- * options['with'] defaults to "Form.Element.serialize('$field_id')",
- * but can be any valid javascript expression defining the
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter
- * @param string $field_id DOM ID of field to observe
- * @param string $url URL for the autocomplete action
- * @param array $options Ajax options
- * @return string Ajax script
- * @access public
- */
- function autoComplete($field, $url = "", $options = array()) {
- $var = '';
- if (isset($options['var'])) {
- $var = 'var ' . $options['var'] . ' = ';
- unset($options['var']);
- }
-
- if (!isset($options['id'])) {
- $options['id'] = Inflector::camelize(r("/", "_", $field));
- }
- $divOptions = array('id' => $options['id'] . "_autoComplete", 'class' => isset($options['class']) ? $options['class'] : 'auto_complete');
-
- if (isset($options['div_id'])) {
- $divOptions['id'] = $options['div_id'];
- unset($options['div_id']);
- }
- $htmlOptions = $this->__getHtmlOptions($options);
- $htmlOptions['autocomplete'] = "off";
-
- foreach ($this->autoCompleteOptions as $opt) {
- unset($htmlOptions[$opt]);
- }
-
- if (isset($options['tokens'])) {
- if (is_array($options['tokens'])) {
- $options['tokens'] = $this->Javascript->object($options['tokens']);
- } else {
- $options['tokens'] = '"' . $options['tokens'] . '"';
- }
- }
- $options = $this->_optionsToString($options, array('paramName', 'indicator'));
- $options = $this->_buildOptions($options, $this->autoCompleteOptions);
- return $this->Html->input($field, $htmlOptions) . "\n" .
- $this->Html->tag('div', $divOptions, true) . "</div>\n" .
- $this->Javascript->codeBlock("{$var}new Ajax.Autocompleter('" . $htmlOptions['id']
- . "', '" . $divOptions['id'] . "', '" . $this->Html->url($url) . "', " .
- $options . ");");
- }
-/**
- * Setup a Draggable Element.
- * For a reference on the options for this function, check out
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Draggable
- * @param sting $id the DOM id to enable
- * @param array $options a set of options
- * @return string Javascript::codeBlock();
- * @access public
- */
- function drag($id, $options = array()) {
- return $this->Javascript->codeBlock("new Draggable('$id', " . $this->_optionsForDraggable($options) . ");");
- }
-/**
- * Creates an Ajax-updateable DIV element
- *
- * @param string $id options for javascript
- * @param array $options a set of options
- * @return string HTML code
- * @access public
- */
- function div($id, $options = array()) {
- if (env('HTTP_X_UPDATE') != null) {
- $divs = explode(' ', env('HTTP_X_UPDATE'));
- if (in_array($id, $divs)) {
- @ob_end_clean();
- ob_start();
- return '';
- }
- }
- $attr = $this->Html->_parseAttributes(am($options, array('id' => $id)));
- return $this->output(sprintf($this->tags['blockstart'], $attr));
- }
-/**
- * Closes an Ajax-updateable DIV element
- *
- * @param string $id The DOM ID of the element
- * @return string HTML code
- * @access public
- */
- function divEnd($id) {
- if (env('HTTP_X_UPDATE') != null) {
- $divs = explode(' ', env('HTTP_X_UPDATE'));
- if (in_array($id, $divs)) {
- $this->__ajaxBuffer[$id] = ob_get_contents();
- ob_end_clean();
- return '';
- }
- }
- return $this->output($this->tags['blockend']);
- }
-/**
- * Protectd helper method to return an array of options for draggable.
- *
- * @param array $options
- * @return array
- * @access protected
- */
- function _optionsForDraggable($options) {
- $options = $this->_optionsToString($options, array('handle', 'constraint'));
- return $this->_buildOptions($options, $this->dragOptions);
- }
-/**
- * Setup a droppable element
- * For a reference on the options for this function, check out
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Droppables.add
- * @param string $id
- * @param array $options
- * @return array
- * @access public
- */
- function drop($id, $options = array()) {
- $options = $this->_optionsForDroppable($options);
- return $this->Javascript->codeBlock("Droppables.add('$id', $options);");
- }
-/**
- * Protected helper method to return an array of options for droppable.
- *
- * @param string $options
- * @return string String of Javascript array definition
- * @access protected
- */
- function _optionsForDroppable($options) {
- $options = $this->_optionsToString($options, array('accept', 'overlap', 'hoverclass'));
- return $this->_buildOptions($options, $this->dropOptions);
- }
-/**
- * Setup a remote droppable element.
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Droppables.add
- * @see link() and remoteFunction()
- * @param string $id DOM id of droppable
- * @param array $options ame as drop()
- * @param array $ajaxOptions same as remoteFunction()
- * @return string Javascript::codeBlock()
- * @access public
- */
- function dropRemote($id, $options = array(), $ajaxOptions = array()) {
- $options['onDrop'] = "function(element) {" . $this->remoteFunction($ajaxOptions) . "}";
- $options = $this->_optionsForDroppable($options);
- return $this->Javascript->codeBlock("Droppables.add('$id', $options);");
- }
-/**
- * Makes a slider control.
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Slider
- * @param string $id DOM ID of slider handle
- * @param string $track_id DOM ID of slider track
- * @param array $options Array of options to control the slider
- * @return string Javascript::codeBlock()
- * @access public
- */
- function slider($id, $track_id, $options = array()) {
- $options = $this->_optionsToString($options, array('axis', 'handleImage', 'handleDisabled'));
-
- if (isset($options['change'])) {
- $options['onChange'] = $options['change'];
- unset($options['change']);
- }
-
- if (isset($options['slide'])) {
- $options['onSlide'] = $options['slide'];
- unset($options['slide']);
- }
-
- $options = $this->_buildOptions($options, $this->sliderOptions);
- return $this->Javascript->codeBlock("var $id = new Control.Slider('$id', '$track_id', $options);");
- }
-/**
- * Makes an Ajax In Place editor control.
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
- * @param string $id DOM ID of input element
- * @param string $url Postback URL of saved data
- * @param array $options Array of options to control the editor, including ajaxOptions (see link).
- * @return string Javascript::codeBlock()
- * @access public
- */
- function editor($id, $url, $options = array()) {
- $url = $this->Html->url($url);
- $options['ajaxOptions'] = $this->__optionsForAjax($options);
-
- foreach ($this->ajaxOptions as $opt) {
- if (isset($options[$opt])) {
- unset($options[$opt]);
- }
- }
-
- if (isset($options['callback'])) {
- $options['callback'] = 'function(form, value) {' . $options['callback'] . '}';
- }
-
- $options = $this->_optionsToString($options, array('okText', 'cancelText', 'savingText', 'formId', 'externalControl', 'highlightcolor', 'highlightendcolor', 'savingClassName', 'formClassName', 'loadTextURL', 'loadingText', 'clickToEditText'));
- $options = $this->_buildOptions($options, $this->editorOptions);
- return $this->Javascript->codeBlock("new Ajax.InPlaceEditor('{$id}', '{$url}', {$options});");
- }
-/**
- * Makes a list or group of floated objects sortable.
- *
- * @link http://wiki.script.aculo.us/scriptaculous/show/Sortable.create
- * @param string $id DOM ID of parent
- * @param array $options Array of options to control sort
- * @return string Javascript::codeBlock()
- * @access public
- */
- function sortable($id, $options = array()) {
- if (!empty($options['url'])) {
- $options['with'] = "Sortable.serialize('$id')";
- $options['onUpdate'] = 'function(sortable) {' . $this->remoteFunction($options) . '}';
- }
-
- $options = $this->__optionsForSortable($options);
- return $this->Javascript->codeBlock("Sortable.create('$id', $options);");
- }
-/**
- * Private method; generates sortables code from array options
- *
- * @param array $options
- * @return string String of Javascript array definition
- * @access private
- */
- function __optionsForSortable($options) {
- $options = $this->_optionsToString($options, array('handle', 'tag', 'constraint', 'ghosting', 'only', 'hoverclass'));
- return $this->_buildOptions($options, $this->sortOptions);
- }
-/**
- * Private helper function for Ajax.
- *
- * @param array $options
- * @return string String of Javascript array definition
- * @access private
- */
- function __optionsForAjax($options = array()) {
-
- if (isset($options['indicator'])) {
- if (isset($options['loading'])) {
- $options['loading'] .= "Element.show('{$options['indicator']}');";
- } else {
- $options['loading'] = "Element.show('{$options['indicator']}');";
- }
- if (isset($options['complete'])) {
- $options['complete'] .= "Element.hide('{$options['indicator']}');";
- } else {
- $options['complete'] = "Element.hide('{$options['indicator']}');";
- }
- unset($options['indicator']);
- }
-
- $jsOptions = am(
- array('asynchronous' => 'true', 'evalScripts' => 'true'),
- $this->_buildCallbacks($options)
- );
- $options = $this->_optionsToString($options, array('method'));
-
- foreach ($options as $key => $value) {
- switch($key) {
- case 'type':
- $jsOptions['asynchronous'] = ife(($value == 'synchronous'), 'false', 'true');
- break;
- case 'evalScripts':
- $jsOptions['evalScripts'] = ife($value, 'true', 'false');
- break;
- case 'position':
- $jsOptions['insertion'] = "Insertion." . Inflector::camelize($options['position']);
- break;
- case 'with':
- $jsOptions['parameters'] = $options['with'];
- break;
- case 'form':
- $jsOptions['parameters'] = 'Form.serialize(this)';
- break;
- case 'requestHeaders':
- $keys = array();
- foreach ($value as $key => $val) {
- $keys[] = "'" . $key . "'";
- $keys[] = "'" . $val . "'";
- }
- $jsOptions['requestHeaders'] = '[' . join(', ', $keys) . ']';
- break;
- }
- }
- return $this->_buildOptions($jsOptions, $this->ajaxOptions);
- }
-/**
- * Private Method to return a string of html options
- * option data as a JavaScript options hash.
- *
- * @param array $options Options in the shape of keys and values
- * @param array $extra Array of legal keys in this options context
- * @return array Array of html options
- * @access private
- */
- function __getHtmlOptions($options, $extra = array()) {
- foreach ($this->ajaxOptions as $key) {
- if (isset($options[$key])) {
- unset($options[$key]);
- }
- }
-
- foreach ($extra as $key) {
- if (isset($options[$key])) {
- unset($options[$key]);
- }
- }
- return $options;
- }
-/**
- * Protected Method to return a string of JavaScript with the given
- * option data as a JavaScript options hash.
- *
- * @param array $options Options in the shape of keys and values
- * @param array $acceptable Array of legal keys in this options context
- * @return string String of Javascript array definition
- * @access protected
- */
- function _buildOptions($options, $acceptable) {
- if (is_array($options)) {
- $out = array();
-
- foreach ($options as $k => $v) {
- if (in_array($k, $acceptable)) {
- $out[] = "$k:$v";
- }
- }
-
- $out = join(', ', $out);
- $out = '{' . $out . '}';
- return $out;
- } else {
- return false;
- }
- }
-/**
- * Protected Method to return JavaScript text for an observer...
- *
- * @param string $klass Name of JavaScript class
- * @param string $name
- * @param array $options Ajax options
- * @return string Formatted JavaScript
- * @access protected
- */
- function _buildObserver($klass, $name, $options = null) {
- if (!isset($options['with']) && isset($options['update'])) {
- $options['with'] = 'value';
- }
-
- $callback = $this->remoteFunction($options);
- $javascript = "new $klass('$name', ";
- $javascript .= (isset($options['frequency']) ? $options['frequency'] : 2) . ", function(element, value) {";
- $javascript .= "$callback})";
- return $javascript;
- }
-/**
- * Protected Method to return JavaScript text for all callbacks...
- *
- * @param array $options
- * @return array
- * @access protected
- */
- function _buildCallbacks($options) {
- $callbacks = array();
-
- foreach ($this->callbacks as $callback) {
- if (isset($options[$callback])) {
- $name = 'on' . ucfirst($callback);
- $code = $options[$callback];
- $callbacks[$name] = "function(request) {" . $code . "}";
- }
- }
- return $callbacks;
- }
-/**
- * Protected Method to return a string of JavaScript with a string representation
- * of given options array.
- *
- * @param array $options Ajax options array
- * @param array $stringOpts Options as strings in an array
- * @access private
- * @return array
- * @access protected
- */
- function _optionsToString($options, $stringOpts = array()) {
- foreach ($stringOpts as $option) {
- if (isset($options[$option]) && !$options[$option][0] != "'") {
- if ($options[$option] === true || $options[$option] === 'true') {
- $options[$option] = 'true';
- } elseif ($options[$option] === false || $options[$option] === 'false') {
- $options[$option] = 'false';
- } else {
- $options[$option] = "'{$options[$option]}'";
- }
- }
- }
- return $options;
- }
-/**
- * afterRender callback
- *
- * @return array
- * @access public
- */
- function afterRender() {
- if (env('HTTP_X_UPDATE') != null && count($this->__ajaxBuffer) > 0) {
- $data = array();
- $divs = explode(' ', env('HTTP_X_UPDATE'));
-
- foreach ($this->__ajaxBuffer as $key => $val) {
- if (in_array($key, $divs)) {
- $data[] = $key . ':"' . rawurlencode($val) . '"';
- }
- }
-
- $out = 'var __ajaxUpdater__ = {' . join(', ', $data) . '};' . "\n";
- $out .= 'for (n in __ajaxUpdater__) { if (typeof __ajaxUpdater__[n] == "string" && $(n)) Element.update($(n), unescape(decodeURIComponent(__ajaxUpdater__[n]))); }';
-
- @ob_end_clean();
- e($this->Javascript->codeBlock($out));
- exit();
- }
- }
-/**
- * Replaced by AjaxHelper::link()
- *
- * @deprecated will not be avialable after 1.1.x.x
- */
- function linkToRemote($title, $options = array(), $html_options = array()) {
- trigger_error('Deprecated function: use AjaxHelper::link', E_USER_WARNING);
- $href = '#';
-
- if (!empty($options['fallback']) && isset($options['fallback'])) {
- $href = $options['fallback'];
- }
-
- if (isset($html_options['id'])) {
- return $this->Html->link($title, $href, $html_options) .
- $this->Javascript->event("$('{$html_options['id']}')", "click", $this->remoteFunction($options));
- } else {
- $html_options['onclick'] = $this->remoteFunction($options) . "; event.returnValue = false; return false;";
- return $this->Html->link($title, $href, $html_options);
- }
- }
-}
-
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/cache.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/cache.php
deleted file mode 100644
index 99d609f..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/cache.php
+++ /dev/null
@@ -1,272 +0,0 @@
-<?php
-/* SVN FILE: $Id: cache.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 1.0.0.2277
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class CacheHelper extends Helper{
-/**
- * Array of strings replaced in cached views.
- * The strings are found between <cake:nocache><cake:nocache> in views
- *
- * @var array
- * @access private
- */
- var $__replace = array();
-/**
- * Array of string that are replace with there var replace above.
- * The strings are any content inside <cake:nocache><cake:nocache> and includes the tags in views
- *
- * @var array
- * @access private
- */
- var $__match = array();
-/**
- * holds the View object passed in final call to CacheHelper::cache()
- *
- * @var object
- * @access public
- */
- var $view;
-/**
- * Main method used to cache a view
- *
- * @param string $file File to cache
- * @param string $out output to cache
- * @param boolean $cache
- * @return view ouput
- */
- function cache($file, $out, $cache = false) {
- if (is_array($this->cacheAction)) {
- $check = str_replace('/', '_', $this->here);
- $replace = str_replace('/', '_', $this->base);
- $match = str_replace($this->base, '', $this->here);
- $match = str_replace('//', '/', $match);
- $match = str_replace('/' . $this->controllerName . '/', '', $match);
- $check = str_replace($replace, '', $check);
- $check = str_replace('_' . $this->controllerName . '_', '', $check);
- $check = convertSlash($check);
- $check = preg_replace('/^_+/', '', $check);
- $keys = str_replace('/', '_', array_keys($this->cacheAction));
- $found = array_keys($this->cacheAction);
- $index = null;
- $count = 0;
-
- foreach ($keys as $key => $value) {
- if (strpos($check, $value) === 0) {
- $index = $found[$count];
- break;
- }
- $count++;
- }
-
- if (isset($index)) {
- $pos1 = strrpos($match, '/');
- $char = strlen($match) - 1;
-
- if ($pos1 == $char) {
- $match = substr($match, 0, $char);
- }
-
- $key = $match;
- } elseif ($this->action == 'index') {
- $index = 'index';
- }
- if (isset($this->cacheAction[$index])) {
- $cacheTime = $this->cacheAction[$index];
- } else {
- $cacheTime = 0;
- }
- } else {
- $cacheTime = $this->cacheAction;
- }
-
- if ($cacheTime != '' && $cacheTime > 0) {
- $this->__parseFile($file, $out);
-
- if ($cache === true) {
- $cached = $this->__parseOutput($out);
- $this->__writeFile($cached, $cacheTime);
- }
- }
- return $out;
- }
-/**
- * Parse file searching for no cache tags
- *
- * @param string $file
- * @param boolean $cache
- * @access private
- */
- function __parseFile($file, $cache) {
- if (is_file($file)) {
- $file = file_get_contents($file);
- } elseif ($file = fileExistsInPath($file)) {
- $file = file_get_contents($file);
- }
-
- preg_match_all('/(<cake:nocache>(?<=<cake:nocache>)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $oresult, PREG_PATTERN_ORDER);
- preg_match_all('/(?<=<cake:nocache>)([\\s\\S]*?)(?=<\/cake:nocache>)/i', $file, $result, PREG_PATTERN_ORDER);
-
- if (!empty($this->__replace)) {
- foreach ($oresult['0'] as $k => $element) {
- if (array_search($element, $this->__match) !== false) {
- array_splice($oresult[0], $k, 1);
- }
- }
- }
-
- if (!empty($result['0'])) {
- $count = 0;
-
- foreach ($result['0'] as $block) {
- if (isset($oresult['0'][$count])) {
- $this->__replace[] = $block;
- $this->__match[] = $oresult['0'][$count];
- }
- $count++;
- }
- }
- }
-/**
- * Parse the output and replace cache tags
- *
- * @param sting $cache
- * @return string with all replacements made to <cake:nocache><cake:nocache>
- * @access private
- */
- function __parseOutput($cache) {
- $count = 0;
- if (!empty($this->__match)) {
-
- foreach ($this->__match as $found) {
- $original = $cache;
- $length = strlen($found);
- $position = 0;
-
- for ($i = 1; $i <= 1; $i++) {
- $position = strpos($cache, $found, $position);
-
- if ($position !== false) {
- $cache = substr($original, 0, $position);
- $cache .= $this->__replace[$count];
- $cache .= substr($original, $position + $length);
- } else {
- break;
- }
- }
- $count++;
- }
- return $cache;
- }
- return $cache;
- }
-/**
- * Write a cached version of the file
- *
- * @param string $content
- * @param sting $timestamp
- * @return cached view
- * @access private
- */
- function __writeFile($content, $timestamp) {
- $now = time();
-
- if (is_numeric($timestamp)) {
- $cacheTime = $now + $timestamp;
- } else {
- $cacheTime = strtotime($timestamp, $now);
- }
-
- $cache = convertSlash($this->here);
- if (empty($cache)) {
- return;
- }
-
- $cache = $cache . '.php';
- $file = '<!--cachetime:' . $cacheTime . '--><?php';
- if (empty($this->plugin)) {
- $file .= '
- loadController(\'' . $this->view->name. '\');
- loadModels();
- ';
- } else {
- $file .= '
- if (!class_exists(\'AppController\')) {
- if (file_exists(\'' . APP . 'app_controller.php\')) {
- require(\''. APP . 'app_controller.php\');
- } else {
- require(\''.CAKE . 'app_controller.php\');
- }
- }
- loadPluginController(\''.$this->plugin.'\',\''.$this->view->name.'\');
- loadPluginModels(\''.$this->plugin.'\');
- ';
- }
- $file .= '$this->controller = new ' . $this->view->name . 'Controller();
- $this->controller->plugin = \''.$this->plugin.'\';
- $this->controller->_initComponents();
- $this->helpers = unserialize(\'' . serialize($this->view->helpers) . '\');
- $this->base = \'' . $this->view->base . '\';
- $this->layout = \'' . $this->view->layout. '\';
- $this->webroot = \'' . $this->view->webroot . '\';
- $this->here = \'' . $this->view->here . '\';
- $this->params = unserialize(stripslashes(\'' . addslashes(serialize($this->view->params)) . '\'));
- $this->action = unserialize(\'' . serialize($this->view->action) . '\');
- $this->data = unserialize(stripslashes(\'' . addslashes(serialize($this->view->data)) . '\'));
- $this->themeWeb = \'' . $this->view->themeWeb . '\';
- $this->plugin = \'' . $this->view->plugin . '\';
- $loadedHelpers = array();
- $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
- foreach (array_keys($loadedHelpers) as $helper)
- {
- $replace = strtolower(substr($helper, 0, 1));
- $camelBackedHelper = preg_replace(\'/\\w/\', $replace, $helper, 1);
- ${$camelBackedHelper} =& $loadedHelpers[$helper];
-
- if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers))
- {
- foreach (${$camelBackedHelper}->helpers as $subHelper)
- {
- ${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper];
- }
- }
- $this->loaded[$camelBackedHelper] = (${$camelBackedHelper});
- }
- ?>';
- $content = preg_replace("/(<\\?xml)/", "<?php echo '$1';?>",$content);
- $file .= $content;
- return cache('views' . DS . $cache, $file, $timestamp);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/form.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/form.php
deleted file mode 100644
index d2d58a4..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/form.php
+++ /dev/null
@@ -1,491 +0,0 @@
-<?php
-/* SVN FILE: $Id: form.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Automatic generation of HTML FORMs from given data.
- *
- * Used for scaffolding.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Tag template for a div with a class attribute.
- */
- define('TAG_DIV', '<div class="%s">%s</div>');
-/**
- * Tag template for a paragraph with a class attribute.
- */
- define('TAG_P_CLASS', '<p class="%s">%s</p>');
-/**
- * Tag template for a label with a for attribute.
- */
- define('TAG_LABEL', '<label for="%s">%s</label>');
-/**
- * Tag template for a fieldset with a legend tag inside.
- */
- define('TAG_FIELDSET', '<fieldset><legend>%s</legend>%s</label>');
-/**
- * Form helper library.
- *
- * Automatic generation of HTML FORMs from given data.
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class FormHelper extends Helper{
-/**
- * Included helpers.
- *
- * @var array
- * @access public
- */
- var $helpers = array('Html');
-/**
- * Returns a formatted error message for given FORM field, NULL if no errors.
- *
- * @param string $field This should be "Modelname/fieldname"
- * @return bool If there are errors this method returns true, else false.
- * @access public
- */
- function isFieldError($field) {
- $error=1;
- $this->Html->setFormTag($field);
-
- if ($error == $this->Html->tagIsInvalid($this->Html->model, $this->Html->field)) {
- return true;
- } else {
- return false;
- }
- }
-/**
- * Returns a formatted LABEL element for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $text Text that will appear in the label field.
- * @return string The formatted LABEL element
- * @access public
- */
- function labelTag($tagName, $text) {
- return sprintf(TAG_LABEL, Inflector::camelize(str_replace('/', '_', $tagName)), $text);
- }
-/**
- * Returns a formatted DIV tag for HTML FORMs.
- *
- * @param string $class CSS class name of the div element.
- * @param string $text String content that will appear inside the div element.
- * @return string The formatted DIV element
- * @access public
- */
- function divTag($class, $text) {
- return sprintf(TAG_DIV, $class, $text);
- }
-/**
- * Returns a formatted P tag with class for HTML FORMs.
- *
- * @param string $class CSS class name of the p element.
- * @param string $text Text that will appear inside the p element.
- * @return string The formatted P element
- * @access public
- */
- function pTag($class, $text) {
- return sprintf(TAG_P_CLASS, $class, $text);
- }
-/**
- * Returns a formatted INPUT tag for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field.
- * @param bool $required True if this field is a required field.
- * @param string $errorMsg Text that will appear if an error has occurred.
- * @param int $size Size attribute for INPUT element
- * @param array $htmlOptions HTML options array.
- * @return string The formatted INPUT element, with a label and wrapped in a div.
- * @access public
- */
- function generateInputDiv($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null) {
- $htmlAttributes = $htmlOptions;
- $htmlAttributes['size'] = $size;
- $str = $this->Html->input($tagName, $htmlAttributes);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError = $this->pTag('error', $errorMsg);
- $divClass = sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- return $this->divTag($divClass, $divTagInside);
- }
-/**
- * Returns a formatted CHECKBOX tag inside a DIV for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field.
- * @param bool $required True if this field is a required field.
- * @param string $errorMsg Text that will appear if an error has occurred.
- * @param array $htmlOptions HTML options array.
- * @return string The formatted checkbox div
- * @access public
- */
- function generateCheckboxDiv($tagName, $prompt, $required = false, $errorMsg = null, $htmlOptions = null) {
- $htmlOptions['class'] = "inputCheckbox";
- $str = $this->Html->checkbox($tagName, null, $htmlOptions);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError = $this->pTag('error', $errorMsg);
- $divClass = sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- return $this->divTag($divClass, $divTagInside);
- }
-/**
- * Returns a formatted date option element for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field.
- * @param bool $required True if this field is a required field.
- * @param string $errorMsg Text that will appear if an error has occurred.
- * @param int $size Not used.
- * @param array $htmlOptions HTML options array
- * @return string Date option wrapped in a div.
- * @todo Remove the $size parameter from this method.
- * @access public
- */
- function generateDate($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
- $str = $this->Html->dateTimeOptionTag($tagName, 'MDY', 'NONE', $selected, $htmlOptions);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError = $this->pTag('error', $errorMsg);
- $divClass = sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- $requiredDiv = $this->divTag($divClass, $divTagInside);
- return $this->divTag("date", $requiredDiv);
- }
-/**
- * Returns a formatted date option element for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field.
- * @param bool $required True if this field is a required field.
- * @param string $errorMsg Text that will appear if an error has occurred.
- * @param int $size Not used.
- * @param array $htmlOptions HTML options array
- * @return string Date option wrapped in a div.
- * @todo Remove the $size parameter from this method.
- * @access public
- */
- function generateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
- $str = $this->Html->dateTimeOptionTag($tagName, 'NONE', '24', $selected, $htmlOptions);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError = $this->pTag('error', $errorMsg);
- $divClass = sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- $requiredDiv = $this->divTag($divClass, $divTagInside);
- return $this->divTag("time", $requiredDiv);
- }
-/**
- * Returns a formatted year option element for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field.
- * @param bool $required True if this field is a required field.
- * @param string $errorMsg Text that will appear if an error has occurred.
- * @param int $size Not used.
- * @param array $htmlOptions HTML options array
- * @return string Date option wrapped in a div.
- * @todo Remove the $size parameter from this method.
- * @access public
- */
- function generateYear($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
- $str = $this->Html->dateTimeOptionTag($tagName, 'Y', 'NONE', $selected, $htmlOptions);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError = $this->pTag('error', $errorMsg);
- $divClass = sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- $requiredDiv = $this->divTag($divClass, $divTagInside);
- return $this->divTag("year", $requiredDiv);
- }
-/**
- * Returns a formatted datetime option element for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field.
- * @param bool $required True if this field is required.
- * @param string $errorMsg Text that will appear if an error has occurred.
- * @param int $size Not used.
- * @param array $htmlOptions HTML options array
- * @param array $selected Selected index in the dateTimeOption tag.
- * @return string The formatted datetime option element wrapped in a div.
- * @todo Remove the $size parameter from this method.
- * @access public
- */
- function generateDateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
- $str = $this->Html->dateTimeOptionTag($tagName, 'MDY', '12', $selected, $htmlOptions);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError = $this->pTag('error', $errorMsg);
- $divClass = sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- $requiredDiv = $this->divTag($divClass, $divTagInside);
- return $this->divTag("date", $requiredDiv);
- }
-/**
- * Returns a formatted TEXTAREA inside a DIV for use with HTML forms.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field.
- * @param boolean $required True if this field is required.
- * @param string $errorMsg ext that will appear if an error has occurred.
- * @param integer $cols Number of columns.
- * @param integer $rows Number of rows.
- * @param array $htmlOptions HTML options array.
- * @return string The formatted TEXTAREA element, wrapped in a div.
- * @access public
- */
- function generateAreaDiv($tagName, $prompt, $required = false, $errorMsg = null, $cols = 60, $rows = 10, $htmlOptions = null) {
- $htmlAttributes = $htmlOptions;
- $htmlAttributes['cols'] = $cols;
- $htmlAttributes['rows'] = $rows;
- $str = $this->Html->textarea($tagName, $htmlAttributes);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
-
- if ($required) {
- $divClass="required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError = $this->pTag('error', $errorMsg);
- $divClass = sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- return $this->divTag($divClass, $divTagInside);
- }
-/**
- * Returns a formatted SELECT tag for HTML FORMs.
- *
- * @param string $tagName This should be "Modelname/fieldname"
- * @param string $prompt Text that will appear in the label field
- * @param array $options Options to be contained in SELECT element
- * @param string $selected Currently selected item
- * @param array $selectAttr Array of HTML attributes for the SELECT element
- * @param array $optionAttr Array of HTML attributes for the OPTION elements
- * @param bool $required True if this field is required
- * @param string $errorMsg Text that will appear if an error has occurred
- * @return string The formatted INPUT element, wrapped in a div
- * @access public
- */
- function generateSelectDiv($tagName, $prompt, $options, $selected = null, $selectAttr = null, $optionAttr = null, $required = false, $errorMsg = null) {
- $str = $this->Html->selectTag($tagName, $options, $selected, $selectAttr, $optionAttr);
- $strLabel = $this->labelTag($tagName, $prompt);
- $divClass = "optional";
-
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
-
- if ($this->isFieldError($tagName)) {
- $strError=$this->pTag('error', $errorMsg);
- $divClass=sprintf("%s error", $divClass);
- }
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- return $this->divTag($divClass, $divTagInside);
- }
-/**
- * Returns a formatted submit widget for HTML FORMs.
- *
- * @param string $displayText Text that will appear on the widget
- * @param array $htmlOptions HTML options array
- * @return string The formatted submit widget
- * @access public
- */
- function generateSubmitDiv($displayText, $htmlOptions = null) {
- return $this->divTag('submit', $this->Html->submit($displayText, $htmlOptions));
- }
-/**
- * Generates a form to go onto a HtmlHelper object.
- *
- * @param array $fields An array of form field definitions
- * @param boolean $readOnly True if the form should be rendered as READONLY
- * @return string The completed form specified by the $fields parameter
- * @access public
- */
- function generateFields($fields, $readOnly = false) {
- $strFormFields = '';
-
- foreach ($fields as $field) {
- if (isset($field['type'])) {
-
- if (!isset($field['required'])) {
- $field['required'] = false;
- }
-
- if (!isset($field['errorMsg'])) {
- $field['errorMsg'] = null;
- }
-
- if (!isset($field['htmlOptions'])) {
- $field['htmlOptions'] = array();
- }
-
- if ($readOnly) {
- $field['htmlOptions']['READONLY'] = "readonly";
- }
-
- switch($field['type']) {
- case "input":
- if (!isset($field['size'])) {
- $field['size'] = 40;
- }
- $strFormFields = $strFormFields . $this->generateInputDiv($field['tagName'], $field['prompt'],
- $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions']);
- break;
- case "checkbox":
- $strFormFields = $strFormFields . $this->generateCheckboxDiv($field['tagName'], $field['prompt'],
- $field['required'], $field['errorMsg'], $field['htmlOptions']);
- break;
- case "select":
- case "selectMultiple":
- if ("selectMultiple" == $field['type']) {
- $field['selectAttr']['multiple'] = 'multiple';
- $field['selectAttr']['class'] = 'selectMultiple';
- }
-
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
-
- if (!isset($field['selectAttr'])) {
- $field['selectAttr'] = null;
- }
-
- if (!isset($field['optionsAttr'])) {
- $field['optionsAttr'] = null;
- }
-
- if ($readOnly) {
- $field['selectAttr']['DISABLED'] = true;
- }
-
- if (!isset($field['options'])) {
- $field['options'] = null;
- }
- $strFormFields = $strFormFields . $this->generateSelectDiv($field['tagName'], $field['prompt'], $field['options'],
- $field['selected'], $field['selectAttr'], $field['optionsAttr'], $field['required'], $field['errorMsg']);
- break;
- case "area":
- if (!isset($field['rows'])) {
- $field['rows'] = 10;
- }
-
- if (!isset($field['cols'])) {
- $field['cols'] = 60;
- }
- $strFormFields = $strFormFields . $this->generateAreaDiv($field['tagName'], $field['prompt'],
- $field['required'], $field['errorMsg'], $field['cols'], $field['rows'], $field['htmlOptions']);
- break;
- case "fieldset":
- $strFieldsetFields = $this->generateFields($field['fields']);
- $strFieldSet = sprintf(' <fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>',
- $field['legend'], $field['noteHeading'], $field['note'], $strFieldsetFields);
- $strFormFields = $strFormFields . $strFieldSet;
- break;
- case "hidden":
- if (!isset($field['value'])) {
- $field['value'] = null;
- }
- $strFormFields = $strFormFields . $this->Html->hidden($field['tagName'], $field['value']);
- break;
- case "date":
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
- $strFormFields = $strFormFields . $this->generateDate($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
- break;
- case "datetime":
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
- $strFormFields = $strFormFields . $this->generateDateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
- break;
- case "time":
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
- $strFormFields = $strFormFields . $this->generateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
- break;
- case "year":
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
- $strFormFields = $strFormFields . $this->generateYear($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
- break;
- default:
- break;
- }
- }
- }
- return $strFormFields;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/html.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/html.php
deleted file mode 100644
index 9b86c91..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/html.php
+++ /dev/null
@@ -1,1257 +0,0 @@
-<?php
-/* SVN FILE: $Id: html.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Html Helper class file.
- *
- * Simplifies the construction of HTML elements.
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 0.9.1
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Html Helper class for easy use of HTML widgets.
- *
- * HtmlHelper encloses all methods needed while working with HTML pages.
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class HtmlHelper extends Helper {
-/**
- * Base URL
- *
- * @var string
- * @access public
- */
- var $base = null;
-/**
- * URL to current action.
- *
- * @var string
- * @access public
- */
- var $here = null;
-/**
- * Parameter array.
- *
- * @var array
- * @access public
- */
- var $params = array();
-/**
- * Current action.
- *
- * @var string
- * @access public
- */
- var $action = null;
-/**
- * Controller::data;
- *
- * @var array
- * @access public
- */
- var $data = null;
-/**
- * Name of model this helper is attached to.
- *
- * @var string
- * @access public
- */
- var $model = null;
-/**
- *
- * @var string
- * @access public
- */
- var $field = null;
-/**
- * Breadcrumbs.
- *
- * @var array
- * @access protected
- */
- var $_crumbs = array();
-/**
- * Adds a link to the breadcrumbs array.
- *
- * @param string $name Text for link
- * @param string $link URL for link
- * @return void
- * @access public
- */
- function addCrumb($name, $link) {
- $this->_crumbs[] = array($name, $link);
- }
-/**
- * Returns a charset META-tag.
- *
- * @param string $charset
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function charset($charset = null, $return = false) {
- if (is_null($charset)) {
- $charset = 'utf-8';
- }
- return $this->output(sprintf($this->tags['charset'], $charset), $return);
- }
-/**
- * Finds URL for specified action.
- *
- * Returns an URL pointing to a combination of controller and action. Param
- * $url can be:
- * + Empty - the method will find adress to actuall controller/action.
- * + '/' - the method will find base URL of application.
- * + A combination of controller/action - the method will find url for it.
- *
- * @param string $url Cake-relative URL, like "/products/edit/92" or "/presidents/elect/4"
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function url($url = null, $return = false) {
- if (isset($this->plugin)) {
- $base = strip_plugin($this->base, $this->plugin);
- } else {
- $base = $this->base;
- }
-
- if (empty($url)) {
- return $this->here;
- } elseif ($url{0} == '/') {
- $output = $base . $url;
- } else {
- $output = $base . '/' . Inflector::underscore($this->params['controller']) . '/' . $url;
- }
-
- return $this->output($output, $return);
- }
-/**
- * Creates an HTML link.
- *
- * If $url starts with "http://" this is treated as an external link. Else,
- * it is treated as a path to controller/action and parsed with the
- * HtmlHelper::url() method.
- *
- * If the $url is empty, $title is used instead.
- *
- * @param string $title The content of the A tag.
- * @param string $url Cake-relative URL, or external URL (starts with http://)
- * @param array $htmlAttributes Array of HTML attributes.
- * @param string $confirmMessage Confirmation message.
- * @param boolean $escapeTitle Whether or not the text in the $title variable should be HTML escaped.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true, $return = false) {
- if ($escapeTitle === true) {
- $title = htmlspecialchars($title, ENT_QUOTES);
- } elseif (is_string($escapeTitle)) {
- $title = htmlentities($title, ENT_QUOTES);
- }
- $url = $url ? $url : $title;
-
- if ($confirmMessage) {
- $confirmMessage = str_replace("'", "\'", $confirmMessage);
- $confirmMessage = str_replace('"', '\"', $confirmMessage);
- $htmlAttributes['onclick']="return confirm('{$confirmMessage}');";
- }
-
- if (((strpos($url, '://')) || (strpos($url, 'javascript:') === 0) || (strpos($url, 'mailto:') === 0) || substr($url,0,1) == '#')) {
- $output = sprintf($this->tags['link'], $url, $this->_parseAttributes($htmlAttributes), $title);
- } else {
- $output = sprintf($this->tags['link'], $this->url($url, true), $this->_parseAttributes($htmlAttributes), $title);
- }
- return $this->output($output, $return);
- }
-/**
- * Creates a submit widget.
- *
- * @param string $caption Text on submit button
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function submit($caption = 'Submit', $htmlAttributes = array(), $return = false) {
- $htmlAttributes['value'] = $caption;
- return $this->output(sprintf($this->tags['submit'], $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
- }
-/**
- * Creates a password input widget.
- *
- * @param string $fieldName Name of a field, like this "Modelname/fieldname"
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function password($fieldName, $htmlAttributes = array(), $return = false) {
- $this->setFormTag($fieldName);
- if (!isset($htmlAttributes['value'])) {
- $htmlAttributes['value'] = $this->tagValue($fieldName);
- }
- if (!isset($htmlAttributes['id'])) {
- $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
- }
-
- if ($this->tagIsInvalid($this->model, $this->field)) {
- if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
- $htmlAttributes['class'] .= ' form_error';
- } else {
- $htmlAttributes['class'] = 'form_error';
- }
- }
- return $this->output(sprintf($this->tags['password'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
- }
-/**
- * Creates a textarea widget.
- *
- * @param string $fieldName Name of a field, like this "Modelname/fieldname"
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function textarea($fieldName, $htmlAttributes = array(), $return = false) {
- $this->setFormTag($fieldName);
- $value = $this->tagValue($fieldName);
- if (!empty($htmlAttributes['value'])) {
- $value = $htmlAttributes['value'];
- unset($htmlAttributes['value']);
- }
- if (!isset($htmlAttributes['id'])) {
- $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
- }
-
- if ($this->tagIsInvalid($this->model, $this->field)) {
- if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
- $htmlAttributes['class'] .= ' form_error';
- } else {
- $htmlAttributes['class'] = 'form_error';
- }
- }
- return $this->output(sprintf($this->tags['textarea'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' '), $value), $return);
- }
-/**
- * Creates a checkbox widget.
- *
- * @param string $fieldName Name of a field, like this "Modelname/fieldname"
- * @deprecated string $title
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function checkbox($fieldName, $title = null, $htmlAttributes = array(), $return = false) {
- $value = $this->tagValue($fieldName);
- $notCheckedValue = 0;
-
- if (!isset($htmlAttributes['id'])) {
- $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
- }
-
- if (isset($htmlAttributes['checked'])) {
- if ($htmlAttributes['checked'] == 'checked' || intval($htmlAttributes['checked']) === 1 || $htmlAttributes['checked'] === true) {
- $htmlAttributes['checked'] = 'checked';
- } else {
- $htmlAttributes['checked'] = null;
- $notCheckedValue = -1;
- }
- } else {
- if (isset($htmlAttributes['value']) || (!class_exists($this->model) && !loadModel($this->model))) {
- $htmlAttributes['checked'] = ($htmlAttributes['value'] == $value) ? 'checked' : null;
-
- if ($htmlAttributes['value'] == '0') {
- $notCheckedValue = -1;
- }
- } else {
- $model = new $this->model;
- $db =& ConnectionManager::getDataSource($model->useDbConfig);
- $value = $db->boolean($value);
- $htmlAttributes['checked'] = $value ? 'checked' : null;
- $htmlAttributes['value'] = 1;
- }
- }
-
- $output = $this->hidden($fieldName, array('value' => $notCheckedValue, 'id' => $htmlAttributes['id'] . '_'), true);
- $output .= sprintf($this->tags['checkbox'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' '));
- return $this->output($output, $return);
- }
-/**
- * Creates a link element for CSS stylesheets.
- *
- * @param string $path Path to CSS file
- * @param string $rel Rel attribute. Defaults to "stylesheet".
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function css($path, $rel = 'stylesheet', $htmlAttributes = array(), $return = false) {
- $url = "{$this->webroot}" . (COMPRESS_CSS ? 'c' : '') . $this->themeWeb . CSS_URL . $path . ".css";
-
- if ($rel == 'import') {
- return $this->output(sprintf($this->tags['style'], $this->parseHtmlOptions($htmlAttributes, null, '', ' '), '@import url(' . $url . ');'), $return);
- } else {
- return $this->output(sprintf($this->tags['css'], $rel, $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return);
- }
- }
-/**
- * Creates file input widget.
- *
- * @param string $fieldName Name of a field, like this "Modelname/fieldname"
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a valueor output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function file($fieldName, $htmlAttributes = array(), $return = false) {
- if (strpos($fieldName, '/')) {
- $this->setFormTag($fieldName);
- if (!isset($htmlAttributes['id'])) {
- $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
- }
- return $this->output(sprintf($this->tags['file'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
- }
- return $this->output(sprintf($this->tags['file_no_model'], $fieldName, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
- }
-/**
- * Returns the breadcrumb trail as a sequence of &raquo;-separated links.
- *
- * @param string $separator Text to separate crumbs.
- * @param string $startText This will be the first crumb, if false it defaults to first crumb in array
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return. If $this->_crumbs is empty, return null.
- * @access public
- */
- function getCrumbs($separator = '&raquo;', $startText = false, $return = false) {
- if (count($this->_crumbs)) {
- $out = array();
- if ($startText) {
- $out[] = $this->link($startText, '/');
- }
-
- foreach ($this->_crumbs as $crumb) {
- $out[] = $this->link($crumb[0], $crumb[1]);
- }
- return $this->output(join($separator, $out), $return);
- } else {
- return null;
- }
- }
-/**
- * Creates a hidden input field.
- *
- * @param string $fieldName Name of a field, like this "Modelname/fieldname"
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function hidden($fieldName, $htmlAttributes = array(), $return = false) {
- $this->setFormTag($fieldName);
- if (!isset($htmlAttributes['value'])) {
- $htmlAttributes['value'] = $this->tagValue($fieldName);
- }
- if (!isset($htmlAttributes['id'])) {
- $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
- }
- return $this->output(sprintf($this->tags['hidden'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
- }
-/**
- * Creates a formatted IMG element.
- *
- * @param string $path Path to the image file, relative to the webroot/img/ directory.
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function image($path, $htmlAttributes = array(), $return = false) {
- if (strpos($path, '://')) {
- $url = $path;
- } else {
- $url = $this->webroot . $this->themeWeb . IMAGES_URL . $path;
- }
- return $this->output(sprintf($this->tags['image'], $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return);
- }
-/**
- * Creates a text input widget.
- *
- * @param string $fieldNamem Name of a field, like this "Modelname/fieldname"
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function input($fieldName, $htmlAttributes = array(), $return = false) {
- $this->setFormTag($fieldName);
- if (!isset($htmlAttributes['value'])) {
- $htmlAttributes['value'] = $this->tagValue($fieldName);
- }
-
- if (!isset($htmlAttributes['type'])) {
- $htmlAttributes['type'] = 'text';
- }
-
- if (!isset($htmlAttributes['id'])) {
- $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
- }
-
- if ($this->tagIsInvalid($this->model, $this->field)) {
- if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
- $htmlAttributes['class'] .= ' form_error';
- } else {
- $htmlAttributes['class'] = 'form_error';
- }
- }
- return $this->output(sprintf($this->tags['input'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
- }
- /**
- * Returns a formatted SELECT element.
- *
- * @param string $fieldName Name attribute of the SELECT
- * @param array $optionElements Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the SELECT element
- * @param mixed $selected Selected option
- * @param array $selectAttr Array of HTML options for the opening SELECT element
- * @param array $optionAttr Array of HTML options for the enclosed OPTION elements
- * @param boolean $show_empty If true, the empty select option is shown
- * @param boolean $return Whether this method should return a value
- * @return string Formatted SELECT element
- * @access public
- */
- function selectTag($fieldName, $optionElements, $selected = null, $selectAttr = array(), $optionAttr = null, $showEmpty = true, $return = false) {
- $this->setFormTag($fieldName);
- if ($this->tagIsInvalid($this->model, $this->field)) {
- if (isset($selectAttr['class']) && trim($selectAttr['class']) != "") {
- $selectAttr['class'] .= ' form_error';
- } else {
- $selectAttr['class'] = 'form_error';
- }
- }
- if (!isset($selectAttr['id'])) {
- $selectAttr['id'] = $this->model . Inflector::camelize($this->field);
- }
-
- if (!is_array($optionElements)) {
- return null;
- }
-
- if (!isset($selected)) {
- $selected = $this->tagValue($fieldName);
- }
-
- if (isset($selectAttr) && array_key_exists("multiple", $selectAttr)) {
- $select[] = sprintf($this->tags['selectmultiplestart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
- } else {
- $select[] = sprintf($this->tags['selectstart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
- }
-
- if ($showEmpty == true) {
- $select[] = sprintf($this->tags['selectempty'], $this->parseHtmlOptions($optionAttr));
- }
-
- foreach ($optionElements as $name => $title) {
- $optionsHere = $optionAttr;
-
- if (($selected != null) && ($selected == $name)) {
- $optionsHere['selected'] = 'selected';
- } elseif (is_array($selected) && in_array($name, $selected)) {
- $optionsHere['selected'] = 'selected';
- }
-
- $select[] = sprintf($this->tags['selectoption'], $name, $this->parseHtmlOptions($optionsHere), h($title));
- }
-
- $select[] = sprintf($this->tags['selectend']);
- return $this->output(implode("\n", $select), $return);
- }
-/**
- * Creates a set of radio widgets.
- *
- * @param string $fieldName Name of a field, like this "Modelname/fieldname"
- * @param array $options Radio button options array
- * @param array $inbetween String that separates the radio buttons.
- * @param array $htmlAttributes Array of HTML attributes.
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
- * @access public
- */
- function radio($fieldName, $options, $inbetween = null, $htmlAttributes = array(), $return = false) {
-
- $this->setFormTag($fieldName);
- $value = isset($htmlAttributes['value']) ? $htmlAttributes['value'] : $this->tagValue($fieldName);
- $out = array();
-
- foreach ($options as $optValue => $optTitle) {
- $optionsHere = array('value' => $optValue);
- if ($value !== false && $optValue == $value) {
- $optionsHere['checked'] = 'checked';
- }
- $parsedOptions = $this->parseHtmlOptions(array_merge($htmlAttributes, $optionsHere), null, '', ' ');
- $individualTagName = "{$this->field}_{$optValue}";
- $out[] = sprintf($this->tags['radio'], $this->model, $this->field, $individualTagName, $parsedOptions, $optTitle);
- }
-
- $out = join($inbetween, $out);
- return $this->output($out ? $out : null, $return);
- }
-/**
- * Returns a SELECT element for days.
- *
- * @param string $tagName Prefix name for the SELECT element
- * @deprecated string $value
- * @param string $selected Option which is selected.
- * @param array $optionAttr Attribute array for the option elements.
- * @param boolean $showEmpty Show/hide the empty select option
- * @return mixed
- * @access public
- */
- function dayOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
- if (empty($selected) && $this->tagValue($tagName)) {
- $selected = date('d', strtotime($this->tagValue($tagName)));
- }
- $dayValue = empty($selected) ? ($showEmpty == true ? NULL : date('d')) : $selected;
- $days = array('01' => '1', '02' => '2', '03' => '3', '04' => '4', '05' => '5', '06' => '6', '07' => '7', '08' => '8', '09' => '9', '10' => '10', '11' => '11', '12' => '12', '13' => '13', '14' => '14', '15' => '15', '16' => '16', '17' => '17', '18' => '18', '19' => '19', '20' => '20', '21' => '21', '22' => '22', '23' => '23', '24' => '24', '25' => '25', '26' => '26', '27' => '27', '28' => '28', '29' => '29', '30' => '30', '31' => '31');
- $option = $this->selectTag($tagName . "_day", $days, $dayValue, $selectAttr, $optionAttr, $showEmpty);
- return $option;
- }
-/**
- * Returns a SELECT element for years
- *
- * @param string $tagName Prefix name for the SELECT element
- * @deprecated string $value
- * @param integer $minYear First year in sequence
- * @param integer $maxYear Last year in sequence
- * @param string $selected Option which is selected.
- * @param array $optionAttr Attribute array for the option elements.
- * @param boolean $showEmpty Show/hide the empty select option
- * @return mixed
- * @access public
- */
- function yearOptionTag($tagName, $value = null, $minYear = null, $maxYear = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
- if (empty($selected) && ($this->tagValue($tagName))) {
- $selected = date('Y', strtotime($this->tagValue($tagName)));
- }
-
- $yearValue = empty($selected) ? ($showEmpty ? NULL : date('Y')) : $selected;
- $currentYear = date('Y');
- $maxYear = is_null($maxYear) ? $currentYear + 11 : $maxYear + 1;
- $minYear = is_null($minYear) ? $currentYear - 60 : $minYear;
-
- if ($minYear > $maxYear) {
- $tmpYear = $minYear;
- $minYear = $maxYear;
- $maxYear = $tmpYear;
- }
-
- $minYear = $currentYear < $minYear ? $currentYear : $minYear;
- $maxYear = $currentYear > $maxYear ? $currentYear : $maxYear;
-
- for ($yearCounter = $minYear; $yearCounter < $maxYear; $yearCounter++) {
- $years[$yearCounter] = $yearCounter;
- }
-
- return $this->selectTag($tagName . "_year", $years, $yearValue, $selectAttr, $optionAttr, $showEmpty);
- }
-/**
- * Returns a SELECT element for months.
- *
- * @param string $tagName Prefix name for the SELECT element
- * @deprecated string $value
- * @param string $selected Option which is selected.
- * @param array $optionAttr Attribute array for the option elements.
- * @param boolean $showEmpty Show/hide the empty select option
- * @return mixed
- * @access public
- */
- function monthOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
- if (empty($selected) && ($this->tagValue($tagName))) {
- $selected = date('m', strtotime($this->tagValue($tagName)));
- }
- $monthValue = empty($selected) ? ($showEmpty ? NULL : date('m')) : $selected;
- $months = array('01' => 'January', '02' => 'February', '03' => 'March', '04' => 'April', '05' => 'May', '06' => 'June', '07' => 'July', '08' => 'August', '09' => 'September', '10' => 'October', '11' => 'November', '12' => 'December');
-
- return $this->selectTag($tagName . "_month", $months, $monthValue, $selectAttr, $optionAttr, $showEmpty);
- }
-/**
- * Returns a SELECT element for hours.
- *
- * @param string $tagName Prefix name for the SELECT element
- * @deprecated string $value
- * @param boolean $format24Hours True for 24 hours format
- * @param string $selected Option which is selected.
- * @param array $optionAttr Attribute array for the option elements.
- * @return mixed
- * @access public
- */
- function hourOptionTag($tagName, $value = null, $format24Hours = false, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
- if (empty($selected) && ($this->tagValue($tagName))) {
- if ($format24Hours) {
- $selected = date('H', strtotime($this->tagValue($tagName)));
- } else {
- $selected = date('g', strtotime($this->tagValue($tagName)));
- }
- }
- if ($format24Hours) {
- $hourValue = empty($selected) ? ($showEmpty ? NULL : date('H')) : $selected;
- } else {
- $hourValue = empty($selected) ? ($showEmpty ? NULL : date('g')) : $selected;
- if (isset($selected) && intval($hourValue) == 0 && !$showEmpty) {
- $hourValue = 12;
- }
- }
-
- if ($format24Hours) {
- $hours = array('00' => '00', '01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12', '13' => '13', '14' => '14', '15' => '15', '16' => '16', '17' => '17', '18' => '18', '19' => '19', '20' => '20', '21' => '21', '22' => '22', '23' => '23');
- } else {
- $hours = array('01' => '1', '02' => '2', '03' => '3', '04' => '4', '05' => '5', '06' => '6', '07' => '7', '08' => '8', '09' => '9', '10' => '10', '11' => '11', '12' => '12');
- }
-
- $option = $this->selectTag($tagName . "_hour", $hours, $hourValue, $selectAttr, $optionAttr, $showEmpty);
- return $option;
- }
-/**
- * Returns a SELECT element for minutes.
- *
- * @param string $tagName Prefix name for the SELECT element
- * @deprecated string $value
- * @param string $selected Option which is selected.
- * @param array $optionAttr Attribute array for the option elements.
- * @return mixed
- * @access public
- */
- function minuteOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
- if (empty($selected) && ($this->tagValue($tagName))) {
- $selected = date('i', strtotime($this->tagValue($tagName)));
- }
- $minValue = empty($selected) ? ($showEmpty ? NULL : date('i')) : $selected;
-
- for ($minCount = 0; $minCount < 60; $minCount++) {
- $mins[sprintf('%02d', $minCount)] = sprintf('%02d', $minCount);
- }
- $option = $this->selectTag($tagName . "_min", $mins, $minValue, $selectAttr, $optionAttr, $showEmpty);
- return $option;
- }
-
-/**
- * Returns a SELECT element for AM or PM.
- *
- * @param string $tagName Prefix name for the SELECT element
- * @deprecated string $value
- * @param string $selected Option which is selected.
- * @param array $optionAttr Attribute array for the option elements.
- * @return mixed
- * @access public
- */
- function meridianOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
- if (empty($selected) && ($this->tagValue($tagName))) {
- $selected = date('a', strtotime($this->tagValue($tagName)));
- }
- $merValue = empty($selected) ? ($showEmpty ? NULL : date('a')) : $selected;
- $meridians = array('am' => 'am', 'pm' => 'pm');
-
- $option = $this->selectTag($tagName . "_meridian", $meridians, $merValue, $selectAttr, $optionAttr, $showEmpty);
- return $option;
- }
-/**
- * Returns a set of SELECT elements for a full datetime setup: day, month and year, and then time.
- *
- * @param string $tagName Prefix name for the SELECT element
- * @param string $dateFormat DMY, MDY, YMD or NONE.
- * @param string $timeFormat 12, 24, NONE
- * @param string $selected Option which is selected.
- * @param array $optionAttr Attribute array for the option elements.
- * @return string The HTML formatted OPTION element
- * @access public
- */
- function dateTimeOptionTag($tagName, $dateFormat = 'DMY', $timeFormat = '12', $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
- $day = null;
- $month = null;
- $year = null;
- $hour = null;
- $min = null;
- $meridian = null;
-
- if (empty($selected)) {
- $selected = $this->tagValue($tagName);
- }
-
- if (!empty($selected)) {
-
- if (is_int($selected)) {
- $selected = strftime('%Y-%m-%d %H:%M:%S', $selected);
- }
-
- $meridian = 'am';
- $pos = strpos($selected, '-');
- if ($pos !== false) {
- $date = explode('-', $selected);
- $days = explode(' ', $date[2]);
- $day = $days[0];
- $month = $date[1];
- $year = $date[0];
- } else {
- $days[1] = $selected;
- }
-
- if ($timeFormat != 'NONE' && !empty($timeFormat)) {
- $time = explode(':', $days[1]);
- $check = str_replace(':', '', $days[1]);
-
- if (($check > 115959) && $timeFormat == '12') {
- $time[0] = $time[0] - 12;
- $meridian = 'pm';
- } elseif ($time[0] > 12) {
- $meridian = 'pm';
- }
-
- $hour = $time[0];
- $min = $time[1];
- }
- }
-
- $elements = array('Day','Month','Year','Hour','Minute','Meridian');
- if (isset($selectAttr['id'])) {
- if (is_string($selectAttr['id'])) {
- // build out an array version
- foreach ($elements as $element) {
- $selectAttrName = 'select' . $element . 'Attr';
- ${$selectAttrName} = $selectAttr;
- ${$selectAttrName}['id'] = $selectAttr['id'] . $element;
- }
- } elseif (is_array($selectAttr['id'])) {
- // check for missing ones and build selectAttr for each element
- foreach ($elements as $element) {
- $selectAttrName = 'select' . $element . 'Attr';
- ${$selectAttrName} = $selectAttr;
- ${$selectAttrName}['id'] = $selectAttr['id'][strtolower($element)];
- }
- }
- } else {
- // build the selectAttrName with empty id's to pass
- foreach ($elements as $element) {
- $selectAttrName = 'select' . $element . 'Attr';
- ${$selectAttrName} = $selectAttr;
- }
- }
-
- switch($dateFormat) {
- case 'DMY': // so uses the new selex
- $opt = $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty) . '-' .
- $this->monthOptionTag($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '-' . $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty);
- break;
- case 'MDY':
- $opt = $this->monthOptionTag($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '-' .
- $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty) . '-' . $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty);
- break;
- case 'YMD':
- $opt = $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty) . '-' .
- $this->monthOptionTag($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '-' .
- $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty);
- break;
- case 'Y':
- $opt = $this->yearOptionTag($tagName, null, null, null, $selected, $selectYearAttr, $optionAttr, $showEmpty);
- break;
- case 'NONE':
- default:
- $opt = '';
- break;
- }
-
- switch($timeFormat) {
- case '24':
- $opt .= $this->hourOptionTag($tagName, null, true, $hour, $selectHourAttr, $optionAttr, $showEmpty) . ':' .
- $this->minuteOptionTag($tagName, null, $min, $selectMinuteAttr, $optionAttr, $showEmpty);
- break;
- case '12':
- $opt .= $this->hourOptionTag($tagName, null, false, $hour, $selectHourAttr, $optionAttr, $showEmpty) . ':' .
- $this->minuteOptionTag($tagName, null, $min, $selectMinuteAttr, $optionAttr, $showEmpty) . ' ' .
- $this->meridianOptionTag($tagName, null, $meridian, $selectMeridianAttr, $optionAttr, $showEmpty);
- break;
- case 'NONE':
- default:
- $opt .= '';
- break;
- }
- return $opt;
- }
-/**
- * Returns a row of formatted and named TABLE headers.
- *
- * @param array $names Array of tablenames.
- * @param array $trOptions HTML options for TR elements.
- * @param array $thOptions HTML options for TH elements.
- * @param boolean $return Wheter this method should return a value
- * @return string
- * @access public
- */
- function tableHeaders($names, $trOptions = null, $thOptions = null, $return = false) {
- $out = array();
- foreach ($names as $arg) {
- $out[] = sprintf($this->tags['tableheader'], $this->parseHtmlOptions($thOptions), $arg);
- }
-
- $data = sprintf($this->tags['tablerow'], $this->parseHtmlOptions($trOptions), join(' ', $out));
- return $this->output($data, $return);
- }
-/**
- * Returns a formatted string of table rows (TR's with TD's in them).
- *
- * @param array $data Array of table data
- * @param array $oddTrOptionsHTML options for odd TR elements
- * @param array $evenTrOptionsHTML options for even TR elements
- * @param boolean $return Wheter this method should return a value
- * @return string Formatted HTML
- * @access public
- */
- function tableCells($data, $oddTrOptions = null, $evenTrOptions = null, $return = false) {
- if (empty($data[0]) || !is_array($data[0])) {
- $data = array($data);
- }
- static $count = 0;
-
- foreach ($data as $line) {
- $count++;
- $cellsOut = array();
-
- foreach ($line as $cell) {
- $cellsOut[] = sprintf($this->tags['tablecell'], null, $cell);
- }
- $options = $this->parseHtmlOptions($count % 2 ? $oddTrOptions : $evenTrOptions);
- $out[] = sprintf($this->tags['tablerow'], $options, join(' ', $cellsOut));
- }
- return $this->output(join("\n", $out), $return);
- }
-/**
- * Generates a nested unordered list tree from an array.
- *
- * @param array $data
- * @param array $htmlAttributes
- * @param string $bodyKey
- * @param string $childrenKey
- * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return. If $this->_crumbs is empty, return null.
- * @access public
- */
- function guiListTree($data, $htmlAttributes = array(), $bodyKey = 'body', $childrenKey = 'children', $return = false) {
- $out="<ul" . $this->_parseAttributes($htmlAttributes) . ">\n";
- foreach ($data as $item) {
- $out .= "<li>{$item[$bodyKey]}\n";
- if (isset($item[$childrenKey]) && is_array($item[$childrenKey]) && count($item[$childrenKey])) {
- $out .= $this->guiListTree($item[$childrenKey], $htmlAttributes, $bodyKey, $childrenKey);
- }
- $out .= "</li>\n";
- }
- $out .= "</ul>\n";
- return $this->output($out, $return);
- }
-/**
- * Returns value of $fieldName. False if the tag does not exist.
- *
- * @param string $fieldName Fieldname as "Modelname/fieldname" string
- * @return string htmlspecialchars Value of the named tag.
- * @access public
- */
- function tagValue($fieldName, $escape = false) {
- $this->setFormTag($fieldName);
- if (isset($this->params['data'][$this->model][$this->field])) {
- return ife($escape, h($this->params['data'][$this->model][$this->field]), $this->params['data'][$this->model][$this->field]);
- } elseif (isset($this->data[$this->model][$this->field])) {
- return ife($escape, h($this->data[$this->model][$this->field]), $this->data[$this->model][$this->field]);
- }
- return false;
- }
-/**
- * Returns false if given FORM field has no errors. Otherwise it returns the constant set in the array Model->validationErrors.
- *
- * @param string $model Model name as string
- * @param string $field Fieldname as string
- * @return boolean True on errors.
- * @access public
- */
- function tagIsInvalid($model, $field) {
- return empty($this->validationErrors[$model][$field]) ? 0 : $this->validationErrors[$model][$field];
- }
-/**
- * Returns number of errors in a submitted FORM.
- *
- * @return int Number of errors
- * @access public
- */
- function validate() {
- $args = func_get_args();
- $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
- return count($errors);
- }
-/**
- * Validates a FORM according to the rules set up in the Model.
- *
- * @return int Number of errors
- * @access public
- */
- function validateErrors() {
- $objects = func_get_args();
- if (!count($objects)) {
- return false;
- }
-
- $errors = array();
- foreach ($objects as $object) {
- $errors = array_merge($errors, $object->invalidFields($object->data));
- }
- return $this->validationErrors = (count($errors) ? $errors : false);
- }
-/**
- * Returns a formatted error message for given FORM field, NULL if no errors.
- *
- * @param string $field A field name, like "Modelname/fieldname"
- * @param string $text Error message
- * @return string If there are errors this method returns an error message, else NULL.
- * @access public
- */
- function tagErrorMsg($field, $text) {
- $error = 1;
- $this->setFormTag($field);
- if ($error == $this->tagIsInvalid($this->model, $this->field)) {
- return sprintf('<div class="error_message">%s</div>', is_array($text) ? (empty($text[$error - 1]) ? 'Error in field' : $text[$error - 1]) : $text);
- } else {
- return null;
- }
- }
-/**
- * Sets this helper's model and field properties to the slash-separated value-pair in $tagValue.
- *
- * @param string $tagValue A field name, like "Modelname/fieldname"
- * @return
- * @access public
- */
- function setFormTag($tagValue) {
- return list($this->model, $this->field) = explode("/", $tagValue);
- }
-/**
- * Returns a space-delimited string with items of the $options array. If a
- * key of $options array happens to be one of:
- * + 'compact'
- * + 'checked'
- * + 'declare'
- * + 'readonly'
- * + 'disabled'
- * + 'selected'
- * + 'defer'
- * + 'ismap'
- * + 'nohref'
- * + 'noshade'
- * + 'nowrap'
- * + 'multiple'
- * + 'noresize'
- *
- * And its value is one of:
- * + 1
- * + true
- * + 'true'
- *
- * Then the value will be reset to be identical with key's name.
- * If the value is not one of these 3, the parameter is not output.
- *
- * @param array $options Array of options.
- * @param array $exclude Array of options to be excluded.
- * @param string $insertBefore String to be inserted before options.
- * @param string $insertAfter String to be inserted ater options.
- * @return string
- * @access protected
- */
- function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
- if (is_array($options)) {
- $default = array (
- 'escape' => true
- );
- $options = am($default, $options);
- if (!is_array($exclude)) {
- $exclude = array();
- }
- $exclude = am($exclude, array('escape'));
- $keys = array_diff(array_keys($options), $exclude);
- $values = array_intersect_key(array_values($options), $keys);
- $escape = $options['escape'];
- $attributes = array();
- foreach ($keys as $index => $key) {
- $attributes[] = $this->__formatAttribute($key, $values[$index], $escape);
- }
- $out = implode(' ', $attributes);
- } else {
- $out = $options;
- }
- return $out ? $insertBefore . $out . $insertAfter : '';
- }
-/**
- * @param string $key
- * @param string $value
- * @return string
- * @access private
- */
- function __formatAttribute($key, $value, $escape = true) {
- $attribute = '';
- $attributeFormat = '%s="%s"';
- $minimizedAttributes = array('compact', 'checked', 'declare', 'readonly', 'disabled', 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize');
-
- if (in_array($key, $minimizedAttributes)) {
- if ($value === 1 || $value === true || $value === 'true' || $value == $key) {
- $attribute = sprintf($attributeFormat, $key, $key);
- }
- } else {
- $attribute = sprintf($attributeFormat, $key, ife($escape, h($value), $value));
- }
- return $attribute;
- }
-/**
- * @deprecated Name changed to 'textarea'. Version 0.9.2.
- * @see HtmlHelper::textarea()
- */
- function areaTag($tagName, $cols = 60, $rows = 10, $htmlAttributes = array(), $return = false) {
- $htmlAttributes['cols']=$cols;
- $htmlAttributes['rows']=$rows;
- return $this->textarea($tagName, $htmlAttributes, $return);
- }
-/**
- * @deprecated Name changed to 'charset'. Version 0.9.2.
- * @see HtmlHelper::charset()
- */
- function charsetTag($charset, $return = false) {
- return $this->charset($charset, $return);
- }
-/**
- * @deprecated Name changed to 'checkbox'. Version 0.9.2.
- * @see HtmlHelper::checkbox()
- */
- function checkboxTag($fieldName, $title = null, $htmlAttributes = array(), $return = false) {
- return $this->checkbox($fieldName, $title, $htmlAttributes, $return);
- }
-/**
- * @deprecated Name changed to 'css'. Version 0.9.2.
- * @see HtmlHelper::css()
- */
- function cssTag($path, $rel = 'stylesheet', $htmlAttributes = array(), $return = false) {
- return $this->css($path, $rel, $htmlAttributes, $return);
- }
-/**
- * @deprecated Name changed to 'file'. Version 0.9.2.
- * @see HtmlHelper::file()
- */
- function fileTag($fieldName, $htmlAttributes = array(), $return = false) {
- return $this->file($fieldName, $htmlAttributes, $return);
- }
-/**
- * @deprecated Name changed to 'hidden'. Version 0.9.2.
- * @see HtmlHelper::hidden()
- */
- function hiddenTag($tagName, $value = null, $htmlOptions = null) {
- $this->setFormTag($tagName);
- $htmlOptions['value'] = $value ? $value : $this->tagValue($tagName);
- return $this->output(sprintf($this->tags['hidden'], $this->model, $this->field, $this->parseHtmlOptions($htmlOptions, null, '', ' ')));
- }
-/**
- * @deprecated Name changed to 'image'. Version 0.9.2.
- * @see HtmlHelper::image()
- */
- function imageTag($path, $alt = null, $htmlAttributes = array(), $return = false) {
- $htmlAttributes['alt'] = $alt;
- return $this->image($path, $htmlAttributes, $return);
- }
-/**
- * @deprecated Name changed to 'input'. Version 0.9.2.
- * @see HtmlHelper::input()
- */
- function inputTag($tagName, $size = 20, $htmlOptions = null) {
- $this->setFormTag($tagName);
- $htmlOptions['value'] = isset($htmlOptions['value']) ? $htmlOptions['value'] : $this->tagValue($tagName);
- $this->tagIsInvalid($this->model, $this->field) ? $htmlOptions['class'] = 'form_error' : null;
- return $this->output(sprintf($this->tags['input'], $this->model, $this->field, $this->parseHtmlOptions($htmlOptions, null, '', ' ')));
- }
-/**
- * @deprecated Unified with 'link'. Version 0.9.2.
- * @see HtmlHelper::link()
- */
- function linkOut($title, $url = null, $htmlAttributes = array(), $escapeTitle = true, $return = false) {
- return $this->link($title, $url, $htmlAttributes, false, $escapeTitle, $return);
- }
-/**
- * @deprecated Unified with 'link'. Version 0.9.2.
- * @see HtmlHelper::link()
- */
- function linkTo($title, $url, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true, $return = false) {
- return $this->link($title, $url, $htmlAttributes, $confirmMessage, $escapeTitle, $return);
- }
-/**
- * @deprecated Name changed to '_parseAttributes'. Version 0.9.2.
- * @see HtmlHelper::_parseAttributes()
- */
- function parseHtmlOptions($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
- if (!is_array($exclude))
- $exclude=array();
-
- if (is_array($options)) {
- $out=array();
-
- foreach ($options as $k => $v) {
- if (!in_array($k, $exclude)) {
- $out[] = "{$k}=\"{$v}\"";
- }
- }
- $out = join(' ', $out);
- return $out ? $insertBefore . $out . $insertAfter : null;
- } else {
- return $options ? $insertBefore . $options . $insertAfter : null;
- }
- }
-/**
- * @deprecated Name changed to 'password'. Version 0.9.2.
- * @see HtmlHelper::password()
- */
- function passwordTag($fieldName, $size = 20, $htmlAttributes = array(), $return = false) {
- $args = func_get_args();
- return call_user_func_array(array(&$this,
- "password"), $args);
- }
-/**
- * @deprecated Name changed to 'radio'. Version 0.9.2.
- * @see HtmlHelper::radio()
- */
- function radioTags($fieldName, $options, $inbetween = null, $htmlAttributes = array(), $return = false) {
- return $this->radio($fieldName, $options, $inbetween, $htmlAttributes, $return);
- }
-/**
- * @deprecated Name changed to 'url'. Version 0.9.2.
- * @see HtmlHelper::url()
- */
- function urlFor($url) {
- return $this->url($url);
- }
-/**
- * @deprecated Name changed to 'submit'. Version 0.9.2.
- * @see HtmlHelper::submit()
- */
- function submitTag() {
- $args = func_get_args();
- return call_user_func_array(array(&$this, "submit"), $args);
- }
-/*************************************************************************
- * Moved methods
- *************************************************************************/
-/**
- * @deprecated Moved to TextHelper. Version 0.9.2.
- */
- function trim() {
- die("Method HtmlHelper::trim() was moved to TextHelper::trim().");
- }
-/**
- * @deprecated Moved to JavascriptHelper. Version 0.9.2.
- */
- function javascriptIncludeTag($url) {
- die("Method HtmlHelper::javascriptIncludeTag() was moved to JavascriptHelper::link().");
- }
-/**
- * @deprecated Moved to JavascriptHelper. Version 0.9.2.
- */
- function javascriptTag($script) {
- die("Method HtmlHelper::javascriptTag() was moved to JavascriptHelper::codeBlock().");
- }
-/**
- * This is very WYSIWYG unfriendly, use HtmlHelper::url() to get contents of "action" attribute. Version 0.9.2.
- * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
- * @see FormHelper::create()
- */
- function formTag($target = null, $type = 'post', $htmlAttributes = array()) {
- $htmlAttributes['action']=$this->urlFor ($target);
- $htmlAttributes['method']=$type == 'get' ? 'get' : 'post';
- $type == 'file' ? $htmlAttributes['enctype'] = 'multipart/form-data' : null;
-
- $append = '';
-
- if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {
- $append .= '<p style="display: inline; margin: 0px; padding: 0px;">';
- $append .= $this->hidden('_Token/key', array('value' => $this->params['_Token']['key'], 'id' => '_TokenKey' . mt_rand()), true);
- $append .= '</p>';
- }
-
- return sprintf($this->tags['form'], $this->parseHtmlOptions($htmlAttributes, null, '')) . $append;
- }
-/**
- * This should be done using a content filter.
- * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
- */
- function linkEmail($title, $email = null, $options = null) {
- // if no $email, then title contains the email.
- if (empty($email))
- $email=$title;
-
- $match=array();
-
- // does the address contain extra attributes?
- preg_match('!^(.*)(\?.*)$!', $email, $match);
-
- // plaintext
- if (empty($options['encode']) || !empty($match[2])) {
- return sprintf($this->tags['mailto'], $email, $this->parseHtmlOptions($options), $title);
- }
- // encoded to avoid spiders
- else {
- $email_encoded=null;
-
- for ($ii = 0; $ii < strlen($email); $ii++) {
- if (preg_match('!\w!', $email[$ii])) {
- $email_encoded .= '%' . bin2hex($email[$ii]);
- } else {
- $email_encoded .= $email[$ii];
- }
- }
-
- $title_encoded=null;
-
- for ($ii = 0; $ii < strlen($title); $ii++) {
- $title_encoded .= preg_match('/^[A-Za-z0-9]$/', $title[$ii])
- ? '&#x' . bin2hex($title[$ii]) . ';' : $title[$ii];
- }
-
- return sprintf($this->tags['mailto'], $email_encoded,
- $this->parseHtmlOptions($options, array('encode')), $title_encoded);
- }
- }
-
-/**
- * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
- */
- function tag($name, $options = null, $open = false) {
- $tag = "<$name " . $this->parseHtmlOptions($options);
- $tag .= $open ? ">" : " />";
- return $tag;
- }
-/**
- * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
- */
- function contentTag($name, $content, $options = null) {
- return "<$name " . $this->parseHtmlOptions($options) . ">$content</$name>";
- }
-
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/javascript.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/javascript.php
deleted file mode 100644
index 1219987..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/javascript.php
+++ /dev/null
@@ -1,317 +0,0 @@
-<?php
-/* SVN FILE: $Id: javascript.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Javascript Helper class file.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Javascript Helper class for easy use of JavaScript.
- *
- * JavascriptHelper encloses all methods needed while working with JavaScript.
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class JavascriptHelper extends Helper{
- var $_cachedEvents = array();
- var $_cacheEvents = false;
- var $_cacheToFile = false;
- var $_cacheAll = false;
- var $_rules = array();
-/**
- * Returns a JavaScript script tag.
- *
- * @param string $script The JavaScript to be wrapped in SCRIPT tags.
- * @param boolean $allowCache Allows the script to be cached if non-event caching is active
- * @return string The full SCRIPT element, with the JavaScript inside it.
- * @access public
- */
- function codeBlock($script, $allowCache = true) {
- if ($this->_cacheEvents && $this->_cacheAll && $allowCache) {
- $this->_cachedEvents[] = $script;
- } else {
- return sprintf($this->tags['javascriptblock'], $script);
- }
- }
-/**
- * Returns a JavaScript include tag (SCRIPT element)
- *
- * @param string $url URL to JavaScript file.
- * @return string
- * @access public
- */
- function link($url) {
- if (strpos($url, '.js') === false) {
- $url .= ".js";
- }
- return sprintf($this->tags['javascriptlink'], $this->webroot . $this->themeWeb . JS_URL . $url);
- }
-/**
- * Returns a JavaScript include tag for an externally-hosted script
- *
- * @param string $url URL to JavaScript file.
- * @return string
- * @access public
- */
- function linkOut($url) {
- if (strpos($url, '.js') === false && strpos($url, '?') === false) {
- $url .= '.js';
- }
- return sprintf($this->tags['javascriptlink'], $url);
- }
-/**
- * Escape carriage returns and single and double quotes for JavaScript segments.
- *
- * @param string $script string that might have javascript elements
- * @return string escaped string
- * @access public
- */
- function escapeScript($script) {
- $script = r(array("\r\n", "\n", "\r"), '\n', $script);
- $script = r(array('"', "'"), array('\"', "\\'"), $script);
- return $script;
- }
-/**
- * Escape a string to be JavaScript friendly.
- *
- * List of escaped ellements:
- * + "\r\n" => '\n'
- * + "\r" => '\n'
- * + "\n" => '\n'
- * + '"' => '\"'
- * + "'" => "\\'"
- *
- * @param string $script String that needs to get escaped.
- * @return string Escaped string.
- * @access public
- */
- function escapeString($string) {
- $escape = array("\r\n" => '\n', "\r" => '\n', "\n" => '\n', '"' => '\"', "'" => "\\'");
- return r(array_keys($escape), array_values($escape), $string);
- }
-/**
- * Attach an event to an element. Used with the Prototype library.
- *
- * @param string $object Object to be observed
- * @param string $event event to observe
- * @param string $observer function to call
- * @param boolean $useCapture default true
- * @return boolean true on success
- * @access public
- */
- function event($object, $event, $observer = null, $useCapture = false) {
-
- if ($useCapture == true) {
- $useCapture = "true";
- } else {
- $useCapture = "false";
- }
-
- if ($object == 'window' || strpos($object, '$(') !== false || strpos($object, '"') !== false || strpos($object, '\'') !== false) {
- $b = "Event.observe($object, '$event', function(event) { $observer }, $useCapture);";
- } else {
- $chars = array('#', ' ', ', ', '.', ':');
- $found = false;
- foreach ($chars as $char) {
- if (strpos($object, $char) !== false) {
- $found = true;
- break;
- }
- }
- if ($found) {
- $this->_rules[$object] = $event;
- } else {
- $b = "Event.observe(\$('$object'), '$event', function(event) { $observer }, $useCapture);";
- }
- }
-
- if (isset($b) && !empty($b)) {
- if ($this->_cacheEvents === true) {
- $this->_cachedEvents[] = $b;
- return;
- } else {
- return $this->codeBlock($b);
- }
- }
- }
-/**
- * Cache JavaScript events created with event()
- *
- * @param boolean $file If true, code will be written to a file
- * @param boolean $all If true, all code written with JavascriptHelper will be sent to a file
- * @return void
- * @access public
- */
- function cacheEvents($file = false, $all = false) {
- $this->_cacheEvents = true;
- $this->_cacheToFile = $file;
- $this->_cacheAll = $all;
- }
-/**
- * Write cached JavaScript events
- *
- * @return string
- * @access public
- */
- function writeEvents() {
-
- $rules = array();
- if (!empty($this->_rules)) {
- foreach ($this->_rules as $sel => $event) {
- $rules[] = "\t'{$sel}': function(element, event) {\n\t\t{$event}\n\t}";
- }
- $this->_cacheEvents = true;
- }
-
- if ($this->_cacheEvents) {
-
- $this->_cacheEvents = false;
- $events = $this->_cachedEvents;
- $data = implode("\n", $events);
- $this->_cachedEvents = array();
-
- if (!empty($rules)) {
- $data .= "\n\nvar SelectorRules = {\n" . implode(",\n\n", $rules) . "\n}\n";
- $data .= "\nEventSelectors.start(SelectorRules);\n";
- }
-
- if (!empty($events) || !empty($rules)) {
- if ($this->_cacheToFile) {
- $filename = md5($data);
- if (!file_exists(JS . $filename . '.js')) {
- cache(r(WWW_ROOT, '', JS) . $filename . '.js', $data, '+999 days', 'public');
- }
- return $this->link($filename);
- } else {
- return $this->codeBlock("\n" . $data . "\n");
- }
- }
- }
- }
-/**
- * Includes the Prototype Javascript library (and anything else) inside a single script tag.
- *
- * Note: The recommended approach is to copy the contents of
- * javascripts into your application's
- * public/javascripts/ directory, and use @see javascriptIncludeTag() to
- * create remote script links.
- *
- * @param string $script name of script to include
- * @return string script with all javascript in/javascripts folder
- * @access public
- */
- function includeScript($script = "") {
- if ($script == "") {
- $dh = opendir(JS);
- while (false !== ($filename = readdir($dh))) {
- $files[] = $filename;
- }
- sort($files);
- $javascript = '';
- foreach ($files as $file) {
- if (substr($file, -3) == '.js') {
- $javascript .= file_get_contents(JS . "{$file}") . "\n\n";
- }
- }
- } else {
- $javascript = file_get_contents(JS . "$script.js") . "\n\n";
- }
- return $this->codeBlock("\n\n" . $javascript);
- }
-/**
- * Generates a JavaScript object in JavaScript Object Notation (JSON)
- * from an array
- *
- * @param array $data Data to be converted
- * @param boolean $block Wraps return value in a <script/> block if true
- * @param string $prefix Prepends the string to the returned data
- * @param string $postfix Appends the string to the returned data
- * @param array $stringKeys A list of array keys to be treated as a string
- * @param boolean $quoteKeys If false, treats $stringKey as a list of keys *not* to be quoted
- * @param string $q The type of quote to use
- * @return string A JSON code block
- * @access public
- */
- function object($data = array(), $block = false, $prefix = '', $postfix = '', $stringKeys = array(), $quoteKeys = true, $q = "\"") {
- if (is_object($data)) {
- $data = get_object_vars($data);
- }
-
- $out = array();
- $key = array();
-
- if (is_array($data)) {
- $keys = array_keys($data);
- }
-
- $numeric = true;
- if (!empty($keys)) {
- $numeric = (array_values($keys) === array_keys(array_values($keys)));
- }
-
- foreach ($data as $key => $val) {
- if (is_array($val) || is_object($val)) {
- $val = $this->object($val, false, '', '', $stringKeys, $quoteKeys, $q);
- } else {
- if ((!count($stringKeys) && !is_numeric($val) && !is_bool($val)) || ($quoteKeys && in_array($key, $stringKeys, true)) || (!$quoteKeys && !in_array($key, $stringKeys, true))) {
- $val = $q . $this->escapeString($val) . $q;
- }
- if ($val === null) {
- $val = 'null';
- }
- if (is_bool($val)) {
- $val = ife($val, 'true', 'false');
- }
- }
-
- if (!$numeric) {
- $val = $q . $key . $q . ':' . $val;
- }
-
- $out[] = $val;
- }
-
- if (!$numeric) {
- $rt = '{' . join(', ', $out) . '}';
- } else {
- $rt = '[' . join(', ', $out) . ']';
- }
- $rt = $prefix . $rt . $postfix;
-
- if ($block) {
- $rt = $this->codeBlock($rt);
- }
-
- return $rt;
- }
-/**
- * AfterRender callback. Writes any cached events to the view, or to a temp file.
- *
- * @return void
- * @access public
- */
- function afterRender() {
- echo $this->writeEvents();
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/number.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/number.php
deleted file mode 100644
index 3d8ea8e..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/number.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/* SVN FILE: $Id: number.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Number Helper.
- *
- * Methods to make numbers more readable.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Number helper library.
- *
- * Methods to make numbers more readable.
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class NumberHelper extends Helper {
-/**
- * Formats a number with a level of precision.
- *
- * @param float $number A floating point number.
- * @param integer $precision The precision of the returned number.
- * @return float Enter description here...
- * @access public
- */
- function precision($number, $precision = 3) {
- return sprintf("%01.{$precision}f", $number);
- }
-
-/**
- * Returns a formatted-for-humans file size.
- *
- * @param integer $length Size in bytes
- * @return string Human readable size
- * @access public
- */
- function toReadableSize($size) {
- switch($size) {
- case 0:
- return '0 Bytes';
- case 1:
- return '1 Byte';
- case $size < 1024:
- return $size . ' Bytes';
- case $size < 1024 * 1024:
- return NumberHelper::precision($size / 1024, 0) . ' KB';
- case $size < 1024 * 1024 * 1024:
- return NumberHelper::precision($size / 1024 / 1024, 2) . ' MB';
- case $size < 1024 * 1024 * 1024 * 1024:
- return NumberHelper::precision($size / 1024 / 1024 / 1024, 2) . ' GB';
- case $size < 1024 * 1024 * 1024 * 1024 * 1024:
- return NumberHelper::precision($size / 1024 / 1024 / 1024 / 1024, 2) . ' TB';
- }
- }
-
-/**
- * Formats a number into a percentage string.
- *
- * @param float $number A floating point number
- * @param integer $precision The precision of the returned number
- * @return string Percentage string
- * @access public
- */
- function toPercentage($number, $precision = 2) {
- return NumberHelper::precision($number, $precision) . '%';
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/session.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/session.php
deleted file mode 100644
index 77eee9a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/session.php
+++ /dev/null
@@ -1,198 +0,0 @@
-<?php
-/* SVN FILE: $Id: session.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 1.1.7.3328
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Session Helper.
- *
- * Session reading from the view.
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- *
- */
-if(!class_exists('cakesession')) {
- uses('session');
-}
-class SessionHelper extends CakeSession {
-/**
- * List of helpers used by this helper
- *
- * @var array
- */
- var $helpers = null;
-/**
- * Used to determine if methods implementation is used, or bypassed
- *
- * @var boolean
- */
- var $__active = true;
-/**
- * Class constructor
- *
- * @param string $base
- */
- function __construct($base = null) {
- if (!defined('AUTO_SESSION') || AUTO_SESSION === true) {
- parent::__construct($base, false);
- } else {
- $this->__active = false;
- }
- }
-/**
- * Turn sessions on if 'Session.start' is set to false in core.php
- *
- * @param string $base
- */
- function activate($base = null) {
- $this->__active = true;
- }
-/**
- * Used to read a session values set in a controller for a key or return values for all keys.
- *
- * In your view: $session->read('Controller.sessKey');
- * Calling the method without a param will return all session vars
- *
- * @param string $name the name of the session key you want to read
- *
- * @return values from the session vars
- * @access public
- */
- function read($name = null) {
- if ($this->__active === true && $this->__start()) {
- return parent::read($name);
- }
- return false;
- }
-/**
- * Used to check is a session key has been set
- *
- * In your view: $session->check('Controller.sessKey');
- *
- * @param string $name
- * @return boolean
- * @access public
- */
- function check($name) {
- if ($this->__active === true && $this->__start()) {
- return parent::check($name);
- }
- return false;
- }
-/**
- * Returns last error encountered in a session
- *
- * In your view: $session->error();
- *
- * @return string last error
- * @access public
- */
- function error() {
- if ($this->__active === true && $this->__start()) {
- return parent::error();
- }
- return false;
- }
-/**
- * Used to render the message set in Controller::Session::setFlash()
- *
- * In your view: $session->flash('somekey');
- * Will default to flash if no param is passed
- *
- * @param string $key The [Message.]key you are rendering in the view.
- * @return string Will echo the value if $key is set, or false if not set.
- * @access public
- */
- function flash($key = 'flash') {
- if ($this->__active === true && $this->__start()) {
- if (parent::check('Message.' . $key)) {
- $flash = parent::read('Message.' . $key);
-
- if ($flash['layout'] == 'default') {
- $out = '<div id="' . $key . 'Message" class="message">' . $flash['message'] . '</div>';
- } elseif ($flash['layout'] == '' || $flash['layout'] == null) {
- $out = $flash['message'];
- } else {
- $view =& ClassRegistry::getObject('view');
- list($tmpLayout, $tmpVars, $tmpTitle) = array($view->layout, $view->viewVars, $view->pageTitle);
- list($view->layout, $view->viewVars, $view->pageTitle) = array($flash['layout'], $flash['params'], '');
- $out = $view->renderLayout($flash['message']);
- list($view->layout, $view->viewVars, $view->pageTitle) = array($tmpLayout, $tmpVars, $tmpTitle);
- }
- e($out);
- parent::del('Message.' . $key);
- return true;
- }
- }
- return false;
- }
-/**
- * Used to check is a session is valid in a view
- *
- * @return boolean
- * @access public
- */
- function valid() {
- if ($this->__active === true && $this->__start()) {
- return parent::valid();
- }
- }
-/**
- * Override CakeSession::write().
- * This method should not be used in a view
- *
- * @return boolean
- * @access public
- */
- function write() {
- trigger_error(__('You can not write to a Session from the view', true), E_USER_WARNING);
- }
-/**
- * Session id
- *
- * @return string Session id
- * @access public
- */
- function id() {
- return parent::id();
- }
-/**
- * Determine if Session has been started
- * and attempt to start it if not
- *
- * @return boolean true if Session is already started, false if
- * Session could not be started
- * @access public
- */
- function __start() {
- if(!parent::started()) {
- parent::start();
- }
- return true;
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/text.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/text.php
deleted file mode 100644
index c545f3c..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/text.php
+++ /dev/null
@@ -1,238 +0,0 @@
-<?php
-/* SVN FILE: $Id: text.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Text Helper
- *
- * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- *
- */
-if (!class_exists('Flay')) {
- uses('flay');
-}
-if (!class_exists('HtmlHelper')) {
- uses('view' . DS . 'helpers' . DS . 'html');
-}
-/**
- * Text helper library.
- *
- * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class TextHelper extends Helper{
-/**
- * Highlights a given phrase in a text.
- *
- * @param string $text Text to search the phrase in
- * @param string $phrase The phrase that will be searched
- * @param string $highlighter The piece of html with that the phrase will be highlighted
- * @return string The highlighted text
- * @access public
- */
- function highlight($text, $phrase, $highlighter = '<span class="highlight">\1</span>') {
- if (empty($phrase))
- return $text;
-
- if (is_array($phrase)) {
- $replace=array();
- $with=array();
-
- foreach ($phrase as $key => $value) {
- if (empty($key)) {
- $key =$value;
- $value=$highlighter;
- }
-
- $replace[]='|(' . $key . ')|i';
- $with[]=empty($value) ? $highlighter : $value;
- }
-
- return preg_replace($replace, $with, $text);
- } else {
- return preg_replace("|({$phrase})|i", $highlighter, $text);
- }
- }
-/**
- * Strips given text of all links (<a href=....)
- *
- * @param string $text Text
- * @return string The text without links
- * @access public
- */
- function stripLinks($text) {
- return preg_replace('|<a.*>(.*)<\/a>|im', '\1', $text);
- }
-/**
- * Adds links (<a href=....) to a given text, by finding text that begins with
- * strings like http:// and ftp://.
- *
- * @param string $text Text to add links to
- * @param array $htmlOptions Array of HTML options.
- * @return string The text with links
- * @access public
- */
- function autoLinkUrls($text, $htmlOptions = array()) {
- $options='array(';
-
- foreach ($htmlOptions as $option => $value) {
- $options .= "'$option' => '$value', ";
- }
-
- $options .= ')';
-
- $text = preg_replace_callback('#(?<!href="|">)((?:http|https|ftp|nntp)://[^ <]+)#i',
- create_function('$matches',
- '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], $matches[0],' . $options . ');'),
- $text);
- return preg_replace_callback('#(?<!href="|">)(?<!http://|https://|ftp://|nntp://)(www\.[^\n\%\ <]+[^<\n\%\,\.\ <])#i',
- create_function('$matches',
- '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], "http://" . $matches[0],' . $options . ');'),
- $text);
- }
-/**
- * Adds email links (<a href="mailto:....) to a given text.
- *
- * @param string $text Text
- * @param array $htmlOptions Array of HTML options.
- * @return string The text with links
- * @access public
- */
- function autoLinkEmails($text, $htmlOptions = array()) {
- $options='array(';
-
- foreach ($htmlOptions as $option => $value) {
- $options .= "'$option' => '$value', ";
- }
-
- $options .= ')';
-
- return preg_replace_callback(
- '#([_A-Za-z0-9+-]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#',
- create_function('$matches',
- '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->linkEmail($matches[0], $matches[0],' . $options . ');'),
- $text);
- }
-/**
- * Convert all links and email adresses to HTML links.
- *
- * @param string $text Text
- * @param array $htmlOptions Array of HTML options.
- * @return string The text with links
- * @access public
- */
- function autoLink($text, $htmlOptions = array()) {
- return $this->autoLinkEmails($this->autoLinkUrls($text, $htmlOptions), $htmlOptions);
- }
-/**
- * Truncates text.
- *
- * Cuts a string to the length of $length and replaces the last characters
- * with the ending if the text is longer than length.
- *
- * @param string $text String to truncate.
- * @param integer $length Length of returned string, including ellipsis.
- * @param string $ending Ending to be appended to the trimmed string.
- * @param boolean $exact If false, $test will not be cut mid-word
- * @return string Trimmed string.
- * @access public
- */
- function truncate($text, $length, $ending = '...', $exact = true) {
- if (strlen($text) <= $length) {
- return $text;
- } else {
- $truncate=substr($text, 0, $length - strlen($ending));
-
- if (!$exact) {
- $spacepos=strrpos($truncate, ' ');
-
- if (isset($spacepos)) {
- return substr($truncate, 0, $spacepos) . $ending;
- }
- }
-
- return $truncate . $ending;
- }
- }
-/**
- * Alias for truncate().
- *
- * @see TextHelper::truncate()
- * @return Text::truncate()
- * @access public
- */
- function trim() {
- $args=func_get_args();
- return call_user_func_array(array(&$this,
- "truncate"), $args);
- }
-/**
- * Extracts an excerpt from the text surrounding the phrase with a number of characters on each side determined by radius.
- *
- * @param string $text String to search the phrase in
- * @param string $phrase Phrase that will be searched for
- * @param integer $radius The amount of characters that will be returned on each side of the founded phrase
- * @param string $ending Ending that will be appended
- * @return string
- * @access public
- */
- function excerpt($text, $phrase, $radius = 100, $ending = "...") {
- if (empty($text) or empty($phrase))
- return $this->truncate($text, $radius * 2, $ending);
-
- if ($radius < strlen($phrase))
- $radius=strlen($phrase);
-
- $pos =strpos($text, $phrase);
- $startPos=$pos <= $radius ? 0 : $pos - $radius;
- $endPos =$pos + strlen($phrase) + $radius >= strlen($text)
- ? strlen($text) : $pos + strlen($phrase) + $radius;
-
- $excerpt =substr($text, $startPos, $endPos - $startPos);
-
- if ($startPos != 0)
- $excerpt=substr_replace($excerpt, $ending, 0, strlen($phrase));
-
- if ($endPos != strlen($text))
- $excerpt=substr_replace($excerpt, $ending, -strlen($phrase));
-
- return $excerpt;
- }
-/**
- * Text-to-html parser, similar to Textile or RedCloth, only with a little different syntax.
- *
- * @param string $text String to "flay"
- * @param boolean $allowHtml Set to true if if html is allowed
- * @return string "Flayed" text
- * @todo Change this. We need a real Textile parser.
- * @access public
- */
- function flay($text, $allowHtml = false) {
- return Flay::toHtml($text, false, $allowHtml);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/time.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/time.php
deleted file mode 100644
index f10cadb..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/helpers/time.php
+++ /dev/null
@@ -1,397 +0,0 @@
-<?php
-/* SVN FILE: $Id: time.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Time Helper class file.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Time Helper class for easy use of time data.
- *
- * Manipulation of time data.
- *
- * @package cake
- * @subpackage cake.cake.libs.view.helpers
- */
-class TimeHelper extends Helper {
-/**
- * Returns given string trimmed to given length, adding an ending (default: "..") if necessary.
- *
- * @param string $string String to trim
- * @param integer $length Length of returned string, excluding ellipsis
- * @param string $ending Ending to be appended after trimmed string
- * @return string Trimmed string
- * @access public
- */
- function trim($string, $length, $ending = '..') {
- return substr($string, 0, $length) . (strlen($string) > $length ? $ending : null);
- }
-/**
- * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
- *
- * @param string $date_string Datetime string
- * @return string Formatted date string
- * @access public
- */
- function fromString($date_string) {
- if (is_integer($date_string) || is_numeric($date_string)) {
- return intval($date_string);
- } else {
- return strtotime($date_string);
- }
- }
-/**
- * Returns a nicely formatted date string for given Datetime string.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Formatted date string
- * @access public
- */
- function nice($date_string = null, $return = false) {
- if ($date_string != null) {
- $date = $this->fromString($date_string);
- } else {
- $date = time();
- }
-
- $ret = date("D, M jS Y, H:i", $date);
- return $this->output($ret, $return);
- }
-/**
- * Returns a formatted descriptive date string for given datetime string.
- *
- * If the given date is today, the returned string could be "Today, 16:54".
- * If the given date was yesterday, the returned string could be "Yesterday, 16:54".
- * If $date_string's year is the current year, the returned string does not
- * include mention of the year.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Described, relative date string
- * @access public
- */
- function niceShort($date_string = null, $return = false) {
- $date = $date_string ? $this->fromString($date_string) : time();
- $y = $this->isThisYear($date) ? '' : ' Y';
-
- if ($this->isToday($date)) {
- $ret = "Today, " . date("H:i", $date);
- } elseif ($this->wasYesterday($date)) {
- $ret = "Yesterday, " . date("H:i", $date);
- } else {
- $ret = date("M jS{$y}, H:i", $date);
- }
-
- return $this->output($ret, $return);
- }
-/**
- * Returns true if given datetime string is today.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return boolean True if datetime string is today
- * @access public
- */
- function isToday($date_string, $return = false) {
- $date = $this->fromString($date_string);
- $ret = date('Y-m-d', $date) == date('Y-m-d', time());
- return $this->output($ret, $return);
- }
-/**
- * Returns a partial SQL string to search for all records between two dates.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param string $end Datetime string or Unix timestamp
- * @param string $field_name Name of database field to compare with
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Partial SQL string.
- * @access public
- */
- function daysAsSql($begin, $end, $field_name, $return = false) {
- $begin = $this->fromString($begin);
- $end = $this->fromString($end);
- $begin = date('Y-m-d', $begin) . ' 00:00:00';
- $end = date('Y-m-d', $end) . ' 23:59:59';
-
- return $this->output("($field_name >= '$begin') AND ($field_name <= '$end')", $return);
- }
-/**
- * Returns a partial SQL string to search for all records between two times
- * occurring on the same day.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param string $field_name Name of database field to compare with
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Partial SQL string.
- * @access public
- */
- function dayAsSql($date_string, $field_name, $return = false) {
- $date = $this->fromString($date_string);
- $ret = $this->daysAsSql($date_string, $date_string, $field_name);
- return $this->output($ret, $return);
- }
-/**
- * Returns true if given datetime string is within current year.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return boolean True if datetime string is within current year
- * @access public
- */
- function isThisYear($date_string, $return = false) {
- $date = $this->fromString($date_string);
- $ret = date('Y', $date) == date('Y', time());
- return $this->output($ret, $return);
- }
-/**
- * Returns true if given datetime string was yesterday.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return boolean True if datetime string was yesterday
- * @access public
- */
- function wasYesterday($date_string, $return = false) {
- $date = $this->fromString($date_string);
- $ret = date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday'));
- return $this->output($ret, $return);
- }
-/**
- * Returns true if given datetime string is tomorrow.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return boolean True if datetime string was yesterday
- * @access public
- */
- function isTomorrow($date_string, $return = false) {
- $date = $this->fromString($date_string);
- $ret = date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow'));
- return $this->output($ret, $return);
- }
-/**
- * Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
- *
- * @param string $date_string Datetime string to be represented as a Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return int Unix timestamp
- * @access public
- */
- function toUnix($date_string, $return = false) {
- $ret = strtotime($date_string);
- return $this->output($ret, $return);
- }
-/**
- * Returns a date formatted for Atom RSS feeds.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Formatted date string
- * @access public
- */
- function toAtom($date_string, $return = false) {
- $date = $this->fromString($date_string);
- $ret = date('Y-m-d\TH:i:s\Z', $date);
- return $this->output($ret, $return);
- }
-/**
- * Formats date for RSS feeds
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Formatted date string
- * @access public
- */
- function toRSS($date_string, $return = false) {
- $date = $this->fromString($date_string);
- $ret = date("r", $date);
- return $this->output($ret, $return);
- }
-/**
- * Returns either a relative date or a formatted date depending
- * on the difference between the current time and given datetime.
- * $datetime should be in a <i>strtotime</i>-parsable format, like MySQL's datetime datatype.
- *
- * Relative dates look something like this:
- * 3 weeks, 4 days ago
- * 15 seconds ago
- * Formatted dates look like this:
- * on 02/18/2004
- *
- * The returned string includes 'ago' or 'on' and assumes you'll properly add a word
- * like 'Posted ' before the function output.
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param string $format Default format if timestamp is used in $date_string
- * @param string $backwards False if $date_string is in the past, true if in the future
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Relative time string.
- * @access public
- */
- function timeAgoInWords($datetime_string, $format = 'j/n/y', $backwards = false, $return = false) {
- $datetime = $this->fromString($datetime_string);
-
- $in_seconds = $datetime;
- if ($backwards) {
- $diff = $in_seconds - time();
- } else {
- $diff = time() - $in_seconds;
- }
-
- $months = floor($diff / 2419200);
- $diff -= $months * 2419200;
- $weeks = floor($diff / 604800);
- $diff -= $weeks * 604800;
- $days = floor($diff / 86400);
- $diff -= $days * 86400;
- $hours = floor($diff / 3600);
- $diff -= $hours * 3600;
- $minutes = floor($diff / 60);
- $diff -= $minutes * 60;
- $seconds = $diff;
-
- if ($months > 0) {
- // over a month old, just show date (mm/dd/yyyy format)
- $relative_date = 'on ' . date($format, $in_seconds);
- $old = true;
- } else {
- $relative_date = '';
- $old = false;
-
- if ($weeks > 0) {
- // weeks and days
- $relative_date .= ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '');
- $relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
- } elseif ($days > 0) {
- // days and hours
- $relative_date .= ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '');
- $relative_date .= $hours > 0 ? ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '') : '';
- } elseif ($hours > 0) {
- // hours and minutes
- $relative_date .= ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '');
- $relative_date .= $minutes > 0 ? ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '') : '';
- } elseif ($minutes > 0) {
- // minutes only
- $relative_date .= ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
- } else {
- // seconds only
- $relative_date .= ($relative_date ? ', ' : '') . $seconds . ' second' . ($seconds != 1 ? 's' : '');
- }
- }
-
- $ret = $relative_date;
-
- // show relative date and add proper verbiage
- if (!$backwards && !$old) {
- $ret .= ' ago';
- }
- return $this->output($ret, $return);
- }
-/**
- * Alias for timeAgoInWords
- *
- * @param string $date_string Datetime string or Unix timestamp
- * @param string $format Default format if timestamp is used in $date_string
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return string Relative time string.
- * @see Time::timeAgoInWords()
- * @access public
- */
- function relativeTime($datetime_string, $format = 'j/n/y', $return = false) {
- $date = strtotime($datetime_string);
-
- if (strtotime("now") > $date) {
- $ret = $this->timeAgoInWords($datetime_string, $format, false);
- } else {
- $ret = $this->timeAgoInWords($datetime_string, $format, true);
- }
-
- return $this->output($ret, $return);
- }
-/**
- * Returns true if specified datetime was within the interval specified, else false.
- *
- * @param mixed $timeInterval the numeric value with space then time type. Example of valid types: 6 hours, 2 days, 1 minute.
- * @param mixed $date_string the datestring or unix timestamp to compare
- * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
- * @return boolean
- * @access public
- */
- function wasWithinLast($timeInterval, $date_string, $return = false) {
- $date = $this->fromString($date_string);
- $result = preg_split('/\\s/', $timeInterval);
- $numInterval = $result[0];
- $textInterval = $result[1];
- $currentTime = floor(time());
- $seconds = ($currentTime - floor($date));
-
- switch($textInterval) {
- case "seconds":
- case "second":
- $timePeriod = $seconds;
- $ret = $return;
- break;
- case "minutes":
- case "minute":
- $minutes = floor($seconds / 60);
- $timePeriod = $minutes;
- break;
- case "hours":
- case "hour":
- $hours = floor($seconds / 3600);
- $timePeriod = $hours;
- break;
- case "days":
- case "day":
- $days = floor($seconds / 86400);
- $timePeriod = $days;
- break;
- case "weeks":
- case "week":
- $weeks = floor($seconds / 604800);
- $timePeriod = $weeks;
- break;
- case "months":
- case "month":
- $months = floor($seconds / 2629743.83);
- $timePeriod = $months;
- break;
- case "years":
- case "year":
- $years = floor($seconds / 31556926);
- $timePeriod = $years;
- break;
- default:
- $days = floor($seconds / 86400);
- $timePeriod = $days;
- break;
- }
- if ($timePeriod <= $numInterval) {
- $ret = true;
- } else {
- $ret = false;
- }
- return $this->output($ret, $return);
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/elements/dump.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/elements/dump.thtml
deleted file mode 100644
index 3591bdb..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/elements/dump.thtml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-/* SVN FILE: $Id: dump.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.elements
- * @since CakePHP(tm) v 0.10.5.1782
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<div>
- <h2>Controller dump:</h2>
- <pre>
- <?php print_r($this->controller); ?>
- </pre>
-</div> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/error404.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/error404.thtml
deleted file mode 100644
index cde78fd..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/error404.thtml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/* SVN FILE: $Id: error404.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1><?php echo $name; ?></h1>
-<p><?php echo $message; ?></p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_action.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_action.thtml
deleted file mode 100644
index e04e94b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_action.thtml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_action.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Method in <?php echo $controller;?></h1>
-<p class="error">You are seeing this error because the action <em><?php echo $action;?></em> is not defined in controller <em><?php echo $controller;?></em></p>
-<p><span class="notice">If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_action.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the <?php echo $controller;?>::<?php echo $action;?>() in file : <?php echo APP_DIR.DS."controllers".DS.Inflector::underscore($controller).".php"; ?></p>
-<p>&lt;?php<br />
-class <?php echo $controller;?> extends AppController {<br />
-&nbsp;&nbsp;&nbsp;<strong>function <?php echo $action;?>() {<br />
-&nbsp;&nbsp;&nbsp;}</strong><br />
-}<br />
-?&gt;<br />
-</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_class.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_class.thtml
deleted file mode 100644
index 42c8783..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_class.thtml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_component_class.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Component Class</h1>
-<p class="error">You are seeing this error because the component class <em><?php echo $component."Component";?></em>
-you have set in <?php echo $controller."Controller";?> can't be found or doesn't exist.</em></p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_component_class.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."controllers".DS."components".DS.$file; ?></p>
-<p>&lt;?php<br />
-class <?php echo $component;?>Component extends Object {<br />
-}<br />
-?&gt;<br />
-</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_file.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_file.thtml
deleted file mode 100644
index 5ff57bd..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_component_file.thtml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_component_file.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Component File</h1>
-<p class="error">You are seeing this error because the component file can't be found or doesn't exist.</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_component_file.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."controllers".DS."components".DS.$file; ?></p>
-<p>&lt;?php<br />
-class <?php echo $component;?>Component extends Object {<br />
-
-}<br />
-?&gt;<br /> </p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_connection.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_connection.thtml
deleted file mode 100644
index de859fb..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_connection.thtml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_connection.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Requires a Database Connection</h1>
-<p class="error">Missing Database Connection: <?php echo $model;?> requires a database connection</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_database.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo APP_DIR.DS."config".DS."database.php"; ?></p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_controller.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_controller.thtml
deleted file mode 100644
index 535fb6a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_controller.thtml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_controller.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing controller</h1>
-<p class="error">You are seeing this error because controller <em><?php echo $controller;?></em> could not be found.</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_controller.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."controllers".DS.Inflector::underscore($controller).".php"; ?></p>
-<p>&lt;?php<br />
-class <?php echo $controller;?> extends AppController {<br />
-&nbsp;&nbsp;&nbsp;var $name = '<?php echo $controllerName;?>';<br />
-}<br />
-?&gt;<br />
-</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_class.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_class.thtml
deleted file mode 100644
index b7bb5a0..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_class.thtml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_helper_class.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Helper Class</h1>
-<p class="error">You are seeing this error because the view helper class <?php echo $helperClass;?> can't be found or doesn't exist.</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_helper_class.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."views".DS."helpers".DS.$file; ?></p>
-<p>&lt;?php<br />
-class <?php echo $helperClass;?> extends Helper {<br />
-}<br />
-?&gt;<br />
-</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_file.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_file.thtml
deleted file mode 100644
index 16c4e0c..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_helper_file.thtml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_helper_file.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Helper File</h1>
-<p class="error">You are seeing this error because the view helper file <?php echo APP_DIR.DS."views".DS."helpers".DS.$file; ?> can't be found or doesn't exist.</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_helper_file.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."views".DS."helpers".DS.$file; ?></p>
-<p>&lt;?php<br />
-class <?php echo $helperClass;?> extends Helper {<br />
-}<br />
-?&gt;<br />
-</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_layout.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_layout.thtml
deleted file mode 100644
index bfd991d..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_layout.thtml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_layout.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Layout</h1>
-<p class="error">You are seeing this error because the layout file <?php echo $file;?> can't be found or doesn't exist.</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_layout.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo $file;?></p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_model.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_model.thtml
deleted file mode 100644
index ade0783..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_model.thtml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_model.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Model</h1>
-<p class="error">No class found for the <em><?php echo $model;?></em> model</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_model.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo "app".DS."models".DS.Inflector::underscore($model).".php"; ?></p>
-<p>&lt;?php<br />
-class <?php echo $model;?> extends AppModel {<br />
-&nbsp;&nbsp;&nbsp;var $name = '<?php echo $model;?>';<br />
-}<br />
-?&gt;<br />
-</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_scaffolddb.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_scaffolddb.thtml
deleted file mode 100644
index a680c2a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_scaffolddb.thtml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_scaffolddb.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Scaffold Requires a Database Connection</h1>
-<p class="error">Missing Database Connection: Scaffold Does not work without a database connection</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_scaffolddb.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo APP_DIR.DS."config".DS."database.php"; ?></p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_table.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_table.thtml
deleted file mode 100644
index 01d3049..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_table.thtml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_table.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing Database Table</h1>
-<p class="error">No Database table for model <?php echo $model;?> (expected "<?php echo $table;?>"), create it first.</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_table.thtml"; ?>.</span></p>
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_view.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_view.thtml
deleted file mode 100644
index d5c2f1f..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/missing_view.thtml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/* SVN FILE: $Id: missing_view.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Missing view</h1>
-<p class="error">You are seeing this error because the view for <em><?php echo $controller.'Controller';?>::<?php echo $action;?>()</em> could not be found.</p>
-<p><span class="notice">If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_view.thtml"; ?>.</span></p>
-<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo $file;?></p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/private_action.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/private_action.thtml
deleted file mode 100644
index 6b9388f..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/private_action.thtml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/* SVN FILE: $Id: private_action.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Private Method in <?php echo $controller;?></h1>
-<p class="error">You are seeing this error because the private class method <em><?php echo $action;?></em> should not be accessed directly</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/private_action.thtml"; ?>.</span></p>
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/scaffold_error.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/scaffold_error.thtml
deleted file mode 100644
index 919aa25..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/errors/scaffold_error.thtml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/* SVN FILE: $Id: scaffold_error.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.errors
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>Scaffold Error</h1>
-<p class="error">Your must implement the following method in your controller</p>
-<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/scaffold_error.thtml"; ?>.</span></p>
-<p>
-&nbsp;&nbsp;&nbsp;function _scaffoldError() {<br />
-&nbsp;&nbsp;&nbsp;}<br />
-</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/ajax.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/ajax.thtml
deleted file mode 100644
index 446beaa..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/ajax.thtml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/* SVN FILE: $Id: ajax.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.layouts
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<?php echo $content_for_layout; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/default.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/default.thtml
deleted file mode 100644
index bb733c5..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/default.thtml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-/* SVN FILE: $Id: default.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.pages
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>CakePHP(tm) : <?php echo $title_for_layout; ?></title>
-<?php echo $html->charset(); ?>
-<link rel="icon" href="<?php echo $this->webroot . 'favicon.ico'; ?>" type="image/x-icon" />
-<link rel="shortcut icon" href="<?php echo $this->webroot . 'favicon.ico'; ?>" type="image/x-icon" />
-<?php echo $html->css('cake.generic'); ?>
-</head>
-<body>
- <div id="container">
- <div id="header">
- <h1>CakePHP Rapid Development</h1>
- </div>
- <div id="content">
- <?php if ($session->check('Message.flash'))
- {
- $session->flash();
- }
- echo $content_for_layout;
- ?>
- </div>
- <div id="footer">
- &nbsp;
- <a href="http://www.cakephp.org/" target="_new">
- <?php echo $html->image('cake.power.png', array('alt'=>"CakePHP(tm) : Rapid Development Framework", 'border'=>"0")); ?>
- </a>
- </div>
- </div>
- <?php echo $cakeDebug; ?>
-</body>
-</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/flash.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/flash.thtml
deleted file mode 100644
index 1d7c808..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/layouts/flash.thtml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/* SVN FILE: $Id: flash.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.layouts
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title><?php echo $page_title; ?></title>
-<?php echo $html->charset(); ?>
-
-<?php if (Configure::read() == 0) { ?>
-<meta http-equiv="Refresh" content="<?php echo $pause; ?>;url=<?php echo $url; ?>"/>
-<?php } ?>
-<style><!--
-P { text-align:center; font:bold 1.1em sans-serif }
-A { color:#444; text-decoration:none }
-A:HOVER { text-decoration: underline; color:#44E }
---></style>
-</head>
-<body>
-<p><a href="<?php echo $url; ?>"><?php echo $message; ?></a></p>
-</body>
-</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/pages/home.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/pages/home.thtml
deleted file mode 100644
index a505e39..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/pages/home.thtml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-/* SVN FILE: $Id: home.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.pages
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<p class="notice">Your database configuration file is <?php echo file_exists(CONFIGS.'database.php') ?' present.' . $filePresent = ' ' : ' not present.'; ?></p>
-<?php if (!empty($filePresent)):?>
-<?php uses('model' . DS . 'connection_manager'); $db = ConnectionManager::getInstance(); ?>
-<?php $connected = $db->getDataSource('default'); ?>
-<p class="notice">Cake<?php echo $connected->isConnected() ? ' is able to' : ' is not able to';?> connect to the database.</p>
-<br />
-<?php endif; ?>
-<h2>CakePHP release information is on CakeForge</h2>
-<a href="https://trac.cakephp.org/wiki/notes/1.1.x.x">Read the release notes and get the latest version</a>
-<h2>Editing this Page</h2>
-<p>
-To change the content of this page, create: /app/views/pages/home.thtml.<br />
-To change its layout, create: /app/views/layouts/default.thtml.<br />
-<a href="http://manual.cakephp.org/">See the views section of the manual for more info</a><br />
-You can also add some CSS styles for your pages at: app/webroot/css/.
-</p>
-<h2>More about Cake</h2>
-<p>
-CakePHP is a rapid development framework for PHP which uses commonly known design patterns like
-Active Record, Association Data Mapping, Front Controller and MVC.
-</p>
-<p>
-Our primary goal is to provide a structured framework that enables PHP users at all levels
-to rapidly develop robust web applications, without any loss to flexibility.
-</p>
-<ul>
- <li><a href="http://www.cakefoundation.org/">Cake Software Foundation</a>
- <ul><li>Promoting development related to CakePHP</li></ul></li>
- <li><a href="http://bakery.cakephp.org">The Bakery</a>
- <ul><li>Everything CakePHP</li></ul></li>
- <li><a href="http://astore.amazon.com/cakesoftwaref-20/">Book Store</a>
- <ul><li>Recommended Software Books</li></ul></li>
- <li><a href="http://www.cafepress.com/cakefoundation">CakeSchwag</a>
- <ul><li>Get your own CakePHP gear - Doughnate to Cake</li></ul></li>
- <li><a href="http://www.cakephp.org">CakePHP</a>
- <ul><li>The Rapid Development Framework</li></ul></li>
- <li><a href="http://manual.cakephp.org">CakePHP Manual</a>
- <ul><li>Your Rapid Development Cookbook</li></ul></li>
- <li><a href="http://api.cakephp.org">CakePHP API</a>
- <ul><li>Docblock Your Best Friend</li></ul></li>
- <li><a href="http://www.cakeforge.org">CakeForge</a>
- <ul><li>Open Development for CakePHP</li></ul></li>
- <li><a href="https://trac.cakephp.org/">CakePHP Trac</a>
- <ul><li>For the Development of CakePHP (Tickets, SVN browser, Roadmap, Changelogs)</li></ul></li>
- <li><a href="http://groups-beta.google.com/group/cake-php">CakePHP Google Group</a>
- <ul><li>Community mailing list</li></ul></li>
- <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
- <ul><li>Live chat about CakePHP</li></ul></li>
-</ul> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/add.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/add.thtml
deleted file mode 100644
index 5291ea9..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/add.thtml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-/* SVN FILE: $Id: add.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.scaffolds
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>New <?php echo Inflector::humanize($this->name)?></h1>
-<?php
-if (is_null($this->plugin)) {
- $path = '/';
-} else {
- $path = '/'.$this->plugin.'/';
-}
-echo $html->formTag($path. Inflector::underscore($this->name).'/create');
-echo $form->generateFields( $fieldNames );
-echo $form->generateSubmitDiv( 'Add' );?>
-</form>
-<ul class='actions'>
-<?php echo "<li>".$html->link('List '.Inflector::humanize($this->name), $path.$this->viewPath.'/index')."</li>"; ?>
-</ul> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/edit.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/edit.thtml
deleted file mode 100644
index bb259a4..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/edit.thtml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/* SVN FILE: $Id: edit.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.scaffolds
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-$modelName = ucwords(Inflector::singularize($this->name));
-$modelKey = $modelName;
-if (is_null($this->plugin)) {
- $path = '/';
-} else {
- $path = '/'.$this->plugin.'/';
-}?>
-<h1><?php echo $type.' '.Inflector::humanize($modelName);?></h1>
-<?php
-if ($type == 'Edit') {
- echo $html->formTag($path . Inflector::underscore($this->name) .'/update');
-} else {
- echo $html->formTag($path. Inflector::underscore($this->name).'/create');
-}
-echo $form->generateFields( $fieldNames );
-echo $form->generateSubmitDiv( 'Save' ); ?>
-</form>
-<ul class='actions'>
-<?php
-if ($type == 'Edit') {
- echo "<li>".$html->link('Delete '.Inflector::humanize($modelName), $path.$this->viewPath.'/delete/'.$data[$modelKey][$this->controller->{$modelName}->primaryKey])."</li>";
-}
-echo "<li>".$html->link('List '.Inflector::humanize($modelName), $path.$this->viewPath.'/index')."</li>";
-if ($type == 'Edit') {
- foreach ($fieldNames as $field => $value) {
- if (isset($value['foreignKey'])) {
- echo "<li>".$html->link( "View ".Inflector::humanize($value['controller']), $path.Inflector::underscore($value['controller'])."/view/".$data[$modelKey][$field] )."</li>";
- }
- }
-}?>
-</ul> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/index.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/index.thtml
deleted file mode 100644
index 3de10af..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/index.thtml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.scaffolds
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<h1>List <?php echo Inflector::humanize($this->name)?></h1>
-<?php
-$model = ucwords(Inflector::singularize($this->name));
-$modelKey = $model;
-$humanName = Inflector::humanize($this->name);
-$humanSingularName = Inflector::singularize( $humanName );
-if (is_null($this->plugin)) {
- $path = '/';
-} else {
- $path = '/'.$this->plugin.'/';
-}
-if (!empty($this->controller->{$model}->modelToTable)) {
- foreach ($this->controller->{$model}->modelToTable as $key => $value) {
- $alias[] = $key;
- }
-}?>
-<table class="inav" cellpadding="0" cellspacing="0">
-<thead>
-<tr>
-<?php
-foreach ($fieldNames as $fieldName) {?>
- <th><?php echo $fieldName['prompt'];?></th>
-<?php }?>
-<th>Actions</th>
-</tr>
-</thead>
-<tbody>
-<?php
-$iRowIndex = 0;
-if (is_array($data)) {
- foreach ($data as $row) {
- if ($iRowIndex++ % 2 == 0) {
- echo "<tr>";
- } else {
- echo "<tr class='altRow'>";
- }
- $count = 0;
- foreach ($fieldNames as $field=>$value) { ?>
- <td>
-<?php
- if (isset($value['foreignKey'])) {
- $otherModelKey = Inflector::underscore($value['modelKey']);
- $otherControllerName = $value['controller'];
- $otherModelObject =& ClassRegistry::getObject( $otherModelKey );
- if (is_object($otherModelObject)) {
- $displayText = $row[$alias[$count]][ $otherModelObject->getDisplayField() ];
- } else {
- $displayText = $row[$alias[$count]][$field];
- }
- echo $html->link( $displayText, $path.Inflector::underscore($otherControllerName)."/view/".$row[$modelKey][$field] );
- $count++;
- } else {
- echo $row[$modelKey][$field];
- }?>
- </td>
-<?php } ?>
- <td class="listactions"><?php echo $html->link('View',$path.$this->viewPath."/view/{$row[$modelKey][$this->controller->{$model}->primaryKey]}/")?>
- <?php echo $html->link('Edit',$path.$this->viewPath."/edit/{$row[$modelKey][$this->controller->{$model}->primaryKey]}/")?>
- <?php echo $html->link('Delete',$path.$this->viewPath."/delete/{$row[$modelKey][$this->controller->{$model}->primaryKey]}/", null, 'Are you sure you want to delete id '.$row[$modelKey][$this->controller->{$model}->primaryKey].' ?')?>
- </td>
- </tr>
-<?php
- }
-}?>
-</tbody>
-</table>
-<ul class="actions">
- <li><?php echo $html->link('New '.$humanSingularName, $path.$this->viewPath.'/add'); ?></li>
-</ul> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/view.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/view.thtml
deleted file mode 100644
index 9bc903b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/templates/scaffolds/view.thtml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?php
-/* SVN FILE: $Id: view.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.scaffolds
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<?php
-$modelName = ucwords(Inflector::singularize($this->name));
-$modelKey = Inflector::underscore($modelName);
-$objModel =& ClassRegistry::getObject($modelKey);
-if (is_null($this->plugin)) {
- $path = '/';
-} else {
- $path = '/'.$this->plugin.'/';
-}
-if (!empty($objModel->modelToTable)) {
- foreach ($objModel->modelToTable as $key => $value) {
- $alias[] = $key;
- }
- $count = 0;
-}?>
-<h1>View
-<?php echo Inflector::humanize($modelName)?>
-</h1>
-<dl>
-<?php
-foreach ($fieldNames as $field => $value) {
- echo "<dt>".$value['prompt']."</dt>";
- if (isset($value['foreignKey'])) {
- $otherModelObject =& ClassRegistry::getObject(Inflector::underscore($objModel->tableToModel[$value['table']]));
- $displayField = $otherModelObject->getDisplayField();
- $displayText = $data[$alias[$count]][$displayField];
- if (!empty($data[$objModel->tableToModel[$objModel->table]][$field]) && (isset($displayText))) {
- echo "<dd>".$html->link($displayText, $path.Inflector::underscore($value['controller']).'/view/'
- .$data[$objModel->tableToModel[$objModel->table]][$field] )."</dd>";
- } else {
- echo "<dd>&nbsp;</dd>";
- }
- $count++;
- } else {
- if ( !empty($data[$objModel->tableToModel[$objModel->table]][$field])) {
- echo "<dd>".$data[$objModel->tableToModel[$objModel->table]][$field]."</dd>";
- } else {
- echo "<dd>&nbsp;</dd>";
- }
- }
-}?>
-</dl>
-<ul class='actions'>
-<?php
-echo "<li>".$html->link('Edit '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/edit/'.$data[$objModel->tableToModel[$objModel->table]][$this->controller->{$modelName}->primaryKey])."</li>";
-echo "<li>".$html->link('Delete '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/delete/'.$data[$objModel->tableToModel[$objModel->table]][$this->controller->{$modelName}->primaryKey], null, 'Are you sure you want to delete id '.$data[$objModel->tableToModel[$objModel->table]][$this->controller->{$modelName}->primaryKey].' ?')."</li>";
-echo "<li>".$html->link('List '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/index')."</li>";
-echo "<li>".$html->link('New '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/add')."</li>";
-
-foreach ( $fieldNames as $field => $value ) {
- if ( isset( $value['foreignKey'] ) ) {
- echo "<li>".$html->link( "List ".Inflector::humanize($value['controller']), $path.Inflector::underscore($value['controller'])."/index/")."</li>";
- }
-}?>
-</ul>
-
-<!--hasOne relationships -->
-<?php
-foreach ($objModel->hasOne as $association => $relation) {
- $model = $relation['className'];
- $otherModelName = $objModel->tableToModel[$objModel->{$model}->table];
- $controller = Inflector::pluralize($model);
- $new = true;
- echo "<div class='related'><H2>Related ".Inflector::humanize($association)."</H2>";
- echo "<dl>";
- if (isset($data[$association]) && is_array($data[$association])) {
- foreach ($data[$association] as $field => $value) {
- if (isset($value)) {
- echo "<dt>".Inflector::humanize($field)."</dt>";
- if (!empty($value)) {
- echo "<dd>".$value."</dd>";
- } else {
- echo "<dd>&nbsp;</dd>";
- }
- $new = null;
- }
- }
- echo "</dl>";
- if ($new == null) {
- echo "<ul class='actions'><li>".$html->link('Edit '.Inflector::humanize($association),$path.Inflector::underscore($controller)."/edit/{$data[$association][$objModel->{$model}->primaryKey]}")."</li></ul></div>";
- } else {
- echo "<ul class='actions'><li>".$html->link('New '.Inflector::humanize($association),$path.Inflector::underscore($controller)."/add/{$data[$association][$objModel->{$model}->primaryKey]}")."</li></ul></div>";
- }
- }
-}
-?>
-
-<!-- HAS MANY AND HASANDBELONGSTOMANY -->
-<?php
-$relations = array_merge($objModel->hasMany, $objModel->hasAndBelongsToMany);
-foreach ($relations as $association => $relation) {
- $model = $relation['className'];
- $count = 0;
- $otherModelName = Inflector::singularize($model);
- $controller = Inflector::pluralize($model);
-
- echo "<div class='related'><H2>Related ".Inflector::humanize(Inflector::pluralize($association))."</H2>";
- if (isset($data[$association][0]) && is_array($data[$association])) {?>
- <table class="inav" cellspacing="0">
- <tr>
-<?php
- $bFound = false;
- foreach ($data[$association][0] as $column=>$value) {
- echo "<th>".Inflector::humanize($column)."</th>";
- }?>
- <th>Actions</th>
- </tr>
-<?php
- foreach ($data[$association] as $row) {
- echo "<tr>";
- foreach ($row as $column=>$value) {
- echo "<td>".$value."</td>";
- }
- if (isset($this->controller->{$modelName}->{$association})) {?>
- <td class="listactions"><?php echo $html->link('View',$path.Inflector::underscore($controller).
- "/view/{$row[$this->controller->{$modelName}->{$association}->primaryKey]}/")?>
- <?php echo $html->link('Edit',$path.Inflector::underscore($controller).
- "/edit/{$row[$this->controller->{$modelName}->{$association}->primaryKey]}/")?>
- <?php echo $html->link('Delete',$path.Inflector::underscore($controller).
- "/delete/{$row[$this->controller->{$modelName}->{$association}->primaryKey]}/", null, 'Are you sure you want to delete id '.$row[$this->controller->{$modelName}->{$association}->primaryKey].' ?')?>
- </td>
-<?php
- } else {?>
- <td class="listactions"><?php echo $html->link('View',$path.Inflector::underscore($controller).
- "/view/{$row[$this->controller->{$modelName}->primaryKey]}/")?>
- <?php echo $html->link('Edit',$path.Inflector::underscore($controller).
- "/edit/{$row[$this->controller->{$modelName}->primaryKey]}/")?>
- <?php echo $html->link('Delete',$path.Inflector::underscore($controller).
- "/delete/{$row[$this->controller->{$modelName}->primaryKey]}/", null, 'Are you sure you want to delete id '.$row[$this->controller->{$modelName}->primaryKey].' ?')?>
- </td>
-<?php
- }
- echo "</tr>";
- }?>
- </table>
-<?php }?>
-<ul class="actions">
-<?php echo "<li>".$html->link('New '.Inflector::humanize($association),$path.Inflector::underscore($controller)."/add/")."</li>";?>
-</ul></div>
-<?php }?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/view.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/view.php
deleted file mode 100644
index 57365ab..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/libs/view/view.php
+++ /dev/null
@@ -1,765 +0,0 @@
-<?php
-/* SVN FILE: $Id: view.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Methods for displaying presentation data in the view.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Included libraries.
- */
-uses ('view' . DS . 'helper', 'class_registry');
-/**
- * View, the V in the MVC triad.
- *
- * Class holding methods for displaying presentation data.
- *
- * @package cake
- * @subpackage cake.cake.libs.view
- */
-class View extends Object{
-/**
- * Name of the controller.
- *
- * @var string Name of controller
- * @access public
- */
- var $name = null;
-/**
- * Stores the current URL (for links etc.)
- *
- * @var string Current URL
- * @access public
- */
- var $here = null;
-/**
- * Action to be performed.
- *
- * @var string Name of action
- * @access public
- */
- var $action = null;
-/**
- * An array of names of built-in helpers to include.
- *
- * @var mixed A single name as a string or a list of names as an array.
- * @access public
- */
- var $helpers = array('Html');
-/**
- * Path to View.
- *
- * @var string Path to View
- * @access public
- */
- var $viewPath;
-/**
- * Replaced with public var viewVars
- * @access protected
- * @deprecated
- */
- var $_viewVars = array();
-/**
- * Variables for the view
- *
- * @var array
- * @access public
- */
- var $viewVars = array();
-/**
- * Title HTML element of this View.
- *
- * @var boolean
- * @access public
- */
- var $pageTitle = false;
-/**
- * Path parts for creating links in views.
- *
- * @var string Base URL
- * @access public
- */
- var $base = null;
-/**
- * Name of layout to use with this View.
- *
- * @var string
- * @access public
- */
- var $layout = 'default';
-/**
- * Turns on or off Cake's conventional mode of rendering views. On by default.
- *
- * @var boolean
- * @access public
- */
- var $autoRender = true;
-/**
- * Turns on or off Cake's conventional mode of finding layout files. On by default.
- *
- * @var boolean
- * @access public
- */
- var $autoLayout = true;
-/**
- * Array of parameter data
- *
- * @var array Parameter data
- * @access public
- */
- var $params;
-/**
- * True when the view has been rendered.
- *
- * @var boolean
- * @access protected
- */
- var $_hasRendered = null;
-/**
- * @deprecated will not be avialable after 1.1.x.x
- */
- var $controller = null;
-/**
- * Array of loaded view helpers.
- *
- * @var array
- * @access public
- */
- var $loaded = array();
-/**
- * File extension. Defaults to Cake's conventional ".thtml".
- *
- * @var array
- * @access public
- */
- var $ext = '.thtml';
-/**
- * Sub-directory for this view file.
- *
- * @var string
- * @access public
- */
- var $subDir = null;
-/**
- * The directory where theme web accessible content is stored
- *
- * @var array
- * @access public
- */
- var $themeWeb = null;
-/**
- * Plugin name. A Plugin is a sub-application.
- * This is used to set the correct paths for views
- *
- * @var string
- * @access public
- */
- var $plugin = null;
-/**
- * Creates system path to plugin: plugins . DS . plugin_name . DS
- *
- * @var string
- */
- var $pluginPath = null;
-/**
- * Holds an array of plugin paths.
- * VIEWS . $this->pluginPath
- * APP . $this->pluginPath . views . DS
- *
- * @var array
- */
- var $pluginPaths = array();
-/**
- * List of variables to collect from the associated controller
- *
- * @var array
- * @access protected
- */
- var $_passedVars = array('viewVars', 'action', 'autoLayout', 'autoRender', 'ext', 'base', 'webroot', 'helpers', 'here', 'layout', 'modelNames', 'name', 'pageTitle', 'viewPath', 'params', 'data', 'webservices', 'plugin');
-/**
- * Constructor
- *
- * Instance is created in Controller::render() and is never called directly
- *
- * @var object instance of the calling controller
- */
- function __construct(&$controller) {
- if (is_object($controller)) {
- $this->controller =& $controller;
- $c = count($this->_passedVars);
-
- for ($j = 0; $j < $c; $j++) {
- $var = $this->_passedVars[$j];
- $this->{$var} = $controller->{$var};
- }
- $this->_viewVars =& $this->viewVars;
- }
- if (!is_null($this->plugin)) {
- $this->pluginPath = 'plugins'. DS . $this->plugin . DS;
- $this->pluginPaths = array(
- VIEWS . $this->pluginPath,
- APP . $this->pluginPath . 'views' . DS,
- );
-
- }
- parent::__construct();
- ClassRegistry::addObject('view', $this);
- }
-/**
- * Renders view for given action and layout. If $file is given, that is used
- * for a view filename (e.g. customFunkyView.thtml).
- *
- * @param string $action Name of action to render for
- * @param string $layout Layout to use
- * @param string $file Custom filename for view
- * @return mixed returns an error if View::render() fails to find a related template.
- * boolean on successful render
- * @access public
- */
- function render($action = null, $layout = null, $file = null) {
-
- if (isset($this->_hasRendered) && $this->_hasRendered) {
- return true;
- } else {
- $this->_hasRendered = false;
- }
-
- if (!$action) {
- $action = $this->action;
- }
- $tempLayout = $this->layout;
-
- if ($layout) {
- $this->setLayout($layout);
- }
-
- if ($file) {
- $viewFileName = $file;
- } else {
- $viewFileName = $this->_getViewFileName($action);
- }
-
- if (!is_null($this->plugin) && is_null($file)) {
- return $this->pluginView($action, $layout);
- }
-
- if (!is_file($viewFileName) && !fileExistsInPath($viewFileName) || $viewFileName === '/' || $viewFileName === '\\') {
- if (strpos($action, 'missingAction') !== false) {
- $errorAction = 'missingAction';
- } else {
- $errorAction = 'missingView';
- }
-
- foreach (array($this->name, 'errors') as $viewDir) {
- $errorAction = Inflector::underscore($errorAction);
-
- if (file_exists(VIEWS . $viewDir . DS . $errorAction . $this->ext)) {
- $missingViewFileName = VIEWS . $viewDir . DS . $errorAction . $this->ext;
- } elseif ($missingViewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $viewDir . DS . $errorAction . '.thtml')) {
- } else {
- $missingViewFileName = false;
- }
-
- $missingViewExists = is_file($missingViewFileName);
-
- if ($missingViewExists) {
- break;
- }
- }
-
- if (strpos($action, 'missingView') === false) {
- return $this->cakeError('missingView', array(array('className' => $this->controller->name,
- 'action' => $action,
- 'file' => $viewFileName,
- 'base' => $this->base)));
-
- $isFatal = isset($this->isFatal) ? $this->isFatal : false;
-
- if (!$isFatal) {
- $viewFileName = $missingViewFileName;
- }
- } else {
- $missingViewExists = false;
- }
-
- if (!$missingViewExists || $isFatal) {
- if (Configure::read() > 0) {
- trigger_error(sprintf("No template file for view %s (expected %s), create it first'", $action, $viewFileName), E_USER_ERROR);
- } else {
- $this->error('404', 'Not found', sprintf("The requested address %s was not found on this server.", '', "missing view \"{$action}\""));
- }
- die();
- }
- }
-
- if ($viewFileName && !$this->_hasRendered) {
- if (substr($viewFileName, -5) === 'thtml') {
- $out = View::_render($viewFileName, $this->viewVars);
- } else {
- $out = $this->_render($viewFileName, $this->viewVars);
- }
-
- if ($out !== false) {
- if ($this->layout && $this->autoLayout) {
- $out = $this->renderLayout($out);
- if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) {
- $replace = array('<cake:nocache>', '</cake:nocache>');
- $out = str_replace($replace, '', $out);
- }
- }
-
- print $out;
- $this->setLayout($tempLayout);
- $this->_hasRendered = true;
- } else {
- $out = $this->_render($viewFileName, $this->viewVars);
- trigger_error(sprintf("Error in view %s, got: <blockquote>%s</blockquote>", $viewFileName, $out), E_USER_ERROR);
- }
- return true;
- }
- }
-/**
- * Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string.
- *
- * This realizes the concept of Elements, (or "partial layouts")
- * and the $params array is used to send data to be used in the Element.
- *
- * @param string $name Name of template file in the/app/views/elements/ folder
- * @param array $params Array of data to be made available to the for rendered view (i.e. the Element)
- * @return string Rendered output
- * @access public
- */
- function renderElement($name, $params = array()) {
- if (isset($params['plugin'])) {
- $this->plugin = $params['plugin'];
- $this->pluginPath = 'plugins' . DS . $this->plugin . DS;
- $this->pluginPaths = array(
- VIEWS . $this->pluginPath,
- APP . $this->pluginPath . 'views' . DS,
- );
- }
-
- $paths = Configure::getInstance();
- $viewPaths = am($this->pluginPaths, $paths->viewPaths);
-
- $file = null;
- foreach ($viewPaths as $path) {
- if (file_exists($path . 'elements' . DS . $name . $this->ext)) {
- $file = $path . 'elements' . DS . $name . $this->ext;
- break;
- } elseif (file_exists($path . 'elements' . DS . $name . '.ctp')) {
- $file = $path . 'elements' . DS . $name . '.ctp';
- break;
- }
- }
-
- if (!is_null($file)) {
- $params = array_merge_recursive($params, $this->loaded);
- return $this->_render($file, array_merge($this->viewVars, $params), false);
- }
-
- if (!is_null($this->pluginPath)) {
- $file = APP . $this->pluginPath . 'views' . DS . 'elements' . DS . $name . $this->ext;
- } else {
- $file = VIEWS . 'elements' . DS . $name . $this->ext;
- }
-
- if (Configure::read() > 0) {
- return "Element Not Found: " . $file;
- }
- }
-/**
- * Wrapper for View::renderElement();
- *
- * @param string $name Name of template file in the/app/views/elements/ folder
- * @param array $params Array of data to be made available to the for rendered view (i.e. the Element)
- * @return string View::renderElement()
- * @access public
- */
- function element($name, $params = array()) {
- return $this->renderElement($name, $params);
- }
-/**
- * Renders a layout. Returns output from _render(). Returns false on error.
- *
- * @param string $contentForLayout Content to render in a view, wrapped by the surrounding layout.
- * @return mixed Rendered output, or false on error
- * @access public
- */
- function renderLayout($contentForLayout) {
- $layoutFilename = $this->_getLayoutFileName();
-
- if (Configure::read() > 2 && $this->controller != null) {
- $debug = View::_render(LIBS . 'view' . DS . 'templates' . DS . 'elements' . DS . 'dump.thtml', array('controller' => $this->controller), false);
- } else {
- $debug = '';
- }
-
- if ($this->pageTitle !== false) {
- $pageTitle = $this->pageTitle;
- } else {
- $pageTitle = Inflector::humanize($this->viewPath);
- }
-
- $dataForLayout = array_merge($this->viewVars, array('title_for_layout' => $pageTitle,
- 'content_for_layout' => $contentForLayout,
- 'cakeDebug' => $debug));
-
- if (is_file($layoutFilename)) {
- if (empty($this->loaded) && !empty($this->helpers)) {
- $loadHelpers = true;
- } else {
- $loadHelpers = false;
- $dataForLayout = array_merge($dataForLayout, $this->loaded);
- }
-
- if (substr($layoutFilename, -5) === 'thtml') {
- $out = View::_render($layoutFilename, $dataForLayout, $loadHelpers, true);
- } else {
- $out = $this->_render($layoutFilename, $dataForLayout, $loadHelpers);
- }
-
- if ($out === false) {
- $out = $this->_render($layoutFilename, $dataForLayout);
- trigger_error(sprintf("Error in layout %s, got: <blockquote>%s</blockquote>", $layoutFilename, $out), E_USER_ERROR);
- return false;
- } else {
- return $out;
- }
- } else {
- return $this->cakeError('missingLayout', array(array('layout' => $this->layout,
- 'file' => $layoutFilename,
- 'base' => $this->base)));
- }
- }
-/**
- * Sets layout to be used when rendering.
- *
- * @param string $layout Name of layout.
- * @return void
- * @access public
- * @deprecated in 1.2.x.x
- */
- function setLayout($layout) {
- $this->layout = $layout;
- }
-/**
- * Displays an error page to the user. Uses layouts/error.html to render the page.
- *
- * @param int $code HTTP Error code (for instance: 404)
- * @param string $name Name of the error (for instance: Not Found)
- * @param string $message Error message as a web page
- * @return rendered error message
- * @access public
- *
- */
- function error($code, $name, $message) {
- header ("HTTP/1.0 {$code} {$name}");
- print ($this->_render(VIEWS . 'layouts/error.thtml', array('code' => $code,
- 'name' => $name,
- 'message' => $message)));
- }
-/**
- * Returns filename of given action's template file (.thtml) as a string. CamelCased action names will be under_scored! This means that you can have LongActionNames that refer to long_action_names.thtml views.
- *
- * @param string $action Controller action to find template filename for
- * @return string Template filename
- * @access protected
- */
- function _getViewFileName($action) {
- $action = Inflector::underscore($action);
-
- if (!is_null($this->webservices)) {
- $type = strtolower($this->webservices) . DS;
- } else {
- $type = null;
- }
-
- $position = strpos($action, '..');
- if ($position !== false) {
- $action = explode('/', $action);
- $i = array_search('..', $action);
- unset($action[$i - 1]);
- unset($action[$i]);
- $action = '..' . DS . implode(DS, $action);
- }
-
- $paths = Configure::getInstance();
- $viewPaths = am($this->pluginPaths, $paths->viewPaths);
-
- $name = $this->viewPath . DS . $this->subDir . $type . $action;
- foreach ($viewPaths as $path) {
- if (file_exists($path . $name . $this->ext)) {
- return $path . $name . $this->ext;
- } elseif (file_exists($path . $name . '.ctp')) {
- return $path . $name . '.ctp';
- }
- }
-
- if ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . $type . $action . '.thtml')) {
- return $viewFileName;
- } elseif ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $this->viewPath . DS . $type . $action . '.thtml')) {
- return $viewFileName;
- } else {
- if (!is_null($this->pluginPath)) {
- $viewFileName = APP . $this->pluginPath . 'views' . DS . $name . $this->ext;
- } else {
- $viewFileName = VIEWS . $name . $this->ext;
- }
- }
- return $viewFileName;
- }
-/**
- * Returns layout filename for this template as a string.
- *
- * @return string Filename for layout file (.thtml).
- * @access protected
- */
- function _getLayoutFileName() {
- if (isset($this->webservices) && !is_null($this->webservices)) {
- $type = strtolower($this->webservices) . DS;
- } else {
- $type = null;
- }
-
- $paths = Configure::getInstance();
- $viewPaths = am($this->pluginPaths, $paths->viewPaths);
-
- $name = $this->subDir . $type . $this->layout;
- foreach ($viewPaths as $path) {
- if (file_exists($path . 'layouts' . DS . $name . $this->ext)) {
- return $path . 'layouts' . DS . $name . $this->ext;
- } elseif (file_exists($path . 'layouts' . DS . $name . '.ctp')) {
- return $path . 'layouts' . DS . $name . '.ctp';
- }
- }
-
- if (!is_null($this->pluginPath)) {
- $layoutFileName = APP . $this->pluginPath . 'views' . DS . 'layouts' . DS . $name . $this->ext;
- } else {
- $layoutFileName = VIEWS . 'layouts' . DS . $name . $this->ext;
- }
-
- $layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'layouts' . DS . $type . $this->layout . '.thtml');
- if (empty($layoutFileName) && !empty($type)) {
- $layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'layouts' . DS . $type . 'default.thtml');
- }
- return $layoutFileName;
- }
-
-/**
- * Renders and returns output for given view filename with its array of data.
- *
- * @param string $___viewFn Filename of the view
- * @param array $___dataForView Data to include in rendered view
- * @return string Rendered output
- * @access protected
- */
- function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
- if ($this->helpers != false && $loadHelpers === true) {
- $loadedHelpers = array();
- $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
-
- foreach (array_keys($loadedHelpers) as $helper) {
- $replace = strtolower(substr($helper, 0, 1));
- $camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1);
-
- ${$camelBackedHelper} =& $loadedHelpers[$helper];
-
- if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) {
- foreach (${$camelBackedHelper}->helpers as $subHelper) {
- ${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper];
- }
- }
- $this->loaded[$camelBackedHelper] =& ${$camelBackedHelper};
- }
- }
- extract($___dataForView, EXTR_SKIP);
- $BASE = $this->base;
- $params =& $this->params;
-
- ob_start();
-
- if (Configure::read() > 0) {
- include ($___viewFn);
- } else {
- @include ($___viewFn);
- }
-
- if ($this->helpers != false && $loadHelpers === true) {
- foreach ($loadedHelpers as $helper) {
- if (is_object($helper)) {
- if (is_subclass_of($helper, 'Helper') || is_subclass_of($helper, 'helper')) {
- $helper->afterRender();
- }
- }
- }
- }
- $out = ob_get_clean();
-
- if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) {
- if (is_a($this->loaded['cache'], 'CacheHelper')) {
- $cache =& $this->loaded['cache'];
-
- if ($cached === true) {
- $cache->view = &$this;
- }
-
- $cache->base = $this->base;
- $cache->here = $this->here;
- $cache->action = $this->action;
- $cache->controllerName = $this->params['controller'];
- $cache->cacheAction = $this->controller->cacheAction;
- $cache->cache($___viewFn, $out, $cached);
- }
- }
- return $out;
- }
-/**
- * Loads helpers, with their dependencies.
- *
- * @param array $loaded List of helpers that are already loaded.
- * @param array $helpers List of helpers to load.
- * @return array
- * @access protected
- */
- function &_loadHelpers(&$loaded, $helpers) {
- static $tags;
- $helpers[] = 'Session';
- if (empty($tags)) {
- $helperTags = new Helper();
- $tags = $helperTags->loadConfig();
- }
-
- foreach ($helpers as $helper) {
- $parts = preg_split('/\/|\./', $helper);
-
- if (count($parts) === 1) {
- $plugin = $this->plugin;
- } else {
- $plugin = Inflector::underscore($parts['0']);
- $helper = $parts[count($parts) - 1];
- }
- $helperCn = $helper . 'Helper';
-
- if (in_array($helper, array_keys($loaded)) !== true) {
- if (!class_exists($helperCn)) {
- if (is_null($plugin) || !loadPluginHelper($plugin, $helper)) {
- if (!loadHelper($helper)) {
- $this->cakeError('missingHelperFile', array(array(
- 'helper' => $helper,
- 'file' => Inflector::underscore($helper) . '.php',
- 'base' => $this->base)));
- exit();
- }
- }
- if (!class_exists($helperCn)) {
- $this->cakeError('missingHelperClass', array(array(
- 'helper' => $helper,
- 'file' => Inflector::underscore($helper) . '.php',
- 'base' => $this->base)));
- exit();
- }
- }
-
- $camelBackedHelper = Inflector::variable($helper);
-
- ${$camelBackedHelper} =& new $helperCn;
- ${$camelBackedHelper}->view =& $this;
- ${$camelBackedHelper}->tags = $tags;
-
- $vars = array('base', 'webroot', 'here', 'params', 'action', 'data', 'themeWeb', 'plugin');
- $c = count($vars);
- for ($j = 0; $j < $c; $j++) {
- ${$camelBackedHelper}->{$vars[$j]} = $this->{$vars[$j]};
- }
-
- if (!empty($this->validationErrors)) {
- ${$camelBackedHelper}->validationErrors = $this->validationErrors;
- }
-
- $loaded[$helper] =& ${$camelBackedHelper};
-
- if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) {
- $loaded = &$this->_loadHelpers($loaded, ${$camelBackedHelper}->helpers);
- }
- }
- }
- return $loaded;
- }
-/**
- * Returns a plugin view
- *
- * @param string $action Name of action to render for
- * @param string $layout Layout to use
- * @return mixed View::render() if template is found, error if template is missing
- * @access public
- */
- function pluginView($action, $layout) {
- $viewFileName = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . $this->viewPath . DS . $action . $this->ext;
-
- if (file_exists($viewFileName)) {
- $this->render($action, $layout, $viewFileName);
- } else {
- return $this->cakeError('missingView', array(array(
- 'className' => $this->controller->name,
- 'action' => $action,
- 'file' => $viewFileName,
- 'base' => $this->base)));
- }
- }
-/**
- * Renders a cached view if timestamp in file is less or equal to current time.
- *
- * If $layout is xml content type will be set before rendering the cache
- *
- * @param string $filename
- * @param int $timeStart
- * @return mixed outputs view, or returns void if timestamp has expired
- * @access public
- */
- function renderCache($filename, $timeStart) {
- ob_start();
- include ($filename);
-
- if (Configure::read() > 0 && $this->layout != 'xml') {
- echo "<!-- Cached Render Time: " . round(getMicrotime() - $timeStart, 4) . "s -->";
- }
- $out = ob_get_clean();
-
- if (preg_match('/^<!--cachetime:(\\d+)-->/', $out, $match)) {
- if (time() >= $match['1']) {
- @unlink($filename);
- unset ($out);
- return;
- } else {
- if ($this->layout === 'xml') {
- header('Content-type: text/xml');
- }
- $out = str_replace('<!--cachetime:'.$match['1'].'-->', '', $out);
- e($out);
- die();
- }
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/acl.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/acl.php
deleted file mode 100644
index b4c7669..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/acl.php
+++ /dev/null
@@ -1,853 +0,0 @@
-#!/usr/bin/php -q
-<?php
-/* SVN FILE: $Id: acl.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.scripts
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Enter description here...
- */
- define ('DS', DIRECTORY_SEPARATOR);
- if (function_exists('ini_set')) {
- ini_set('display_errors', '1');
- ini_set('error_reporting', '7');
- ini_set('max_execution_time',0);
- }
-
- $app = 'app';
- $core = null;
- $root = dirname(dirname(dirname(__FILE__)));
- $here = $argv[0];
- $dataSource = 'default';
- $unset = array();
- for ($i = 1; $i < count($argv); $i++) {
- // Process command-line modifiers here
- switch (strtolower($argv[$i])) {
- case '-app':
- $app = $argv[$i + 1];
- $unset[$i] = $argv[$i];
- $unset[$i + 1] = $argv[$i + 1];
- break;
- case '-core':
- $core = $argv[$i + 1];
- $unset[$i] = $argv[$i];
- $unset[$i + 1] = $argv[$i + 1];
- break;
- case '-root':
- $root = $argv[$i + 1];
- $unset[$i] = $argv[$i];
- $unset[$i + 1] = $argv[$i + 1];
- break;
- case '-datasource':
- $dataSource = $argv[$i + 1];
- $unset[$i] = $argv[$i];
- $unset[$i + 1] = $argv[$i + 1];
- break;
- }
- }
-
- if (strlen($app) && $app[0] == DS) {
- $cnt = substr_count($root, DS);
- $app = str_repeat('..' . DS, $cnt) . $app;
- }
- define ('ROOT', $root.DS);
- define ('APP_DIR', $app);
- define ('DEBUG', 1);;
- define('CAKE_CORE_INCLUDE_PATH', ROOT);
- define('DATASOURCE', $dataSource);
-
- if (function_exists('ini_set')) {
- ini_set('include_path',ini_get('include_path').
- PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.DS.
- PATH_SEPARATOR.CORE_PATH.DS.
- PATH_SEPARATOR.ROOT.DS.APP_DIR.DS.
- PATH_SEPARATOR.APP_DIR.DS.
- PATH_SEPARATOR.APP_PATH);
- define('APP_PATH', null);
- define('CORE_PATH', null);
- } else {
- define('APP_PATH', ROOT . DS . APP_DIR . DS);
- define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
- }
-
- require ('cake'.DS.'basics.php');
- require ('cake'.DS.'config'.DS.'paths.php');
- require (CONFIGS.'core.php');
- uses ('object', 'configure', 'neat_array', 'session', 'security', 'inflector', 'model'.DS.'connection_manager',
- 'model'.DS.'datasources'.DS.'dbo_source', 'model'.DS.'model');
- require(CAKE.'app_model.php');
- uses ('controller'.DS.'components'.DS.'acl', 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode',
- 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco', 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'acoaction',
- 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aro');
- //Get and format args: first arg is the name of the script.
- $serverArgs = $argv;
- if (!empty($unset)) {
- $serverArgs = array_values(array_diff($argv, $unset));
- }
-
- $wasted = array_shift($serverArgs);
- $command = array_shift($serverArgs);
- $args = $serverArgs;
- $aclCLI = new AclCLI ($command, $args);
-/**
- * @package cake
- * @subpackage cake.cake.scritps
- */
-class AclCLI {
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $stdin;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $stdout;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $stderr;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $acl;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $args;
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $dataSource = 'default';
-/**
- * Enter description here...
- *
- * @param unknown_type $command
- * @param unknown_type $args
- * @return AclCLI
- */
- function AclCLI($command, $args) {
- $this->__construct($command, $args);
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $command
- * @param unknown_type $args
- */
- function __construct ($command, $args) {
- $this->stdin = fopen('php://stdin', 'r');
- $this->stdout = fopen('php://stdout', 'w');
- $this->stderr = fopen('php://stderr', 'w');
-
- if (ACL_CLASSNAME != 'DB_ACL') {
- $out = "--------------------------------------------------\n";
- $out .= "Error: Your current Cake configuration is set to \n";
- $out .= "an ACL implementation other than DB. Please change \n";
- $out .= "your core config to reflect your decision to use \n";
- $out .= "DB_ACL before attempting to use this script.\n";
- $out .= "--------------------------------------------------\n";
- $out .= "Current ACL Classname: " . ACL_CLASSNAME . "\n";
- $out .= "--------------------------------------------------\n";
- fwrite($this->stderr, $out);
- exit();
- }
-
- if (!in_array($command, array('help'))) {
- if (!file_exists(CONFIGS.'database.php')) {
- $this->stdout('');
- $this->stdout('Your database configuration was not found.');
- $this->stdout('Take a moment to create one:');
- $this->doDbConfig();
- }
- require_once (CONFIGS.'database.php');
-
- if (!in_array($command, array('initdb'))) {
- $this->dataSource = DATASOURCE;
- $this->Acl = new AclComponent();
- $this->args = $args;
- $this->db =& ConnectionManager::getDataSource($this->dataSource);
- }
- }
-
- switch ($command) {
- case 'create':
- $this->create();
- break;
- case 'delete':
- $this->delete();
- break;
- case 'setParent':
- $this->setParent();
- break;
- case 'getPath':
- $this->getPath();
- break;
- case 'grant':
- $this->grant();
- break;
- case 'deny':
- $this->deny();
- break;
- case 'inherit':
- $this->inherit();
- break;
- case 'view':
- $this->view();
- break;
- case 'initdb':
- $this->initdb();
- break;
- case 'upgrade':
- $this->upgradedb();
- break;
- case 'help':
- $this->help();
- break;
- default:
- fwrite($this->stderr, "Unknown ACL command '$command'.\nFor usage, try 'php acl.php help'.\n\n");
- break;
- }
- }
-/**
- * Enter description here...
- *
- */
- function create() {
- $this->checkArgNumber(4, 'create');
- $this->checkNodeType();
- extract($this->__dataVars());
-
- $parent = (is_numeric($this->args[2])) ? intval($this->args[2]) : $this->args[2];
- if (!$this->Acl->{$class}->create(intval($this->args[1]), $parent, $this->args[3])) {
- $this->displayError("Parent Node Not Found", "There was an error creating the ".$class.", probably couldn't find the parent node.\n If you wish to create a new root node, specify the <parent_id> as '0'.");
- }
- $this->stdout("New $class '".$this->args[3]."' created.\n\n");
- }
-/**
- * Enter description here...
- *
- */
- function delete() {
- $this->checkArgNumber(2, 'delete');
- $this->checkNodeType();
- extract($this->__dataVars());
- if (!$this->Acl->{$class}->delete($this->args[1])) {
- $this->displayError("Node Not Deleted", "There was an error deleting the ".$class.". Check that the node exists.\n");
- }
- $this->stdout("{$class} deleted.\n\n");
- }
-
-/**
- * Enter description here...
- *
- */
- function setParent() {
- $this->checkArgNumber(3, 'setParent');
- $this->checkNodeType();
- extract($this->__dataVars());
- if (!$this->Acl->{$class}->setParent($this->args[2], $this->args[1])) {
- $this->stdout("Error in setting new parent. Please make sure the parent node exists, and is not a descendant of the node specified.\n");
- } else {
- $this->stdout("Node parent set to ".$this->args[2]."\n\n");
- }
- }
-/**
- * Enter description here...
- *
- */
- function getPath() {
- $this->checkArgNumber(2, 'getPath');
- $this->checkNodeType();
- extract($this->__dataVars());
- $id = (is_numeric($this->args[2])) ? intval($this->args[1]) : $this->args[1];
- $nodes = $this->Acl->{$class}->getPath($id);
- if (empty($nodes)) {
- $this->displayError("Supplied Node '".$this->args[1]."' not found", "No tree returned.");
- }
- for ($i = 0; $i < count($nodes); $i++) {
- $this->stdout(str_repeat(' ', $i) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias'] . "\n");
- }
- }
-/**
- * Enter description here...
- *
- */
- function grant() {
- $this->checkArgNumber(3, 'grant');
- //add existence checks for nodes involved
- $aro = $this->args[0];
- if (is_numeric($aro)) {
- $aro = intval($aro);
- }
- $aco = $this->args[1];
- if (is_numeric($aco)) {
- $aco = intval($aco);
- }
- if ($this->Acl->allow($aro, $aco, $this->args[2])) {
- $this->stdout("Permission granted.\n");
- } else {
- $this->stdout("Permission could not be granted.\n");
- }
- }
-/**
- * Enter description here...
- *
- */
- function deny() {
- $this->checkArgNumber(3, 'deny');
- //add existence checks for nodes involved
- $aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
- $aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
- $aro = $this->args[0];
- if (is_numeric($aro)) {
- $aro = intval($aro);
- }
- $aco = $this->args[1];
- if (is_numeric($aco)) {
- $aco = intval($aco);
- }
- if ($this->Acl->deny($aro, $aco, $this->args[2])) {
- $this->stdout("Permission denied.\n");
- } else {
- $this->stdout("Permission could not be denied.\n");
- }
- }
-/**
- * Enter description here...
- *
- */
- function inherit() {
- $this->checkArgNumber(3, 'inherit');
- $aro = $this->args[0];
- if (is_numeric($aro)) {
- $aro = intval($aro);
- }
- $aco = $this->args[1];
- if (is_numeric($aco)) {
- $aco = intval($aco);
- }
- if ($this->Acl->inherit($aro, $aco, $this->args[2])) {
- $this->stdout("Permission inherited.\n");
- } else {
- $this->stdout("Permission could not be inherited.\n");
- }
- }
-/**
- * Enter description here...
- *
- */
- function view() {
- $this->checkArgNumber(1, 'view');
- $this->checkNodeType();
- extract($this->__dataVars());
- if (!is_null($this->args[1])) {
- $conditions = $this->Acl->{$class}->_resolveID($this->args[1]);
- } else {
- $conditions = null;
- }
- $nodes = $this->Acl->{$class}->findAll($conditions, null, 'lft ASC');
- if (empty($nodes)) {
- $this->displayError($this->args[1]." not found", "No tree returned.");
- }
- $right = array();
-
- $this->stdout($class . " tree:\n");
- $this->stdout("------------------------------------------------\n");
-
- for ($i = 0; $i < count($nodes); $i++) {
- if (count($right) > 0) {
- while ($right[count($right)-1] < $nodes[$i][$class]['rght']) {
- if ($right[count($right)-1]) {
- array_pop($right);
- } else {
- break;
- }
- }
- }
- $this->stdout(str_repeat(' ',count($right)) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias']."\n");
- $right[] = $nodes[$i][$class]['rght'];
- }
- $this->stdout("------------------------------------------------\n");
- }
-/**
- * Enter description here...
- *
- */
- function initdb() {
- $db =& ConnectionManager::getDataSource($this->dataSource);
- $this->stdout("Initializing Database...\n");
- $this->stdout("Creating access control objects table (acos)...\n");
- $sql = " CREATE TABLE ".$db->fullTableName('acos')." (
- ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
- ".$db->name('object_id')." ".$db->column($db->columns['integer'])." default NULL,
- ".$db->name('alias')." ".$db->column($db->columns['string'])." NOT NULL default '',
- ".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
- ".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
- PRIMARY KEY (".$db->name('id').")
- );";
- if ($db->query($sql) === false) {
- die("Error: " . $db->lastError() . "\n\n");
- }
-
- $this->stdout("Creating access request objects table (aros)...\n");
- $sql2 = "CREATE TABLE ".$db->fullTableName('aros')." (
- ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
- ".$db->name('foreign_key')." ".$db->column($db->columns['integer'])." default NULL,
- ".$db->name('alias')." ".$db->column($db->columns['string'])." NOT NULL default '',
- ".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
- ".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
- PRIMARY KEY (".$db->name('id').")
- );";
- if ($db->query($sql2) === false) {
- die("Error: " . $db->lastError() . "\n\n");
- }
-
- $this->stdout("Creating relationships table (aros_acos)...\n");
- $sql3 = "CREATE TABLE ".$db->fullTableName('aros_acos')." (
- ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
- ".$db->name('aro_id')." ".$db->column($db->columns['integer'])." default NULL,
- ".$db->name('aco_id')." ".$db->column($db->columns['integer'])." default NULL,
- ".$db->name('_create')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
- ".$db->name('_read')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
- ".$db->name('_update')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
- ".$db->name('_delete')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
- PRIMARY KEY (".$db->name('id').")
- );";
- if ($db->query($sql3) === false) {
- die("Error: " . $db->lastError() . "\n\n");
- }
-
- $this->stdout("\nDone.\n");
- }
-
-/**
- * Enter description here...
- *
- */
- function upgradedb() {
- $db =& ConnectionManager::getDataSource($this->dataSource);
- $this->stdout("Initializing Database...\n");
- $this->stdout("Upgrading table (aros)...\n");
- $sql = "ALTER TABLE ".$db->fullTableName('aros')."
- CHANGE ".$db->name('user_id')."
- ".$db->name('foreign_key')."
- INT( 10 ) UNSIGNED NULL DEFAULT NULL;";
- $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_create')
- . " " . $db->name('_create') . " CHAR(2) NOT NULL DEFAULT '0';";
- $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_update')
- . " " . $db->name('_update') . " CHAR(2) NOT NULL DEFAULT '0';";
- $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_read')
- . " " . $db->name('_read') . " CHAR(2) NOT NULL DEFAULT '0';";
- $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_delete')
- . " " . $db->name('_delete') . " CHAR(2) NOT NULL DEFAULT '0';";
- if ($db->query($sql) === false) {
- die("Error: " . $db->lastError() . "\n\n");
- }
- $this->stdout("\nDatabase upgrade is complete.\n");
- }
-
-/**
- * Enter description here...
- *
- */
- function help() {
- $out = "Usage: php acl.php <command> <arg1> <arg2>...\n";
- $out .= "-----------------------------------------------\n";
- $out .= "Commands:\n";
- $out .= "\n";
- $out .= "\tcreate aro|aco <link_id> <parent_id> <alias>\n";
- $out .= "\t\tCreates a new ACL object under the parent specified by <parent_id>, an id/alias (see\n";
- $out .= "\t\t'view'). The link_id allows you to link a user object to Cake's\n";
- $out .= "\t\tACL structures. The alias parameter allows you to address your object\n";
- $out .= "\t\tusing a non-integer ID. Example: \"\$php acl.php create aro 57 0 John\"\n";
- $out .= "\t\twould create a new ARO object at the root of the tree, linked to 57\n";
- $out .= "\t\tin your users table, with an internal alias 'John'.";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tdelete aro|aco <id>\n";
- $out .= "\t\tDeletes the ACL object with the specified ID (see 'view').\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tsetParent aro|aco <id> <parent_id>\n";
- $out .= "\t\tUsed to set the parent of the ACL object specified by <id> to the ID\n";
- $out .= "\t\tspecified by <parent_id>.\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tgetPath aro|aco <id>\n";
- $out .= "\t\tReturns the path to the ACL object specified by <id>. This command is\n";
- $out .= "\t\tis useful in determining the inhertiance of permissions for a certain\n";
- $out .= "\t\tobject in the tree.\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tgrant <Aro.alias|Aro.foreign_key> <Aco.alias|Aco.object_id> <aco_action>\n";
- $out .= "\t\tUse this command to grant ACL permissions. Once executed, the ARO\n";
- $out .= "\t\tspecified (and its children, if any) will have ALLOW access to the\n";
- $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
- $out .= "\t\tIf an integer is passed permissions will be granted based on the foreign_key or object_id.\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tdeny <Aro.alias|Aro.foreign_key> <Aco.alias|Aco.object_id> <aco_action>\n";
- $out .= "\t\tUse this command to deny ACL permissions. Once executed, the ARO\n";
- $out .= "\t\tspecified (and its children, if any) will have DENY access to the\n";
- $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
- $out .= "\t\tIf an integer is passed permissions will be denied based on the foreign_key or object_id.\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tinherit <Aro.alias|Aro.foreign_key> <Aco.alias|Aco.object_id> <aco_action>\n";
- $out .= "\t\tUse this command to force a child ARO object to inherit its\n";
- $out .= "\t\tpermissions settings from its parent.\n";
- $out .= "\t\tIf an integer is passed permissions will be inherited based on the foreign_key or object_id.\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tview aro|aco [id]\n";
- $out .= "\t\tThe view command will return the ARO or ACO tree. The optional\n";
- $out .= "\t\tid/alias parameter allows you to return only a portion of the requested\n";
- $out .= "\t\ttree.\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\tinitdb\n";
- $out .= "\t\tUse this command to create the database tables needed to use DB ACL.\n";
- $out .= "\n";
- $out .= "\n";
- $out .= "\thelp\n";
- $out .= "\t\tDisplays this help message.\n";
- $out .= "\n";
- $out .= "\n";
- $this->stdout($out);
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $title
- * @param unknown_type $msg
- */
- function displayError($title, $msg) {
- $out = "\n";
- $out .= "Error: $title\n";
- $out .= "$msg\n";
- $out .= "\n";
- $this->stdout($out);
- exit();
- }
-
-/**
- * Enter description here...
- *
- * @param unknown_type $expectedNum
- * @param unknown_type $command
- */
- function checkArgNumber($expectedNum, $command) {
- if (count($this->args) < $expectedNum) {
- $this->displayError('Wrong number of parameters: '.count($this->args), 'Please type \'php acl.php help\' for help on usage of the '.$command.' command.');
- }
- }
-/**
- * Enter description here...
- *
- */
- function checkNodeType() {
- if ($this->args[0] != 'aco' && $this->args[0] != 'aro') {
- $this->displayError("Missing/Unknown node type: '".$this->args[0]."'", 'Please specify which ACL object type you wish to create.');
- }
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $type
- * @param unknown_type $id
- * @return unknown
- */
- function nodeExists($type, $id) {
- //$this->stdout("Check to see if $type with ID = $id exists...\n");
- extract($this->__dataVars($type));
- $conditions = $this->Acl->{$class}->_resolveID($id);
- $possibility = $this->Acl->{$class}->findAll($conditions);
- return $possibility;
- }
-
-/**
- * Enter description here...
- *
- * @param unknown_type $type
- * @return unknown
- */
- function __dataVars($type = null) {
- if ($type == null) {
- $type = $this->args[0];
- }
-
- $vars = array();
- $class = ucwords($type);
- $vars['secondary_id'] = ($class == 'aro' ? 'foreign_key' : 'object_id');
- $vars['data_name'] = $type;
- $vars['table_name'] = $type . 's';
- $vars['class'] = $class;
- return $vars;
- }
-/**
- * Database configuration setup.
- *
- */
- function doDbConfig() {
- $this->hr();
- $this->stdout('Database Configuration:');
- $this->hr();
-
- $driver = '';
-
- while ($driver == '') {
- $driver = $this->getInput('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
- if ($driver == '') {
- $this->stdout('The database driver supplied was empty. Please supply a database driver.');
- }
- }
-
- switch($driver) {
- case 'mysql':
- $connect = 'mysql_connect';
- break;
- case 'mysqli':
- $connect = 'mysqli_connect';
- break;
- case 'mssql':
- $connect = 'mssql_connect';
- break;
- case 'sqlite':
- $connect = 'sqlite_open';
- break;
- case 'postgres':
- $connect = 'pg_connect';
- break;
- case 'odbc':
- $connect = 'odbc_connect';
- break;
- default:
- $this->stdout('The connection parameter could not be set.');
- break;
- }
-
- $host = '';
-
- while ($host == '') {
- $host = $this->getInput('What is the hostname for the database server?', null, 'localhost');
- if ($host == '') {
- $this->stdout('The host name you supplied was empty. Please supply a hostname.');
- }
- }
- $login = '';
-
- while ($login == '') {
- $login = $this->getInput('What is the database username?', null, 'root');
-
- if ($login == '') {
- $this->stdout('The database username you supplied was empty. Please try again.');
- }
- }
- $password = '';
- $blankPassword = false;
-
- while ($password == '' && $blankPassword == false) {
- $password = $this->getInput('What is the database password?');
- if ($password == '') {
- $blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
- if ($blank == 'y')
- {
- $blankPassword = true;
- }
- }
- }
- $database = '';
-
- while ($database == '') {
- $database = $this->getInput('What is the name of the database you will be using?', null, 'cake');
-
- if ($database == '') {
- $this->stdout('The database name you supplied was empty. Please try again.');
- }
- }
-
- $prefix = '';
-
- while ($prefix == '') {
- $prefix = $this->getInput('Enter a table prefix?', null, 'n');
- }
- if (low($prefix) == 'n') {
- $prefix = '';
- }
-
- $this->stdout('');
- $this->hr();
- $this->stdout('The following database configuration will be created:');
- $this->hr();
- $this->stdout("Driver: $driver");
- $this->stdout("Connection: $connect");
- $this->stdout("Host: $host");
- $this->stdout("User: $login");
- $this->stdout("Pass: " . str_repeat('*', strlen($password)));
- $this->stdout("Database: $database");
- $this->stdout("Table prefix: $prefix");
- $this->hr();
- $looksGood = $this->getInput('Look okay?', array('y', 'n'), 'y');
-
- if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
- $this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
- } else {
- $this->stdout('Bake Aborted.');
- }
- }
-/**
- * Creates a database configuration file for Bake.
- *
- * @param string $host
- * @param string $login
- * @param string $password
- * @param string $database
- */
- function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
- $out = "<?php\n";
- $out .= "class DATABASE_CONFIG {\n\n";
- $out .= "\tvar \$default = array(\n";
- $out .= "\t\t'driver' => '{$driver}',\n";
- $out .= "\t\t'connect' => '{$connect}',\n";
- $out .= "\t\t'host' => '{$host}',\n";
- $out .= "\t\t'login' => '{$login}',\n";
- $out .= "\t\t'password' => '{$password}',\n";
- $out .= "\t\t'database' => '{$database}', \n";
- $out .= "\t\t'prefix' => '{$prefix}' \n";
- $out .= "\t);\n";
- $out .= "}\n";
- $out .= "?>";
- $filename = CONFIGS.'database.php';
- $this->__createFile($filename, $out);
- }
-/**
- * Prompts the user for input, and returns it.
- *
- * @param string $prompt Prompt text.
- * @param mixed $options Array or string of options.
- * @param string $default Default input value.
- * @return Either the default value, or the user-provided input.
- */
- function getInput($prompt, $options = null, $default = null) {
- if (!is_array($options)) {
- $print_options = '';
- } else {
- $print_options = '(' . implode('/', $options) . ')';
- }
-
- if ($default == null) {
- $this->stdout('');
- $this->stdout($prompt . " $print_options \n" . '> ', false);
- } else {
- $this->stdout('');
- $this->stdout($prompt . " $print_options \n" . "[$default] > ", false);
- }
- $result = trim(fgets($this->stdin));
-
- if ($default != null && empty($result)) {
- return $default;
- } else {
- return $result;
- }
- }
-/**
- * Outputs to the stdout filehandle.
- *
- * @param string $string String to output.
- * @param boolean $newline If true, the outputs gets an added newline.
- */
- function stdout($string, $newline = true) {
- if ($newline) {
- fwrite($this->stdout, $string . "\n");
- } else {
- fwrite($this->stdout, $string);
- }
- }
-/**
- * Outputs to the stderr filehandle.
- *
- * @param string $string Error text to output.
- */
- function stderr($string) {
- fwrite($this->stderr, $string);
- }
-/**
- * Outputs a series of minus characters to the standard output, acts as a visual separator.
- *
- */
- function hr() {
- $this->stdout('---------------------------------------------------------------');
- }
-/**
- * Creates a file at given path.
- *
- * @param string $path Where to put the file.
- * @param string $contents Content to put in the file.
- * @return Success
- */
- function __createFile ($path, $contents) {
- $path = str_replace('//', '/', $path);
- echo "\nCreating file $path\n";
- if (is_file($path) && $this->interactive === true) {
- fwrite($this->stdout, "File exists, overwrite?" . " {$path} (y/n/q):");
- $key = trim(fgets($this->stdin));
-
- if ($key=='q') {
- fwrite($this->stdout, "Quitting.\n");
- exit;
- } elseif ($key == 'a') {
- $this->dont_ask = true;
- } elseif ($key == 'y') {
- } else {
- fwrite($this->stdout, "Skip" . " {$path}\n");
- return false;
- }
- }
-
- if ($f = fopen($path, 'w')) {
- fwrite($f, $contents);
- fclose($f);
- fwrite($this->stdout, "Wrote" . "{$path}\n");
- return true;
- } else {
- fwrite($this->stderr, "Error! Could not write to" . " {$path}.\n");
- return false;
- }
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/bake.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/bake.php
deleted file mode 100644
index 2365ee8..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/bake.php
+++ /dev/null
@@ -1,2635 +0,0 @@
-#!/usr/bin/php -q
-<?php
-/* SVN FILE: $Id: bake.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Command-line code generation utility to automate programmer chores.
- *
- * Bake is CakePHP's code generation script, which can help you kickstart
- * application development by writing fully functional skeleton controllers,
- * models, and views. Going further, Bake can also write Unit Tests for you.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.scripts.bake
- * @since CakePHP(tm) v 0.10.0.1232
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
- define ('DS', DIRECTORY_SEPARATOR);
- if (function_exists('ini_set')) {
- ini_set('display_errors', '1');
- ini_set('error_reporting', '7');
- ini_set('max_execution_time',0);
- }
-
- $app = null;
- $root = dirname(dirname(dirname(__FILE__)));
- $core = null;
- $here = $argv[0];
- $help = null;
- $project = null;
-
- for ($i = 1; $i < count($argv); $i += 2) {
- switch ($argv[$i]) {
- case '-a':
- case '-app':
- $app = $argv[$i + 1];
- break;
- case '-c':
- case '-core':
- $core = $argv[$i + 1];
- break;
- case '-r':
- case '-root':
- $root = $argv[$i + 1];
- break;
- case '-h':
- case '-help':
- $help = true;
- break;
- case '-p':
- case '-project':
- $project = true;
- $projectPath = $argv[$i + 1];
- $app = $argv[$i + 1];
- break;
- }
- }
-
- if (!$app && isset($argv[1])) {
- $app = $argv[1];
- } elseif (!$app) {
- $app = 'app';
- }
- if (!is_dir($app)) {
- $project = true;
- $projectPath = $app;
-
- }
- if ($project) {
- $app = $projectPath;
- }
-
- $shortPath = str_replace($root, '', $app);
- $shortPath = str_replace('..'.DS, '', $shortPath);
- $shortPath = str_replace(DS.DS, DS, $shortPath);
-
- $pathArray = explode(DS, $shortPath);
- if (end($pathArray) != '') {
- $appDir = array_pop($pathArray);
- } else {
- array_pop($pathArray);
- $appDir = array_pop($pathArray);
- }
- $rootDir = implode(DS, $pathArray);
- $rootDir = str_replace(DS.DS, DS, $rootDir);
-
- if (!$rootDir) {
- $rootDir = $root;
- $projectPath = $root.DS.$appDir;
- }
-
- define ('ROOT', $rootDir);
- define ('APP_DIR', $appDir);
- define ('DEBUG', 1);
-
- if (!empty($core)) {
- define('CAKE_CORE_INCLUDE_PATH', dirname($core));
- } else {
- define('CAKE_CORE_INCLUDE_PATH', $root);
- }
-
- if (function_exists('ini_set')) {
- ini_set('include_path',ini_get('include_path').
- PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.DS.
- PATH_SEPARATOR.ROOT.DS.APP_DIR.DS);
- define('APP_PATH', null);
- define('CORE_PATH', null);
- } else {
- define('APP_PATH', ROOT . DS . APP_DIR . DS);
- define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
- }
-
- require_once (CORE_PATH.'cake'.DS.'basics.php');
- require_once (CORE_PATH.'cake'.DS.'config'.DS.'paths.php');
- require_once (CORE_PATH.'cake'.DS.'scripts'.DS.'templates'.DS.'skel'.DS.'config'.DS.'core.php');
- require_once (CORE_PATH.'cake'.DS.'dispatcher.php');
- uses('object', 'session', 'security', 'configure', 'inflector', 'model'.DS.'connection_manager');
-
- $pattyCake = new Bake();
- if ($help === true)
- {
- $pattyCake->help();
- exit();
- }
- if ($project === true)
- {
- $pattyCake->project($projectPath);
- exit();
- }
- $pattyCake->main();
-/**
- * Bake is a command-line code generation utility for automating programmer chores.
- *
- * @package cake
- * @subpackage cake.cake.scripts
- */
-class Bake {
-
-/**
- * Standard input stream.
- *
- * @var filehandle
- */
- var $stdin;
-/**
- * Standard output stream.
- *
- * @var filehandle
- */
- var $stdout;
-/**
- * Standard error stream.
- *
- * @var filehandle
- */
- var $stderr;
-/**
- * Associated controller name.
- *
- * @var string
- */
- var $controllerName = null;
-/**
- * If true, Bake will ask for permission to perform actions.
- *
- * @var boolean
- */
- var $interactive = false;
-
- var $__modelAlias = false;
-/**
- * Private helper function for constructor
- * @access private
- */
- function __construct() {
- $this->stdin = fopen('php://stdin', 'r');
- $this->stdout = fopen('php://stdout', 'w');
- $this->stderr = fopen('php://stderr', 'w');
- $this->welcome();
- }
-/**
- * Constructor.
- *
- * @return Bake
- */
- function Bake() {
- return $this->__construct();
- }
-/**
- * Main-loop method.
- *
- */
- function main() {
-
- $this->stdout('');
- $this->stdout('');
- $this->stdout('Baking...');
- $this->hr();
- $this->stdout('Name: '. APP_DIR);
- $this->stdout('Path: '. ROOT.DS.APP_DIR);
- $this->hr();
-
- if (!file_exists(CONFIGS.'database.php')) {
- $this->stdout('');
- $this->stdout('Your database configuration was not found. Take a moment to create one:');
- $this->doDbConfig();
- }
- require_once (CONFIGS.'database.php');
- $this->stdout('[M]odel');
- $this->stdout('[C]ontroller');
- $this->stdout('[V]iew');
- $invalidSelection = true;
-
- while ($invalidSelection) {
- $classToBake = strtoupper($this->getInput('What would you like to Bake?', array('M', 'V', 'C')));
- switch($classToBake) {
- case 'M':
- $invalidSelection = false;
- $this->doModel();
- break;
- case 'V':
- $invalidSelection = false;
- $this->doView();
- break;
- case 'C':
- $invalidSelection = false;
- $this->doController();
- break;
- default:
- $this->stdout('You have made an invalid selection. Please choose a type of class to Bake by entering M, V, or C.');
- }
- }
- }
-/**
- * Database configuration setup.
- *
- */
- function doDbConfig() {
- $this->hr();
- $this->stdout('Database Configuration:');
- $this->hr();
-
- $driver = '';
-
- while ($driver == '') {
- $driver = $this->getInput('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
- if ($driver == '') {
- $this->stdout('The database driver supplied was empty. Please supply a database driver.');
- }
- }
-
- switch($driver) {
- case 'mysql':
- $connect = 'mysql_connect';
- break;
- case 'mysqli':
- $connect = 'mysqli_connect';
- break;
- case 'mssql':
- $connect = 'mssql_connect';
- break;
- case 'sqlite':
- $connect = 'sqlite_open';
- break;
- case 'postgres':
- $connect = 'pg_connect';
- break;
- case 'odbc':
- $connect = 'odbc_connect';
- break;
- default:
- $this->stdout('The connection parameter could not be set.');
- break;
- }
-
- $host = '';
-
- while ($host == '') {
- $host = $this->getInput('What is the hostname for the database server?', null, 'localhost');
- if ($host == '') {
- $this->stdout('The host name you supplied was empty. Please supply a hostname.');
- }
- }
- $login = '';
-
- while ($login == '') {
- $login = $this->getInput('What is the database username?', null, 'root');
-
- if ($login == '') {
- $this->stdout('The database username you supplied was empty. Please try again.');
- }
- }
- $password = '';
- $blankPassword = false;
-
- while ($password == '' && $blankPassword == false) {
- $password = $this->getInput('What is the database password?');
- if ($password == '') {
- $blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
- if ($blank == 'y')
- {
- $blankPassword = true;
- }
- }
- }
- $database = '';
-
- while ($database == '') {
- $database = $this->getInput('What is the name of the database you will be using?', null, 'cake');
-
- if ($database == '') {
- $this->stdout('The database name you supplied was empty. Please try again.');
- }
- }
-
- $prefix = '';
-
- while ($prefix == '') {
- $prefix = $this->getInput('Enter a table prefix?', null, 'n');
- }
- if (low($prefix) == 'n') {
- $prefix = '';
- }
-
- $this->stdout('');
- $this->hr();
- $this->stdout('The following database configuration will be created:');
- $this->hr();
- $this->stdout("Driver: $driver");
- $this->stdout("Connection: $connect");
- $this->stdout("Host: $host");
- $this->stdout("User: $login");
- $this->stdout("Pass: " . str_repeat('*', strlen($password)));
- $this->stdout("Database: $database");
- $this->stdout("Table prefix: $prefix");
- $this->hr();
- $looksGood = $this->getInput('Look okay?', array('y', 'n'), 'y');
-
- if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
- $this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
- } else {
- $this->stdout('Bake Aborted.');
- }
- }
-/**
- * Action to create a Model.
- *
- */
- function doModel()
- {
- $this->hr();
- $this->stdout('Model Bake:');
- $this->hr();
- $this->interactive = true;
-
- $useTable = null;
- $primaryKey = 'id';
- $validate = array();
- $associations = array();
- $useDbConfig = 'default';
- $this->__doList($useDbConfig);
-
-
- $enteredModel = '';
-
- while ($enteredModel == '') {
- $enteredModel = $this->getInput('Enter a number from the list above, or type in the name of another model.');
-
- if ($enteredModel == '' || intval($enteredModel) > count($this->__modelNames)) {
- $this->stdout('Error:');
- $this->stdout("The model name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
- $enteredModel = '';
- }
- }
-
- if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->__modelNames)) {
- $currentModelName = $this->__modelNames[intval($enteredModel) - 1];
- } else {
- $currentModelName = $enteredModel;
- }
-
- $db =& ConnectionManager::getDataSource($useDbConfig);
-
- $useTable = Inflector::tableize($currentModelName);
- $fullTableName = $db->fullTableName($useTable, false);
- if (array_search($useTable, $this->__tables) === false) {
- $this->stdout("\nGiven your model named '$currentModelName', Cake would expect a database table named '" . $fullTableName . "'.");
- $tableIsGood = $this->getInput('do you want to use this table?', array('y','n'), 'y');
- }
-
- if (low($tableIsGood) == 'n' || low($tableIsGood) == 'no') {
- $useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
- }
- $tableIsGood = false;
- while ($tableIsGood == false && low($useTable) != 'null') {
- if (is_array($this->__tables) && !in_array($useTable, $this->__tables)) {
- $fullTableName = $db->fullTableName($useTable, false);
- $this->stdout($fullTableName . ' does not exist.');
- $useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
- $tableIsGood = false;
- } else {
- $tableIsGood = true;
- }
- }
- $wannaDoValidation = $this->getInput('Would you like to supply validation criteria for the fields in your model?', array('y','n'), 'y');
-
- if (in_array($useTable, $this->__tables)) {
- loadModel();
- $tempModel = new Model(false, $useTable);
- $modelFields = $db->describe($tempModel);
-
- if (!array_key_exists('id', $modelFields)) {
- foreach ($modelFields as $name => $field) {
- break;
- }
- $primaryKey = $this->getInput('What is the primaryKey?', null, $name);
- }
- }
- $validate = array();
-
- if (array_search($useTable, $this->__tables) !== false && (low($wannaDoValidation) == 'y' || low($wannaDoValidation) == 'yes')) {
- foreach ($modelFields as $name => $field) {
- $this->stdout('');
- $prompt = 'Name: ' . $name . "\n";
- $prompt .= 'Type: ' . $field['type'] . "\n";
- $prompt .= '---------------------------------------------------------------'."\n";
- $prompt .= 'Please select one of the following validation options:'."\n";
- $prompt .= '---------------------------------------------------------------'."\n";
- $prompt .= "1- VALID_NOT_EMPTY\n";
- $prompt .= "2- VALID_EMAIL\n";
- $prompt .= "3- VALID_NUMBER\n";
- $prompt .= "4- VALID_YEAR\n";
- $prompt .= "5- Do not do any validation on this field.\n\n";
- $prompt .= "... or enter in a valid regex validation string.\n\n";
-
- if ($field['null'] == 1 || $name == $primaryKey || $name == 'created' || $name == 'modified') {
- $validation = $this->getInput($prompt, null, '5');
- } else {
- $validation = $this->getInput($prompt, null, '1');
- }
-
- switch ($validation) {
- case '1':
- $validate[$name] = 'VALID_NOT_EMPTY';
- break;
- case '2':
- $validate[$name] = 'VALID_EMAIL';
- break;
- case '3':
- $validate[$name] = 'VALID_NUMBER';
- break;
- case '4':
- $validate[$name] = 'VALID_YEAR';
- break;
- case '5':
- break;
- default:
- $validate[$name] = $validation;
- break;
- }
- }
- }
-
- $wannaDoAssoc = $this->getInput('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', array('y','n'), 'y');
-
- if ((low($wannaDoAssoc) == 'y' || low($wannaDoAssoc) == 'yes')) {
- $this->stdout('One moment while I try to detect any associations...');
- $possibleKeys = array();
- $i = 0;
- foreach ($modelFields as $name => $field) {
- $offset = strpos($name, '_id');
- if ($name != $primaryKey && $offset !== false) {
- $tmpModelName = $this->__modelNameFromKey($name);
- $associations['belongsTo'][$i]['alias'] = $tmpModelName;
- $associations['belongsTo'][$i]['className'] = $tmpModelName;
- $associations['belongsTo'][$i]['foreignKey'] = $name;
- $i++;
- }
- }
- $i = 0;
- $j = 0;
- foreach ($this->__tables as $otherTable) {
- $tempOtherModel = & new Model(false, $otherTable);
- $modelFieldsTemp = $db->describe($tempOtherModel);
- foreach ($modelFieldsTemp as $name => $field) {
- if ($field['type'] == 'integer' || $field['type'] == 'string') {
- $possibleKeys[$otherTable][] = $name;
- }
- if ($name != $primaryKey && $name == $this->__modelKey($currentModelName)) {
- $tmpModelName = $this->__modelName($otherTable);
- $associations['hasOne'][$j]['alias'] = $tmpModelName;
- $associations['hasOne'][$j]['className'] = $tmpModelName;
- $associations['hasOne'][$j]['foreignKey'] = $name;
-
- $associations['hasMany'][$j]['alias'] = $tmpModelName;
- $associations['hasMany'][$j]['className'] = $tmpModelName;
- $associations['hasMany'][$j]['foreignKey'] = $name;
- $j++;
- }
- }
- $offset = strpos($otherTable, $useTable . '_');
- if ($offset !== false) {
- $offset = strlen($useTable . '_');
- $tmpModelName = $this->__modelName(substr($otherTable, $offset));
- $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
- $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
- $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
- $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
- $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
- $i++;
- }
- $offset = strpos($otherTable, '_' . $useTable);
- if ($offset !== false) {
- $tmpModelName = $this->__modelName(substr($otherTable, 0, $offset));
- $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
- $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
- $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
- $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
- $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
- $i++;
- }
- }
- $this->stdout('Done.');
- $this->hr();
- if (empty($associations)) {
- $this->stdout('None found.');
- } else {
- $this->stdout('Please confirm the following associations:');
- $this->hr();
- if (!empty($associations['belongsTo'])) {
- $count = count($associations['belongsTo']);
- for ($i = 0; $i < $count; $i++) {
- if ($currentModelName == $associations['belongsTo'][$i]['alias']) {
- $response = $this->getInput("{$currentModelName} belongsTo {$associations['belongsTo'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
- if ('y' == low($response) || 'yes' == low($response)) {
- $associations['belongsTo'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['belongsTo'][$i]['alias']);
- }
- if ($currentModelName != $associations['belongsTo'][$i]['alias']) {
- $response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
- } else {
- $response = 'n';
- }
- } else {
- $response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
- }
- if ('n' == low($response) || 'no' == low($response)) {
- unset($associations['belongsTo'][$i]);
- }
- }
- $associations['belongsTo'] = array_merge($associations['belongsTo']);
- }
-
- if (!empty($associations['hasOne'])) {
- $count = count($associations['hasOne']);
- for ($i = 0; $i < $count; $i++) {
- if ($currentModelName == $associations['hasOne'][$i]['alias']) {
- $response = $this->getInput("{$currentModelName} hasOne {$associations['hasOne'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
- if ('y' == low($response) || 'yes' == low($response)) {
- $associations['hasOne'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasOne'][$i]['alias']);
- }
- if ($currentModelName != $associations['hasOne'][$i]['alias']) {
- $response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
- } else {
- $response = 'n';
- }
- } else {
- $response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
- }
- if ('n' == low($response) || 'no' == low($response)) {
- unset($associations['hasOne'][$i]);
- }
- }
- $associations['hasOne'] = array_merge($associations['hasOne']);
- }
-
- if (!empty($associations['hasMany'])) {
- $count = count($associations['hasMany']);
- for ($i = 0; $i < $count; $i++) {
- if ($currentModelName == $associations['hasMany'][$i]['alias']) {
- $response = $this->getInput("{$currentModelName} hasMany {$associations['hasMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
- if ('y' == low($response) || 'yes' == low($response)) {
- $associations['hasMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasMany'][$i]['alias']);
- }
- if ($currentModelName != $associations['hasMany'][$i]['alias']) {
- $response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
- } else {
- $response = 'n';
- }
- } else {
- $response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
- }
- if ('n' == low($response) || 'no' == low($response)) {
- unset($associations['hasMany'][$i]);
- }
- }
- $associations['hasMany'] = array_merge($associations['hasMany']);
- }
-
- if (!empty($associations['hasAndBelongsToMany'])) {
- $count = count($associations['hasAndBelongsToMany']);
- for ($i = 0; $i < $count; $i++) {
- if ($currentModelName == $associations['hasAndBelongsToMany'][$i]['alias']) {
- $response = $this->getInput("{$currentModelName} hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
- if ('y' == low($response) || 'yes' == low($response)) {
- $associations['hasAndBelongsToMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasAndBelongsToMany'][$i]['alias']);
- }
- if ($currentModelName != $associations['hasAndBelongsToMany'][$i]['alias']) {
- $response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
- } else {
- $response = 'n';
- }
- } else {
- $response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
- }
- if ('n' == low($response) || 'no' == low($response)) {
- unset($associations['hasAndBelongsToMany'][$i]);
- }
- }
- $associations['hasAndBelongsToMany'] = array_merge($associations['hasAndBelongsToMany']);
- }
- }
- $wannaDoMoreAssoc = $this->getInput('Would you like to define some additional model associations?', array('y','n'), 'y');
-
- while ((low($wannaDoMoreAssoc) == 'y' || low($wannaDoMoreAssoc) == 'yes')) {
- $assocs = array(1=>'belongsTo', 2=>'hasOne', 3=>'hasMany', 4=>'hasAndBelongsToMany');
- $bad = true;
- while ($bad) {
- $this->stdout('What is the association type?');
- $prompt = "1- belongsTo\n";
- $prompt .= "2- hasOne\n";
- $prompt .= "3- hasMany\n";
- $prompt .= "4- hasAndBelongsToMany\n";
- $assocType = intval($this->getInput($prompt, null, null));
-
- if (intval($assocType) < 1 || intval($assocType) > 4) {
- $this->stdout('The selection you entered was invalid. Please enter a number between 1 and 4.');
- } else {
- $bad = false;
- }
- }
- $this->stdout('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.');
- $this->hr();
- $associationName = $this->getInput('What is the name of this association?');
- $className = $this->getInput('What className will '.$associationName.' use?', null, $associationName );
- $suggestedForeignKey = null;
- if ($assocType == '1') {
- $showKeys = $possibleKeys[$useTable];
- $suggestedForeignKey = $this->__modelKey($associationName);
- } else {
- $otherTable = Inflector::tableize($className);
- if (in_array($otherTable, $this->__tables)) {
- if ($assocType < '4') {
- $showKeys = $possibleKeys[$otherTable];
- } else {
- $showKeys = null;
- }
- } else {
- $otherTable = $this->getInput('What is the table for this class?');
- $showKeys = $possibleKeys[$otherTable];
- }
- $suggestedForeignKey = $this->__modelKey($currentModelName);
- }
- if (!empty($showKeys)) {
- $this->stdout('A helpful List of possible keys');
- for ($i = 0; $i < count($showKeys); $i++) {
- $this->stdout($i + 1 . ". " . $showKeys[$i]);
- }
- $foreignKey = $this->getInput('What is the foreignKey? Choose a number.');
- if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
- $foreignKey = $showKeys[intval($foreignKey) - 1];
- }
- }
- if (!isset($foreignKey)) {
- $foreignKey = $this->getInput('What is the foreignKey? Specify your own.', null, $suggestedForeignKey);
- }
- if ($assocType == '4') {
- $associationForeignKey = $this->getInput('What is the associationForeignKey?', null, $this->__modelKey($currentModelName));
- $joinTable = $this->getInput('What is the joinTable?');
- }
- $associations[$assocs[$assocType]] = array_values($associations[$assocs[$assocType]]);
- $count = count($associations[$assocs[$assocType]]);
- $i = ($count > 0) ? $count : 0;
- $associations[$assocs[$assocType]][$i]['alias'] = $associationName;
- $associations[$assocs[$assocType]][$i]['className'] = $className;
- $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
- if ($assocType == '4') {
- $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
- $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
- }
- $wannaDoMoreAssoc = $this->getInput('Define another association?', array('y','n'), 'y');
- }
- }
- $this->stdout('');
- $this->hr();
- $this->stdout('The following model will be created:');
- $this->hr();
- $this->stdout("Model Name: $currentModelName");
- $this->stdout("DB Connection: " . ($usingDefault ? 'default' : $useDbConfig));
- $this->stdout("DB Table: " . $fullTableName);
- if ($primaryKey != 'id') {
- $this->stdout("Primary Key: " . $primaryKey);
- }
- $this->stdout("Validation: " . print_r($validate, true));
-
- if (!empty($associations)) {
- $this->stdout("Associations:");
-
- if (count($associations['belongsTo'])) {
- for ($i = 0; $i < count($associations['belongsTo']); $i++) {
- $this->stdout(" $currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}");
- }
- }
-
- if (count($associations['hasOne'])) {
- for ($i = 0; $i < count($associations['hasOne']); $i++) {
- $this->stdout(" $currentModelName hasOne {$associations['hasOne'][$i]['alias']}");
- }
- }
-
- if (count($associations['hasMany'])) {
- for ($i = 0; $i < count($associations['hasMany']); $i++) {
- $this->stdout(" $currentModelName hasMany {$associations['hasMany'][$i]['alias']}");
- }
- }
-
- if (count($associations['hasAndBelongsToMany'])) {
- for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
- $this->stdout(" $currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}");
- }
- }
- }
- $this->hr();
- $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
-
- if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
- if ($useTable == Inflector::tableize($currentModelName)) {
- $useTable = null;
- }
- $this->bakeModel($currentModelName, $useDbConfig, $useTable, $primaryKey, $validate, $associations);
-
- if ($this->doUnitTest()) {
- $this->bakeUnitTest('model', $currentModelName);
- }
- } else {
- $this->stdout('Bake Aborted.');
- }
- }
-/**
- * Action to create a View.
- *
- */
- function doView() {
- $this->hr();
- $this->stdout('View Bake:');
- $this->hr();
- $uses = array();
- $wannaUseSession = 'y';
- $wannaDoScaffold = 'y';
-
-
- $useDbConfig = 'default';
- $this->__doList($useDbConfig, 'Controllers');
-
- $enteredController = '';
-
- while ($enteredController == '') {
- $enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
-
- if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
- $this->stdout('Error:');
- $this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
- $enteredController = '';
- }
- }
-
- if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
- $controllerName = $this->__controllerNames[intval($enteredController) - 1];
- } else {
- $controllerName = Inflector::camelize($enteredController);
- }
-
- $controllerPath = low(Inflector::underscore($controllerName));
-
- $doItInteractive = $this->getInput("Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite {$controllerClassName} views if it exist.", array('y','n'), 'y');
-
- if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
- $this->interactive = true;
- $wannaDoScaffold = $this->getInput("Would you like to create some scaffolded views (index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller and model classes (including associated models).", array('y','n'), 'n');
- }
-
- $admin = null;
- $admin_url = null;
- if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
- $wannaDoAdmin = $this->getInput("Would you like to create the views for admin routing?", array('y','n'), 'n');
- }
-
- if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
- require(CONFIGS.'core.php');
- if (defined('CAKE_ADMIN')) {
- $admin = CAKE_ADMIN . '_';
- $admin_url = '/'.CAKE_ADMIN;
- } else {
- $adminRoute = '';
- $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
- $this->stdout('What would you like the admin route to be?');
- $this->stdout('Example: www.example.com/admin/controller');
- while ($adminRoute == '') {
- $adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
- }
- if ($this->__addAdminRoute($adminRoute) !== true) {
- $this->stdout('Unable to write to /app/config/core.php.');
- $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
- exit();
- } else {
- $admin = $adminRoute . '_';
- $admin_url = '/'.$adminRoute;
- }
- }
- }
- if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
- $file = CONTROLLERS . $controllerPath . '_controller.php';
-
- if (!file_exists($file)) {
- $shortPath = str_replace(ROOT, null, $file);
- $shortPath = str_replace('../', '', $shortPath);
- $shortPath = str_replace('//', '/', $shortPath);
- $this->stdout('');
- $this->stdout("The file '$shortPath' could not be found.\nIn order to scaffold, you'll need to first create the controller. ");
- $this->stdout('');
- die();
- } else {
- uses('controller'.DS.'controller');
- loadController($controllerName);
- if ($admin) {
- $this->__bakeViews($controllerName, $controllerPath, $admin, $admin_url);
- }
- $this->__bakeViews($controllerName, $controllerPath, null, null);
-
- $this->hr();
- $this->stdout('');
- $this->stdout('View Scaffolding Complete.'."\n");
- }
- } else {
- $actionName = '';
-
- while ($actionName == '') {
- $actionName = $this->getInput('Action Name? (use camelCased function name)');
-
- if ($actionName == '') {
- $this->stdout('The action name you supplied was empty. Please try again.');
- }
- }
- $this->stdout('');
- $this->hr();
- $this->stdout('The following view will be created:');
- $this->hr();
- $this->stdout("Controller Name: $controllerName");
- $this->stdout("Action Name: $actionName");
- $this->stdout("Path: app/views/" . $controllerPath . DS . Inflector::underscore($actionName) . '.thtml');
- $this->hr();
- $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
-
- if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
- $this->bakeView($controllerName, $actionName);
- } else {
- $this->stdout('Bake Aborted.');
- }
- }
- }
-
- function __bakeViews($controllerName, $controllerPath, $admin= null, $admin_url = null) {
- $controllerClassName = $controllerName.'Controller';
- $controllerObj = & new $controllerClassName();
-
- if (!in_array('Html', $controllerObj->helpers)) {
- $controllerObj->helpers[] = 'Html';
- }
- if (!in_array('Form', $controllerObj->helpers)) {
- $controllerObj->helpers[] = 'Form';
- }
-
- $controllerObj->constructClasses();
- $currentModelName = $controllerObj->modelClass;
- $this->__modelClass = $currentModelName;
- $modelKey = Inflector::underscore($currentModelName);
- $modelObj =& ClassRegistry::getObject($modelKey);
- $singularName = $this->__singularName($currentModelName);
- $pluralName = $this->__pluralName($currentModelName);
- $singularHumanName = $this->__singularHumanName($currentModelName);
- $pluralHumanName = $this->__pluralHumanName($controllerName);
-
- $fieldNames = $controllerObj->generateFieldNames(null, false);
- $indexView = null;
-
- if (!empty($modelObj->alias)) {
- foreach ($modelObj->alias as $key => $value) {
- $alias[] = $key;
- }
- }
- $indexView .= "<div class=\"{$pluralName}\">\n";
- $indexView .= "<h2>List " . $pluralHumanName . "</h2>\n\n";
- $indexView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
- $indexView .= "<tr>\n";
-
- foreach ($fieldNames as $fieldName) {
- $indexView .= "\t<th>".$fieldName['prompt']."</th>\n";
- }
- $indexView .= "\t<th>Actions</th>\n";
- $indexView .= "</tr>\n";
- $indexView .= "<?php foreach (\${$pluralName} as \${$singularName}): ?>\n";
- $indexView .= "<tr>\n";
- $count = 0;
- foreach ($fieldNames as $field => $value) {
- if (isset($value['foreignKey'])) {
- $otherModelName = $this->__modelName($value['model']);
- $otherModelKey = Inflector::underscore($otherModelName);
- $otherModelObj =& ClassRegistry::getObject($otherModelKey);
- $otherControllerName = $this->__controllerName($otherModelName);
- $otherControllerPath = $this->__controllerPath($otherControllerName);
- if (is_object($otherModelObj)) {
- $displayField = $otherModelObj->getDisplayField();
- $indexView .= "\t<td>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></td>\n";
- } else {
- $indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
- }
- $count++;
- } else {
- $indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
- }
- }
- $indexView .= "\t<td class=\"actions\">\n";
- $indexView .= "\t\t<?php echo \$html->link('View','{$admin_url}/{$controllerPath}/view/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
- $indexView .= "\t\t<?php echo \$html->link('Edit','{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
- $indexView .= "\t\t<?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
- $indexView .= "\t</td>\n";
- $indexView .= "</tr>\n";
- $indexView .= "<?php endforeach; ?>\n";
- $indexView .= "</table>\n\n";
- $indexView .= "<ul class=\"actions\">\n";
- $indexView .= "\t<li><?php echo \$html->link('New {$singularHumanName}', '{$admin_url}/{$controllerPath}/add'); ?></li>\n";
- $indexView .= "</ul>\n";
- $indexView .= "</div>";
- $viewView = null;
- $viewView .= "<div class=\"{$singularName}\">\n";
- $viewView .= "<h2>View " . $singularHumanName . "</h2>\n\n";
- $viewView .= "<dl>\n";
- $count = 0;
- foreach ($fieldNames as $field => $value) {
- $viewView .= "\t<dt>" . $value['prompt'] . "</dt>\n";
- if (isset($value['foreignKey'])) {
- $otherModelName = $this->__modelName($value['model']);
- $otherModelKey = Inflector::underscore($otherModelName);
- $otherModelObj =& ClassRegistry::getObject($otherModelKey);
- $otherControllerName = $this->__controllerName($otherModelName);
- $otherControllerPath = $this->__controllerPath($otherControllerName);
- $displayField = $otherModelObj->getDisplayField();
- $viewView .= "\t<dd>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></dd>\n";
- $count++;
- } else {
- $viewView .= "\t<dd>&nbsp;<?php echo \$".$singularName."['{$modelObj->name}']['{$field}']?></dd>\n";
- }
- }
- $viewView .= "</dl>\n";
- $viewView .= "<ul class=\"actions\">\n";
- $viewView .= "\t<li><?php echo \$html->link('Edit " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}']) ?> </li>\n";
- $viewView .= "\t<li><?php echo \$html->link('Delete " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'] . '?') ?> </li>\n";
- $viewView .= "\t<li><?php echo \$html->link('List " . $pluralHumanName ."', '{$admin_url}/{$controllerPath}/index') ?> </li>\n";
- $viewView .= "\t<li><?php echo \$html->link('New " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/add') ?> </li>\n";
- foreach ( $fieldNames as $field => $value ) {
- if ( isset( $value['foreignKey'] ) ) {
- $otherModelName = $this->__modelName($value['model']);
- if ($otherModelName != $currentModelName) {
- $otherControllerName = $this->__controllerName($otherModelName);
- $otherControllerPath = $this->__controllerPath($otherControllerName);
- $otherSingularHumanName = $this->__singularHumanName($value['controller']);
- $otherPluralHumanName = $this->__pluralHumanName($value['controller']);
- $viewView .= "\t<li><?php echo \$html->link('List " . $otherSingularHumanName . "', '{$admin_url}/" . $otherControllerPath . "/index/')?> </li>\n";
- $viewView .= "\t<li><?php echo \$html->link('New " . $otherPluralHumanName . "', '{$admin_url}/" . $otherControllerPath . "/add/')?> </li>\n";
- }
- }
- }
- $viewView .= "</ul>\n\n";
-
- $viewView .= "</div>\n";
-
-
- foreach ($modelObj->hasOne as $associationName => $relation) {
- $new = true;
-
- $otherModelName = $this->__modelName($relation['className']);
- $otherControllerName = $this->__controllerName($otherModelName);
- $otherControllerPath = $this->__controllerPath($otherControllerName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralHumanName = $this->__pluralHumanName($associationName);
- $otherSingularHumanName = $this->__singularHumanName($associationName);
-
- $viewView .= "<div class=\"related\">\n";
- $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
- $viewView .= "<?php if (!empty(\$".$singularName."['{$associationName}'])): ?>\n";
- $viewView .= "<dl>\n";
- $viewView .= "\t<?php foreach (\$".$singularName."['{$associationName}'] as \$field => \$value): ?>\n";
- $viewView .= "\t\t<dt><?php echo \$field ?></dt>\n";
- $viewView .= "\t\t<dd>&nbsp;<?php echo \$value ?></dd>\n";
- $viewView .= "\t<?php endforeach; ?>\n";
- $viewView .= "</dl>\n";
- $viewView .= "<?php endif; ?>\n";
- $viewView .= "<ul class=\"actions\">\n";
- $viewView .= "\t<li><?php echo \$html->link('Edit " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/edit/' . \$".$singularName."['{$associationName}']['" . $modelObj->{$otherModelName}->primaryKey . "']);?></li>\n";
- $viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
- $viewView .= "</ul>\n";
- $viewView .= "</div>\n";
- }
- $relations = array_merge($modelObj->hasMany, $modelObj->hasAndBelongsToMany);
-
- foreach ($relations as $associationName => $relation) {
- $otherModelName = $this->__modelName($relation['className']);
- $otherControllerName = $this->__controllerName($otherModelName);
- $otherControllerPath = $this->__controllerPath($otherControllerName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralHumanName = $this->__pluralHumanName($associationName);
- $otherSingularHumanName = $this->__singularHumanName($associationName);
- $otherModelKey = Inflector::underscore($otherModelName);
- $otherModelObj =& ClassRegistry::getObject($otherModelKey);
-
- $viewView .= "<div class=\"related\">\n";
- $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
- $viewView .= "<?php if (!empty(\$".$singularName."['{$associationName}'])):?>\n";
- $viewView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
- $viewView .= "<tr>\n";
- $viewView .= "<?php foreach (\$".$singularName."['{$associationName}']['0'] as \$column => \$value): ?>\n";
- $viewView .= "<th><?php echo \$column?></th>\n";
- $viewView .= "<?php endforeach; ?>\n";
- $viewView .= "<th>Actions</th>\n";
- $viewView .= "</tr>\n";
- $viewView .= "<?php foreach (\$".$singularName."['{$associationName}'] as \$".$otherSingularName."):?>\n";
- $viewView .= "<tr>\n";
- $viewView .= "\t<?php foreach (\$".$otherSingularName." as \$column => \$value):?>\n";
- $viewView .= "\t\t<td><?php echo \$value;?></td>\n";
- $viewView .= "\t<?php endforeach;?>\n";
- $viewView .= "\t<td class=\"actions\">\n";
- $viewView .= "\t\t<?php echo \$html->link('View', '{$admin_url}/" . $otherControllerPath . "/view/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
- $viewView .= "\t\t<?php echo \$html->link('Edit', '{$admin_url}/" . $otherControllerPath . "/edit/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
- $viewView .= "\t\t<?php echo \$html->link('Delete', '{$admin_url}/" . $otherControllerPath . "/delete/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'] . '?');?>\n";
- $viewView .= "\t</td>\n";
- $viewView .= "</tr>\n";
- $viewView .= "<?php endforeach; ?>\n";
- $viewView .= "</table>\n";
- $viewView .= "<?php endif; ?>\n\n";
- $viewView .= "<ul class=\"actions\">\n";
- $viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
- $viewView .= "</ul>\n";
-
- $viewView .= "</div>\n";
- }
- $addView = null;
- $addView .= "<h2>New " . $singularHumanName . "</h2>\n";
- $addView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/add'); ?>\" method=\"post\">\n";
- $addView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
- $addView .= $this->generateSubmitDiv('Add');
- $addView .= "</form>\n";
- $addView .= "<ul class=\"actions\">\n";
- $addView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
- foreach ($modelObj->belongsTo as $associationName => $relation) {
- $otherModelName = $this->__modelName($associationName);
- if ($otherModelName != $currentModelName) {
- $otherControllerName = $this->__controllerName($otherModelName);
- $otherControllerPath = $this->__controllerPath($otherControllerName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralHumanName($associationName);
- $addView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
- $addView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
- }
- }
- $addView .= "</ul>\n";
- $editView = null;
- $editView .= "<h2>Edit " . $singularHumanName . "</h2>\n";
- $editView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/edit/'.\$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}')); ?>\" method=\"post\">\n";
- $editView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
- $editView .= "<?php echo \$html->hidden('{$modelObj->name}/{$modelObj->primaryKey}')?>\n";
- $editView .= $this->generateSubmitDiv('Save');
- $editView .= "</form>\n";
- $editView .= "<ul class=\"actions\">\n";
- $editView .= "<li><?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'), null, 'Are you sure you want to delete: id ' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'));?>\n";
- $editView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
- foreach ($modelObj->belongsTo as $associationName => $relation) {
- $otherModelName = $this->__modelName($associationName);
- if ($otherModelName != $currentModelName) {
- $otherControllerName = $this->__controllerName($otherModelName);
- $otherControllerPath = $this->__controllerPath($otherControllerName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralHumanName($associationName);
- $editView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
- $editView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
- }
- }
- $editView .= "</ul>\n";
-
- if (!file_exists(VIEWS.$controllerPath)) {
- mkdir(VIEWS.$controllerPath);
- }
- $filename = VIEWS . $controllerPath . DS . $admin . 'index.thtml';
- $this->__createFile($filename, $indexView);
- $filename = VIEWS . $controllerPath . DS . $admin . 'view.thtml';
- $this->__createFile($filename, $viewView);
- $filename = VIEWS . $controllerPath . DS . $admin . 'add.thtml';
- $this->__createFile($filename, $addView);
- $filename = VIEWS . $controllerPath . DS . $admin . 'edit.thtml';
- $this->__createFile($filename, $editView);
- }
-/**
- * Action to create a Controller.
- *
- */
- function doController() {
- $this->hr();
- $this->stdout('Controller Bake:');
- $this->hr();
- $uses = array();
- $helpers = array();
- $components = array();
- $wannaUseSession = 'y';
- $wannaDoScaffolding = 'y';
-
- $useDbConfig = 'default';
- $this->__doList($useDbConfig, 'Controllers');
-
- $enteredController = '';
-
- while ($enteredController == '') {
- $enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
-
- if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
- $this->stdout('Error:');
- $this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
- $enteredController = '';
- }
- }
-
- if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
- $controllerName = $this->__controllerNames[intval($enteredController) - 1];
- } else {
- $controllerName = Inflector::camelize($enteredController);
- }
-
- $controllerPath = low(Inflector::underscore($controllerName));
-
- $doItInteractive = $this->getInput("Would you like bake to build your controller interactively?\nWarning: Choosing no will overwrite {$controllerClassName} controller if it exist.", array('y','n'), 'y');
-
- if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
- $this->interactive = true;
-
- $wannaUseScaffold = $this->getInput("Would you like to use scaffolding?", array('y','n'), 'y');
-
- if (low($wannaUseScaffold) == 'n' || low($wannaUseScaffold) == 'no') {
-
- $wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'n');
-
- if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
- $wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'n');
- }
-
- $wannaDoUses = $this->getInput("Would you like this controller to use other models besides '" . $this->__modelName($controllerName) . "'?", array('y','n'), 'n');
-
- if (low($wannaDoUses) == 'y' || low($wannaDoUses) == 'yes') {
- $usesList = $this->getInput("Please provide a comma separated list of the classnames of other models you'd like to use.\nExample: 'Author, Article, Book'");
- $usesListTrimmed = str_replace(' ', '', $usesList);
- $uses = explode(',', $usesListTrimmed);
- }
- $wannaDoHelpers = $this->getInput("Would you like this controller to use other helpers besides HtmlHelper and FormHelper?", array('y','n'), 'n');
-
- if (low($wannaDoHelpers) == 'y' || low($wannaDoHelpers) == 'yes') {
- $helpersList = $this->getInput("Please provide a comma separated list of the other helper names you'd like to use.\nExample: 'Ajax, Javascript, Time'");
- $helpersListTrimmed = str_replace(' ', '', $helpersList);
- $helpers = explode(',', $helpersListTrimmed);
- }
- $wannaDoComponents = $this->getInput("Would you like this controller to use any components?", array('y','n'), 'n');
-
- if (low($wannaDoComponents) == 'y' || low($wannaDoComponents) == 'yes') {
- $componentsList = $this->getInput("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, MyNiftyHelper'");
- $componentsListTrimmed = str_replace(' ', '', $componentsList);
- $components = explode(',', $componentsListTrimmed);
- }
-
- $wannaUseSession = $this->getInput("Would you like to use Sessions?", array('y','n'), 'y');
- } else {
- $wannaDoScaffolding = 'n';
- }
- } else {
- $wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'y');
-
- if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
- $wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'y');
- }
- }
-
- $admin = null;
- $admin_url = null;
- if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
- require(CONFIGS.'core.php');
- if (defined('CAKE_ADMIN')) {
- $admin = CAKE_ADMIN.'_';
- $admin_url = '/'.CAKE_ADMIN;
- } else {
- $adminRoute = '';
- $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
- $this->stdout('What would you like the admin route to be?');
- $this->stdout('Example: www.example.com/admin/controller');
- while ($adminRoute == '') {
- $adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
- }
- if ($this->__addAdminRoute($adminRoute) !== true) {
- $this->stdout('Unable to write to /app/config/core.php.');
- $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
- exit();
- } else {
- $admin = $adminRoute . '_';
- $admin_url = '/'.$adminRoute;
- }
- }
- }
-
- if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
- $actions = $this->__bakeActions($controllerName, null, null, $wannaUseSession);
- if ($admin) {
- $actions .= $this->__bakeActions($controllerName, $admin, $admin_url, $wannaUseSession);
- }
- }
-
- if ($this->interactive === true) {
- $this->stdout('');
- $this->hr();
- $this->stdout('The following controller will be created:');
- $this->hr();
- $this->stdout("Controller Name: $controllerName");
- if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
- $this->stdout(" var \$scaffold;");
- }
- if (count($uses)) {
- $this->stdout("Uses: ", false);
-
- foreach ($uses as $use) {
- if ($use != $uses[count($uses) - 1]) {
- $this->stdout(ucfirst($use) . ", ", false);
- } else {
- $this->stdout(ucfirst($use));
- }
- }
- }
-
- if (count($helpers)) {
- $this->stdout("Helpers: ", false);
-
- foreach ($helpers as $help) {
- if ($help != $helpers[count($helpers) - 1]) {
- $this->stdout(ucfirst($help) . ", ", false);
- } else {
- $this->stdout(ucfirst($help));
- }
- }
- }
-
- if (count($components)) {
- $this->stdout("Components: ", false);
-
- foreach ($components as $comp) {
- if ($comp != $components[count($components) - 1]) {
- $this->stdout(ucfirst($comp) . ", ", false);
- } else {
- $this->stdout(ucfirst($comp));
- }
- }
- }
- $this->hr();
- $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
-
- if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
- $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
-
- if ($this->doUnitTest()) {
- $this->bakeUnitTest('controller', $controllerName);
- }
- } else {
- $this->stdout('Bake Aborted.');
- }
- } else {
- $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
- if ($this->doUnitTest()) {
- $this->bakeUnitTest('controller', $controllerName);
- }
- exit();
- }
- }
-
- function __bakeActions($controllerName, $admin = null, $admin_url = null, $wannaUseSession = 'y') {
- $currentModelName = $this->__modelName($controllerName);
- loadModel($currentModelName);
- $modelObj =& new $currentModelName();
- $controllerPath = $this->__controllerPath($controllerName);
- $pluralName = $this->__pluralName($currentModelName);
- $singularName = $this->__singularName($currentModelName);
- $singularHumanName = $this->__singularHumanName($currentModelName);
- $pluralHumanName = $this->__pluralHumanName($controllerName);
- if (!class_exists($currentModelName)) {
- $this->stdout('You must have a model for this class to build scaffold methods. Please try again.');
- exit;
- }
- $actions .= "\n";
- $actions .= "\tfunction {$admin}index() {\n";
- $actions .= "\t\t\$this->{$currentModelName}->recursive = 0;\n";
- $actions .= "\t\t\$this->set('{$pluralName}', \$this->{$currentModelName}->findAll());\n";
- $actions .= "\t}\n";
- $actions .= "\n";
- $actions .= "\tfunction {$admin}view(\$id = null) {\n";
- $actions .= "\t\tif (!\$id) {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}.');\n";
- $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
- } else {
- $actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
- }
- $actions .= "\t\t}\n";
- $actions .= "\t\t\$this->set('".$singularName."', \$this->{$currentModelName}->read(null, \$id));\n";
- $actions .= "\t}\n";
- $actions .= "\n";
- $actions .= "\tfunction {$admin}add() {\n";
- $actions .= "\t\tif (empty(\$this->data)) {\n";
-
- foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
- $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- $actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', null);\n";
- }
- }
- foreach ($modelObj->belongsTo as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- }
- }
- $actions .= "\t\t\t\$this->render();\n";
- $actions .= "\t\t} else {\n";
- $actions .= "\t\t\t\$this->cleanUpFields();\n";
- $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." has been saved');\n";
- $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
- } else {
- $actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
- }
- $actions .= "\t\t\t} else {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
- }
-
- foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
- $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- $actions .= "\t\t\t\tif (empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
- $actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
- }
- }
- foreach ($modelObj->belongsTo as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- }
- }
- $actions .= "\t\t\t}\n";
- $actions .= "\t\t}\n";
- $actions .= "\t}\n";
- $actions .= "\n";
- $actions .= "\tfunction {$admin}edit(\$id = null) {\n";
- $actions .= "\t\tif (empty(\$this->data)) {\n";
- $actions .= "\t\t\tif (!\$id) {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
- $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
- } else {
- $actions .= "\t\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
- }
- $actions .= "\t\t\t}\n";
- $actions .= "\t\t\t\$this->data = \$this->{$currentModelName}->read(null, \$id);\n";
-
- foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $otherModelKey = Inflector::underscore($otherModelName);
- $otherModelObj =& ClassRegistry::getObject($otherModelKey);
- $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
- $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- $actions .= "\t\t\tif (empty(\$this->data['{$associationName}'])) { \$this->data['{$associationName}'] = null; }\n";
- $actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->_selectedArray(\$this->data['{$associationName}']));\n";
- }
- }
- foreach ($modelObj->belongsTo as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- }
- }
- $actions .= "\t\t} else {\n";
- $actions .= "\t\t\t\$this->cleanUpFields();\n";
- $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($currentModelName)." has been saved');\n";
- $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
- } else {
- $actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
- }
- $actions .= "\t\t\t} else {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
- }
-
- foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
- $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- $actions .= "\t\t\t\tif (empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
- $actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
- }
- }
- foreach ($modelObj->belongsTo as $associationName => $relation) {
- if (!empty($associationName)) {
- $otherModelName = $this->__modelName($associationName);
- $otherSingularName = $this->__singularName($associationName);
- $otherPluralName = $this->__pluralName($associationName);
- $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
- }
- }
- $actions .= "\t\t\t}\n";
- $actions .= "\t\t}\n";
- $actions .= "\t}\n";
- $actions .= "\n";
- $actions .= "\tfunction {$admin}delete(\$id = null) {\n";
- $actions .= "\t\tif (!\$id) {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
- $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
- } else {
- $actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
- }
- $actions .= "\t\t}\n";
- $actions .= "\t\tif (\$this->{$currentModelName}->del(\$id)) {\n";
- if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
- $actions .= "\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." deleted: id '.\$id.'');\n";
- $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
- } else {
- $actions .= "\t\t\t\$this->flash('{$currentModelName} deleted: id '.\$id.'.', '{$admin_url}/{$controllerPath}/index');\n";
- }
- $actions .= "\t\t}\n";
- $actions .= "\t}\n";
- $actions .= "\n";
- return $actions;
- }
-/**
- * Action to create a Unit Test.
- *
- * @return Success
- */
- function doUnitTest() {
- if (is_dir(VENDORS.'simpletest') || is_dir(ROOT.DS.APP_DIR.DS.'vendors'.DS.'simpletest')) {
- return true;
- }
- $unitTest = $this->getInput('Cake test suite not installed. Do you want to bake unit test files anyway?', array('y','n'), 'y');
- $result = low($unitTest) == 'y' || low($unitTest) == 'yes';
-
- if ($result) {
- $this->stdout("\nYou can download the Cake test suite from http://cakeforge.org/projects/testsuite/", true);
- }
- return $result;
- }
-/**
- * Creates a database configuration file for Bake.
- *
- * @param string $host
- * @param string $login
- * @param string $password
- * @param string $database
- */
- function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
- $out = "<?php\n";
- $out .= "class DATABASE_CONFIG {\n\n";
- $out .= "\tvar \$default = array(\n";
- $out .= "\t\t'driver' => '{$driver}',\n";
- $out .= "\t\t'connect' => '{$connect}',\n";
- $out .= "\t\t'host' => '{$host}',\n";
- $out .= "\t\t'login' => '{$login}',\n";
- $out .= "\t\t'password' => '{$password}',\n";
- $out .= "\t\t'database' => '{$database}', \n";
- $out .= "\t\t'prefix' => '{$prefix}' \n";
- $out .= "\t);\n";
- $out .= "}\n";
- $out .= "?>";
- $filename = CONFIGS.'database.php';
- $this->__createFile($filename, $out);
- }
-/**
- * Assembles and writes a Model file.
- *
- * @param string $name
- * @param object $useDbConfig
- * @param string $useTable
- * @param string $primaryKey
- * @param array $validate
- * @param array $associations
- */
- function bakeModel($name, $useDbConfig = 'default', $useTable = null, $primaryKey = 'id', $validate=array(), $associations=array()) {
- $out = "<?php\n";
- $out .= "class {$name} extends AppModel {\n\n";
- $out .= "\tvar \$name = '{$name}';\n";
-
- if ($useDbConfig != 'default') {
- $out .= "\tvar \$useDbConfig = '$useDbConfig';\n";
- }
-
- if ($useTable != null) {
- $out .= "\tvar \$useTable = '$useTable';\n";
- }
-
- if ($primaryKey != 'id') {
- $out .= "\tvar \$primaryKey = '$primaryKey';\n";
- }
-
-
- if (count($validate)) {
- $out .= "\tvar \$validate = array(\n";
- $keys = array_keys($validate);
- for ($i = 0; $i < count($validate); $i++) {
- $out .= "\t\t'" . $keys[$i] . "' => " . $validate[$keys[$i]] . ",\n";
- }
- $out .= "\t);\n";
- }
- $out .= "\n";
-
- if (!empty($associations)) {
- $out.= "\t//The Associations below have been created with all possible keys, those that are not needed can be removed\n";
- if (!empty($associations['belongsTo'])) {
- $out .= "\tvar \$belongsTo = array(\n";
-
- for ($i = 0; $i < count($associations['belongsTo']); $i++) {
- $out .= "\t\t\t'{$associations['belongsTo'][$i]['alias']}' =>\n";
- $out .= "\t\t\t\tarray('className' => '{$associations['belongsTo'][$i]['className']}',\n";
- $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['belongsTo'][$i]['foreignKey']}',\n";
- $out .= "\t\t\t\t\t\t'conditions' => '',\n";
- $out .= "\t\t\t\t\t\t'fields' => '',\n";
- $out .= "\t\t\t\t\t\t'order' => '',\n";
- $out .= "\t\t\t\t\t\t'counterCache' => ''\n";
- $out .= "\t\t\t\t),\n\n";
- }
- $out .= "\t);\n\n";
- }
-
- if (!empty($associations['hasOne'])) {
- $out .= "\tvar \$hasOne = array(\n";
-
- for ($i = 0; $i < count($associations['hasOne']); $i++) {
- $out .= "\t\t\t'{$associations['hasOne'][$i]['alias']}' =>\n";
- $out .= "\t\t\t\tarray('className' => '{$associations['hasOne'][$i]['className']}',\n";
- $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasOne'][$i]['foreignKey']}',\n";
- $out .= "\t\t\t\t\t\t'conditions' => '',\n";
- $out .= "\t\t\t\t\t\t'fields' => '',\n";
- $out .= "\t\t\t\t\t\t'order' => '',\n";
- $out .= "\t\t\t\t\t\t'dependent' => ''\n";
- $out .= "\t\t\t\t),\n\n";
- }
- $out .= "\t);\n\n";
- }
-
- if (!empty($associations['hasMany'])) {
- $out .= "\tvar \$hasMany = array(\n";
-
- for ($i = 0; $i < count($associations['hasMany']); $i++) {
- $out .= "\t\t\t'{$associations['hasMany'][$i]['alias']}' =>\n";
- $out .= "\t\t\t\tarray('className' => '{$associations['hasMany'][$i]['className']}',\n";
- $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasMany'][$i]['foreignKey']}',\n";
- $out .= "\t\t\t\t\t\t'conditions' => '',\n";
- $out .= "\t\t\t\t\t\t'fields' => '',\n";
- $out .= "\t\t\t\t\t\t'order' => '',\n";
- $out .= "\t\t\t\t\t\t'limit' => '',\n";
- $out .= "\t\t\t\t\t\t'offset' => '',\n";
- $out .= "\t\t\t\t\t\t'dependent' => '',\n";
- $out .= "\t\t\t\t\t\t'exclusive' => '',\n";
- $out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
- $out .= "\t\t\t\t\t\t'counterQuery' => ''\n";
- $out .= "\t\t\t\t),\n\n";
- }
- $out .= "\t);\n\n";
- }
-
- if (!empty($associations['hasAndBelongsToMany'])) {
- $out .= "\tvar \$hasAndBelongsToMany = array(\n";
-
- for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
- $out .= "\t\t\t'{$associations['hasAndBelongsToMany'][$i]['alias']}' =>\n";
- $out .= "\t\t\t\tarray('className' => '{$associations['hasAndBelongsToMany'][$i]['className']}',\n";
- $out .= "\t\t\t\t\t\t'joinTable' => '{$associations['hasAndBelongsToMany'][$i]['joinTable']}',\n";
- $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasAndBelongsToMany'][$i]['foreignKey']}',\n";
- $out .= "\t\t\t\t\t\t'associationForeignKey' => '{$associations['hasAndBelongsToMany'][$i]['associationForeignKey']}',\n";
- $out .= "\t\t\t\t\t\t'conditions' => '',\n";
- $out .= "\t\t\t\t\t\t'fields' => '',\n";
- $out .= "\t\t\t\t\t\t'order' => '',\n";
- $out .= "\t\t\t\t\t\t'limit' => '',\n";
- $out .= "\t\t\t\t\t\t'offset' => '',\n";
- $out .= "\t\t\t\t\t\t'unique' => '',\n";
- $out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
- $out .= "\t\t\t\t\t\t'deleteQuery' => '',\n";
- $out .= "\t\t\t\t\t\t'insertQuery' => ''\n";
- $out .= "\t\t\t\t),\n\n";
- }
- $out .= "\t);\n\n";
- }
- }
- $out .= "}\n";
- $out .= "?>";
- $filename = MODELS.Inflector::underscore($name) . '.php';
- $this->__createFile($filename, $out);
- }
-/**
- * Assembles and writes a View file.
- *
- * @param string $controllerName
- * @param string $actionName
- * @param string $content
- */
- function bakeView($controllerName, $actionName, $content = '') {
- $out = "<h2>{$actionName}</h2>\n";
- $out .= $content;
- if (!file_exists(VIEWS.$this->__controllerPath($controllerName))) {
- mkdir(VIEWS.$this->__controllerPath($controllerName));
- }
- $filename = VIEWS . $this->__controllerPath($controllerName) . DS . Inflector::underscore($actionName) . '.thtml';
- $this->__createFile($filename, $out);
- }
-/**
- * Assembles and writes a Controller file.
- *
- * @param string $controllerName
- * @param array $uses
- * @param array $helpers
- * @param array $components
- * @param string $actions
- */
- function bakeController($controllerName, $uses, $helpers, $components, $actions = '', $wannaUseScaffold = 'y') {
- $out = "<?php\n";
- $out .= "class $controllerName" . "Controller extends AppController {\n\n";
- $out .= "\tvar \$name = '$controllerName';\n";
- if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
- $out .= "\tvar \$scaffold;\n";
- } else {
-
- if (count($uses)) {
- $out .= "\tvar \$uses = array('" . $this->__modelName($controllerName) . "', ";
-
- foreach ($uses as $use) {
- if ($use != $uses[count($uses) - 1]) {
- $out .= "'" . $this->__modelName($use) . "', ";
- } else {
- $out .= "'" . $this->__modelName($use) . "'";
- }
- }
- $out .= ");\n";
- }
-
- $out .= "\tvar \$helpers = array('Html', 'Form' ";
- if (count($helpers)) {
- foreach ($helpers as $help) {
- if ($help != $helpers[count($helpers) - 1]) {
- $out .= ", '" . Inflector::camelize($help) . "'";
- } else {
- $out .= ", '" . Inflector::camelize($help) . "'";
- }
- }
- }
- $out .= ");\n";
-
- if (count($components)) {
- $out .= "\tvar \$components = array(";
-
- foreach ($components as $comp) {
- if ($comp != $components[count($components) - 1]) {
- $out .= "'" . Inflector::camelize($comp) . "', ";
- } else {
- $out .= "'" . Inflector::camelize($comp) . "'";
- }
- }
- $out .= ");\n";
- }
- }
- $out .= $actions;
- $out .= "}\n";
- $out .= "?>";
- $filename = CONTROLLERS . $this->__controllerPath($controllerName) . '_controller.php';
- $this->__createFile($filename, $out);
- }
-/**
- * Assembles and writes a unit test file.
- *
- * @param string $type One of "model", and "controller".
- * @param string $className
- */
- function bakeUnitTest($type, $className) {
- $out = '<?php '."\n\n";
- $error = false;
- switch ($type) {
- case 'model':
- $out .= "loadModel('$className');\n\n";
- $out .= "class {$className}TestCase extends UnitTestCase {\n";
- $out .= "\tvar \$object = null;\n\n";
- $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}();\n";
- $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
- $out .= "\n\t/*\n\tfunction testMe() {\n";
- $out .= "\t\t\$result = \$this->object->doSomething();\n";
- $out .= "\t\t\$expected = 1;\n";
- $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
- $path = MODEL_TESTS;
- $filename = $this->__singularName($className).'.test.php';
- break;
- case 'controller':
- $out .= "loadController('$className');\n\n";
- $out .= "class {$className}ControllerTestCase extends UnitTestCase {\n";
- $out .= "\tvar \$object = null;\n\n";
- $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}Controller();\n";
- $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
- $out .= "\n\t/*\n\tfunction testMe() {\n";
- $out .= "\t\t\$result = \$this->object->doSomething();\n";
- $out .= "\t\t\$expected = 1;\n";
- $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
- $path = CONTROLLER_TESTS;
- $filename = $this->__pluralName($className).'_controller.test.php';
- break;
- default:
- $error = true;
- break;
- }
- $out .= "\n?>";
-
- if (!$error) {
- $this->stdout("Baking unit test for $className...");
- $path = explode(DS, $path);
- foreach ($path as $i => $val) {
- if ($val == '' || $val == '../') {
- unset($path[$i]);
- }
- }
- $path = implode(DS, $path);
- $unixPath = DS;
- if (strpos(PHP_OS, 'WIN') === 0) {
- $unixPath = null;
- }
- if (!is_dir($unixPath.$path)) {
- $create = $this->getInput("Unit test directory does not exist. Create it?", array('y','n'), 'y');
- if (low($create) == 'y' || low($create) == 'yes') {
- $build = array();
-
- foreach (explode(DS, $path) as $i => $dir) {
- $build[] = $dir;
- if (!is_dir($unixPath.implode(DS, $build))) {
- mkdir($unixPath.implode(DS, $build));
- }
- }
- } else {
- return false;
- }
- }
- $this->__createFile($unixPath.$path.DS.$filename, $out);
- }
- }
-/**
- * Prompts the user for input, and returns it.
- *
- * @param string $prompt Prompt text.
- * @param mixed $options Array or string of options.
- * @param string $default Default input value.
- * @return Either the default value, or the user-provided input.
- */
- function getInput($prompt, $options = null, $default = null) {
- if (!is_array($options)) {
- $print_options = '';
- } else {
- $print_options = '(' . implode('/', $options) . ')';
- }
-
- if ($default == null) {
- $this->stdout('');
- $this->stdout($prompt . " $print_options \n" . '> ', false);
- } else {
- $this->stdout('');
- $this->stdout($prompt . " $print_options \n" . "[$default] > ", false);
- }
- $result = fgets($this->stdin);
-
- if($result === false){
- exit;
- }
- $result = trim($result);
-
- if ($default != null && empty($result)) {
- return $default;
- } else {
- return $result;
- }
- }
-/**
- * Outputs to the stdout filehandle.
- *
- * @param string $string String to output.
- * @param boolean $newline If true, the outputs gets an added newline.
- */
- function stdout($string, $newline = true) {
- if ($newline) {
- fwrite($this->stdout, $string . "\n");
- } else {
- fwrite($this->stdout, $string);
- }
- }
-/**
- * Outputs to the stderr filehandle.
- *
- * @param string $string Error text to output.
- */
- function stderr($string) {
- fwrite($this->stderr, $string, true);
- }
-/**
- * Outputs a series of minus characters to the standard output, acts as a visual separator.
- *
- */
- function hr() {
- $this->stdout('---------------------------------------------------------------');
- }
-/**
- * Creates a file at given path.
- *
- * @param string $path Where to put the file.
- * @param string $contents Content to put in the file.
- * @return Success
- */
- function __createFile ($path, $contents) {
- $path = str_replace('//', '/', $path);
- echo "\nCreating file $path\n";
- if (is_file($path) && $this->interactive === true) {
- fwrite($this->stdout, __("File exists, overwrite?", true). " {$path} (y/n/q):");
- $key = trim(fgets($this->stdin));
-
- if ($key=='q') {
- fwrite($this->stdout, __("Quitting.", true) ."\n");
- exit;
- } elseif ($key == 'a') {
- $this->dont_ask = true;
- } elseif ($key == 'y') {
- } else {
- fwrite($this->stdout, __("Skip", true) ." {$path}\n");
- return false;
- }
- }
-
- if ($f = fopen($path, 'w')) {
- fwrite($f, $contents);
- fclose($f);
- fwrite($this->stdout, __("Wrote", true) ."{$path}\n");
- return true;
- } else {
- fwrite($this->stderr, __("Error! Could not write to", true)." {$path}.\n");
- return false;
- }
- }
-/**
- * Takes an array of database fields, and generates an HTML form for a View.
- * This is an extraction from the Scaffold functionality.
- *
- * @param array $fields
- * @param boolean $readOnly
- * @return Generated HTML and PHP.
- */
- function generateFields( $fields, $readOnly = false ) {
- $strFormFields = '';
- foreach ( $fields as $field ) {
- if (isset( $field['type'])) {
- if (!isset($field['required'])) {
- $field['required'] = false;
- }
-
- if (!isset( $field['errorMsg'])) {
- $field['errorMsg'] = null;
- }
-
- if (!isset( $field['htmlOptions'])) {
- $field['htmlOptions'] = array();
- }
-
- if ( $readOnly ) {
- $field['htmlOptions']['READONLY'] = "readonly";
- }
-
- switch( $field['type'] ) {
- case "input" :
- if (!isset( $field['size'])) {
- $field['size'] = 60;
- }
- $strFormFields = $strFormFields.$this->generateInputDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions'] );
- break;
- case "checkbox" :
- $strFormFields = $strFormFields.$this->generateCheckboxDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['htmlOptions'] );
- break;
- case "select";
- case "selectMultiple";
- if ( "selectMultiple" == $field['type'] ) {
- $field['selectAttr']['multiple'] = 'multiple';
- $field['selectAttr']['class'] = 'selectMultiple';
- }
- if (!isset( $field['selected'])) {
- $field['selected'] = null;
- }
- if (!isset( $field['selectAttr'])) {
- $field['selectAttr'] = null;
- }
- if (!isset( $field['optionsAttr'])) {
- $field['optionsAttr'] = null;
- }
- if ($readOnly) {
- $field['selectAttr']['DISABLED'] = true;
- }
- if (!isset( $field['options'])) {
- $field['options'] = null;
- }
- $this->__modelAlias = null;
- if (isset($field['foreignKey'])) {
- $modelKey = Inflector::underscore($this->__modelClass);
- $modelObj =& ClassRegistry::getObject($modelKey);
- foreach ($modelObj->belongsTo as $associationName => $value) {
- if ($field['model'] == $value['className']) {
- $this->__modelAlias = $this->__modelName($associationName);
- break;
- }
- }
- }
- $strFormFields = $strFormFields.$this->generateSelectDiv( $field['tagName'], $field['prompt'], $field['options'], $field['selected'], $field['selectAttr'], $field['optionsAttr'], $field['required'], $field['errorMsg'] );
- break;
- case "area";
- if (!isset( $field['rows'])) {
- $field['rows'] = 10;
- }
- if (!isset( $field['cols'])) {
- $field['cols'] = 60;
- }
- $strFormFields = $strFormFields.$this->generateAreaDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['cols'], $field['rows'], $field['htmlOptions'] );
- break;
- case "fieldset";
- $strFieldsetFields = $this->generateFields( $field['fields'] );
- $strFieldSet = sprintf( '
- <fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>',
- $field['legend'], $field['noteHeading'], $field['note'], $strFieldsetFields );
- $strFormFields = $strFormFields.$strFieldSet;
- break;
- case "hidden";
- //$strFormFields = $strFormFields . $this->Html->hiddenTag( $field['tagName']);
- break;
- case "date":
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
- $strFormFields = $strFormFields . $this->generateDate($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
- break;
- case "datetime":
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
- $strFormFields = $strFormFields . $this->generateDateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
- break;
- case "time":
- if (!isset($field['selected'])) {
- $field['selected'] = null;
- }
- $strFormFields = $strFormFields . $this->generateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
- break;
- default:
- break;
- }
- }
- }
- return $strFormFields;
- }
-/**
- * Generates PHP code for a View file that makes a textarea.
- *
- * @param string $tagName
- * @param string $prompt
- * @param boolean $required
- * @param string $errorMsg
- * @param integer $cols
- * @param integer $rows
- * @param array $htmlOptions
- * @return Generated HTML and PHP.
- */
- function generateAreaDiv($tagName, $prompt, $required=false, $errorMsg=null, $cols=60, $rows=10, $htmlOptions=null ) {
- $htmlAttributes = $htmlOptions;
- $htmlAttributes['cols'] = $cols;
- $htmlAttributes['rows'] = $rows;
- $str = "\t<?php echo \$html->textarea('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
- $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
- $strLabel = "\n\t<?php echo \$form->labelTag( '{$tagName}', '{$prompt}' );?>\n";
- $divClass = "optional";
-
- if ( $required ) {
- $divClass = "required";
- }
- $strError = "";
- $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
- return $this->divTag( $divClass, $divTagInside );
- }
-/**
- * Generates PHP code for a View file that makes a checkbox, wrapped in a DIV.
- *
- * @param string $tagName
- * @param string $prompt
- * @param boolean $required
- * @param string $errorMsg
- * @param array $htmlOptions
- * @return Generated HTML and PHP.
- */
- function generateCheckboxDiv($tagName, $prompt, $required=false, $errorMsg=null, $htmlOptions=null ) {
- $htmlAttributes = $htmlOptions;
- $strLabel = "\n\t<?php echo \$html->checkbox('{$tagName}', null, " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
- $strLabel .= "\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
- $str = "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please check the {$prompt}.');?>\n";
- $divClass = "optional";
-
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
- $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str);
- return $this->divTag( $divClass, $divTagInside );
- }
-/**
- * Generates PHP code for a View file that makes a date-picker, wrapped in a DIV.
- *
- * @param string $tagName
- * @param string $prompt
- * @param boolean $required
- * @param string $errorMsg
- * @param integer $size
- * @param array $htmlOptions
- * @param string $selected
- * @return Generated HTML and PHP.
- */
- function generateDate($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected=null ) {
- $str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , 'NONE', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
- $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
- $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
- $divClass = "optional";
-
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
- $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
- return $this->divTag( $divClass, $divTagInside );
- }
-/**
- * Generates PHP code for a View file that makes a time-picker, wrapped in a DIV.
- *
- * @param string $tagName
- * @param string $prompt
- * @param boolean $required
- * @param string $errorMsg
- * @param integer $size
- * @param array $htmlOptions
- * @param string $selected
- * @return Generated HTML and PHP.
- */
- function generateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
- $str = "\n\t\<?php echo \$html->dateTimeOptionTag('{$tagName}', 'NONE', '24', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
- $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
- $divClass = "optional";
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
- $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
- return $this->divTag($divClass, $divTagInside);
- }
-/**
- * EGenerates PHP code for a View file that makes a datetime-picker, wrapped in a DIV.
- *
- * @param string $tagName
- * @param string $prompt
- * @param boolean $required
- * @param string $errorMsg
- * @param integer $size
- * @param array $htmlOptions
- * @param string $selected
- * @return Generated HTML and PHP.
- */
- function generateDateTime($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected = null ) {
- $str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , '12', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
- $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
- $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
- $divClass = "optional";
-
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
- $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
- return $this->divTag( $divClass, $divTagInside );
- }
-/**
- * Generates PHP code for a View file that makes an INPUT field, wrapped in a DIV.
- *
- * @param string $tagName
- * @param string $prompt
- * @param boolean $required
- * @param string $errorMsg
- * @param integer $size
- * @param array $htmlOptions
- * @return Generated HTML and PHP.
- */
- function generateInputDiv($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null ) {
- $htmlAttributes = $htmlOptions;
- $htmlAttributes['size'] = $size;
- $str = "\t<?php echo \$html->input('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
- $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
- $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
- $divClass = "optional";
-
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
- $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
- return $this->divTag( $divClass, $divTagInside );
- }
-
-/**
- * Generates PHP code for a View file that makes a SELECT box, wrapped in a DIV.
- *
- * @param string $tagName
- * @param string $prompt
- * @param array $options
- * @param string $selected
- * @param array $selectAttr
- * @param array $optionAttr
- * @param boolean $required
- * @param string $errorMsg
- * @return Generated HTML and PHP.
- */
- function generateSelectDiv($tagName, $prompt, $options, $selected=null, $selectAttr=null, $optionAttr=null, $required=false, $errorMsg=null) {
-
- if ($this->__modelAlias) {
- $pluralName = $this->__pluralName($this->__modelAlias);
- } else {
- $tagArray = explode('/', $tagName);
- $pluralName = $this->__pluralName($this->__modelNameFromKey($tagArray[1]));
- }
- $showEmpty = 'true';
- if ($required) {
- $showEmpty = 'false';
- }
- if ($selectAttr['multiple'] != 'multiple') {
- $str = "\t<?php echo \$html->selectTag('{$tagName}', " . "\${$pluralName}, \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
- $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.') ?>\n";
- } else {
- $selectedPluralName = 'selected' . ucfirst($pluralName);
- $selectAttr = am(array('multiple' => 'multiple', 'class' => 'selectMultiple'), $selectAttr);
- $str = "\t<?php echo \$html->selectTag('{$tagName}', \${$pluralName}, \${$selectedPluralName}, " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
- $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
- }
- $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
- $divClass = "optional";
-
- if ($required) {
- $divClass = "required";
- }
- $strError = "";
- $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
- return $this->divTag( $divClass, $divTagInside );
- }
-/**
- * Generates PHP code for a View file that makes a submit button, wrapped in a DIV.
- *
- * @param string $displayText
- * @param array $htmlOptions
- * @return Generated HTML.
- */
- function generateSubmitDiv($displayText, $htmlOptions = null) {
- $str = "\n\t<?php echo \$html->submit('{$displayText}');?>\n";
- $divTagInside = sprintf( "%s", $str );
- return $this->divTag( 'submit', $divTagInside);
- }
-/**
- * Returns the text wrapped in an HTML DIV, followed by a newline.
- *
- * @param string $class
- * @param string $text
- * @return Generated HTML.
- */
- function divTag($class, $text) {
- return sprintf('<div class="%s">%s</div>', $class, $text ) . "\n";
- }
-/**
- * Parses the HTML attributes array, which is a common data structure in View files.
- * Returns PHP code for initializing this array in a View file.
- *
- * @param array $htmlAttributes
- * @return Generated PHP code.
- */
- function __attributesToArray($htmlAttributes) {
- if (is_array($htmlAttributes)) {
- $keys = array_keys($htmlAttributes);
- $vals = array_values($htmlAttributes);
- $out = "array(";
-
- for ($i = 0; $i < count($htmlAttributes); $i++) {
- if (substr($vals[$i], 0, 1) != '$') {
- $out .= "'{$keys[$i]}' => '{$vals[$i]}', ";
- } else {
- $out .= "'{$keys[$i]}' => {$vals[$i]}, ";
- }
- }
- if (substr($out, -2, 1) == ',') {
- $out = substr($out, 0, strlen($out) - 2);
- }
- $out .= ")";
- return $out;
- } else {
- return 'array()';
- }
- }
-/**
- * Outputs usage text on the standard output.
- *
- */
- function help() {
- $this->stdout('CakePHP Bake:');
- $this->hr();
- $this->stdout('The Bake script generates controllers, views and models for your application.');
- $this->stdout('If run with no command line arguments, Bake guides the user through the class');
- $this->stdout('creation process. You can customize the generation process by telling Bake');
- $this->stdout('where different parts of your application are using command line arguments.');
- $this->stdout('');
- $this->hr('');
- $this->stdout('usage: php bake.php [command] [path...]');
- $this->stdout('');
- $this->stdout('commands:');
- $this->stdout(' -app [path...] Absolute path to Cake\'s app Folder.');
- $this->stdout(' -core [path...] Absolute path to Cake\'s cake Folder.');
- $this->stdout(' -help Shows this help message.');
- $this->stdout(' -project [path...] Generates a new app folder in the path supplied.');
- $this->stdout(' -root [path...] Absolute path to Cake\'s \app\webroot Folder.');
- $this->stdout('');
- }
-/**
- * Checks that given project path does not already exist, and
- * finds the app directory in it. Then it calls __buildDirLayout() with that information.
- *
- * @param string $projectPath
- */
- function project($projectPath = null) {
- if ($projectPath != '') {
- while ($this->__checkPath($projectPath) === true && $this->__checkPath(CONFIGS) === true) {
- $response = $this->getInput('Bake -app in '.$projectPath, array('y','n'), 'y');
- if (low($response) == 'y') {
- $this->main();
- exit();
- } else {
- $projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
- }
- }
- } else {
- while ($projectPath == '') {
- $projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
-
- if ($projectPath == '') {
- $this->stdout('The directory path you supplied was empty. Please try again.');
- }
- }
- }
- while ($newPath != 'y' && ($this->__checkPath($projectPath) === true || $projectPath == '')) {
- $newPath = $this->getInput('Directory '.$projectPath.' exists. Overwrite (y) or insert a new path', null, 'y');
- if ($newPath != 'y') {
- $projectPath = $newPath;
- }
- while ($projectPath == '') {
- $projectPath = $this->getInput('The directory path you supplied was empty. Please try again.');
- }
- }
- $parentPath = explode(DS, $projectPath);
- $count = count($parentPath);
- $appName = $parentPath[$count - 1];
- if ($appName == '') {
- $appName = $parentPath[$count - 2];
- }
- $this->__buildDirLayout($projectPath, $appName);
- exit();
- }
-/**
- * Returns true if given path is a directory.
- *
- * @param string $projectPath
- * @return True if given path is a directory.
- */
- function __checkPath($projectPath) {
- if (is_dir($projectPath)) {
- return true;
- } else {
- return false;
- }
- }
-/**
- * Looks for a skeleton template of a Cake application,
- * and if not found asks the user for a path. When there is a path
- * this method will make a deep copy of the skeleton to the project directory.
- * A default home page will be added, and the tmp file storage will be chmod'ed to 0777.
- *
- * @param string $projectPath
- * @param string $appName
- */
- function __buildDirLayout($projectPath, $appName) {
- $skel = '';
- if ($this->__checkPath(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel') === true) {
- $skel = CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel';
- } else {
-
- while ($skel == '') {
- $skel = $this->getInput("What is the full path for the cake install app directory?\nExample: ", null, ROOT.'myapp'.DS);
-
- if ($skel == '') {
- $this->stdout('The directory path you supplied was empty. Please try again.');
- } else {
- while ($this->__checkPath($skel) === false) {
- $skel = $this->getInput('Directory path does not exist please choose another:');
- }
- }
- }
- }
- $this->stdout('');
- $this->hr();
- $this->stdout("Skel Directory: $skel");
- $this->stdout("Will be copied to:");
- $this->stdout("New App Directory: $projectPath");
- $this->hr();
- $looksGood = $this->getInput('Look okay?', array('y', 'n', 'q'), 'y');
-
- if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
- $verboseOuptut = $this->getInput('Do you want verbose output?', array('y', 'n'), 'n');
- $verbose = false;
-
- if (low($verboseOuptut) == 'y' || low($verboseOuptut) == 'yes') {
- $verbose = true;
- }
- $this->__copydirr($skel, $projectPath, 0755, $verbose);
- $this->hr();
- $this->stdout('Created: '.$projectPath);
- $this->hr();
- $this->stdout('Creating welcome page');
- $this->hr();
- $this->__defaultHome($projectPath, $appName);
- $this->stdout('Welcome page created');
- if (chmodr($projectPath.DS.'tmp', 0777) === false) {
- $this->stdout('Could not set permissions on '. $projectPath.DS.'tmp'.DS.'*');
- $this->stdout('You must manually check that these directories can be wrote to by the server');
- }
- return;
- } elseif (low($looksGood) == 'q' || low($looksGood) == 'quit') {
- $this->stdout('Bake Aborted.');
- } else {
- $this->project();
- }
- }
-/**
- * Recursive directory copy.
- *
- * @param string $fromDir
- * @param string $toDir
- * @param octal $chmod
- * @param boolean $verbose
- * @return Success.
- */
- function __copydirr($fromDir, $toDir, $chmod = 0755, $verbose = false) {
- $errors=array();
- $messages=array();
-
- uses('folder');
- $folder = new Folder($toDir, true, 0755);
-
- if (!is_writable($toDir)) {
- $errors[]='target '.$toDir.' is not writable';
- }
-
- if (!is_dir($fromDir)) {
- $errors[]='source '.$fromDir.' is not a directory';
- }
-
- if (!empty($errors)) {
- if ($verbose) {
- foreach ($errors as $err) {
- $this->stdout('Error: '.$err);
- }
- }
- return false;
- }
- $exceptions=array('.','..','.svn');
- $handle = opendir($fromDir);
-
- while (false!==($item = readdir($handle))) {
- if (!in_array($item,$exceptions)) {
- $from = $folder->addPathElement($fromDir, $item);
- $to = $folder->addPathElement($toDir, $item);
- if (is_file($from)) {
- if (@copy($from, $to)) {
- chmod($to, $chmod);
- touch($to, filemtime($from));
- $messages[]='File copied from '.$from.' to '.$to;
- } else {
- $errors[]='cannot copy file from '.$from.' to '.$to;
- }
- }
-
- if (is_dir($from)) {
- if (@mkdir($to)) {
- chmod($to,$chmod);
- $messages[]='Directory created: '.$to;
- } else {
- $errors[]='cannot create directory '.$to;
- }
- $this->__copydirr($from,$to,$chmod,$verbose);
- }
- }
- }
- closedir($handle);
-
- if ($verbose) {
- foreach ($errors as $err) {
- $this->stdout('Error: '.$err);
- }
- foreach ($messages as $msg) {
- $this->stdout($msg);
- }
- }
- return true;
- }
-
- function __addAdminRoute($name) {
- $file = file_get_contents(CONFIGS.'core.php');
- if (preg_match('%([/\\t\\x20]*define\\(\'CAKE_ADMIN\',[\\t\\x20\'a-z]*\\);)%', $file, $match)) {
- $result = str_replace($match[0], 'define(\'CAKE_ADMIN\', \''.$name.'\');', $file);
-
- if (file_put_contents(CONFIGS.'core.php', $result)) {
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-/**
- * Outputs an ASCII art banner to standard output.
- *
- */
- function welcome()
- {
- $this->stdout('');
- $this->stdout(' ___ __ _ _ ___ __ _ _ __ __ __ _ _ ___ ');
- $this->stdout('| |__| |_/ |__ |__] |__| |__] |__] |__| |_/ |__ ');
- $this->stdout('|___ | | | \_ |___ | | | | |__] | | | \_ |___ ');
- $this->hr();
- $this->stdout('');
- }
-/**
- * Writes a file with a default home page to the project.
- *
- * @param string $dir
- * @param string $app
- */
- function __defaultHome($dir, $app) {
- $path = $dir.DS.'views'.DS.'pages'.DS;
- include(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'views'.DS.'home.thtml');
- $this->__createFile($path.'home.thtml', $output);
- }
-/**
- * creates the proper pluralize controller for the url
- *
- * @param string $name must be a controller name in pluralized form
- * @return string $name
- */
- function __controllerPath($name) {
- return low(Inflector::underscore($name));
- }
-/**
- * creates the proper pluralize controller class name.
- *
- * @param string $name
- * @return string $name
- */
- function __controllerName($name) {
- return Inflector::pluralize(Inflector::camelize($name));
- }
-/**
- * creates the proper singular model name.
- *
- * @param string $name
- * @return string $name
- */
- function __modelName($name) {
- return Inflector::camelize(Inflector::singularize($name));
- }
-/**
- * creates the proper singular model key for associations.
- *
- * @param string $name
- * @return string $name
- */
- function __modelKey($name) {
- return Inflector::underscore(Inflector::singularize($name)).'_id';
- }
-/**
- * creates the proper model name from a foreign key.
- *
- * @param string $key
- * @return string $name
- */
- function __modelNameFromKey($key) {
- $name = str_replace('_id', '',$key);
- return $this->__modelName($name);
- }
-/**
- * creates the singular name for use in views.
- *
- * @param string $name
- * @return string $name
- */
- function __singularName($name) {
- return Inflector::variable(Inflector::singularize($name));
- }
-/**
- * creates the plural name for views.
- *
- * @param string $name
- * @return string $name
- */
- function __pluralName($name) {
- return Inflector::variable(Inflector::pluralize($name));
- }
-/**
- * creates the singular human name used in views
- *
- * @param string $name
- * @return string $name
- */
- function __singularHumanName($name) {
- return Inflector::humanize(Inflector::underscore(Inflector::singularize($name)));
- }
-/**
- * creates the plural humna name used in views
- *
- * @param string $name
- * @return string $name
- */
- function __pluralHumanName($name) {
- return Inflector::humanize(Inflector::underscore(Inflector::pluralize($name)));
- }
-/**
- * outputs the a list of possible models or controllers from database
- *
- * @param string $useDbConfig
- * @param string $type = Models or Controllers
- * @return output
- */
- function __doList($useDbConfig = 'default', $type = 'Models') {
- $db =& ConnectionManager::getDataSource($useDbConfig);
- $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
- if ($usePrefix) {
- $tables = array();
- foreach ($db->listSources() as $table) {
- if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
- $tables[] = substr($table, strlen($usePrefix));
- }
- }
- } else {
- $tables = $db->listSources();
- }
- $this->__tables = $tables;
- $this->stdout('Possible '.$type.' based on your current database:');
- $this->__controllerNames = array();
- $this->__modelNames = array();
- $count = count($tables);
- for ($i = 0; $i < $count; $i++) {
- if (low($type) == 'controllers') {
- $this->__controllerNames[] = $this->__controllerName($this->__modelName($tables[$i]));
- $this->stdout($i + 1 . ". " . $this->__controllerNames[$i]);
- } else {
- $this->__modelNames[] = $this->__modelName($tables[$i]);
- $this->stdout($i + 1 . ". " . $this->__modelNames[$i]);
- }
- }
- }
-
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/.htaccess b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/.htaccess
deleted file mode 100644
index 00d12ab..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/.htaccess
+++ /dev/null
@@ -1,5 +0,0 @@
-<IfModule mod_rewrite.c>
- RewriteEngine on
- RewriteRule ^$ webroot/ [L]
- RewriteRule (.*) webroot/$1 [L]
- </IfModule> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_controller.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_controller.php
deleted file mode 100644
index 411f7f0..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_controller.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-/* SVN FILE: $Id: app_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * This file is application-wide controller file. You can put all
- * application-wide controller-related methods here.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Short description for class.
- *
- * Add your application-wide methods in the class below, your controllers
- * will inherit them.
- *
- * @package cake
- * @subpackage cake.app
- */
-class AppController extends Controller {
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_model.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_model.php
deleted file mode 100644
index 37eaecc..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/app_model.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-/* SVN FILE: $Id: app_model.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * Application model for Cake.
- *
- * This file is application-wide model file. You can put all
- * application-wide model-related methods here.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Application model for Cake.
- *
- * Add your application-wide methods in the class below, your models
- * will inherit them.
- *
- * @package cake
- * @subpackage cake.app
- */
-class AppModel extends Model{
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/bootstrap.php
deleted file mode 100644
index ef4cedf..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/bootstrap.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/* SVN FILE: $Id: bootstrap.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.10.8.2117
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- *
- * This file is loaded automatically by the app/webroot/index.php file after the core bootstrap.php is loaded
- * This is an application wide file to load any function that is not used within a class define.
- * You can also use this to include or require any files in your application.
- *
- */
-/**
- * The settings below can be used to set additional paths to models, views and controllers.
- * This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
- *
- * $modelPaths = array('full path to models', 'second full path to models', 'etc...');
- * $viewPaths = array('this path to views', 'second full path to views', 'etc...');
- * $controllerPaths = array('this path to controllers', 'second full path to controllers', 'etc...');
- *
- */
-//EOF
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/core.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/core.php
deleted file mode 100644
index 77cf1ff..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/core.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-/* SVN FILE: $Id: core.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * If you do not have mod rewrite on your system
- * or if you prefer to use CakePHP pretty urls.
- * uncomment the line below.
- * Note: If you do have mod rewrite but prefer the
- * CakePHP pretty urls, you also have to remove the
- * .htaccess files
- * release/.htaccess
- * release/app/.htaccess
- * release/app/webroot/.htaccess
- */
-// define ('BASE_URL', env('SCRIPT_NAME'));
-/**
- * Set debug level here:
- * - 0: production
- * - 1: development
- * - 2: full debug with sql
- * - 3: full debug with sql and dump of the current object
- *
- * In production, the "flash messages" redirect after a time interval.
- * With the other debug levels you get to click the "flash message" to continue.
- *
- */
- define('DEBUG', 1);
-/**
- * Turn of caching checking wide.
- * You must still use the controller var cacheAction inside you controller class.
- * You can either set it controller wide, or in each controller method.
- * use var $cacheAction = true; or in the controller method $this->cacheAction = true;
- */
- define('CACHE_CHECK', false);
-/**
- * Error constant. Used for differentiating error logging and debugging.
- * Currently PHP supports LOG_DEBUG
- */
- define('LOG_ERROR', 2);
-/**
- * CakePHP includes 3 types of session saves
- * database or file. Set this to your preferred method.
- * If you want to use your own save handler place it in
- * app/config/name.php DO NOT USE file or database as the name.
- * and use just the name portion below.
- *
- * Setting this to cake will save files to /cakedistro/tmp directory
- * Setting it to php will use the php default save path
- * Setting it to database will use the database
- *
- */
- define('CAKE_SESSION_SAVE', 'php');
-/**
- * If using you own table name for storing sessions
- * set the table name here.
- * DO NOT INCLUDE PREFIX IF YOU HAVE SET ONE IN database.php
- *
- */
- define('CAKE_SESSION_TABLE', 'cake_sessions');
-/**
- * Set a random string of used in session.
- *
- */
- define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
-/**
- * Set the name of session cookie
- *
- */
- define('CAKE_SESSION_COOKIE', 'CAKEPHP');
-/**
- * Set level of Cake security.
- *
- */
- define('CAKE_SECURITY', 'high');
-/**
- * Set Cake Session time out.
- * If CAKE_SECURITY define is set
- * high: multiplied by 10
- * medium: is multiplied by 100
- * low is: multiplied by 300
- *
- * Number below is seconds.
- */
- define('CAKE_SESSION_TIMEOUT', '120');
-/**
- * Uncomment the define below to use cake built in admin routes.
- * You can set this value to anything you want.
- * All methods related to the admin route should be prefixed with the
- * name you set CAKE_ADMIN to.
- * For example: admin_index, admin_edit
- */
-// define('CAKE_ADMIN', 'admin');
-/**
- * The define below is used to turn cake built webservices
- * on or off. Default setting is off.
- */
- define('WEBSERVICES', 'off');
-/**
- * Compress output CSS (removing comments, whitespace, repeating tags etc.)
- * This requires a/var/cache directory to be writable by the web server (caching).
- * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use Controller::cssTag().
- */
- define('COMPRESS_CSS', false);
-/**
- * If set to true, helpers would output data instead of returning it.
- */
- define('AUTO_OUTPUT', false);
-/**
- * If set to false, session would not automatically be started.
- */
- define('AUTO_SESSION', true);
-/**
- * Set the max size of file to use md5() .
- */
- define('MAX_MD5SIZE', (5 * 1024) * 1024);
-/**
- * To use Access Control Lists with Cake...
- */
- define('ACL_CLASSNAME', 'DB_ACL');
- define('ACL_FILENAME', 'dbacl' . DS . 'db_acl');
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/database.php.default b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/database.php.default
deleted file mode 100644
index fbbb1a3..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/database.php.default
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/* SVN FILE: $Id: database.php.default 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * In this file you set up your database connection details.
- *
- * @package cake
- * @subpackage cake.config
- */
-/**
- * Database configuration class.
- * You can specify multiple configurations for production, development and testing.
- *
- * driver =>
- * mysql, postgres, sqlite, adodb-drivername, pear-drivername
- *
- * connect =>
- * MySQL set the connect to either mysql_pconnect of mysql_connect
- * PostgreSQL set the connect to either pg_pconnect of pg_connect
- * SQLite set the connect to sqlite_popen sqlite_open
- * ADOdb set the connect to one of these
- * (http://phplens.com/adodb/supported.databases.html) and
- * append it '|p' for persistent connection. (mssql|p for example, or just mssql for not persistent)
- *
- * host =>
- * the host you connect to the database
- * MySQL 'localhost' to add a port number use 'localhost:port#'
- * PostgreSQL 'localhost' to add a port number use 'localhost port=5432'
- *
- */
-class DATABASE_CONFIG
-{
- var $default = array('driver' => 'mysql',
- 'connect' => 'mysql_connect',
- 'host' => 'localhost',
- 'login' => 'user',
- 'password' => 'password',
- 'database' => 'project_name',
- 'prefix' => '');
-
- var $test = array('driver' => 'mysql',
- 'connect' => 'mysql_connect',
- 'host' => 'localhost',
- 'login' => 'user',
- 'password' => 'password',
- 'database' => 'project_name-test',
- 'prefix' => '');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/inflections.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/inflections.php
deleted file mode 100644
index e08a7d8..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/inflections.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/* SVN FILE: $Id: inflections.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Custom Inflected Words.
- *
- * This file is used to hold words that are not matched in the normail Inflector::pluralize() and
- * Inflector::singularize()
- *
- * PHP versions 4 and %
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 1.0.0.2312
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * This is a key => value array of regex used to match words.
- * If key matches then the value is returned.
- *
- * $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
- */
- $pluralRules = array();
-/**
- * This is a key only array of plural words that should not be inflected.
- * Notice the last comma
- *
- * $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
- */
- $uninflectedPlural = array();
-/**
- * This is a key => value array of plural irregular words.
- * If key matches then the value is returned.
- *
- * $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
- */
- $irregularPlural = array();
-/**
- * This is a key => value array of regex used to match words.
- * If key matches then the value is returned.
- *
- * $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
- */
- $singularRules = array();
-/**
- * This is a key only array of singular words that should not be inflected.
- * You should not have to change this value below if you do change it use same format
- * as the $uninflectedPlural above.
- */
- $uninflectedSingular = $uninflectedPlural;
-/**
- * This is a key => value array of singular irregular words.
- * Most of the time this will be a reverse of the above $irregularPlural array
- * You should not have to change this value below if you do change it use same format
- *
- * $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
- */
- $irregularSingular = array_flip($irregularPlural);
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/routes.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/routes.php
deleted file mode 100644
index 45ae36a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/routes.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/* SVN FILE: $Id: routes.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * In this file, you set up routes to your controllers and their actions.
- * Routes are very important mechanism that allows you to freely connect
- * different urls to chosen controllers and their actions (functions).
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Here, we are connecting '/' (base path) to controller called 'Pages',
- * its action called 'display', and we pass a param to select the view file
- * to use (in this case, /app/views/pages/home.thtml)...
- */
- $Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
-/**
- * ...and connect the rest of 'Pages' controller's urls.
- */
- $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
-/**
- * Then we connect url '/test' to our test controller. This is helpfull in
- * developement.
- */
- $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index'));
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/db_acl.sql b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/db_acl.sql
deleted file mode 100644
index 8c7aae8..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/db_acl.sql
+++ /dev/null
@@ -1,30 +0,0 @@
-CREATE TABLE `acos` (
- `id` int(11) NOT NULL auto_increment,
- `model` varchar(255) NOT NULL default '',
- `object_id` int(11) default NULL,
- `alias` varchar(255) NOT NULL default '',
- `lft` int(11) default NULL,
- `rght` int(11) default NULL,
- PRIMARY KEY (`id`)
-);
-
-CREATE TABLE `aros` (
- `id` int(11) NOT NULL auto_increment,
- `model` varchar(255) NOT NULL default '',
- `user_id` int(11) default NULL,
- `alias` varchar(255) NOT NULL default '',
- `lft` int(11) default NULL,
- `rght` int(11) default NULL,
- PRIMARY KEY (`id`)
-);
-
-CREATE TABLE `aros_acos` (
- `id` int(11) NOT NULL auto_increment,
- `aro_id` int(11) default NULL,
- `aco_id` int(11) default NULL,
- `_create` int(1) NOT NULL default '0',
- `_read` int(1) NOT NULL default '0',
- `_update` int(1) NOT NULL default '0',
- `_delete` int(11) NOT NULL default '0',
- PRIMARY KEY (`id`)
-);
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/sessions.sql b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/sessions.sql
deleted file mode 100644
index 7166ae4..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/sql/sessions.sql
+++ /dev/null
@@ -1,11 +0,0 @@
--- @copyright Copyright 2005-2007, Cake Software Foundation, Inc.
--- @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
--- @since CakePHP v 0.10.8.1997
--- @version $Revision: 4409 $
-
-CREATE TABLE cake_sessions (
- id varchar(255) NOT NULL default '',
- data text,
- expires int(11) default NULL,
- PRIMARY KEY (id)
-); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/controllers/pages_controller.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/controllers/pages_controller.php
deleted file mode 100644
index b308565..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/controllers/pages_controller.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-/* SVN FILE: $Id: pages_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- * Short description for file.
- *
- * This file is application-wide controller file. You can put all
- * application-wide controller-related methods here.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.controllers
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-
-/**
- * Short description for class.
- *
- * This file is application-wide controller file. You can put all
- * application-wide controller-related methods here.
- *
- * Add your application-wide methods in the class below, your controllers
- * will inherit them.
- *
- * @package cake
- * @subpackage cake.app.controllers
- */
-class PagesController extends AppController{
-
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $name = 'Pages';
-
-/**
- * Enter description here...
- *
- * @var unknown_type
- */
- var $helpers = array('Html');
-
-/**
- * This controller does not use a model
- *
- * @var $uses
- */
- var $uses = null;
-
-/**
- * Displays a view
- *
- */
- function display() {
- if (!func_num_args()) {
- $this->redirect('/');
- }
-
- $path=func_get_args();
-
- if (!count($path)) {
- $this->redirect('/');
- }
-
- $count =count($path);
- $page =null;
- $subpage=null;
- $title =null;
-
- if (!empty($path[0])) {
- $page = $path[0];
- }
-
- if (!empty($path[1])) {
- $subpage = $path[1];
- }
-
- if (!empty($path[$count - 1])) {
- $title = ucfirst($path[$count - 1]);
- }
-
- $this->set('page', $page);
- $this->set('subpage', $subpage);
- $this->set('title', $title);
- $this->render(join('/', $path));
- }
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/index.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/index.php
deleted file mode 100644
index bd8993b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/index.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/ajax.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/ajax.thtml
deleted file mode 100644
index c6daffc..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/ajax.thtml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/* SVN FILE: $Id: ajax.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- *
- *
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.layouts
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<?php echo $content_for_layout; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/default.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/default.thtml
deleted file mode 100644
index 0172200..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/default.thtml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>CakePHP(tm) : <?php echo $title_for_layout;?></title>
-<link rel="icon" href="<?php echo $this->webroot . 'favicon.ico';?>" type="image/x-icon" />
-<link rel="shortcut icon" href="<?php echo $this->webroot . 'favicon.ico';?>" type="image/x-icon" />
-<?php echo $html->css('cake.generic');?>
-</head>
-<body>
- <div id="container">
- <div id="header">
- <h1>CakePHP Rapid Development</h1>
- </div>
- <div id="content">
- <?php if ($session->check('Message.flash'))
- {
- $session->flash();
- }
- echo $content_for_layout;
- ?>
- </div>
- <div id="footer">
- &nbsp;
- <a href="http://www.cakephp.org/" target="_new">
- <?php echo $html->image('cake.power.png', array('alt'=>"CakePHP(tm) : Rapid Development Framework", 'border'=>"0"));?>
- </a>
- </div>
- </div>
-</body>
-</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/flash.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/flash.thtml
deleted file mode 100644
index b1880c2..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/views/layouts/flash.thtml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/* SVN FILE: $Id: flash.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
-
-/**
- *
- *
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.cake.libs.view.templates.layouts
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title><?php echo $page_title?></title>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<?php if (Configure::read() == 0) { ?>
-<meta http-equiv="Refresh" content="<?php echo $pause?>;url=<?php echo $url?>"/>
-<?php } ?>
-<style><!--
-P { text-align:center; font:bold 1.1em sans-serif }
-A { color:#444; text-decoration:none }
-A:HOVER { text-decoration: underline; color:#44E }
---></style>
-</head>
-
-<body>
-
-<p><a href="<?php echo $url?>"><?php echo $message?></a></p>
-
-</body>
-</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/.htaccess b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/.htaccess
deleted file mode 100644
index 8ca27c0..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/.htaccess
+++ /dev/null
@@ -1,6 +0,0 @@
-<IfModule mod_rewrite.c>
- RewriteEngine On
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
-</IfModule> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css.php
deleted file mode 100644
index 23223a6..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-/* SVN FILE: $Id: css.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Enter description here...
- */
- require(CONFIGS . 'paths.php');
- require(CAKE . 'basics.php');
- require(LIBS . 'folder.php');
- require(LIBS . 'file.php');
- require(LIBS . 'legacy.php');
-/**
- * Enter description here...
- *
- * @param unknown_type $path
- * @param unknown_type $name
- * @return unknown
- */
- function make_clean_css($path, $name) {
- require(VENDORS . 'csspp' . DS . 'csspp.php');
- $data =file_get_contents($path);
- $csspp =new csspp();
- $output=$csspp->compress($data);
- $ratio =100 - (round(strlen($output) / strlen($data), 3) * 100);
- $output=" /* file: $name, ratio: $ratio% */ " . $output;
- return $output;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $path
- * @param unknown_type $content
- * @return unknown
- */
- function write_css_cache($path, $content) {
- if (!is_dir(dirname($path))) {
- mkdir(dirname($path));
- }
- $cache=new File($path);
- return $cache->write($content);
- }
-
- if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
- die('Wrong file name.');
- }
-
- $filename = 'css/' . $regs[1];
- $filepath = CSS . $regs[1];
- $cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
-
- if (!file_exists($filepath)) {
- die('Wrong file name.');
- }
-
- if (file_exists($cachepath)) {
- $templateModified=filemtime($filepath);
- $cacheModified =filemtime($cachepath);
-
- if ($templateModified > $cacheModified) {
- $output=make_clean_css($filepath, $filename);
- write_css_cache($cachepath, $output);
- } else {
- $output = file_get_contents($cachepath);
- }
- } else {
- $output=make_clean_css($filepath, $filename);
- write_css_cache($cachepath, $output);
- }
- header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT');
- header("Content-Type: text/css");
- header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
- header("Cache-Control: cache"); // HTTP/1.1
- header("Pragma: cache"); // HTTP/1.0
- print $output;
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css/cake.generic.css b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css/cake.generic.css
deleted file mode 100644
index 491dc7a..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/css/cake.generic.css
+++ /dev/null
@@ -1,251 +0,0 @@
-*{
-margin:0;
-padding:0;
-}
-
-body{
-font-family:"frutiger linotype","lucida grande",helvetica,arial,sans-serif;
-text-align:center;
-color:#333;
-font-size: 76%;
-}
-
-/* General Style Info */
-a{
-color:#003d4c;
-text-decoration:underline;
-}
-a:hover{
-color:#003d4c;
-text-decoration:none;
-}
-
-a img{
-border:none;
-}
-
-h1, h2, h3, h4{
-font-weight:normal;
-}
-
-h1{
-color: #003d4c;
-margin:0.3em 0;
-font-size: 180%;
-}
-
-h2{
-color:#c6c65b;
-padding-top: 1em;
-margin:0.3em 0;
-font-size: 180%;
-}
-
-h3{
-color:#c6c65b;
-padding-top:2em;
-font-size: 140%;
-}
-
-h4{
-color:#c6c65b;
-padding-top:0.5em;
-font-weight:normal;
-}
-
-em {
-font-size: 12px;
-}
-
-ul, li {
-margin: 0 12px;
-}
-
-/* Layout */
-
-#container{
-text-align:left;
-}
-
-#header{
-margin-top: 1em;
-padding: 4px 20px;
-}
-
-#content{
-clear:both;
-padding: 0px 40px 10px 40px;
-background-color: #fff;
-color: #333;
-}
-#footer{
-clear:both;
-padding: 6px 10px;
-text-align: right;
-}
-
-/* tables */
-
-table {
-width: 100%;
-border-top: 1px solid #ccc;
-border-left: 1px solid #ccc;
-border-bottom: 1px solid #ccc;
-color:#333;
-background-color: #fff;
-clear:both;
-padding: 0;
-margin: 0 0 2em 0;
-white-space: normal;
-}
-th {
-background-color: #e2e2e2;
-border-top: 1px solid #fff;
-border-left: 1px solid #fff;
-border-right: 1px solid #003d4c;
-border-bottom: 1px solid #003d4c;
-text-align: center;
-padding:1px 4px;
-}
-table tr td {
-border-right: 1px solid #ddd;
-padding:4px 4px;
-vertical-align:top;
-text-align: center;
-}
-table tr.altRow td {
-background: #f4f4f4;
-}
-table td.actions {
- white-space: nowrap;
-}
-#cakeSqlLog td {
-text-align: left;
-padding: 4px 8px;
-background: #fff;
-border-bottom: 2px solid #ccc;
-}
-
-/* scaffold show */
-
-div.related {
-clear:both;
-display:block;
-}
-dl {
-line-height:2em;
-margin:0em 1em;
-float:left;
-width: 400px;
-}
-dt {
-font-weight: bold;
-vertical-align:top;
-}
-dd {
-margin-left:10em;
-margin-top:-2em;
-vertical-align:top;
-}
-
-/* notices and errors */
-
-#flashMessage, .error, .error_message {
-color:#900;
-font-size: 16px;
-background-color: #fff;
-margin: 8px 0px;
-font-weight: bold;
-}
-.error_message {
-clear: both;
-}
-.error em {
-font-size: 18px;
-color: #003d4c;
-}
-.notice {
-color: #656565;
-font-size: 14px;
-background-color: #f4f4f4;
-padding: 0.5em;
-margin: 1em 0;
-display:block;
-}
-.tip {
-color: #656565;
-background-color: #ddd;
-}
-
-/* forms */
-
-form {
-margin-top: 2em;
-}
-form div{
-vertical-align: text-top;
-margin-left: 1em;
-margin-bottom:2em;
-}
-form div.date{
-margin-left: 0em;
-}
-label {
-display: block;
-float:left;
-width: 140px;
-font-size: 14px;
-padding-right: 20px;
-}
-input[type=checkbox] {
-float: left;
-clear: left;
-margin: 2px 6px 7px 2px;
-}
-input, textarea {
-clear: both;
-display:block;
-font-size: 14px;
-font-family: inherit;
-}
-select {
-clear: both;
-vertical-align: text-bottom;
-font-size: 14px;
-font-family: inherit;
-}
-option {
-font-size: 14px;
-font-family: inherit;
-padding: 0 0.3em;
-}
-input[type=submit] {
-display: inline;
-vertical-align: bottom;
-}
-div.required {
-clear: both;
-color:#222;
-font-weight:bold;
-}
-div.optional {
-clear: both;
-color:#555;
-}
-div.submit {
-clear: both;
-margin-top: 40px;
-margin-left: 140px;
-}
-/* action links */
-ul.actions {
-float: left;
-margin-left:20px;
-width: 200px;
-}
-ul.actions li {
-margin-top: 4px;
-}
-pre {
-padding: 1em;
-} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/favicon.ico b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/favicon.ico
deleted file mode 100644
index 1bc32bd..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/img/cake.power.png b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/img/cake.power.png
deleted file mode 100644
index 699ef80..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/img/cake.power.png
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/index.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/index.php
deleted file mode 100644
index 6874e2b..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/index.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Do not change
- */
- if (!defined('DS')) {
- define('DS', DIRECTORY_SEPARATOR);
- }
-/**
- * These defines should only be edited if you have cake installed in
- * a directory layout other than the way it is distributed.
- * Each define has a commented line of code that explains what you would change.
- *
- */
- if (!defined('ROOT')) {
- //define('ROOT', 'FULL PATH TO DIRECTORY WHERE APP DIRECTORY IS LOCATED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
- //You should also use the DS define to seperate your directories
- define('ROOT', dirname(dirname(dirname(__FILE__))));
- }
- if (!defined('APP_DIR')) {
- //define('APP_DIR', 'DIRECTORY NAME OF APPLICATION';
- define('APP_DIR', basename(dirname(dirname(__FILE__))));
- }
-/**
- * This only needs to be changed if the cake installed libs are located
- * outside of the distributed directory structure.
- */
- if (!defined('CAKE_CORE_INCLUDE_PATH')) {
- //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
- //You should also use the DS define to seperate your directories
- define('CAKE_CORE_INCLUDE_PATH', ROOT);
- }
-///////////////////////////////
-//DO NOT EDIT BELOW THIS LINE//
-///////////////////////////////
- if (!defined('WEBROOT_DIR')) {
- define('WEBROOT_DIR', basename(dirname(__FILE__)));
- }
- if (!defined('WWW_ROOT')) {
- define('WWW_ROOT', dirname(__FILE__) . DS);
- }
- if (!defined('CORE_PATH')) {
- if (function_exists('ini_set')) {
- ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'));
- define('APP_PATH', null);
- define('CORE_PATH', null);
- } else {
- define('APP_PATH', ROOT . DS . APP_DIR . DS);
- define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
- }
- }
- require CORE_PATH . 'cake' . DS . 'bootstrap.php';
- if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
- } else {
- $Dispatcher = new Dispatcher();
- $Dispatcher->dispatch($url);
- }
- if (Configure::read() > 0) {
- echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
- }
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/js/vendors.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/js/vendors.php
deleted file mode 100644
index 1075bfb..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/webroot/js/vendors.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-/* SVN FILE: $Id: vendors.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * This file includes js vendor-files from /vendor/ directory if they need to
- * be accessible to the public.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot.js
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Enter description here...
- */
-$file = $_GET['file'];
-$pos = strpos($file, '..');
-if ($pos === false) {
- if (is_file('../../vendors/javascript/'.$file) && (preg_match('/(\/.+)\\.js/', $file)))
- {
- readfile('../../vendors/javascript/'.$file);
- }
-} else {
- header('HTTP/1.1 404 Not Found');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/views/home.thtml b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/views/home.thtml
deleted file mode 100644
index d107e55..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/views/home.thtml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-$output = "<p class=\"notice\">Your database configuration file is <?php echo file_exists(CONFIGS.'database.php') ?' present.' . \$filePresent = ' ' : ' not present.'; ?></p>\n";
-$output .= "<?php if (!empty(\$filePresent)):?>\n";
-$output .= "<?php uses('model' . DS . 'connection_manager'); \$db = ConnectionManager::getInstance(); ?>\n";
-$output .= "<?php \$connected = \$db->getDataSource('default'); ?>\n";
-$output .= "<p class=\"notice\">Cake<?php echo \$connected->isConnected() ? ' is able to' : ' is not able to';?> connect to the database.</p>\n";
-$output .= "<br />\n";
-$output .= "<?php endif; ?>\n";
-$output .= "<h1>Sweet, \"".Inflector::humanize($app)."\" got Baked by CakePHP!</h1>\n";
-$output .= "<h2>Editing this Page</h2>\n";
-$output .= "<p>\n";
-$output .= "To change the content of this page, edit: ".$dir.DS."views".DS."pages".DS."home.thtml.<br />\n";
-$output .= "To change its layout, edit: ".$dir.DS."views".DS."layouts".DS."default.thtml.<br />\n";
-$output .= "You can also add some CSS styles for your pages at: ".$dir.DS."webroot/css/.\n";
-$output .= "</p>\n";
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/CHANGELOG.txt b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/CHANGELOG.txt
deleted file mode 100644
index 7d1e628..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/CHANGELOG.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// +---------------------------------------------------------------------------------------------------+//
-// + $Id: CHANGELOG.txt 4064 2006-12-04 05:29:12Z phpnut $
-// + Last Modified: $Date: 2006-12-04 00:29:12 -0500 (Mon, 04 Dec 2006) $
-// + Modified By: $LastChangedBy: phpnut $
-// +---------------------------------------------------------------------------------------------------+//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-Changelog:
-https://trac.cakephp.org/wiki/changelog/1.1.x.x
-
-Release Notes:
-https://trac.cakephp.org/wiki/notes/1.1.x.x \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/COPYING.txt b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/COPYING.txt
deleted file mode 100644
index 4787242..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/COPYING.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-The MIT License
-
-CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
-Copyright 2005-2007, Cake Software Foundation, Inc.
- 1785 E. Sahara Avenue, Suite 490-204
- Las Vegas, Nevada 89104
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/INSTALL.txt b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/INSTALL.txt
deleted file mode 100644
index 47698fc..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/INSTALL.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// +---------------------------------------------------------------------------------------------------+//
-// + $Id: INSTALL.txt 4409 2007-02-02 13:20:59Z phpnut $
-// + Last Modified: $Date: 2007-02-02 08:20:59 -0500 (Fri, 02 Feb 2007) $
-// + Modified By: $LastChangedBy: phpnut $
-// +---------------------------------------------------------------------------------------------------+//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-In order use CakePHP you must first have a server that has all the required libraries and programs to run CakePHP:
-
-Here are the requirements for setting up a server to run CakePHP:
-
- 1. An HTTP server (like Apache) with the following enabled.
- 2. PHP 4.3.2 or greater. Yes, CakePHP works great in either PHP 4 or 5.
- 3. A database engine (right now, there is support for MySQL, MsSQL, Oracle, Sqlite, PostgreSQL and a wrapper for ADODB).
-
-For development we can place the whole Cake installation directory inside the specified DocumentRoot.
-
- 1. Unpack latest distribution in your DocumentRoot.
- 2. Rename the directory to anything you like.
- 3. Access the install.
- a. If mod_rewrite is working then http://www.example.com/my_directory
- 1. If you receive a "Bad Request" add the trailing slash, http://www.example.com/my_directory/
- 4. If mod_rewrite is not working you will need to remove the comment from app/config/core.php
- a. Around line 40: define ('BASE_URL', env('SCRIPT_NAME'));
- b. Then access using http://www.example.com/my_directory/index.php/pages to verify installation is working
-
-For more information on installation see http://manual.cakephp.org/chapter/installing
-
-Good resources for help.
-* The Bakery :: Everything CakePHP (http://bakery.cakephp.org/)
-* CakePHP Manual :: Your Rapid Development Cookbook (http://manual.cakephp.org/)
-* CakePHP API :: Docblock Your Best Friend (http://api.cakephp.org/)
-* CakePHP Google Group :: Community mailing list (http://groups-beta.google.com/group/cake-php)
-* CakePHP(tm) :: The Rapid Development Framework (http://www.cakephp.org/)
-* CakeForge :: Open Development for CakePHP (http://cakeforge.org/)
-* CakePHP Trac :: For the Development of CakePHP (Tickets, SVN browser, Roadmap, Changelogs) (https://trac.cakephp.org/)
-* Live chat about CakePHP (irc.freenode.net #cakephp)
- Web Interface to IRC (http://irc.cakephp.org/irc.htm) \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/README.txt b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/README.txt
deleted file mode 100644
index 234e171..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/docs/README.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// +---------------------------------------------------------------------------------------------------+//
-// + $Id: README.txt 4064 2006-12-04 05:29:12Z phpnut $
-// + Last Modified: $Date: 2006-12-04 00:29:12 -0500 (Mon, 04 Dec 2006) $
-// + Modified By: $LastChangedBy: phpnut $
-// +---------------------------------------------------------------------------------------------------+//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-This README will be updated
-
-Home:
-http://www.cakephp.org/
-
-Documentation
-http://manual.cakephp.org/
-
-Development:
-https://trac.cakephp.org/
-
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/index.php b/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/index.php
deleted file mode 100644
index e78de13..0000000
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/index.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Requests collector.
- *
- * This file collects requests if:
- * - no mod_rewrite is avilable or .htaccess files are not supported
- * -/public is not set as a web root.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Get Cake's root directory
- */
- define('APP_DIR', 'app');
- define('DS', DIRECTORY_SEPARATOR);
- define('ROOT', dirname(__FILE__));
- define('WEBROOT_DIR', 'webroot');
- define('WWW_ROOT', ROOT . DS . APP_DIR . DS . WEBROOT_DIR . DS);
-/**
- * This only needs to be changed if the cake installed libs are located
- * outside of the distributed directory structure.
- */
- if (!defined('CAKE_CORE_INCLUDE_PATH')) {
- //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
- define('CAKE_CORE_INCLUDE_PATH', ROOT);
- }
- if (function_exists('ini_set')) {
- ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS);
- define('APP_PATH', null);
- define('CORE_PATH', null);
- } else {
- define('APP_PATH', ROOT . DS . APP_DIR . DS);
- define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
- }
- require CORE_PATH . 'cake' . DS . 'basics.php';
- require APP_PATH . 'config' . DS . 'core.php';
- require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
- $bootstrap=true;
- $uri =setUri();
-/**
- * As mod_rewrite (or .htaccess files) is not working, we need to take care
- * of what would normally be rewritten, i.e. the static files in app/webroot/
- */
- if ($uri === '/' || $uri === '/index.php') {
- $_GET['url'] = '/';
- require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
- } else {
- $elements=explode('/index.php', $uri);
-
- if (!empty($elements[1])) {
- $path = $elements[1];
- } else {
- $path = '/';
- }
- $_GET['url']=$path;
- require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
- }
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.gitignore b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.gitignore
new file mode 100644
index 0000000..de4f6ff
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.gitignore
@@ -0,0 +1,9 @@
+/app/Config
+/app/tmp
+/lib/Cake/Console/Templates/skel/tmp/
+/plugins
+/vendors
+/build
+/dist
+.DS_Store
+/tags
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/.htaccess b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.htaccess
index f23dbaf..f23dbaf 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/.htaccess
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.htaccess
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.travis.yml b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.travis.yml
new file mode 100644
index 0000000..5af60d8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/.travis.yml
@@ -0,0 +1,111 @@
+language: php
+
+php:
+ - 5.2
+ - 5.3
+ - 5.4
+
+env:
+ - DB=mysql
+ - DB=pgsql
+ - DB=sqlite
+
+before_script:
+ - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi"
+ - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test2;'; fi"
+ - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test3;'; fi"
+ - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi"
+ - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE SCHEMA test2;' -U postgres -d cakephp_test; fi"
+ - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE SCHEMA test3;' -U postgres -d cakephp_test; fi"
+ - chmod -R 777 ./app/tmp
+ - echo "var net = require('net');
+ var server = net.createServer();
+ server.listen(80, 'localhost');
+ console.log('TCP server listening on port 80 at localhost.');" > app/tmp/socket.js
+ - sudo node ./app/tmp/socket.js &
+ - set +H
+ - echo "<?php
+ class DATABASE_CONFIG {
+ private \$identities = array(
+ 'mysql' => array(
+ 'datasource' => 'Database/Mysql',
+ 'host' => '0.0.0.0',
+ 'login' => 'travis'
+ ),
+ 'pgsql' => array(
+ 'datasource' => 'Database/Postgres',
+ 'host' => '127.0.0.1',
+ 'login' => 'postgres',
+ 'database' => 'cakephp_test',
+ 'schema' => array(
+ 'default' => 'public',
+ 'test' => 'public',
+ 'test2' => 'test2',
+ 'test_database_three' => 'test3'
+ )
+ ),
+ 'sqlite' => array(
+ 'datasource' => 'Database/Sqlite',
+ 'database' => array(
+ 'default' => ':memory:',
+ 'test' => ':memory:',
+ 'test2' => '/tmp/cakephp_test2.db',
+ 'test_database_three' => '/tmp/cakephp_test3.db'
+ ),
+ )
+ );
+ public \$default = array(
+ 'persistent' => false,
+ 'host' => '',
+ 'login' => '',
+ 'password' => '',
+ 'database' => 'cakephp_test',
+ 'prefix' => ''
+ );
+ public \$test = array(
+ 'persistent' => false,
+ 'host' => '',
+ 'login' => '',
+ 'password' => '',
+ 'database' => 'cakephp_test',
+ 'prefix' => ''
+ );
+ public \$test2 = array(
+ 'persistent' => false,
+ 'host' => '',
+ 'login' => '',
+ 'password' => '',
+ 'database' => 'cakephp_test2',
+ 'prefix' => ''
+ );
+ public \$test_database_three = array(
+ 'persistent' => false,
+ 'host' => '',
+ 'login' => '',
+ 'password' => '',
+ 'database' => 'cakephp_test3',
+ 'prefix' => ''
+ );
+ public function __construct() {
+ \$db = 'mysql';
+ if (!empty(\$_SERVER['DB'])) {
+ \$db = \$_SERVER['DB'];
+ }
+ foreach (array('default', 'test', 'test2', 'test_database_three') as \$source) {
+ \$config = array_merge(\$this->{\$source}, \$this->identities[\$db]);
+ if (is_array(\$config['database'])) {
+ \$config['database'] = \$config['database'][\$source];
+ }
+ if (!empty(\$config['schema']) && is_array(\$config['schema'])) {
+ \$config['schema'] = \$config['schema'][\$source];
+ }
+ \$this->{\$source} = \$config;
+ }
+ }
+ }" > app/Config/database.php
+
+script:
+ - ./lib/Cake/Console/cake test core AllTests --stderr
+
+notifications:
+ email: false \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/README b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/README
new file mode 100644
index 0000000..ddf4202
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/README
@@ -0,0 +1,28 @@
+CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC. Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.
+
+The Cake Software Foundation - promoting development related to CakePHP
+http://cakefoundation.org/
+
+CakePHP - the rapid development PHP framework
+http://www.cakephp.org
+
+Cookbook - user documentation for learning about CakePHP
+http://book.cakephp.org
+
+API - quick reference to CakePHP
+http://api.cakephp.org
+
+The Bakery - everything CakePHP
+http://bakery.cakephp.org
+
+The Show - live and archived podcasts about CakePHP and more
+http://live.cakephp.org
+
+CakePHP TV - screen casts from events and video tutorials
+http://tv.cakephp.org
+
+CakePHP Google Group - community mailing list and forum
+http://groups.google.com/group/cake-php
+
+#cakephp on irc.freenode.net - chat with CakePHP developers
+irc://irc.freenode.net/cakephp
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/.htaccess b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/.htaccess
index 0ed8662..fc3aac4 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/.htaccess
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/.htaccess
@@ -2,4 +2,4 @@
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
- </IfModule> \ No newline at end of file
+</IfModule> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.php
new file mode 100644
index 0000000..149ded0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * This is Acl Schema file
+ *
+ * Use it to configure database for ACL
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config.Schema
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create DbAcl
+ *
+ */
+class DbAclSchema extends CakeSchema {
+
+ public $name = 'DbAcl';
+
+ public function before($event = array()) {
+ return true;
+ }
+
+ public function after($event = array()) {
+ }
+
+ public $acos = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'alias' => array('type' => 'string', 'null' => true),
+ 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+ public $aros = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'alias' => array('type' => 'string', 'null' => true),
+ 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+ public $aros_acos = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'aro_id' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
+ 'aco_id' => array('type' => 'integer', 'null' => false, 'length' => 10),
+ '_create' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ '_read' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ '_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ '_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1))
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.sql b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.sql
new file mode 100644
index 0000000..f50f392
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/db_acl.sql
@@ -0,0 +1,40 @@
+# $Id$
+#
+# Copyright 2005-2012, Cake Software Foundation, Inc.
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+CREATE TABLE acos (
+ id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ parent_id INTEGER(10) DEFAULT NULL,
+ model VARCHAR(255) DEFAULT '',
+ foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
+ alias VARCHAR(255) DEFAULT '',
+ lft INTEGER(10) DEFAULT NULL,
+ rght INTEGER(10) DEFAULT NULL,
+ PRIMARY KEY (id)
+);
+
+CREATE TABLE aros_acos (
+ id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ aro_id INTEGER(10) UNSIGNED NOT NULL,
+ aco_id INTEGER(10) UNSIGNED NOT NULL,
+ _create CHAR(2) NOT NULL DEFAULT 0,
+ _read CHAR(2) NOT NULL DEFAULT 0,
+ _update CHAR(2) NOT NULL DEFAULT 0,
+ _delete CHAR(2) NOT NULL DEFAULT 0,
+ PRIMARY KEY(id)
+);
+
+CREATE TABLE aros (
+ id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ parent_id INTEGER(10) DEFAULT NULL,
+ model VARCHAR(255) DEFAULT '',
+ foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
+ alias VARCHAR(255) DEFAULT '',
+ lft INTEGER(10) DEFAULT NULL,
+ rght INTEGER(10) DEFAULT NULL,
+ PRIMARY KEY (id)
+); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.php
new file mode 100644
index 0000000..8de0052
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * This is i18n Schema file
+ *
+ * Use it to configure database for i18n
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config.Schema
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create i18n
+ *
+ */
+class i18nSchema extends CakeSchema {
+
+ public $name = 'i18n';
+
+ public function before($event = array()) {
+ return true;
+ }
+
+ public function after($event = array()) {
+ }
+
+ public $i18n = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'locale' => array('type' => 'string', 'null' => false, 'length' => 6, 'key' => 'index'),
+ 'model' => array('type' => 'string', 'null' => false, 'key' => 'index'),
+ 'foreign_key' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
+ 'field' => array('type' => 'string', 'null' => false, 'key' => 'index'),
+ 'content' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'locale' => array('column' => 'locale', 'unique' => 0), 'model' => array('column' => 'model', 'unique' => 0), 'row_id' => array('column' => 'foreign_key', 'unique' => 0), 'field' => array('column' => 'field', 'unique' => 0))
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.sql b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.sql
new file mode 100644
index 0000000..239e146
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/i18n.sql
@@ -0,0 +1,26 @@
+# $Id$
+#
+# Copyright 2005-2012, Cake Software Foundation, Inc.
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+CREATE TABLE i18n (
+ id int(10) NOT NULL auto_increment,
+ locale varchar(6) NOT NULL,
+ model varchar(255) NOT NULL,
+ foreign_key int(10) NOT NULL,
+ field varchar(255) NOT NULL,
+ content mediumtext,
+ PRIMARY KEY (id),
+# UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
+# INDEX I18N_LOCALE_ROW(locale, model, foreign_key),
+# INDEX I18N_LOCALE_MODEL(locale, model),
+# INDEX I18N_FIELD(model, foreign_key, field),
+# INDEX I18N_ROW(model, foreign_key),
+ INDEX locale (locale),
+ INDEX model (model),
+ INDEX row_id (foreign_key),
+ INDEX field (field)
+); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/sessions.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/sessions.php
new file mode 100644
index 0000000..e98ca06
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/sessions.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * This is Sessions Schema file
+ *
+ * Use it to configure database for Sessions
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config.Schema
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create Sessions
+ *
+ */
+class SessionsSchema extends CakeSchema {
+
+ public $name = 'Sessions';
+
+ public function before($event = array()) {
+ return true;
+ }
+
+ public function after($event = array()) {
+ }
+
+ public $cake_sessions = array(
+ 'id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
+ 'data' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'expires' => array('type' => 'integer', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/sql/sessions.sql b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/sessions.sql
index 14c0036..b8951b6 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/sql/sessions.sql
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/Schema/sessions.sql
@@ -1,12 +1,12 @@
-# $Id: sessions.sql 6305 2008-01-02 02:33:56Z phpnut $
+# $Id$
#
-# Copyright 2005-2008, Cake Software Foundation, Inc.
+# Copyright 2005-2012, Cake Software Foundation, Inc.
# 1785 E. Sahara Avenue, Suite 490-204
# Las Vegas, Nevada 89104
#
# Licensed under The MIT License
# Redistributions of files must retain the above copyright notice.
-# http://www.opensource.org/licenses/mit-license.php The MIT License
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE cake_sessions (
id varchar(255) NOT NULL default '',
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/acl.ini.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/acl.ini.php
index 8179591..11ce65b 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/scripts/templates/skel/config/acl.ini.php
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/acl.ini.php
@@ -1,29 +1,21 @@
-;<?php die() ?>
-; SVN FILE: $Id: acl.ini.php 6305 2008-01-02 02:33:56Z phpnut $
+;<?php exit() ?>
;/**
-; * Short description for file.
+; * ACL Configuration
; *
; *
-; * PHP versions 4 and 5
+; * PHP 5
; *
-; * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
-; * Copyright 2005-2008, Cake Software Foundation, Inc.
-; * 1785 E. Sahara Avenue, Suite 490-204
-; * Las Vegas, Nevada 89104
+; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
; *
; * Licensed under The MIT License
; * Redistributions of files must retain the above copyright notice.
; *
-; * @filesource
-; * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
-; * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
-; * @package cake
-; * @subpackage cake.app.config
-; * @since CakePHP(tm) v 0.10.0.1076
-; * @version $Revision: 6305 $
-; * @modifiedby $LastChangedBy: phpnut $
-; * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
-; * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+; * @link http://cakephp.org CakePHP(tm) Project
+; * @package app.Config
+; * @since CakePHP(tm) v 0.10.0.1076
+; * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
; */
; acl.ini.php - Cake ACL Configuration
@@ -73,4 +65,4 @@ allow = aco3, aco4
[groupname-goes-here]
deny = aco5, aco6
-allow = aco7, aco8 \ No newline at end of file
+allow = aco7, aco8
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/acl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/acl.php
new file mode 100644
index 0000000..21f8dda
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/acl.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * This is the PHP base ACL configuration file.
+ *
+ * Use it to configure access control of your Cake application.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Example
+ * -------
+ *
+ * Assumptions:
+ *
+ * 1. In your application you created a User model with the following properties:
+ * username, group_id, password, email, firstname, lastname and so on.
+ * 2. You configured AuthComponent to authorize actions via
+ * $this->Auth->authorize = array('Actions' => array('actionPath' => 'controllers/'),...)
+ *
+ * Now, when a user (i.e. jeff) authenticates successfully and requests a controller action (i.e. /invoices/delete)
+ * that is not allowed by default (e.g. via $this->Auth->allow('edit') in the Invoices controller) then AuthComponent
+ * will ask the configured ACL interface if access is granted. Under the assumptions 1. and 2. this will be
+ * done via a call to Acl->check() with
+ *
+ * array('User' => array('username' => 'jeff', 'group_id' => 4, ...))
+ *
+ * as ARO and
+ *
+ * '/controllers/invoices/delete'
+ *
+ * as ACO.
+ *
+ * If the configured map looks like
+ *
+ * $config['map'] = array(
+ * 'User' => 'User/username',
+ * 'Role' => 'User/group_id',
+ * );
+ *
+ * then PhpAcl will lookup if we defined a role like User/jeff. If that role is not found, PhpAcl will try to
+ * find a definition for Role/4. If the definition isn't found then a default role (Role/default) will be used to
+ * check rules for the given ACO. The search can be expanded by defining aliases in the alias configuration.
+ * E.g. if you want to use a more readable name than Role/4 in your definitions you can define an alias like
+ *
+ * $config['alias'] = array(
+ * 'Role/4' => 'Role/editor',
+ * );
+ *
+ * In the roles configuration you can define roles on the lhs and inherited roles on the rhs:
+ *
+ * $config['roles'] = array(
+ * 'Role/admin' => null,
+ * 'Role/accountant' => null,
+ * 'Role/editor' => null,
+ * 'Role/manager' => 'Role/editor, Role/accountant',
+ * 'User/jeff' => 'Role/manager',
+ * );
+ *
+ * In this example manager inherits all rules from editor and accountant. Role/admin doesn't inherit from any role.
+ * Lets define some rules:
+ *
+ * $config['rules'] = array(
+ * 'allow' => array(
+ * '*' => 'Role/admin',
+ * 'controllers/users/(dashboard|profile)' => 'Role/default',
+ * 'controllers/invoices/*' => 'Role/accountant',
+ * 'controllers/articles/*' => 'Role/editor',
+ * 'controllers/users/*' => 'Role/manager',
+ * 'controllers/invoices/delete' => 'Role/manager',
+ * ),
+ * 'deny' => array(
+ * 'controllers/invoices/delete' => 'Role/accountant, User/jeff',
+ * 'controllers/articles/(delete|publish)' => 'Role/editor',
+ * ),
+ * );
+ *
+ * Ok, so as jeff inherits from Role/manager he's matched every rule that references User/jeff, Role/manager,
+ * Role/editor, Role/accountant and Role/default. However, for jeff, rules for User/jeff are more specific than
+ * rules for Role/manager, rules for Role/manager are more specific than rules for Role/editor and so on.
+ * This is important when allow and deny rules match for a role. E.g. Role/accountant is allowed
+ * controllers/invoices/* but at the same time controllers/invoices/delete is denied. But there is a more
+ * specific rule defined for Role/manager which is allowed controllers/invoices/delete. However, the most specific
+ * rule denies access to the delete action explicitly for User/jeff, so he'll be denied access to the resource.
+ *
+ * If we would remove the role definition for User/jeff, then jeff would be granted access as he would be resolved
+ * to Role/manager and Role/manager has an allow rule.
+ */
+
+/**
+ * The role map defines how to resolve the user record from your application
+ * to the roles you defined in the roles configuration.
+ */
+$config['map'] = array(
+ 'User' => 'User/username',
+ 'Role' => 'User/group_id',
+);
+
+/**
+ * define aliases to map your model information to
+ * the roles defined in your role configuration.
+ */
+$config['alias'] = array(
+ 'Role/4' => 'Role/editor',
+);
+
+/**
+ * role configuration
+ */
+$config['roles'] = array(
+ 'Role/admin' => null,
+);
+
+/**
+ * rule configuration
+ */
+$config['rules'] = array(
+ 'allow' => array(
+ '*' => 'Role/admin',
+ ),
+ 'deny' => array(),
+);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/bootstrap.php
new file mode 100644
index 0000000..bcc50f6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/bootstrap.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * This file is loaded automatically by the app/webroot/index.php file after core.php
+ *
+ * This file should load/create any application wide configuration settings, such as
+ * Caching, Logging, loading additional configuration files.
+ *
+ * You should also use this file to include any files that provide global functions/constants
+ * that your application uses.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.10.8.2117
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Cache Engine Configuration
+ * Default settings provided below
+ *
+ * File storage engine.
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'File', //[required]
+ * 'duration'=> 3600, //[optional]
+ * 'probability'=> 100, //[optional]
+ * 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
+ * 'prefix' => 'cake_', //[optional] prefix every cache file with this string
+ * 'lock' => false, //[optional] use file locking
+ * 'serialize' => true, // [optional]
+ * 'mask' => 0666, // [optional] permission mask to use when creating cache files
+ * ));
+ *
+ * APC (http://pecl.php.net/package/APC)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Apc', //[required]
+ * 'duration'=> 3600, //[optional]
+ * 'probability'=> 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * ));
+ *
+ * Xcache (http://xcache.lighttpd.net/)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Xcache', //[required]
+ * 'duration'=> 3600, //[optional]
+ * 'probability'=> 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * 'user' => 'user', //user from xcache.admin.user settings
+ * 'password' => 'password', //plaintext password (xcache.admin.pass)
+ * ));
+ *
+ * Memcache (http://memcached.org/)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Memcache', //[required]
+ * 'duration'=> 3600, //[optional]
+ * 'probability'=> 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * 'servers' => array(
+ * '127.0.0.1:11211' // localhost, default port 11211
+ * ), //[optional]
+ * 'persistent' => true, // [optional] set this to false for non-persistent connections
+ * 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
+ * ));
+ *
+ * Wincache (http://php.net/wincache)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Wincache', //[required]
+ * 'duration'=> 3600, //[optional]
+ * 'probability'=> 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * ));
+ *
+ * Redis (http://http://redis.io/)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Redis', //[required]
+ * 'duration'=> 3600, //[optional]
+ * 'probability'=> 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * 'server' => '127.0.0.1' // localhost
+ * 'port' => 6379 // default port 6379
+ * 'timeout' => 0 // timeout in seconds, 0 = unlimited
+ * 'persistent' => true, // [optional] set this to false for non-persistent connections
+ * ));
+ */
+Cache::config('default', array('engine' => 'File'));
+
+/**
+ * The settings below can be used to set additional paths to models, views and controllers.
+ *
+ * App::build(array(
+ * 'Model' => array('/path/to/models', '/next/path/to/models'),
+ * 'Model/Behavior' => array('/path/to/behaviors', '/next/path/to/behaviors'),
+ * 'Model/Datasource' => array('/path/to/datasources', '/next/path/to/datasources'),
+ * 'Model/Datasource/Database' => array('/path/to/databases', '/next/path/to/database'),
+ * 'Model/Datasource/Session' => array('/path/to/sessions', '/next/path/to/sessions'),
+ * 'Controller' => array('/path/to/controllers', '/next/path/to/controllers'),
+ * 'Controller/Component' => array('/path/to/components', '/next/path/to/components'),
+ * 'Controller/Component/Auth' => array('/path/to/auths', '/next/path/to/auths'),
+ * 'Controller/Component/Acl' => array('/path/to/acls', '/next/path/to/acls'),
+ * 'View' => array('/path/to/views', '/next/path/to/views'),
+ * 'View/Helper' => array('/path/to/helpers', '/next/path/to/helpers'),
+ * 'Console' => array('/path/to/consoles', '/next/path/to/consoles'),
+ * 'Console/Command' => array('/path/to/commands', '/next/path/to/commands'),
+ * 'Console/Command/Task' => array('/path/to/tasks', '/next/path/to/tasks'),
+ * 'Lib' => array('/path/to/libs', '/next/path/to/libs'),
+ * 'Locale' => array('/path/to/locales', '/next/path/to/locales'),
+ * 'Vendor' => array('/path/to/vendors', '/next/path/to/vendors'),
+ * 'Plugin' => array('/path/to/plugins', '/next/path/to/plugins'),
+ * ));
+ *
+ */
+
+/**
+ * Custom Inflector rules, can be set to correctly pluralize or singularize table, model, controller names or whatever other
+ * string is passed to the inflection functions
+ *
+ * Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
+ * Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
+ *
+ */
+
+/**
+ * Plugins need to be loaded manually, you can either load them one by one or all of them in a single call
+ * Uncomment one of the lines below, as you need. make sure you read the documentation on CakePlugin to use more
+ * advanced ways of loading plugins
+ *
+ * CakePlugin::loadAll(); // Loads all plugins at once
+ * CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit
+ *
+ */
+
+
+/**
+ * You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters:
+ *
+ * - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins
+ * - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers
+ *
+ * Feel free to remove or add filters as you see fit for your application. A few examples:
+ *
+ * Configure::write('Dispatcher.filters', array(
+ * 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app.
+ * 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin.
+ * array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch
+ * array('callable' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch
+ *
+ * ));
+ */
+Configure::write('Dispatcher.filters', array(
+ 'AssetDispatcher',
+ 'CacheDispatcher'
+));
+
+/**
+ * Configures default file logging options
+ */
+App::uses('CakeLog', 'Log');
+CakeLog::config('debug', array(
+ 'engine' => 'FileLog',
+ 'types' => array('notice', 'info', 'debug'),
+ 'file' => 'debug',
+));
+CakeLog::config('error', array(
+ 'engine' => 'FileLog',
+ 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
+ 'file' => 'error',
+));
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/core.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/core.php
new file mode 100644
index 0000000..4bbfabe
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/core.php
@@ -0,0 +1,278 @@
+<?php
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behavior of Cake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * CakePHP Debug Level:
+ *
+ * Production Mode:
+ * 0: No error messages, errors, or warnings shown. Flash messages redirect.
+ *
+ * Development Mode:
+ * 1: Errors and warnings shown, model caches refreshed, flash messages halted.
+ * 2: As in 1, but also with full debug messages and SQL output.
+ *
+ * In production mode, flash messages redirect after a time interval.
+ * In development mode, you need to click the flash message to continue.
+ */
+ Configure::write('debug', 2);
+
+/**
+ * Configure the Error handler used to handle errors for your application. By default
+ * ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0
+ * and log errors with CakeLog when debug = 0.
+ *
+ * Options:
+ *
+ * - `handler` - callback - The callback to handle errors. You can set this to any callable type,
+ * including anonymous functions.
+ * - `level` - int - The level of errors you are interested in capturing.
+ * - `trace` - boolean - Include stack traces for errors in log files.
+ *
+ * @see ErrorHandler for more information on error handling and configuration.
+ */
+ Configure::write('Error', array(
+ 'handler' => 'ErrorHandler::handleError',
+ 'level' => E_ALL & ~E_DEPRECATED,
+ 'trace' => true
+ ));
+
+/**
+ * Configure the Exception handler used for uncaught exceptions. By default,
+ * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and
+ * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0,
+ * framework errors will be coerced into generic HTTP errors.
+ *
+ * Options:
+ *
+ * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type,
+ * including anonymous functions.
+ * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you
+ * should place the file for that class in app/Lib/Error. This class needs to implement a render method.
+ * - `log` - boolean - Should Exceptions be logged?
+ *
+ * @see ErrorHandler for more information on exception handling and configuration.
+ */
+ Configure::write('Exception', array(
+ 'handler' => 'ErrorHandler::handleException',
+ 'renderer' => 'ExceptionRenderer',
+ 'log' => true
+ ));
+
+/**
+ * Application wide charset encoding
+ */
+ Configure::write('App.encoding', 'UTF-8');
+
+/**
+ * To configure CakePHP *not* to use mod_rewrite and to
+ * use CakePHP pretty URLs, remove these .htaccess
+ * files:
+ *
+ * /.htaccess
+ * /app/.htaccess
+ * /app/webroot/.htaccess
+ *
+ * And uncomment the App.baseUrl below:
+ */
+ //Configure::write('App.baseUrl', env('SCRIPT_NAME'));
+
+/**
+ * Uncomment the define below to use CakePHP prefix routes.
+ *
+ * The value of the define determines the names of the routes
+ * and their associated controller actions:
+ *
+ * Set to an array of prefixes you want to use in your application. Use for
+ * admin or other prefixed routes.
+ *
+ * Routing.prefixes = array('admin', 'manager');
+ *
+ * Enables:
+ * `admin_index()` and `/admin/controller/index`
+ * `manager_index()` and `/manager/controller/index`
+ *
+ */
+ //Configure::write('Routing.prefixes', array('admin'));
+
+/**
+ * Turn off all caching application-wide.
+ *
+ */
+ //Configure::write('Cache.disable', true);
+
+/**
+ * Enable cache checking.
+ *
+ * If set to true, for view caching you must still use the controller
+ * public $cacheAction inside your controllers to define caching settings.
+ * You can either set it controller-wide by setting public $cacheAction = true,
+ * or in each action using $this->cacheAction = true.
+ *
+ */
+ //Configure::write('Cache.check', true);
+
+/**
+ * Defines the default error type when using the log() function. Used for
+ * differentiating error logging and debugging. Currently PHP supports LOG_DEBUG.
+ */
+ define('LOG_ERROR', LOG_ERR);
+
+/**
+ * Session configuration.
+ *
+ * Contains an array of settings to use for session configuration. The defaults key is
+ * used to define a default preset to use for sessions, any settings declared here will override
+ * the settings of the default config.
+ *
+ * ## Options
+ *
+ * - `Session.cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'
+ * - `Session.timeout` - The number of minutes you want sessions to live for. This timeout is handled by CakePHP
+ * - `Session.cookieTimeout` - The number of minutes you want session cookies to live for.
+ * - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the
+ * value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX
+ * - `Session.defaults` - The default configuration set to use as a basis for your session.
+ * There are four builtins: php, cake, cache, database.
+ * - `Session.handler` - Can be used to enable a custom session handler. Expects an array of of callables,
+ * that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler`
+ * to the ini array.
+ * - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and
+ * sessionids that change frequently. See CakeSession::$requestCountdown.
+ * - `Session.ini` - An associative array of additional ini values to set.
+ *
+ * The built in defaults are:
+ *
+ * - 'php' - Uses settings defined in your php.ini.
+ * - 'cake' - Saves session files in CakePHP's /tmp directory.
+ * - 'database' - Uses CakePHP's database sessions.
+ * - 'cache' - Use the Cache class to save sessions.
+ *
+ * To define a custom session handler, save it at /app/Model/Datasource/Session/<name>.php.
+ * Make sure the class implements `CakeSessionHandlerInterface` and set Session.handler to <name>
+ *
+ * To use database sessions, run the app/Config/Schema/sessions.php schema using
+ * the cake shell command: cake schema create Sessions
+ *
+ */
+ Configure::write('Session', array(
+ 'defaults' => 'php'
+ ));
+
+/**
+ * The level of CakePHP security.
+ */
+ Configure::write('Security.level', 'medium');
+
+/**
+ * A random string used in security hashing methods.
+ */
+ Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
+
+/**
+ * A random numeric string (digits only) used to encrypt/decrypt strings.
+ */
+ Configure::write('Security.cipherSeed', '76859309657453542496749683645');
+
+/**
+ * Apply timestamps with the last modified time to static assets (js, css, images).
+ * Will append a querystring parameter containing the time the file was modified. This is
+ * useful for invalidating browser caches.
+ *
+ * Set to `true` to apply timestamps when debug > 0. Set to 'force' to always enable
+ * timestamping regardless of debug value.
+ */
+ //Configure::write('Asset.timestamp', true);
+
+/**
+ * Compress CSS output by removing comments, whitespace, repeating tags, etc.
+ * This requires a/var/cache directory to be writable by the web server for caching.
+ * and /vendors/csspp/csspp.php
+ *
+ * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use HtmlHelper::css().
+ */
+ //Configure::write('Asset.filter.css', 'css.php');
+
+/**
+ * Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the
+ * output, and setting the config below to the name of the script.
+ *
+ * To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JavaScriptHelper::link().
+ */
+ //Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');
+
+/**
+ * The classname and database used in CakePHP's
+ * access control lists.
+ */
+ Configure::write('Acl.classname', 'DbAcl');
+ Configure::write('Acl.database', 'default');
+
+/**
+ * Uncomment this line and correct your server timezone to fix
+ * any date & time related errors.
+ */
+ //date_default_timezone_set('UTC');
+
+/**
+ * Pick the caching engine to use. If APC is enabled use it.
+ * If running via cli - apc is disabled by default. ensure it's available and enabled in this case
+ *
+ * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
+ * Please check the comments in boostrap.php for more info on the cache engines available
+ * and their setttings.
+ */
+$engine = 'File';
+if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
+ $engine = 'Apc';
+}
+
+// In development mode, caches should expire quickly.
+$duration = '+999 days';
+if (Configure::read('debug') >= 1) {
+ $duration = '+10 seconds';
+}
+
+// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
+$prefix = 'myapp_';
+
+/**
+ * Configure the cache used for general framework caching. Path information,
+ * object listings, and translation cache files are stored with this configuration.
+ */
+Cache::config('_cake_core_', array(
+ 'engine' => $engine,
+ 'prefix' => $prefix . 'cake_core_',
+ 'path' => CACHE . 'persistent' . DS,
+ 'serialize' => ($engine === 'File'),
+ 'duration' => $duration
+));
+
+/**
+ * Configure the cache for model and datasource caches. This cache configuration
+ * is used to store schema descriptions, and table listings in connections.
+ */
+Cache::config('_cake_model_', array(
+ 'engine' => $engine,
+ 'prefix' => $prefix . 'cake_model_',
+ 'path' => CACHE . 'models' . DS,
+ 'serialize' => ($engine === 'File'),
+ 'duration' => $duration
+));
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/database.php.default b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/database.php.default
new file mode 100644
index 0000000..d0aeb1f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/database.php.default
@@ -0,0 +1,83 @@
+<?php
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour of Cake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * In this file you set up your database connection details.
+ *
+ * @package cake.config
+ */
+/**
+ * Database configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * datasource => The name of a supported datasource; valid options are as follows:
+ * Database/Mysql - MySQL 4 & 5,
+ * Database/Sqlite - SQLite (PHP5 only),
+ * Database/Postgres - PostgreSQL 7 and higher,
+ * Database/Sqlserver - Microsoft SQL Server 2005 and higher
+ *
+ * You can add custom database datasources (or override existing datasources) by adding the
+ * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php',
+ *
+ *
+ * persistent => true / false
+ * Determines whether or not the database should use a persistent connection
+ *
+ * host =>
+ * the host you connect to the database. To add a socket or port number, use 'port' => #
+ *
+ * prefix =>
+ * Uses the given prefix for all the tables in this database. This setting can be overridden
+ * on a per-table basis with the Model::$tablePrefix property.
+ *
+ * schema =>
+ * For Postgres specifies which schema you would like to use the tables in. Postgres defaults to 'public'.
+ *
+ * encoding =>
+ * For MySQL, Postgres specifies the character encoding to use when connecting to the
+ * database. Uses database default not specified.
+ *
+ * unix_socket =>
+ * For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port`
+ */
+class DATABASE_CONFIG {
+
+ public $default = array(
+ 'datasource' => 'Database/Mysql',
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'login' => 'user',
+ 'password' => 'password',
+ 'database' => 'database_name',
+ 'prefix' => '',
+ //'encoding' => 'utf8',
+ );
+
+ public $test = array(
+ 'datasource' => 'Database/Mysql',
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'login' => 'user',
+ 'password' => 'password',
+ 'database' => 'test_database_name',
+ 'prefix' => '',
+ //'encoding' => 'utf8',
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/email.php.default b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/email.php.default
new file mode 100644
index 0000000..fa252e8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/email.php.default
@@ -0,0 +1,97 @@
+<?php
+/**
+ * This is email configuration file.
+ *
+ * Use it to configure email transports of Cake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * In this file you set up your send email details.
+ *
+ * @package cake.config
+ */
+/**
+ * Email configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * transport => The name of a supported transport; valid options are as follows:
+ * Mail - Send using PHP mail function
+ * Smtp - Send using SMTP
+ * Debug - Do not send the email, just return the result
+ *
+ * You can add custom transports (or override existing transports) by adding the
+ * appropriate file to app/Network/Email. Transports should be named 'YourTransport.php',
+ * where 'Your' is the name of the transport.
+ *
+ * from =>
+ * The origin email. See CakeEmail::from() about the valid values
+ *
+ */
+class EmailConfig {
+
+ public $default = array(
+ 'transport' => 'Mail',
+ 'from' => 'you@localhost',
+ //'charset' => 'utf-8',
+ //'headerCharset' => 'utf-8',
+ );
+
+ public $smtp = array(
+ 'transport' => 'Smtp',
+ 'from' => array('site@localhost' => 'My Site'),
+ 'host' => 'localhost',
+ 'port' => 25,
+ 'timeout' => 30,
+ 'username' => 'user',
+ 'password' => 'secret',
+ 'client' => null,
+ 'log' => false,
+ //'charset' => 'utf-8',
+ //'headerCharset' => 'utf-8',
+ );
+
+ public $fast = array(
+ 'from' => 'you@localhost',
+ 'sender' => null,
+ 'to' => null,
+ 'cc' => null,
+ 'bcc' => null,
+ 'replyTo' => null,
+ 'readReceipt' => null,
+ 'returnPath' => null,
+ 'messageId' => true,
+ 'subject' => null,
+ 'message' => null,
+ 'headers' => null,
+ 'viewRender' => null,
+ 'template' => false,
+ 'layout' => false,
+ 'viewVars' => null,
+ 'attachments' => null,
+ 'emailFormat' => null,
+ 'transport' => 'Smtp',
+ 'host' => 'localhost',
+ 'port' => 25,
+ 'timeout' => 30,
+ 'username' => 'user',
+ 'password' => 'secret',
+ 'client' => null,
+ 'log' => true,
+ //'charset' => 'utf-8',
+ //'headerCharset' => 'utf-8',
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/routes.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/routes.php
new file mode 100644
index 0000000..b382377
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Config/routes.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Routes configuration
+ *
+ * In this file, you set up routes to your controllers and their actions.
+ * Routes are very important mechanism that allows you to freely connect
+ * different urls to chosen controllers and their actions (functions).
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * Here, we are connecting '/' (base path) to controller called 'Pages',
+ * its action called 'display', and we pass a param to select the view file
+ * to use (in this case, /app/View/Pages/home.ctp)...
+ */
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+/**
+ * ...and connect the rest of 'Pages' controller's urls.
+ */
+ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+
+/**
+ * Load all plugin routes. See the CakePlugin documentation on
+ * how to customize the loading of plugin routes.
+ */
+ CakePlugin::routes();
+
+/**
+ * Load the CakePHP default routes. Remove this if you do not want to use
+ * the built-in default routes.
+ */
+ require CAKE . 'Config' . DS . 'routes.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Command/AppShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Command/AppShell.php
new file mode 100644
index 0000000..5cc915f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Command/AppShell.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * AppShell file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Shell', 'Console');
+
+/**
+ * Application Shell
+ *
+ * Add your application-wide methods in the class below, your shells
+ * will inherit them.
+ *
+ * @package app.Console.Command
+ */
+class AppShell extends Shell {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/controllers/components/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Command/Task/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/controllers/components/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Command/Task/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/models/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Templates/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/models/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/Templates/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake
new file mode 100755
index 0000000..b7e3825
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+################################################################################
+#
+# Bake is a shell script for running CakePHP bake script
+# PHP 5
+#
+# CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+# Copyright 2005-2012, Cake Software Foundation, Inc.
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+#
+# @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+# @link http://cakephp.org CakePHP(tm) Project
+# @package app.Console
+# @since CakePHP(tm) v 2.0
+# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+#
+################################################################################
+LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0")
+
+while [ -h "$LIB" ]; do
+ DIR=$(dirname -- "$LIB")
+ SYM=$(readlink "$LIB")
+ LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
+done
+
+LIB=$(dirname -- "$LIB")/
+APP=$(dirname $(cd $(dirname $0) && pwd))
+
+exec php -q "$LIB"cake.php -working "$APP" "$@"
+
+exit;
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.bat b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.bat
new file mode 100644
index 0000000..b28ec8d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.bat
@@ -0,0 +1,32 @@
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: Bake is a shell script for running CakePHP bake script
+:: PHP 5
+::
+:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+:: Copyright 2005-2012, Cake Software Foundation, Inc.
+::
+:: Licensed under The MIT License
+:: Redistributions of files must retain the above copyright notice.
+::
+:: @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+:: @link http://cakephp.org CakePHP(tm) Project
+:: @package app.Console
+:: @since CakePHP(tm) v 2.0
+:: @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:: In order for this script to work as intended, the cake\console\ folder must be in your PATH
+
+@echo.
+@echo off
+
+SET app=%0
+SET lib=%~dp0
+
+php -q "%lib%cake.php" -working "%CD% " %*
+
+echo.
+
+exit /B %ERRORLEVEL%
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.php
new file mode 100644
index 0000000..edef894
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Console/cake.php
@@ -0,0 +1,33 @@
+#!/usr/bin/php -q
+<?php
+/**
+ * Command-line code generation utility to automate programmer chores.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$ds = DIRECTORY_SEPARATOR;
+$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
+
+if (function_exists('ini_set')) {
+ $root = dirname(dirname(dirname(__FILE__)));
+ ini_set('include_path', $root . $ds . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
+}
+
+if (!include ($dispatcher)) {
+ trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
+}
+unset($paths, $path, $dispatcher, $root, $ds);
+
+return ShellDispatcher::run($argv);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/AppController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/AppController.php
new file mode 100644
index 0000000..7aab7e9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/AppController.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Application level Controller
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+
+/**
+ * Application Controller
+ *
+ * Add your application-wide methods in the class below, your controllers
+ * will inherit them.
+ *
+ * @package app.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
+ */
+class AppController extends Controller {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/plugins/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/Component/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/plugins/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/Component/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/PagesController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/PagesController.php
new file mode 100644
index 0000000..5a2e57d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Controller/PagesController.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Static content controller.
+ *
+ * This file will render views from views/pages/
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppController', 'Controller');
+
+/**
+ * Static content controller
+ *
+ * Override this controller by placing a copy in controllers directory of an application
+ *
+ * @package app.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers/pages-controller.html
+ */
+class PagesController extends AppController {
+
+/**
+ * Controller name
+ *
+ * @var string
+ */
+ public $name = 'Pages';
+
+/**
+ * This controller does not use a model
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * Displays a view
+ *
+ * @param mixed What page to display
+ * @return void
+ */
+ public function display() {
+ $path = func_get_args();
+
+ $count = count($path);
+ if (!$count) {
+ $this->redirect('/');
+ }
+ $page = $subpage = $title_for_layout = null;
+
+ if (!empty($path[0])) {
+ $page = $path[0];
+ }
+ if (!empty($path[1])) {
+ $subpage = $path[1];
+ }
+ if (!empty($path[$count - 1])) {
+ $title_for_layout = Inflector::humanize($path[$count - 1]);
+ }
+ $this->set(compact('page', 'subpage', 'title_for_layout'));
+ $this->render(implode('/', $path));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Lib/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Lib/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/models/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Locale/eng/LC_MESSAGES/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/models/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Locale/eng/LC_MESSAGES/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/AppModel.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/AppModel.php
new file mode 100644
index 0000000..94e5e5f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/AppModel.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Application model for Cake.
+ *
+ * This file is application-wide model file. You can put all
+ * application-wide model-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+
+/**
+ * Application model for Cake.
+ *
+ * Add your application-wide methods in the class below, your models
+ * will inherit them.
+ *
+ * @package app.Model
+ */
+class AppModel extends Model {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/persistent/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/Behavior/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/persistent/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/Behavior/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/views/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/Datasource/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/cache/views/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Model/Datasource/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Plugin/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Plugin/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/logs/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/Controller/Component/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/logs/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/Controller/Component/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/sessions/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/Model/Behavior/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/sessions/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/Model/Behavior/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/tests/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/View/Helper/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/tmp/tests/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Case/View/Helper/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/vendors/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Fixture/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/vendors/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Test/Fixture/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/elements/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Vendor/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/elements/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/Vendor/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/errors/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Elements/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/errors/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Elements/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/html/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/html/default.ctp
new file mode 100644
index 0000000..0eb7f57
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/html/default.ctp
@@ -0,0 +1,25 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Emails.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php
+$content = explode("\n", $content);
+
+foreach ($content as $line):
+ echo '<p> ' . $line . "</p>\n";
+endforeach;
+?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/text/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/text/default.ctp
new file mode 100644
index 0000000..56be8c1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Emails/text/default.ctp
@@ -0,0 +1,19 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Emails.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo $content; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error400.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error400.ctp
new file mode 100644
index 0000000..6d50860
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error400.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo $name; ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake', 'Error'); ?>: </strong>
+ <?php printf(
+ __d('cake', 'The requested address %s was not found on this server.'),
+ "<strong>'{$url}'</strong>"
+ ); ?>
+</p>
+<?php
+if (Configure::read('debug') > 0 ):
+ echo $this->element('exception_stack_trace');
+endif;
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error500.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error500.ctp
new file mode 100644
index 0000000..4e1f36e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Errors/error500.ctp
@@ -0,0 +1,28 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo $name; ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake', 'Error'); ?>: </strong>
+ <?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
+</p>
+<?php
+if (Configure::read('debug') > 0 ):
+ echo $this->element('exception_stack_trace');
+endif;
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Helper/AppHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Helper/AppHelper.php
new file mode 100644
index 0000000..0fddaea
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Helper/AppHelper.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Application level View Helper
+ *
+ * This file is application-wide helper file. You can put all
+ * application-wide helper-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Helper
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Helper', 'View');
+
+/**
+ * Application helper
+ *
+ * Add your application-wide methods in the class below, your helpers
+ * will inherit them.
+ *
+ * @package app.View.Helper
+ */
+class AppHelper extends Helper {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/html/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/html/default.ctp
new file mode 100644
index 0000000..4d360d9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/html/default.ctp
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Layouts.Emails.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+<head>
+ <title><?php echo $title_for_layout;?></title>
+</head>
+<body>
+ <?php echo $content_for_layout;?>
+
+ <p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/text/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/text/default.ctp
new file mode 100644
index 0000000..94ed222
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/Emails/text/default.ctp
@@ -0,0 +1,21 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Layouts.Emails.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo $content_for_layout;?>
+
+This email was sent using the CakePHP Framework, http://cakephp.org.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/ajax.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/ajax.ctp
new file mode 100644
index 0000000..c0da850
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/ajax.ctp
@@ -0,0 +1,19 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo $this->fetch('content'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/default.ctp
new file mode 100644
index 0000000..39704bf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/default.ctp
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <?php echo $this->Html->charset(); ?>
+ <title>
+ <?php echo $cakeDescription ?>:
+ <?php echo $title_for_layout; ?>
+ </title>
+ <?php
+ echo $this->Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $this->fetch('meta');
+ echo $this->fetch('css');
+ echo $this->fetch('script');
+ ?>
+</head>
+<body>
+ <div id="container">
+ <div id="header">
+ <h1><?php echo $this->Html->link($cakeDescription, 'http://cakephp.org'); ?></h1>
+ </div>
+ <div id="content">
+
+ <?php echo $this->Session->flash(); ?>
+
+ <?php echo $this->fetch('content'); ?>
+ </div>
+ <div id="footer">
+ <?php echo $this->Html->link(
+ $this->Html->image('cake.power.gif', array('alt' => $cakeDescription, 'border' => '0')),
+ 'http://www.cakephp.org/',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+ </div>
+ </div>
+ <?php echo $this->element('sql_dump'); ?>
+</body>
+</html>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/error.ctp
new file mode 100644
index 0000000..4947734
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/error.ctp
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <?php echo $this->Html->charset(); ?>
+ <title>
+ <?php echo $cakeDescription ?>:
+ <?php echo $title_for_layout; ?>
+ </title>
+ <?php
+ echo $this->Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $this->fetch('meta');
+ echo $this->fetch('css');
+ echo $this->fetch('script');
+ ?>
+</head>
+<body>
+ <div id="container">
+ <div id="header">
+ <h1><?php echo $this->Html->link($cakeDescription, 'http://cakephp.org'); ?></h1>
+ </div>
+ <div id="content">
+
+ <?php echo $this->Session->flash(); ?>
+
+ <?php echo $this->fetch('content'); ?>
+ </div>
+ <div id="footer">
+ <?php echo $this->Html->link(
+ $this->Html->image('cake.power.gif', array('alt' => $cakeDescription, 'border' => '0')),
+ 'http://www.cakephp.org/',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+ </div>
+ </div>
+ <?php echo $this->element('sql_dump'); ?>
+</body>
+</html>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/flash.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/flash.ctp
new file mode 100644
index 0000000..76fae34
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/flash.ctp
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<?php echo $this->Html->charset(); ?>
+<title><?php echo $page_title; ?></title>
+
+<?php if (Configure::read('debug') == 0) { ?>
+<meta http-equiv="Refresh" content="<?php echo $pause; ?>;url=<?php echo $url; ?>"/>
+<?php } ?>
+<style><!--
+P { text-align:center; font:bold 1.1em sans-serif }
+A { color:#444; text-decoration:none }
+A:HOVER { text-decoration: underline; color:#44E }
+--></style>
+</head>
+<body>
+<p><a href="<?php echo $url; ?>"><?php echo $message; ?></a></p>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/js/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/js/default.ctp
new file mode 100644
index 0000000..7239b5d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/js/default.ctp
@@ -0,0 +1,2 @@
+<?php echo $scripts_for_layout; ?>
+<script type="text/javascript"><?php echo $this->fetch('content'); ?></script>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/rss/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/rss/default.ctp
new file mode 100644
index 0000000..077de61
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/rss/default.ctp
@@ -0,0 +1,14 @@
+<?php
+if (!isset($channel)) {
+ $channel = array();
+}
+if (!isset($channel['title'])) {
+ $channel['title'] = $title_for_layout;
+}
+
+echo $this->Rss->document(
+ $this->Rss->channel(
+ array(), $channel, $this->fetch('content')
+ )
+);
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/xml/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/xml/default.ctp
new file mode 100644
index 0000000..fbd5ee0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Layouts/xml/default.ctp
@@ -0,0 +1 @@
+<?php echo $this->fetch('content'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Pages/home.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Pages/home.ctp
new file mode 100644
index 0000000..9a22923
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Pages/home.ctp
@@ -0,0 +1,188 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Pages
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+if (Configure::read('debug') == 0):
+ throw new NotFoundException();
+endif;
+App::uses('Debugger', 'Utility');
+?>
+<iframe src="http://cakephp.org/bake-banner" width="830" height="160" style="overflow:hidden; border:none;">
+ <p>For updates and important announcements, visit http://cakefest.org</p>
+</iframe>
+<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
+<a href="http://cakephp.org/changelogs/<?php echo Configure::version(); ?>"><?php echo __d('cake_dev', 'Read the changelog'); ?> </a>
+<?php
+if (Configure::read('debug') > 0):
+ Debugger::checkSecurityKeys();
+endif;
+?>
+<p id="url-rewriting-warning" style="background-color:#e32; color:#fff;">
+ <?php echo __d('cake_dev', 'URL rewriting is not properly configured on your server.'); ?>
+ 1) <a target="_blank" href="http://book.cakephp.org/2.0/en/installation/advanced-installation.html#apache-and-mod-rewrite-and-htaccess" style="color:#fff;">Help me configure it</a>
+ 2) <a target="_blank" href="http://book.cakephp.org/2.0/en/development/configuration.html#cakephp-core-configuration" style="color:#fff;">I don't / can't use URL rewriting</a>
+</p>
+<p>
+<?php
+ if (version_compare(PHP_VERSION, '5.2.8', '>=')):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your version of PHP is 5.2.8 or higher.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your version of PHP is too low. You need PHP 5.2.8 or higher to use CakePHP.');
+ echo '</span>';
+ endif;
+?>
+</p>
+<p>
+ <?php
+ if (is_writable(TMP)):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your tmp directory is writable.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your tmp directory is NOT writable.');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<p>
+ <?php
+ $settings = Cache::settings();
+ if (!empty($settings)):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit APP/Config/core.php ', '<em>'. $settings['engine'] . 'Engine</em>');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in APP/Config/core.php');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<p>
+ <?php
+ $filePresent = null;
+ if (file_exists(APP . 'Config' . DS . 'database.php')):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your database configuration file is present.');
+ $filePresent = true;
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your database configuration file is NOT present.');
+ echo '<br/>';
+ echo __d('cake_dev', 'Rename APP/Config/database.php.default to APP/Config/database.php');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<?php
+if (isset($filePresent)):
+ App::uses('ConnectionManager', 'Model');
+ try {
+ $connected = ConnectionManager::getDataSource('default');
+ } catch (Exception $connectionError) {
+ $connected = false;
+ }
+?>
+<p>
+ <?php
+ if ($connected && $connected->isConnected()):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Cake is able to connect to the database.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Cake is NOT able to connect to the database.');
+ echo '<br /><br />';
+ echo $connectionError->getMessage();
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<?php endif;?>
+<?php
+ App::uses('Validation', 'Utility');
+ if (!Validation::alphaNumeric('cakephp')) {
+ echo '<p><span class="notice">';
+ echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.');
+ echo '<br/>';
+ echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
+ echo '</span></p>';
+ }
+?>
+<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
+<p>
+<?php
+echo __d('cake_dev', 'To change the content of this page, edit: APP/View/Pages/home.ctp.<br />
+To change its layout, edit: APP/View/Layouts/default.ctp.<br />
+You can also add some CSS styles for your pages at: APP/webroot/css.');
+?>
+</p>
+
+<h3><?php echo __d('cake_dev', 'Getting Started'); ?></h3>
+<p>
+ <?php
+ echo $this->Html->link(
+ sprintf('<strong>%s</strong> %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 2.0 Docs')),
+ 'http://book.cakephp.org/2.0/en/',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+</p>
+<p>
+ <?php
+ echo $this->Html->link(
+ __d('cake_dev', 'The 15 min Blog Tutorial'),
+ 'http://book.cakephp.org/2.0/en/tutorials-and-examples/blog/blog.html',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+</p>
+
+<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3>
+<p>
+<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
+</p>
+<p>
+<?php echo __d('cake_dev', 'Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.'); ?>
+</p>
+
+<ul>
+ <li><a href="http://cakefoundation.org/"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
+ <li><a href="http://www.cakephp.org"><?php echo __d('cake_dev', 'CakePHP'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li>
+ <li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li>
+ <li><a href="http://api20.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li>
+ <li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
+ <li><a href="http://live.cakephp.org"><?php echo __d('cake_dev', 'The Show'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'The Show is a live and archived internet radio broadcast CakePHP-related topics and answer questions live via IRC, Skype, and telephone.'); ?></li></ul></li>
+ <li><a href="http://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
+ <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
+ <ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li>
+ <li><a href="http://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'For the Development of CakePHP Git repository, Downloads'); ?></li></ul></li>
+ <li><a href="http://cakephp.lighthouseapp.com/"><?php echo __d('cake_dev', 'CakePHP Lighthouse'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'CakePHP Tickets, Wiki pages, Roadmap'); ?></li></ul></li>
+</ul>
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/helpers/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Scaffolds/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/helpers/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/View/Scaffolds/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/index.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/index.php
new file mode 100644
index 0000000..29f2c57
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/index.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/layouts/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/models/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/layouts/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/models/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/pages/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/persistent/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/views/pages/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/persistent/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/controllers/components/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/views/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/controllers/components/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/cache/views/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/models/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/logs/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/models/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/logs/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/plugins/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/sessions/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/plugins/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/sessions/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/tests/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/tmp/tests/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/.htaccess b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/.htaccess
index f9d8b93..48a63f0 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/.htaccess
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/.htaccess
@@ -2,5 +2,5 @@
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
- RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
-</IfModule> \ No newline at end of file
+ RewriteRule ^(.*)$ index.php [QSA,L]
+</IfModule>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/css/cake.generic.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/css/cake.generic.css
new file mode 100644
index 0000000..2244ad2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/css/cake.generic.css
@@ -0,0 +1,739 @@
+@charset "utf-8";
+/**
+ *
+ * Generic CSS for CakePHP
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.webroot.css
+ * @since CakePHP(tm)
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+* {
+ margin:0;
+ padding:0;
+}
+
+/** General Style Info **/
+body {
+ background: #003d4c;
+ color: #fff;
+ font-family:'lucida grande',verdana,helvetica,arial,sans-serif;
+ font-size:90%;
+ margin: 0;
+}
+a {
+ color: #003d4c;
+ text-decoration: underline;
+ font-weight: bold;
+}
+a:hover {
+ color: #367889;
+ text-decoration:none;
+}
+a img {
+ border:none;
+}
+h1, h2, h3, h4 {
+ font-weight: normal;
+ margin-bottom:0.5em;
+}
+h1 {
+ background:#fff;
+ color: #003d4c;
+ font-size: 100%;
+}
+h2 {
+ background:#fff;
+ color: #e32;
+ font-family:'Gill Sans','lucida grande', helvetica, arial, sans-serif;
+ font-size: 190%;
+}
+h3 {
+ color: #2c6877;
+ font-family:'Gill Sans','lucida grande', helvetica, arial, sans-serif;
+ font-size: 165%;
+}
+h4 {
+ color: #993;
+ font-weight: normal;
+}
+ul, li {
+ margin: 0 12px;
+}
+p {
+ margin: 0 0 1em 0;
+}
+
+/** Layout **/
+#container {
+ text-align: left;
+}
+
+#header{
+ padding: 10px 20px;
+}
+#header h1 {
+ line-height:20px;
+ background: #003d4c url('../img/cake.icon.png') no-repeat left;
+ color: #fff;
+ padding: 0px 30px;
+}
+#header h1 a {
+ color: #fff;
+ background: #003d4c;
+ font-weight: normal;
+ text-decoration: none;
+}
+#header h1 a:hover {
+ color: #fff;
+ background: #003d4c;
+ text-decoration: underline;
+}
+#content{
+ background: #fff;
+ clear: both;
+ color: #333;
+ padding: 10px 20px 40px 20px;
+ overflow: auto;
+}
+#footer {
+ clear: both;
+ padding: 6px 10px;
+ text-align: right;
+}
+
+/** containers **/
+div.form,
+div.index,
+div.view {
+ float:right;
+ width:76%;
+ border-left:1px solid #666;
+ padding:10px 2%;
+}
+div.actions {
+ float:left;
+ width:16%;
+ padding:10px 1.5%;
+}
+div.actions h3 {
+ padding-top:0;
+ color:#777;
+}
+
+
+/** Tables **/
+table {
+ border-right:0;
+ clear: both;
+ color: #333;
+ margin-bottom: 10px;
+ width: 100%;
+}
+th {
+ border:0;
+ border-bottom:2px solid #555;
+ text-align: left;
+ padding:4px;
+}
+th a {
+ display: block;
+ padding: 2px 4px;
+ text-decoration: none;
+}
+th a.asc:after {
+ content: ' ⇣';
+}
+th a.desc:after {
+ content: ' ⇡';
+}
+table tr td {
+ padding: 6px;
+ text-align: left;
+ vertical-align: top;
+ border-bottom:1px solid #ddd;
+}
+table tr:nth-child(even) {
+ background: #f9f9f9;
+}
+td.actions {
+ text-align: center;
+ white-space: nowrap;
+}
+table td.actions a {
+ margin: 0px 6px;
+ padding:2px 5px;
+}
+
+/* SQL log */
+.cake-sql-log {
+ background: #fff;
+}
+.cake-sql-log td {
+ padding: 4px 8px;
+ text-align: left;
+ font-family: Monaco, Consolas, "Courier New", monospaced;
+}
+.cake-sql-log caption {
+ color:#fff;
+}
+
+/** Paging **/
+.paging {
+ background:#fff;
+ color: #ccc;
+ margin-top: 1em;
+ clear:both;
+}
+.paging .current,
+.paging .disabled,
+.paging a {
+ text-decoration: none;
+ padding: 5px 8px;
+ display: inline-block
+}
+.paging > span {
+ display: inline-block;
+ border: 1px solid #ccc;
+ border-left: 0;
+}
+.paging > span:hover {
+ background: #efefef;
+}
+.paging .prev {
+ border-left: 1px solid #ccc;
+ -moz-border-radius: 4px 0 0 4px;
+ -webkit-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+.paging .next {
+ -moz-border-radius: 0 4px 4px 0;
+ -webkit-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+.paging .disabled {
+ color: #ddd;
+}
+.paging .disabled:hover {
+ background: transparent;
+}
+.paging .current {
+ background: #efefef;
+ color: #c73e14;
+}
+
+/** Scaffold View **/
+dl {
+ line-height: 2em;
+ margin: 0em 0em;
+ width: 60%;
+}
+dl dd:nth-child(4n+2),
+dl dt:nth-child(4n+1) {
+ background: #f4f4f4;
+}
+
+dt {
+ font-weight: bold;
+ padding-left: 4px;
+ vertical-align: top;
+ width: 10em;
+}
+dd {
+ margin-left: 10em;
+ margin-top: -2em;
+ vertical-align: top;
+}
+
+/** Forms **/
+form {
+ clear: both;
+ margin-right: 20px;
+ padding: 0;
+ width: 95%;
+}
+fieldset {
+ border: none;
+ margin-bottom: 1em;
+ padding: 16px 10px;
+}
+fieldset legend {
+ color: #e32;
+ font-size: 160%;
+ font-weight: bold;
+}
+fieldset fieldset {
+ margin-top: 0;
+ padding: 10px 0 0;
+}
+fieldset fieldset legend {
+ font-size: 120%;
+ font-weight: normal;
+}
+fieldset fieldset div {
+ clear: left;
+ margin: 0 20px;
+}
+form div {
+ clear: both;
+ margin-bottom: 1em;
+ padding: .5em;
+ vertical-align: text-top;
+}
+form .input {
+ color: #444;
+}
+form .required {
+ font-weight: bold;
+}
+form .required label:after {
+ color: #e32;
+ content: '*';
+ display:inline;
+}
+form div.submit {
+ border: 0;
+ clear: both;
+ margin-top: 10px;
+}
+label {
+ display: block;
+ font-size: 110%;
+ margin-bottom:3px;
+}
+input, textarea {
+ clear: both;
+ font-size: 140%;
+ font-family: "frutiger linotype", "lucida grande", "verdana", sans-serif;
+ padding: 1%;
+ width:98%;
+}
+select {
+ clear: both;
+ font-size: 120%;
+ vertical-align: text-bottom;
+}
+select[multiple=multiple] {
+ width: 100%;
+}
+option {
+ font-size: 120%;
+ padding: 0 3px;
+}
+input[type=checkbox] {
+ clear: left;
+ float: left;
+ margin: 0px 6px 7px 2px;
+ width: auto;
+}
+div.checkbox label {
+ display: inline;
+}
+input[type=radio] {
+ float:left;
+ width:auto;
+ margin: 6px 0;
+ padding: 0;
+ line-height: 26px;
+}
+.radio label {
+ margin: 0 0 6px 20px;
+ line-height: 26px;
+}
+input[type=submit] {
+ display: inline;
+ font-size: 110%;
+ width: auto;
+}
+form .submit input[type=submit] {
+ background:#62af56;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#76BF6B), to(#3B8230));
+ background-image: -webkit-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -moz-linear-gradient(top, #76BF6B, #3B8230);
+ border-color: #2d6324;
+ color: #fff;
+ text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px;
+ padding: 8px 10px;
+}
+form .submit input[type=submit]:hover {
+ background: #5BA150;
+}
+/* Form errors */
+form .error {
+ background: #FFDACC;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ font-weight: normal;
+}
+form .error-message {
+ -moz-border-radius: none;
+ -webkit-border-radius: none;
+ border-radius: none;
+ border: none;
+ background: none;
+ margin: 0;
+ padding-left: 4px;
+ padding-right: 0;
+}
+form .error,
+form .error-message {
+ color: #9E2424;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ -ms-box-shadow: none;
+ -o-box-shadow: none;
+ box-shadow: none;
+ text-shadow: none;
+}
+
+/** Notices and Errors **/
+.message {
+ clear: both;
+ color: #fff;
+ font-size: 140%;
+ font-weight: bold;
+ margin: 0 0 1em 0;
+ padding: 5px;
+}
+
+.success,
+.message,
+.cake-error,
+.cake-debug,
+.notice,
+p.error,
+.error-message {
+ background: #ffcc00;
+ background-repeat: repeat-x;
+ background-image: -moz-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: -ms-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ffcc00), to(#E6B800));
+ background-image: -webkit-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: -o-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: linear-gradient(top, #ffcc00, #E6B800);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ margin-bottom: 18px;
+ padding: 7px 14px;
+ color: #404040;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+}
+.success,
+.message,
+.cake-error,
+p.error,
+.error-message {
+ clear: both;
+ color: #fff;
+ background: #c43c35;
+ border: 1px solid rgba(0, 0, 0, 0.5);
+ background-repeat: repeat-x;
+ background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
+ background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: linear-gradient(top, #ee5f5b, #c43c35);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+}
+.success {
+ clear: both;
+ color: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.5);
+ background: #3B8230;
+ background-repeat: repeat-x;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#76BF6B), to(#3B8230));
+ background-image: -webkit-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -moz-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -ms-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -o-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: linear-gradient(top, #76BF6B, #3B8230);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+}
+p.error {
+ font-family: Monaco, Consolas, Courier, monospace;
+ font-size: 120%;
+ padding: 0.8em;
+ margin: 1em 0;
+}
+p.error em {
+ font-weight: normal;
+ line-height: 140%;
+}
+.notice {
+ color: #000;
+ display: block;
+ font-size: 120%;
+ padding: 0.8em;
+ margin: 1em 0;
+}
+.success {
+ color: #fff;
+}
+
+/** Actions **/
+.actions ul {
+ margin: 0;
+ padding: 0;
+}
+.actions li {
+ margin:0 0 0.5em 0;
+ list-style-type: none;
+ white-space: nowrap;
+ padding: 0;
+}
+.actions ul li a {
+ font-weight: normal;
+ display: block;
+ clear: both;
+}
+
+/* Buttons and button links */
+input[type=submit],
+.actions ul li a,
+.actions a {
+ font-weight:normal;
+ padding: 4px 8px;
+ background: #dcdcdc;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fefefe), to(#dcdcdc));
+ background-image: -webkit-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -moz-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -ms-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -o-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: linear-gradient(top, #fefefe, #dcdcdc);
+ color:#333;
+ border:1px solid #bbb;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ text-decoration: none;
+ text-shadow: #fff 0px 1px 0px;
+ min-width: 0;
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0px 1px 1px rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0px 1px 1px rgba(0, 0, 0, 0.2);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0px 1px 1px rgba(0, 0, 0, 0.2);
+ -webkit-user-select: none;
+ user-select: none;
+}
+.actions ul li a:hover,
+.actions a:hover {
+ background: #ededed;
+ border-color: #acacac;
+ text-decoration: none;
+}
+input[type=submit]:active,
+.actions ul li a:active,
+.actions a:active {
+ background: #eee;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dfdfdf), to(#eee));
+ background-image: -webkit-linear-gradient(top, #dfdfdf, #eee);
+ background-image: -moz-linear-gradient(top, #dfdfdf, #eee);
+ background-image: -ms-linear-gradient(top, #dfdfdf, #eee);
+ background-image: -o-linear-gradient(top, #dfdfdf, #eee);
+ background-image: linear-gradient(top, #dfdfdf, #eee);
+ text-shadow: #eee 0px 1px 0px;
+ -moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
+ box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
+ border-color: #aaa;
+ text-decoration: none;
+}
+
+/** Related **/
+.related {
+ clear: both;
+ display: block;
+}
+
+/** Debugging **/
+pre {
+ color: #000;
+ background: #f0f0f0;
+ padding: 15px;
+ -moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
+}
+.cake-debug-output {
+ padding: 0;
+ position: relative;
+}
+.cake-debug-output > span {
+ position: absolute;
+ top: 5px;
+ right: 5px;
+ background: rgba(255, 255, 255, 0.3);
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ padding: 5px 6px;
+ color: #000;
+ display: block;
+ float: left;
+ -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(255, 255, 255, 0.5);
+ -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(255, 255, 255, 0.5);
+ box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(255, 255, 255, 0.5);
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
+}
+.cake-debug,
+.cake-error {
+ font-size: 16px;
+ line-height: 20px;
+ clear: both;
+}
+.cake-error > a {
+ text-shadow: none;
+}
+.cake-error {
+ white-space: normal;
+}
+.cake-stack-trace {
+ background: rgba(255, 255, 255, 0.7);
+ color: #333;
+ margin: 10px 0 5px 0;
+ padding: 10px 10px 0 10px;
+ font-size: 120%;
+ line-height: 140%;
+ overflow: auto;
+ position: relative;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+}
+.cake-stack-trace a {
+ text-shadow: none;
+ background: rgba(255, 255, 255, 0.7);
+ padding: 5px;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+ margin: 0px 4px 10px 2px;
+ font-family: sans-serif;
+ font-size: 14px;
+ line-height: 14px;
+ display: inline-block;
+ text-decoration: none;
+ -moz-box-shadow: inset 0px 1px 0 rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: inset 0px 1px 0 rgba(0, 0, 0, 0.3);
+ box-shadow: inset 0px 1px 0 rgba(0, 0, 0, 0.3);
+}
+.cake-code-dump pre {
+ position: relative;
+ overflow: auto;
+}
+.cake-context {
+ margin-bottom: 10px;
+}
+.cake-stack-trace pre {
+ color: #000;
+ background-color: #F0F0F0;
+ margin: 0px 0 10px 0;
+ padding: 1em;
+ overflow: auto;
+ text-shadow: none;
+}
+.cake-stack-trace li {
+ padding: 10px 5px 0px;
+ margin: 0 0 4px 0;
+ font-family: monospace;
+ border: 1px solid #bbb;
+ -moz-border-radius: 4px;
+ -wekbkit-border-radius: 4px;
+ border-radius: 4px;
+ background: #dcdcdc;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fefefe), to(#dcdcdc));
+ background-image: -webkit-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -moz-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -ms-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -o-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: linear-gradient(top, #fefefe, #dcdcdc);
+}
+/* excerpt */
+.cake-code-dump pre,
+.cake-code-dump pre code {
+ clear: both;
+ font-size: 12px;
+ line-height: 15px;
+ margin: 4px 2px;
+ padding: 4px;
+ overflow: auto;
+}
+.cake-code-dump .code-highlight {
+ display: block;
+ background-color: rgba(255, 255, 0, 0.5);
+}
+.code-coverage-results div.code-line {
+ padding-left:5px;
+ display:block;
+ margin-left:10px;
+}
+.code-coverage-results div.uncovered span.content {
+ background:#ecc;
+}
+.code-coverage-results div.covered span.content {
+ background:#cec;
+}
+.code-coverage-results div.ignored span.content {
+ color:#aaa;
+}
+.code-coverage-results span.line-num {
+ color:#666;
+ display:block;
+ float:left;
+ width:20px;
+ text-align:right;
+ margin-right:5px;
+}
+.code-coverage-results span.line-num strong {
+ color:#666;
+}
+.code-coverage-results div.start {
+ border:1px solid #aaa;
+ border-width:1px 1px 0px 1px;
+ margin-top:30px;
+ padding-top:5px;
+}
+.code-coverage-results div.end {
+ border:1px solid #aaa;
+ border-width:0px 1px 1px 1px;
+ margin-bottom:30px;
+ padding-bottom:5px;
+}
+.code-coverage-results div.realstart {
+ margin-top:0px;
+}
+.code-coverage-results p.note {
+ color:#bbb;
+ padding:5px;
+ margin:5px 0 10px;
+ font-size:10px;
+}
+.code-coverage-results span.result-bad {
+ color: #a00;
+}
+.code-coverage-results span.result-ok {
+ color: #fa0;
+}
+.code-coverage-results span.result-good {
+ color: #0a0;
+}
+
+/** Elements **/
+#url-rewriting-warning {
+ display:none;
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/favicon.ico b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/favicon.ico
new file mode 100644
index 0000000..b36e81f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/favicon.ico
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/models/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/files/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/models/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/files/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.icon.png
new file mode 100644
index 0000000..394fa42
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.power.gif b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.power.gif
new file mode 100644
index 0000000..8f8d570
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/cake.power.gif
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/favicon.ico b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-error-icon.png
index 1bc32bd..07bb124 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/favicon.ico
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-error-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-fail-icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-fail-icon.png
new file mode 100644
index 0000000..f9d2f14
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-fail-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-pass-icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-pass-icon.png
new file mode 100644
index 0000000..99c5eb0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-pass-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-skip-icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-skip-icon.png
new file mode 100644
index 0000000..749771c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/img/test-skip-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/index.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/index.php
new file mode 100644
index 0000000..e125e09
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/index.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Index
+ *
+ * The Front Controller for handling every request
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.webroot
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * Use the DS to separate the directories in other defines
+ */
+if (!defined('DS')) {
+ define('DS', DIRECTORY_SEPARATOR);
+}
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * When using custom settings be sure to use the DS and do not add a trailing DS.
+ */
+
+/**
+ * The full path to the directory which holds "app", WITHOUT a trailing DS.
+ *
+ */
+if (!defined('ROOT')) {
+ define('ROOT', dirname(dirname(dirname(__FILE__))));
+}
+/**
+ * The actual directory name for the "app".
+ *
+ */
+if (!defined('APP_DIR')) {
+ define('APP_DIR', basename(dirname(dirname(__FILE__))));
+}
+
+/**
+ * The absolute path to the "cake" directory, WITHOUT a trailing DS.
+ *
+ * Un-comment this line to specify a fixed path to CakePHP.
+ * This should point at the directory containing `Cake`.
+ *
+ * For ease of development CakePHP uses PHP's include_path. If you
+ * cannot modify your include_path set this value.
+ *
+ * Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
+ */
+ //define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
+
+/**
+ * Editing below this line should NOT be necessary.
+ * Change at your own risk.
+ *
+ */
+if (!defined('WEBROOT_DIR')) {
+ define('WEBROOT_DIR', basename(dirname(__FILE__)));
+}
+if (!defined('WWW_ROOT')) {
+ define('WWW_ROOT', dirname(__FILE__) . DS);
+}
+
+if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ if (function_exists('ini_set')) {
+ ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
+ }
+ if (!include ('Cake' . DS . 'bootstrap.php')) {
+ $failed = true;
+ }
+} else {
+ if (!include (CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) {
+ $failed = true;
+ }
+}
+if (!empty($failed)) {
+ trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
+}
+
+App::uses('Dispatcher', 'Routing');
+
+$Dispatcher = new Dispatcher();
+$Dispatcher->dispatch(new CakeRequest(), new CakeResponse(array('charset' => Configure::read('App.encoding'))));
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/persistent/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/js/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/persistent/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/js/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/test.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/test.php
new file mode 100644
index 0000000..39bea7a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/app/webroot/test.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Web Access Frontend for TestSuite
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html
+ * @package app.webroot
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+set_time_limit(0);
+ini_set('display_errors', 1);
+/**
+ * Use the DS to separate the directories in other defines
+ */
+if (!defined('DS')) {
+ define('DS', DIRECTORY_SEPARATOR);
+}
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * When using custom settings be sure to use the DS and do not add a trailing DS.
+ */
+
+/**
+ * The full path to the directory which holds "app", WITHOUT a trailing DS.
+ *
+ */
+if (!defined('ROOT')) {
+ define('ROOT', dirname(dirname(dirname(__FILE__))));
+}
+/**
+ * The actual directory name for the "app".
+ *
+ */
+if (!defined('APP_DIR')) {
+ define('APP_DIR', basename(dirname(dirname(__FILE__))));
+}
+
+/**
+ * The absolute path to the "Cake" directory, WITHOUT a trailing DS.
+ *
+ * For ease of development CakePHP uses PHP's include_path. If you
+ * need to cannot modify your include_path, you can set this path.
+ *
+ * Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
+ */
+ //define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
+
+/**
+ * Editing below this line should not be necessary.
+ * Change at your own risk.
+ *
+ */
+if (!defined('WEBROOT_DIR')) {
+ define('WEBROOT_DIR', basename(dirname(__FILE__)));
+}
+if (!defined('WWW_ROOT')) {
+ define('WWW_ROOT', dirname(__FILE__) . DS);
+}
+
+if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ if (function_exists('ini_set')) {
+ ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
+ }
+ if (!include ('Cake' . DS . 'bootstrap.php')) {
+ $failed = true;
+ }
+} else {
+ if (!include (CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) {
+ $failed = true;
+ }
+}
+if (!empty($failed)) {
+ trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
+}
+
+if (Configure::read('debug') < 1) {
+ die(__d('cake_dev', 'Debug setting does not allow access to this url.'));
+}
+
+require_once CAKE . 'TestSuite' . DS . 'CakeTestSuiteDispatcher.php';
+
+CakeTestSuiteDispatcher::run();
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.properties b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.properties
new file mode 100644
index 0000000..e3c99ca
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.properties
@@ -0,0 +1,12 @@
+# Name
+project.name = CakePHP
+
+# Git stuff
+git.remote = changeme!
+
+# Directories
+build.dir = build
+dist.dir = dist
+
+# Server
+pirum.dir = /home/cakephp/www-live/pear.cakephp.org
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.xml b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.xml
new file mode 100644
index 0000000..fca6ec4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/build.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project name="CakePHP" default="build">
+ <!--
+ Build.xml file for CakePHP
+
+ Uses phing to create releases, and pear packages.
+ Based off of build.xml in doctrine.
+
+ Requires the d51PearPkg2 to be installed:
+
+ pear channel-discover pear.domain51.com
+ pear install domain51/Phing_d51PearPkg2Task
+
+ Use the `release` task to update VERSION.txt, and create a new tag.
+ Use the `build` task to create a pear package based on the current working copy.
+ Use the `clean` task to clean up packaging artifacts.
+
+ -->
+
+ <taskdef classname="phing.tasks.ext.d51PearPkg2Task" name="d51pearpkg2" />
+ <property file="build.properties" />
+
+ <!--
+ The set of files we're going to package
+ Exclude the cli scripts, as they get installed separately.
+ -->
+ <fileset id="libs" dir="./lib/Cake">
+ <include name="**" />
+ <exclude name="Console/cake.bat" />
+ <exclude name="Console/cake.php" />
+ <exclude name="Console/cake" />
+ </fileset>
+
+ <!--
+ CLI scripts to package and install
+ -->
+ <fileset id="cli" dir="./lib/Cake/Console">
+ <include name="cake.bat" />
+ <include name="cake.php" />
+ <include name="cake" />
+ </fileset>
+
+
+ <!-- start fresh each time. Remove the dist and build dirs -->
+ <target name="clean">
+ <delete dir="${build.dir}" includeemptydirs="true" />
+ <delete dir="${dist.dir}" includeemptydirs="true" />
+ </target>
+
+ <!-- Read the current version, so we can replace it -->
+ <target name="current-version">
+ <exec executable="php" outputProperty="version">
+ <arg value="-r" />
+ <arg value="$fh = file('./lib/Cake/VERSION.txt'); echo array_pop($fh);" />
+ </exec>
+ </target>
+
+ <!-- Makes directories and sets properties -->
+ <target name="prepare" depends="current-version">
+ <!-- set PEAR stability based on version number. -->
+ <condition property="pear.stability" value="beta">
+ <contains string="${version}" substring="beta" casesensitive="false"/>
+ </condition>
+ <condition property="pear.stability" value="alpha">
+ <contains string="${version}" substring="alpha" casesensitive="false"/>
+ </condition>
+ <condition property="pear.stability" value="devel">
+ <contains string="${version}" substring="dev" casesensitive="false"/>
+ </condition>
+ <condition property="pear.stability" value="beta">
+ <contains string="${version}" substring="rc" casesensitive="false" />
+ </condition>
+ <condition property="pear.stability" value="stable">
+ <not><isset property="pear.stability"/></not>
+ </condition>
+
+ <!-- pear versions need to not have '-' -->
+ <exec executable="php" outputProperty="pear.version">
+ <arg value="-r" />
+ <arg value="echo str_replace(array('-'), array(''), '${version}');" />
+ </exec>
+
+ <!-- Used for other targets -->
+ <property name="pear.package" value="${project.name}-${pear.version}" />
+
+ <echo msg="Preparing package of ${version} (${pear.version}+${pear.stability})" />
+
+ <!-- Get the current git branch -->
+ <exec command="git name-rev HEAD 2>/dev/null | awk '{ print $2 }'" outputProperty="git.branch" />
+ </target>
+
+ <!--
+ Copy all the files to build/ so they can be packaged up.
+ -->
+ <target name="copy-files" depends="clean,prepare">
+ <echo msg="Creating build + dist directories." />
+ <mkdir dir="${build.dir}" />
+ <mkdir dir="${dist.dir}" />
+
+ <echo msg="Copying files to build directory" />
+ <copy todir="${build.dir}/${pear.package}/Cake">
+ <fileset refid="libs" />
+ </copy>
+ <copy todir="${build.dir}/${pear.package}/bin">
+ <fileset refid="cli" />
+ </copy>
+ </target>
+
+ <!--
+ Define the package.xml. Using xml to make xml is fun!
+ -->
+ <target name="define-pear-package" depends="copy-files">
+ <d51pearpkg2 baseinstalldir="/" dir="${build.dir}/${pear.package}">
+ <name>CakePHP</name>
+ <summary>CakePHP Rapid Development Framework</summary>
+ <channel>pear.cakephp.org</channel>
+ <description>CakePHP is an application development framework for PHP 5.2+</description>
+
+ <lead user="mark_story" name="Mark Story" email="mark@mark-story.com" />
+ <lead user="lorenzo" name="José Lorenzo Rodríguez" email="jose.zap@gmail.com" />
+ <lead user="PhpNut" name="Larry Masters" email="phpnut@cakephp.org" />
+ <developer user="ADmad" name="Adnan Sarela" email="admad.coder@gmail.com" />
+ <developer user="AD7six" name="Andy Dawson" email="andydawson76@gmail.com" />
+ <developer user="Ceeram" name="Marc Ypes" email="c33ram@gmail.com" />
+ <developer user="jrbasso" name="Juan Basso" email="" />
+ <developer user="Predominant" name="Graham Weldon" email="graham@grahamweldon.com" />
+ <developer user="renan.saddam" name="Renan Gonçalves" email="renan.saddam@gmail.com" />
+ <developer user="rchavik" name="Rachman Chavik" email="rchavik@xintesa.com" />
+
+ <license>MIT License</license>
+ <version release="${pear.version}" api="${pear.version}" />
+ <stability release="${pear.stability}" api="${pear.stability}" />
+ <notes>http://github.com/cakephp/cakephp/blob/master/README</notes>
+ <dependencies>
+ <php minimum_version="5.2.8" />
+ <pear minimum_version="1.9.0" recommended_version="1.9.4" />
+ <package name="PHPUnit" channel="pear.phpunit.de" minimum_version="3.5.0" type="optional" />
+ </dependencies>
+ <dirroles key="bin">script</dirroles>
+ <dirroles key="Cake/Test">php</dirroles>
+ <dirroles key="Cake/Console/Templates/skel">php</dirroles>
+ <dirroles key="Cake/Console/Templates/default">php</dirroles>
+ <dirroles key="Cake/View">php</dirroles>
+ <release>
+ <install as="cake" name="bin/cake" />
+ <install as="cake.php" name="bin/cake.php" />
+ <install as="cake.bat" name="bin/cake.bat" />
+ </release>
+ <exceptions key="Cake/VERSION.txt">php</exceptions>
+ <exceptions key="Cake/LICENSE.txt">php</exceptions>
+ </d51pearpkg2>
+ </target>
+
+ <!-- Generate the PEAR package from a directory and move the files to the dist folder -->
+ <target name="generate-package" depends="define-pear-package">
+ <exec command="pear package" dir="${build.dir}/${pear.package}" passthru="true"/>
+ <echo msg="Moving ${pear.package}.tgz"/>
+ <move file="${build.dir}/${pear.package}/${pear.package}.tgz" todir="${dist.dir}" />
+ </target>
+
+ <!--
+ Bump the version number and commit that.
+ -->
+ <target name="next-version" depends="current-version">
+ <echo msg="Incrementing version." />
+ <propertyprompt propertyName="release_version" defaultValue="${version}" promptText="Enter version to be released."/>
+ <echo msg="$file = file_get_contents('./lib/Cake/VERSION.txt'); $file = str_replace('${version}', '${release_version}', $file); file_put_contents('./lib/Cake/VERSION.txt', $file);" />
+ <exec executable="php">
+ <arg value="-r" />
+ <arg value="$file = file_get_contents('./lib/Cake/VERSION.txt'); $file = str_replace('${version}', '${release_version}', $file); file_put_contents('./lib/Cake/VERSION.txt', $file);" />
+ </exec>
+ <echo msg="Version number updated." />
+ <property name="version" value="${release_version}" override="true" />
+ </target>
+
+ <!--
+ Create the release commit that updates the version number and pushes the commits.
+ -->
+ <target name="release-commit" depends="next-version,prepare">
+ <echo msg="Creating new release commit" />
+ <exec command="git add ./lib/Cake/VERSION.txt" logoutput="true" checkreturn="true" />
+ <exec command="git commit -m 'Update version number to ${release_version}'" logoutput="true" checkreturn="true" />
+ <exec command="git tag -s ${release_version} -m 'CakePHP ${release_version}'" logoutput="true" checkreturn="true" />
+
+ <propertyprompt propertyName="shipit" defaultValue="n" promptText="Ship the new commit and tag?" />
+ <condition property="noshipit" value="1">
+ <equals arg1="n" arg2="${shipit}" casesensitive="false" />
+ </condition>
+ <fail if="noshipit" msg="You said not to ship it." />
+
+ <echo msg="Pushing commit and tag." />
+ <exec command="git push ${git.remote} ${git.branch}" logoutput="true" checkreturn="true" />
+ <exec command="git push ${git.remote} ${release_version}" logoutput="true" checkreturn="true" />
+ <echo msg="Push complete." />
+ </target>
+
+ <!--
+ Upload to pirum pear channel.
+ -->
+ <target name="distribute" depends="prepare">
+ <echo msg="Uploading tgz file to cakephp.org" />
+ <exec command="scp ${dist.dir}/${pear.package}.tgz cakephp@cakephp.org:${pirum.dir}" dir="." checkreturn="true" />
+
+ <echo msg="Adding new release to pirum" />
+ <exec command="ssh cakephp@cakephp.org pirum add ${pirum.dir} ${pirum.dir}/${pear.package}.tgz" checkreturn="true" />
+ </target>
+
+ <!--
+ Top level easy to type targets
+ -->
+ <target name="build" depends="generate-package" />
+ <target name="release" depends="release-commit,build,distribute" />
+
+</project>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/index.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/index.php
new file mode 100644
index 0000000..b54f617
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Requests collector.
+ *
+ * This file collects requests if:
+ * - no mod_rewrite is available or .htaccess files are not supported
+ * - requires App.baseUrl to be uncommented in app/Config/core.php
+ * - app/webroot is not set as a document root.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Get Cake's root directory
+ */
+define('APP_DIR', 'app');
+define('DS', DIRECTORY_SEPARATOR);
+define('ROOT', dirname(__FILE__));
+define('WEBROOT_DIR', 'webroot');
+define('WWW_ROOT', ROOT . DS . APP_DIR . DS . WEBROOT_DIR . DS);
+
+/**
+ * This only needs to be changed if the "cake" directory is located
+ * outside of the distributed structure.
+ * Full path to the directory containing "cake". Do not add trailing directory separator
+ */
+if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
+}
+
+require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Cache.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Cache.php
new file mode 100644
index 0000000..cb705f6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Cache.php
@@ -0,0 +1,501 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Cache
+ * @since CakePHP(tm) v 1.2.0.4933
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Inflector', 'Utility');
+App::uses('CacheEngine', 'Cache');
+
+/**
+ * Cache provides a consistent interface to Caching in your application. It allows you
+ * to use several different Cache engines, without coupling your application to a specific
+ * implementation. It also allows you to change out cache storage or configuration without effecting
+ * the rest of your application.
+ *
+ * You can configure Cache engines in your application's `bootstrap.php` file. A sample configuration would
+ * be
+ *
+ * {{{
+ * Cache::config('shared', array(
+ * 'engine' => 'Apc',
+ * 'prefix' => 'my_app_'
+ * ));
+ * }}}
+ *
+ * This would configure an APC cache engine to the 'shared' alias. You could then read and write
+ * to that cache alias by using it for the `$config` parameter in the various Cache methods. In
+ * general all Cache operations are supported by all cache engines. However, Cache::increment() and
+ * Cache::decrement() are not supported by File caching.
+ *
+ * @package Cake.Cache
+ */
+class Cache {
+
+/**
+ * Cache configuration stack
+ * Keeps the permanent/default settings for each cache engine.
+ * These settings are used to reset the engines after temporary modification.
+ *
+ * @var array
+ */
+ protected static $_config = array();
+
+/**
+ * Whether to reset the settings with the next call to Cache::set();
+ *
+ * @var array
+ */
+ protected static $_reset = false;
+
+/**
+ * Engine instances keyed by configuration name.
+ *
+ * @var array
+ */
+ protected static $_engines = array();
+
+/**
+ * Set the cache configuration to use. config() can
+ * both create new configurations, return the settings for already configured
+ * configurations.
+ *
+ * To create a new configuration, or to modify an existing configuration permanently:
+ *
+ * `Cache::config('my_config', array('engine' => 'File', 'path' => TMP));`
+ *
+ * If you need to modify a configuration temporarily, use Cache::set().
+ * To get the settings for a configuration:
+ *
+ * `Cache::config('default');`
+ *
+ * There are 5 built-in caching engines:
+ *
+ * - `FileEngine` - Uses simple files to store content. Poor performance, but good for
+ * storing large objects, or things that are not IO sensitive.
+ * - `ApcEngine` - Uses the APC object cache, one of the fastest caching engines.
+ * - `MemcacheEngine` - Uses the PECL::Memcache extension and Memcached for storage.
+ * Fast reads/writes, and benefits from memcache being distributed.
+ * - `XcacheEngine` - Uses the Xcache extension, an alternative to APC.
+ * - `WincacheEngine` - Uses Windows Cache Extension for PHP. Supports wincache 1.1.0 and higher.
+ *
+ * The following keys are used in core cache engines:
+ *
+ * - `duration` Specify how long items in this cache configuration last.
+ * - `groups` List of groups or 'tags' associated to every key stored in this config.
+ * handy for deleting a complete group from cache.
+ * - `prefix` Prefix appended to all entries. Good for when you need to share a keyspace
+ * with either another cache config or another application.
+ * - `probability` Probability of hitting a cache gc cleanup. Setting to 0 will disable
+ * cache::gc from ever being called automatically.
+ * - `servers' Used by memcache. Give the address of the memcached servers to use.
+ * - `compress` Used by memcache. Enables memcache's compressed format.
+ * - `serialize` Used by FileCache. Should cache objects be serialized first.
+ * - `path` Used by FileCache. Path to where cachefiles should be saved.
+ * - `lock` Used by FileCache. Should files be locked before writing to them?
+ * - `user` Used by Xcache. Username for XCache
+ * - `password` Used by Xcache. Password for XCache
+ *
+ * @see app/Config/core.php for configuration settings
+ * @param string $name Name of the configuration
+ * @param array $settings Optional associative array of settings passed to the engine
+ * @return array(engine, settings) on success, false on failure
+ * @throws CacheException
+ */
+ public static function config($name = null, $settings = array()) {
+ if (is_array($name)) {
+ $settings = $name;
+ }
+
+ $current = array();
+ if (isset(self::$_config[$name])) {
+ $current = self::$_config[$name];
+ }
+
+ if (!empty($settings)) {
+ self::$_config[$name] = array_merge($current, $settings);
+ }
+
+ if (empty(self::$_config[$name]['engine'])) {
+ return false;
+ }
+
+ $engine = self::$_config[$name]['engine'];
+
+ if (!isset(self::$_engines[$name])) {
+ self::_buildEngine($name);
+ $settings = self::$_config[$name] = self::settings($name);
+ } elseif ($settings = self::set(self::$_config[$name], null, $name)) {
+ self::$_config[$name] = $settings;
+ }
+ return compact('engine', 'settings');
+ }
+
+/**
+ * Finds and builds the instance of the required engine class.
+ *
+ * @param string $name Name of the config array that needs an engine instance built
+ * @return boolean
+ * @throws CacheException
+ */
+ protected static function _buildEngine($name) {
+ $config = self::$_config[$name];
+
+ list($plugin, $class) = pluginSplit($config['engine'], true);
+ $cacheClass = $class . 'Engine';
+ App::uses($cacheClass, $plugin . 'Cache/Engine');
+ if (!class_exists($cacheClass)) {
+ return false;
+ }
+ $cacheClass = $class . 'Engine';
+ if (!is_subclass_of($cacheClass, 'CacheEngine')) {
+ throw new CacheException(__d('cake_dev', 'Cache engines must use CacheEngine as a base class.'));
+ }
+ self::$_engines[$name] = new $cacheClass();
+ if (self::$_engines[$name]->init($config)) {
+ if (self::$_engines[$name]->settings['probability'] && time() % self::$_engines[$name]->settings['probability'] === 0) {
+ self::$_engines[$name]->gc();
+ }
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Returns an array containing the currently configured Cache settings.
+ *
+ * @return array Array of configured Cache config names.
+ */
+ public static function configured() {
+ return array_keys(self::$_config);
+ }
+
+/**
+ * Drops a cache engine. Deletes the cache configuration information
+ * If the deleted configuration is the last configuration using an certain engine,
+ * the Engine instance is also unset.
+ *
+ * @param string $name A currently configured cache config you wish to remove.
+ * @return boolean success of the removal, returns false when the config does not exist.
+ */
+ public static function drop($name) {
+ if (!isset(self::$_config[$name])) {
+ return false;
+ }
+ unset(self::$_config[$name], self::$_engines[$name]);
+ return true;
+ }
+
+/**
+ * Temporarily change the settings on a cache config. The settings will persist for the next write
+ * operation (write, decrement, increment, clear). Any reads that are done before the write, will
+ * use the modified settings. If `$settings` is empty, the settings will be reset to the
+ * original configuration.
+ *
+ * Can be called with 2 or 3 parameters. To set multiple values at once.
+ *
+ * `Cache::set(array('duration' => '+30 minutes'), 'my_config');`
+ *
+ * Or to set one value.
+ *
+ * `Cache::set('duration', '+30 minutes', 'my_config');`
+ *
+ * To reset a config back to the originally configured values.
+ *
+ * `Cache::set(null, 'my_config');`
+ *
+ * @param string|array $settings Optional string for simple name-value pair or array
+ * @param string $value Optional for a simple name-value pair
+ * @param string $config The configuration name you are changing. Defaults to 'default'
+ * @return array Array of settings.
+ */
+ public static function set($settings = array(), $value = null, $config = 'default') {
+ if (is_array($settings) && $value !== null) {
+ $config = $value;
+ }
+ if (!isset(self::$_config[$config]) || !isset(self::$_engines[$config])) {
+ return false;
+ }
+ if (!empty($settings)) {
+ self::$_reset = true;
+ }
+
+ if (self::$_reset === true) {
+ if (empty($settings)) {
+ self::$_reset = false;
+ $settings = self::$_config[$config];
+ } else {
+ if (is_string($settings) && $value !== null) {
+ $settings = array($settings => $value);
+ }
+ $settings = array_merge(self::$_config[$config], $settings);
+ if (isset($settings['duration']) && !is_numeric($settings['duration'])) {
+ $settings['duration'] = strtotime($settings['duration']) - time();
+ }
+ }
+ self::$_engines[$config]->settings = $settings;
+ }
+ return self::settings($config);
+ }
+
+/**
+ * Garbage collection
+ *
+ * Permanently remove all expired and deleted data
+ *
+ * @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default'
+ * @param integer $expires [optional] An expires timestamp. Defaults to NULL
+ * @return void
+ */
+ public static function gc($config = 'default', $expires = null) {
+ self::$_engines[$config]->gc($expires);
+ }
+
+/**
+ * Write data for key into cache. Will automatically use the currently
+ * active cache configuration. To set the currently active configuration use
+ * Cache::config()
+ *
+ * ### Usage:
+ *
+ * Writing to the active cache config:
+ *
+ * `Cache::write('cached_data', $data);`
+ *
+ * Writing to a specific cache config:
+ *
+ * `Cache::write('cached_data', $data, 'long_term');`
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached - anything except a resource
+ * @param string $config Optional string configuration name to write to. Defaults to 'default'
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ public static function write($key, $value, $config = 'default') {
+ $settings = self::settings($config);
+
+ if (empty($settings)) {
+ return false;
+ }
+ if (!self::isInitialized($config)) {
+ return false;
+ }
+ $key = self::$_engines[$config]->key($key);
+
+ if (!$key || is_resource($value)) {
+ return false;
+ }
+
+ $success = self::$_engines[$config]->write($settings['prefix'] . $key, $value, $settings['duration']);
+ self::set(null, $config);
+ if ($success === false && $value !== '') {
+ trigger_error(
+ __d('cake_dev',
+ "%s cache was unable to write '%s' to %s cache",
+ $config,
+ $key,
+ self::$_engines[$config]->settings['engine']
+ ),
+ E_USER_WARNING
+ );
+ }
+ return $success;
+ }
+
+/**
+ * Read a key from the cache. Will automatically use the currently
+ * active cache configuration. To set the currently active configuration use
+ * Cache::config()
+ *
+ * ### Usage:
+ *
+ * Reading from the active cache configuration.
+ *
+ * `Cache::read('my_data');`
+ *
+ * Reading from a specific cache configuration.
+ *
+ * `Cache::read('my_data', 'long_term');`
+ *
+ * @param string $key Identifier for the data
+ * @param string $config optional name of the configuration to use. Defaults to 'default'
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
+ */
+ public static function read($key, $config = 'default') {
+ $settings = self::settings($config);
+
+ if (empty($settings)) {
+ return false;
+ }
+ if (!self::isInitialized($config)) {
+ return false;
+ }
+ $key = self::$_engines[$config]->key($key);
+ if (!$key) {
+ return false;
+ }
+ return self::$_engines[$config]->read($settings['prefix'] . $key);
+ }
+
+/**
+ * Increment a number under the key and return incremented value.
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to add
+ * @param string $config Optional string configuration name. Defaults to 'default'
+ * @return mixed new value, or false if the data doesn't exist, is not integer,
+ * or if there was an error fetching it.
+ */
+ public static function increment($key, $offset = 1, $config = 'default') {
+ $settings = self::settings($config);
+
+ if (empty($settings)) {
+ return false;
+ }
+ if (!self::isInitialized($config)) {
+ return false;
+ }
+ $key = self::$_engines[$config]->key($key);
+
+ if (!$key || !is_integer($offset) || $offset < 0) {
+ return false;
+ }
+ $success = self::$_engines[$config]->increment($settings['prefix'] . $key, $offset);
+ self::set(null, $config);
+ return $success;
+ }
+
+/**
+ * Decrement a number under the key and return decremented value.
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @param string $config Optional string configuration name. Defaults to 'default'
+ * @return mixed new value, or false if the data doesn't exist, is not integer,
+ * or if there was an error fetching it
+ */
+ public static function decrement($key, $offset = 1, $config = 'default') {
+ $settings = self::settings($config);
+
+ if (empty($settings)) {
+ return false;
+ }
+ if (!self::isInitialized($config)) {
+ return false;
+ }
+ $key = self::$_engines[$config]->key($key);
+
+ if (!$key || !is_integer($offset) || $offset < 0) {
+ return false;
+ }
+ $success = self::$_engines[$config]->decrement($settings['prefix'] . $key, $offset);
+ self::set(null, $config);
+ return $success;
+ }
+
+/**
+ * Delete a key from the cache.
+ *
+ * ### Usage:
+ *
+ * Deleting from the active cache configuration.
+ *
+ * `Cache::delete('my_data');`
+ *
+ * Deleting from a specific cache configuration.
+ *
+ * `Cache::delete('my_data', 'long_term');`
+ *
+ * @param string $key Identifier for the data
+ * @param string $config name of the configuration to use. Defaults to 'default'
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public static function delete($key, $config = 'default') {
+ $settings = self::settings($config);
+
+ if (empty($settings)) {
+ return false;
+ }
+ if (!self::isInitialized($config)) {
+ return false;
+ }
+ $key = self::$_engines[$config]->key($key);
+ if (!$key) {
+ return false;
+ }
+
+ $success = self::$_engines[$config]->delete($settings['prefix'] . $key);
+ self::set(null, $config);
+ return $success;
+ }
+
+/**
+ * Delete all keys from the cache.
+ *
+ * @param boolean $check if true will check expiration, otherwise delete all
+ * @param string $config name of the configuration to use. Defaults to 'default'
+ * @return boolean True if the cache was successfully cleared, false otherwise
+ */
+ public static function clear($check = false, $config = 'default') {
+ if (!self::isInitialized($config)) {
+ return false;
+ }
+ $success = self::$_engines[$config]->clear($check);
+ self::set(null, $config);
+ return $success;
+ }
+
+/**
+ * Delete all keys from the cache belonging to the same group.
+ *
+ * @param string $group name of the group to be cleared
+ * @param string $config name of the configuration to use. Defaults to 'default'
+ * @return boolean True if the cache group was successfully cleared, false otherwise
+ */
+ public static function clearGroup($group, $config = 'default') {
+ if (!self::isInitialized($config)) {
+ return false;
+ }
+ $success = self::$_engines[$config]->clearGroup($group);
+ self::set(null, $config);
+ return $success;
+ }
+
+/**
+ * Check if Cache has initialized a working config for the given name.
+ *
+ * @param string $config name of the configuration to use. Defaults to 'default'
+ * @return boolean Whether or not the config name has been initialized.
+ */
+ public static function isInitialized($config = 'default') {
+ if (Configure::read('Cache.disable')) {
+ return false;
+ }
+ return isset(self::$_engines[$config]);
+ }
+
+/**
+ * Return the settings for the named cache engine.
+ *
+ * @param string $name Name of the configuration to get settings for. Defaults to 'default'
+ * @return array list of settings for this engine
+ * @see Cache::config()
+ */
+ public static function settings($name = 'default') {
+ if (!empty(self::$_engines[$name])) {
+ return self::$_engines[$name]->settings();
+ }
+ return array();
+ }
+
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/CacheEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/CacheEngine.php
new file mode 100644
index 0000000..6994701
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/CacheEngine.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Cache
+ * @since CakePHP(tm) v 1.2.0.4933
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Storage engine for CakePHP caching
+ *
+ * @package Cake.Cache
+ */
+abstract class CacheEngine {
+
+/**
+ * Settings of current engine instance
+ *
+ * @var array
+ */
+ public $settings = array();
+
+/**
+ * Contains the compiled string with all groups
+ * prefixes to be prepeded to every key in this cache engine
+ *
+ * @var string
+ **/
+ protected $_groupPrefix = null;
+
+/**
+ * Initialize the cache engine
+ *
+ * Called automatically by the cache frontend
+ *
+ * @param array $settings Associative array of parameters for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ */
+ public function init($settings = array()) {
+ $settings += $this->settings + array(
+ 'prefix' => 'cake_',
+ 'duration' => 3600,
+ 'probability' => 100,
+ 'groups' => array()
+ );
+ $this->settings = $settings;
+ if (!empty($this->settings['groups'])) {
+ sort($this->settings['groups']);
+ $this->_groupPrefix = str_repeat('%s_', count($this->settings['groups']));
+ }
+ if (!is_numeric($this->settings['duration'])) {
+ $this->settings['duration'] = strtotime($this->settings['duration']) - time();
+ }
+ return true;
+ }
+
+/**
+ * Garbage collection
+ *
+ * Permanently remove all expired and deleted data
+ *
+ * @param integer $expires [optional] An expires timestamp, invalidataing all data before.
+ * @return void
+ */
+ public function gc($expires = null) {
+ }
+
+/**
+ * Write value for a key into cache
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached
+ * @param integer $duration How long to cache for.
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ abstract public function write($key, $value, $duration);
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
+ */
+ abstract public function read($key);
+
+/**
+ * Increment a number under the key and return incremented value
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to add
+ * @return New incremented value, false otherwise
+ */
+ abstract public function increment($key, $offset = 1);
+
+/**
+ * Decrement a number under the key and return decremented value
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @return New incremented value, false otherwise
+ */
+ abstract public function decrement($key, $offset = 1);
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ abstract public function delete($key);
+
+/**
+ * Delete all keys from the cache
+ *
+ * @param boolean $check if true will check expiration, otherwise delete all
+ * @return boolean True if the cache was successfully cleared, false otherwise
+ */
+ abstract public function clear($check);
+
+/**
+ * Clears all values belonging to a group. Is upt to the implementing engine
+ * to decide whether actually deete the keys or just simulate it to acheive
+ * the same result.
+ *
+ * @param string $groups name of the group to be cleared
+ * @return boolean
+ */
+ public function clearGroup($group) {
+ return false;
+ }
+
+/**
+ * Does whatever initialization for each group is required
+ * and returns the `group value` for each of them, this is
+ * the token representing each group in the cache key
+ *
+ * @return array
+ */
+ public function groups() {
+ return $this->settings['groups'];
+ }
+
+/**
+ * Cache Engine settings
+ *
+ * @return array settings
+ */
+ public function settings() {
+ return $this->settings;
+ }
+
+/**
+ * Generates a safe key for use with cache engine storage engines.
+ *
+ * @param string $key the key passed over
+ * @return mixed string $key or false
+ */
+ public function key($key) {
+ if (empty($key)) {
+ return false;
+ }
+
+ $prefix = '';
+ if (!empty($this->_groupPrefix)) {
+ $prefix = vsprintf($this->_groupPrefix, $this->groups());
+ }
+
+ $key = preg_replace('/[\s]+/', '_', strtolower(trim(str_replace(array(DS, '/', '.'), '_', strval($key)))));
+ return $prefix . $key;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/ApcEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/ApcEngine.php
new file mode 100644
index 0000000..7b93cbb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/ApcEngine.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ * APC storage engine for cache.
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.4933
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * APC storage engine for cache
+ *
+ * @package Cake.Cache.Engine
+ */
+class ApcEngine extends CacheEngine {
+
+/**
+ * Contains the compiled group names
+ * (prefixed witht the global configuration prefix)
+ *
+ * @var array
+ **/
+ protected $_compiledGroupNames = array();
+
+/**
+ * Initialize the Cache Engine
+ *
+ * Called automatically by the cache frontend
+ * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
+ *
+ * @param array $settings array of setting for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ * @see CacheEngine::__defaults
+ */
+ public function init($settings = array()) {
+ if (!isset($settings['prefix'])) {
+ $settings['prefix'] = Inflector::slug(APP_DIR) . '_';
+ }
+ $settings += array('engine' => 'Apc');
+ parent::init($settings);
+ return function_exists('apc_dec');
+ }
+
+/**
+ * Write data for key into cache
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached
+ * @param integer $duration How long to cache the data, in seconds
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ public function write($key, $value, $duration) {
+ if ($duration == 0) {
+ $expires = 0;
+ } else {
+ $expires = time() + $duration;
+ }
+ apc_store($key . '_expires', $expires, $duration);
+ return apc_store($key, $value, $duration);
+ }
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
+ */
+ public function read($key) {
+ $time = time();
+ $cachetime = intval(apc_fetch($key . '_expires'));
+ if ($cachetime !== 0 && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) {
+ return false;
+ }
+ return apc_fetch($key);
+ }
+
+/**
+ * Increments the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to increment
+ * @return New incremented value, false otherwise
+ */
+ public function increment($key, $offset = 1) {
+ return apc_inc($key, $offset);
+ }
+
+/**
+ * Decrements the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @return New decremented value, false otherwise
+ */
+ public function decrement($key, $offset = 1) {
+ return apc_dec($key, $offset);
+ }
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public function delete($key) {
+ return apc_delete($key);
+ }
+
+/**
+ * Delete all keys from the cache. This will clear every cache config using APC.
+ *
+ * @param boolean $check If true, nothing will be cleared, as entries are removed
+ * from APC as they expired. This flag is really only used by FileEngine.
+ * @return boolean True Returns true.
+ */
+ public function clear($check) {
+ if ($check) {
+ return true;
+ }
+ $info = apc_cache_info('user');
+ $cacheKeys = $info['cache_list'];
+ unset($info);
+ foreach ($cacheKeys as $key) {
+ if (strpos($key['info'], $this->settings['prefix']) === 0) {
+ apc_delete($key['info']);
+ }
+ }
+ return true;
+ }
+
+/**
+ * Returns the `group value` for each of the configured groups
+ * If the group initial value was not found, then it initializes
+ * the group accordingly.
+ *
+ * @return array
+ **/
+ public function groups() {
+ if (empty($this->_compiledGroupNames)) {
+ foreach ($this->settings['groups'] as $group) {
+ $this->_compiledGroupNames[] = $this->settings['prefix'] . $group;
+ }
+ }
+
+ $groups = apc_fetch($this->_compiledGroupNames);
+ if (count($groups) !== count($this->settings['groups'])) {
+ foreach ($this->_compiledGroupNames as $group) {
+ if (!isset($groups[$group])) {
+ apc_store($group, 1);
+ $groups[$group] = 1;
+ }
+ }
+ ksort($groups);
+ }
+
+ $result = array();
+ $groups = array_values($groups);
+ foreach ($this->settings['groups'] as $i => $group) {
+ $result[] = $group . $groups[$i];
+ }
+ return $result;
+ }
+
+/**
+ * Increments the group value to simulate deletion of all keys under a group
+ * old values will remain in storage until they expire.
+ *
+ * @return boolean success
+ **/
+ public function clearGroup($group) {
+ apc_inc($this->settings['prefix'] . $group, 1, $success);
+ return $success;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/FileEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/FileEngine.php
new file mode 100644
index 0000000..9388faf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/FileEngine.php
@@ -0,0 +1,373 @@
+<?php
+/**
+ * File Storage engine for cache. Filestorage is the slowest cache storage
+ * to read and write. However, it is good for servers that don't have other storage
+ * engine available, or have content which is not performance sensitive.
+ *
+ * You can configure a FileEngine cache, using Cache::config()
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.4933
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * File Storage engine for cache. Filestorage is the slowest cache storage
+ * to read and write. However, it is good for servers that don't have other storage
+ * engine available, or have content which is not performance sensitive.
+ *
+ * You can configure a FileEngine cache, using Cache::config()
+ *
+ * @package Cake.Cache.Engine
+ */
+class FileEngine extends CacheEngine {
+
+/**
+ * Instance of SplFileObject class
+ *
+ * @var File
+ */
+ protected $_File = null;
+
+/**
+ * Settings
+ *
+ * - path = absolute path to cache directory, default => CACHE
+ * - prefix = string prefix for filename, default => cake_
+ * - lock = enable file locking on write, default => false
+ * - serialize = serialize the data, default => true
+ *
+ * @var array
+ * @see CacheEngine::__defaults
+ */
+ public $settings = array();
+
+/**
+ * True unless FileEngine::__active(); fails
+ *
+ * @var boolean
+ */
+ protected $_init = true;
+
+/**
+ * Initialize the Cache Engine
+ *
+ * Called automatically by the cache frontend
+ * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
+ *
+ * @param array $settings array of setting for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ */
+ public function init($settings = array()) {
+ $settings += array(
+ 'engine' => 'File',
+ 'path' => CACHE,
+ 'prefix' => 'cake_',
+ 'lock' => true,
+ 'serialize' => true,
+ 'isWindows' => false,
+ 'mask' => 0664
+ );
+ parent::init($settings);
+
+ if (DS === '\\') {
+ $this->settings['isWindows'] = true;
+ }
+ if (substr($this->settings['path'], -1) !== DS) {
+ $this->settings['path'] .= DS;
+ }
+ if (!empty($this->_groupPrefix)) {
+ $this->_groupPrefix = str_replace('_', DS, $this->_groupPrefix);
+ }
+ return $this->_active();
+ }
+
+/**
+ * Garbage collection. Permanently remove all expired and deleted data
+ *
+ * @param integer $expires [optional] An expires timestamp, invalidataing all data before.
+ * @return boolean True if garbage collection was successful, false on failure
+ */
+ public function gc($expires = null) {
+ return $this->clear(true);
+ }
+
+/**
+ * Write data for key into cache
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $data Data to be cached
+ * @param integer $duration How long to cache the data, in seconds
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ public function write($key, $data, $duration) {
+ if ($data === '' || !$this->_init) {
+ return false;
+ }
+
+ if ($this->_setKey($key, true) === false) {
+ return false;
+ }
+
+ $lineBreak = "\n";
+
+ if ($this->settings['isWindows']) {
+ $lineBreak = "\r\n";
+ }
+
+ if (!empty($this->settings['serialize'])) {
+ if ($this->settings['isWindows']) {
+ $data = str_replace('\\', '\\\\\\\\', serialize($data));
+ } else {
+ $data = serialize($data);
+ }
+ }
+
+ $expires = time() + $duration;
+ $contents = $expires . $lineBreak . $data . $lineBreak;
+
+ if ($this->settings['lock']) {
+ $this->_File->flock(LOCK_EX);
+ }
+
+ $this->_File->rewind();
+ $success = $this->_File->ftruncate(0) && $this->_File->fwrite($contents) && $this->_File->fflush();
+
+ if ($this->settings['lock']) {
+ $this->_File->flock(LOCK_UN);
+ }
+
+ return $success;
+ }
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
+ */
+ public function read($key) {
+ if (!$this->_init || $this->_setKey($key) === false) {
+ return false;
+ }
+
+ if ($this->settings['lock']) {
+ $this->_File->flock(LOCK_SH);
+ }
+
+ $this->_File->rewind();
+ $time = time();
+ $cachetime = intval($this->_File->current());
+
+ if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) {
+ if ($this->settings['lock']) {
+ $this->_File->flock(LOCK_UN);
+ }
+ return false;
+ }
+
+ $data = '';
+ $this->_File->next();
+ while ($this->_File->valid()) {
+ $data .= $this->_File->current();
+ $this->_File->next();
+ }
+
+ if ($this->settings['lock']) {
+ $this->_File->flock(LOCK_UN);
+ }
+
+ $data = trim($data);
+
+ if ($data !== '' && !empty($this->settings['serialize'])) {
+ if ($this->settings['isWindows']) {
+ $data = str_replace('\\\\\\\\', '\\', $data);
+ }
+ $data = unserialize((string)$data);
+ }
+ return $data;
+ }
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public function delete($key) {
+ if ($this->_setKey($key) === false || !$this->_init) {
+ return false;
+ }
+ $path = $this->_File->getRealPath();
+ $this->_File = null;
+ return unlink($path);
+ }
+
+/**
+ * Delete all values from the cache
+ *
+ * @param boolean $check Optional - only delete expired cache items
+ * @return boolean True if the cache was successfully cleared, false otherwise
+ */
+ public function clear($check) {
+ if (!$this->_init) {
+ return false;
+ }
+ $dir = dir($this->settings['path']);
+ if ($check) {
+ $now = time();
+ $threshold = $now - $this->settings['duration'];
+ }
+ $prefixLength = strlen($this->settings['prefix']);
+ while (($entry = $dir->read()) !== false) {
+ if (substr($entry, 0, $prefixLength) !== $this->settings['prefix']) {
+ continue;
+ }
+ if ($this->_setKey($entry) === false) {
+ continue;
+ }
+ if ($check) {
+ $mtime = $this->_File->getMTime();
+
+ if ($mtime > $threshold) {
+ continue;
+ }
+
+ $expires = (int)$this->_File->current();
+
+ if ($expires > $now) {
+ continue;
+ }
+ }
+ $path = $this->_File->getRealPath();
+ $this->_File = null;
+ if (file_exists($path)) {
+ unlink($path);
+ }
+ }
+ $dir->close();
+ return true;
+ }
+
+/**
+ * Not implemented
+ *
+ * @param string $key
+ * @param integer $offset
+ * @return void
+ * @throws CacheException
+ */
+ public function decrement($key, $offset = 1) {
+ throw new CacheException(__d('cake_dev', 'Files cannot be atomically decremented.'));
+ }
+
+/**
+ * Not implemented
+ *
+ * @param string $key
+ * @param integer $offset
+ * @return void
+ * @throws CacheException
+ */
+ public function increment($key, $offset = 1) {
+ throw new CacheException(__d('cake_dev', 'Files cannot be atomically incremented.'));
+ }
+
+/**
+ * Sets the current cache key this class is managing, and creates a writable SplFileObject
+ * for the cache file the key is referring to.
+ *
+ * @param string $key The key
+ * @param boolean $createKey Whether the key should be created if it doesn't exists, or not
+ * @return boolean true if the cache key could be set, false otherwise
+ */
+ protected function _setKey($key, $createKey = false) {
+ $groups = null;
+ if (!empty($this->_groupPrefix)) {
+ $groups = vsprintf($this->_groupPrefix, $this->groups());
+ }
+ $dir = $this->settings['path'] . $groups;
+
+ if (!is_dir($dir)) {
+ mkdir($dir, 0777, true);
+ }
+ $path = new SplFileInfo($dir . $key);
+
+ if (!$createKey && !$path->isFile()) {
+ return false;
+ }
+ if (empty($this->_File) || $this->_File->getBaseName() !== $key) {
+ $exists = file_exists($path->getPathname());
+ try {
+ $this->_File = $path->openFile('c+');
+ } catch (Exception $e) {
+ trigger_error($e->getMessage(), E_USER_WARNING);
+ return false;
+ }
+ unset($path);
+
+ if (!$exists && !chmod($this->_File->getPathname(), (int)$this->settings['mask'])) {
+ trigger_error(__d(
+ 'cake_dev', 'Could not apply permission mask "%s" on cache file "%s"',
+ array($this->_File->getPathname(), $this->settings['mask'])), E_USER_WARNING);
+ }
+ }
+ return true;
+ }
+
+/**
+ * Determine is cache directory is writable
+ *
+ * @return boolean
+ */
+ protected function _active() {
+ $dir = new SplFileInfo($this->settings['path']);
+ if ($this->_init && !($dir->isDir() && $dir->isWritable())) {
+ $this->_init = false;
+ trigger_error(__d('cake_dev', '%s is not writable', $this->settings['path']), E_USER_WARNING);
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Generates a safe key for use with cache engine storage engines.
+ *
+ * @param string $key the key passed over
+ * @return mixed string $key or false
+ */
+ public function key($key) {
+ if (empty($key)) {
+ return false;
+ }
+
+ $key = Inflector::underscore(str_replace(array(DS, '/', '.'), '_', strval($key)));
+ return $key;
+ }
+
+/**
+ * Recursively deletes all files under any directory named as $group
+ *
+ * @return boolean success
+ **/
+ public function clearGroup($group) {
+ $directoryIterator = new RecursiveDirectoryIterator($this->settings['path']);
+ $contents = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($contents as $object) {
+ $containsGroup = strpos($object->getPathName(), DS . $group . DS) !== false;
+ if ($object->isFile() && $containsGroup) {
+ unlink($object->getPathName());
+ }
+ }
+ return true;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/MemcacheEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/MemcacheEngine.php
new file mode 100644
index 0000000..4729de3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/MemcacheEngine.php
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Memcache storage engine for cache
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.4933
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Memcache storage engine for cache. Memcache has some limitations in the amount of
+ * control you have over expire times far in the future. See MemcacheEngine::write() for
+ * more information.
+ *
+ * @package Cake.Cache.Engine
+ */
+class MemcacheEngine extends CacheEngine {
+
+/**
+ * Contains the compiled group names
+ * (prefixed witht the global configuration prefix)
+ *
+ * @var array
+ **/
+ protected $_compiledGroupNames = array();
+
+/**
+ * Memcache wrapper.
+ *
+ * @var Memcache
+ */
+ protected $_Memcache = null;
+
+/**
+ * Settings
+ *
+ * - servers = string or array of memcache servers, default => 127.0.0.1. If an
+ * array MemcacheEngine will use them as a pool.
+ * - compress = boolean, default => false
+ *
+ * @var array
+ */
+ public $settings = array();
+
+/**
+ * Initialize the Cache Engine
+ *
+ * Called automatically by the cache frontend
+ * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
+ *
+ * @param array $settings array of setting for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ */
+ public function init($settings = array()) {
+ if (!class_exists('Memcache')) {
+ return false;
+ }
+ if (!isset($settings['prefix'])) {
+ $settings['prefix'] = Inflector::slug(APP_DIR) . '_';
+ }
+ $settings += array(
+ 'engine' => 'Memcache',
+ 'servers' => array('127.0.0.1'),
+ 'compress' => false,
+ 'persistent' => true
+ );
+ parent::init($settings);
+
+ if ($this->settings['compress']) {
+ $this->settings['compress'] = MEMCACHE_COMPRESSED;
+ }
+ if (is_string($this->settings['servers'])) {
+ $this->settings['servers'] = array($this->settings['servers']);
+ }
+ if (!isset($this->_Memcache)) {
+ $return = false;
+ $this->_Memcache = new Memcache();
+ foreach ($this->settings['servers'] as $server) {
+ list($host, $port) = $this->_parseServerString($server);
+ if ($this->_Memcache->addServer($host, $port, $this->settings['persistent'])) {
+ $return = true;
+ }
+ }
+ return $return;
+ }
+ return true;
+ }
+
+/**
+ * Parses the server address into the host/port. Handles both IPv6 and IPv4
+ * addresses and Unix sockets
+ *
+ * @param string $server The server address string.
+ * @return array Array containing host, port
+ */
+ protected function _parseServerString($server) {
+ if ($server[0] == 'u') {
+ return array($server, 0);
+ }
+ if (substr($server, 0, 1) == '[') {
+ $position = strpos($server, ']:');
+ if ($position !== false) {
+ $position++;
+ }
+ } else {
+ $position = strpos($server, ':');
+ }
+ $port = 11211;
+ $host = $server;
+ if ($position !== false) {
+ $host = substr($server, 0, $position);
+ $port = substr($server, $position + 1);
+ }
+ return array($host, $port);
+ }
+
+/**
+ * Write data for key into cache. When using memcache as your cache engine
+ * remember that the Memcache pecl extension does not support cache expiry times greater
+ * than 30 days in the future. Any duration greater than 30 days will be treated as never expiring.
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached
+ * @param integer $duration How long to cache the data, in seconds
+ * @return boolean True if the data was successfully cached, false on failure
+ * @see http://php.net/manual/en/memcache.set.php
+ */
+ public function write($key, $value, $duration) {
+ if ($duration > 30 * DAY) {
+ $duration = 0;
+ }
+ return $this->_Memcache->set($key, $value, $this->settings['compress'], $duration);
+ }
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
+ */
+ public function read($key) {
+ return $this->_Memcache->get($key);
+ }
+
+/**
+ * Increments the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to increment
+ * @return New incremented value, false otherwise
+ * @throws CacheException when you try to increment with compress = true
+ */
+ public function increment($key, $offset = 1) {
+ if ($this->settings['compress']) {
+ throw new CacheException(
+ __d('cake_dev', 'Method increment() not implemented for compressed cache in %s', __CLASS__)
+ );
+ }
+ return $this->_Memcache->increment($key, $offset);
+ }
+
+/**
+ * Decrements the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @return New decremented value, false otherwise
+ * @throws CacheException when you try to decrement with compress = true
+ */
+ public function decrement($key, $offset = 1) {
+ if ($this->settings['compress']) {
+ throw new CacheException(
+ __d('cake_dev', 'Method decrement() not implemented for compressed cache in %s', __CLASS__)
+ );
+ }
+ return $this->_Memcache->decrement($key, $offset);
+ }
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public function delete($key) {
+ return $this->_Memcache->delete($key);
+ }
+
+/**
+ * Delete all keys from the cache
+ *
+ * @param boolean $check
+ * @return boolean True if the cache was successfully cleared, false otherwise
+ */
+ public function clear($check) {
+ if ($check) {
+ return true;
+ }
+ foreach ($this->_Memcache->getExtendedStats('slabs') as $slabs) {
+ foreach (array_keys($slabs) as $slabId) {
+ if (!is_numeric($slabId)) {
+ continue;
+ }
+
+ foreach ($this->_Memcache->getExtendedStats('cachedump', $slabId) as $stats) {
+ if (!is_array($stats)) {
+ continue;
+ }
+ foreach (array_keys($stats) as $key) {
+ if (strpos($key, $this->settings['prefix']) === 0) {
+ $this->_Memcache->delete($key);
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Connects to a server in connection pool
+ *
+ * @param string $host host ip address or name
+ * @param integer $port Server port
+ * @return boolean True if memcache server was connected
+ */
+ public function connect($host, $port = 11211) {
+ if ($this->_Memcache->getServerStatus($host, $port) === 0) {
+ if ($this->_Memcache->connect($host, $port)) {
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Returns the `group value` for each of the configured groups
+ * If the group initial value was not found, then it initializes
+ * the group accordingly.
+ *
+ * @return array
+ **/
+ public function groups() {
+ if (empty($this->_compiledGroupNames)) {
+ foreach ($this->settings['groups'] as $group) {
+ $this->_compiledGroupNames[] = $this->settings['prefix'] . $group;
+ }
+ }
+
+ $groups = $this->_Memcache->get($this->_compiledGroupNames);
+ if (count($groups) !== count($this->settings['groups'])) {
+ foreach ($this->_compiledGroupNames as $group) {
+ if (!isset($groups[$group])) {
+ $this->_Memcache->set($group, 1, false, 0);
+ $groups[$group] = 1;
+ }
+ }
+ ksort($groups);
+ }
+
+ $result = array();
+ $groups = array_values($groups);
+ foreach ($this->settings['groups'] as $i => $group) {
+ $result[] = $group . $groups[$i];
+ }
+
+ return $result;
+ }
+
+/**
+ * Increments the group value to simulate deletion of all keys under a group
+ * old values will remain in storage until they expire.
+ *
+ * @return boolean success
+ **/
+ public function clearGroup($group) {
+ return (bool)$this->_Memcache->increment($this->settings['prefix'] . $group);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/RedisEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/RedisEngine.php
new file mode 100644
index 0000000..e058dcb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/RedisEngine.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * Redis storage engine for cache
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Cache.Engine
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Redis storage engine for cache.
+ *
+ * @package Cake.Cache.Engine
+ */
+class RedisEngine extends CacheEngine {
+
+/**
+ * Redis wrapper.
+ *
+ * @var Redis
+ */
+ protected $_Redis = null;
+
+/**
+ * Settings
+ *
+ * - server = string url or ip to the Redis server host
+ * - port = integer port number to the Redis server (default: 6379)
+ * - timeout = float timeout in seconds (default: 0)
+ * - persistent = bool Connects to the Redis server with a persistent connection (default: true)
+ *
+ * @var array
+ */
+ public $settings = array();
+
+/**
+ * Initialize the Cache Engine
+ *
+ * Called automatically by the cache frontend
+ * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
+ *
+ * @param array $settings array of setting for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ */
+ public function init($settings = array()) {
+ if (!class_exists('Redis')) {
+ return false;
+ }
+ parent::init(array_merge(array(
+ 'engine' => 'Redis',
+ 'prefix' => null,
+ 'server' => '127.0.0.1',
+ 'port' => 6379,
+ 'timeout' => 0,
+ 'persistent' => true
+ ), $settings)
+ );
+
+ return $this->_connect();
+ }
+
+/**
+ * Connects to a Redis server
+ *
+ * @return boolean True if Redis server was connected
+ */
+ protected function _connect() {
+ $return = false;
+ try {
+ $this->_Redis = new Redis();
+ if (empty($this->settings['persistent'])) {
+ $return = $this->_Redis->connect($this->settings['server'], $this->settings['port'], $this->settings['timeout']);
+ } else {
+ $return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout']);
+ }
+ } catch (RedisException $e) {
+ return false;
+ }
+ return $return;
+ }
+
+/**
+ * Write data for key into cache.
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached
+ * @param integer $duration How long to cache the data, in seconds
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ public function write($key, $value, $duration) {
+ if (!is_int($value)) {
+ $value = serialize($value);
+ }
+ if ($duration === 0) {
+ return $this->_Redis->set($key, $value);
+ }
+
+ return $this->_Redis->setex($key, $duration, $value);
+ }
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
+ */
+ public function read($key) {
+ $value = $this->_Redis->get($key);
+ if (ctype_digit($value)) {
+ $value = (int)$value;
+ }
+ if ($value !== false && is_string($value)) {
+ $value = unserialize($value);
+ }
+ return $value;
+ }
+
+/**
+ * Increments the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to increment
+ * @return New incremented value, false otherwise
+ * @throws CacheException when you try to increment with compress = true
+ */
+ public function increment($key, $offset = 1) {
+ return (int)$this->_Redis->incrBy($key, $offset);
+ }
+
+/**
+ * Decrements the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @return New decremented value, false otherwise
+ * @throws CacheException when you try to decrement with compress = true
+ */
+ public function decrement($key, $offset = 1) {
+ return (int)$this->_Redis->decrBy($key, $offset);
+ }
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public function delete($key) {
+ return $this->_Redis->delete($key) > 0;
+ }
+
+/**
+ * Delete all keys from the cache
+ *
+ * @param boolean $check
+ * @return boolean True if the cache was successfully cleared, false otherwise
+ */
+ public function clear($check) {
+ if ($check) {
+ return true;
+ }
+ $keys = $this->_Redis->getKeys($this->settings['prefix'] . '*');
+ $this->_Redis->del($keys);
+
+ return true;
+ }
+
+/**
+ * Returns the `group value` for each of the configured groups
+ * If the group initial value was not found, then it initializes
+ * the group accordingly.
+ *
+ * @return array
+ **/
+ public function groups() {
+ $result = array();
+ foreach ($this->settings['groups'] as $group) {
+ $value = $this->_Redis->get($this->settings['prefix'] . $group);
+ if (!$value) {
+ $value = 1;
+ $this->_Redis->set($this->settings['prefix'] . $group, $value);
+ }
+ $result[] = $group . $value;
+ }
+ return $result;
+ }
+
+/**
+ * Increments the group value to simulate deletion of all keys under a group
+ * old values will remain in storage until they expire.
+ *
+ * @return boolean success
+ **/
+ public function clearGroup($group) {
+ return (bool)$this->_Redis->incr($this->settings['prefix'] . $group);
+ }
+
+/**
+ * Disconnects from the redis server
+ *
+ * @return voind
+ **/
+ public function __destruct() {
+ if (!$this->settings['persistent']) {
+ $this->_Redis->close();
+ }
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/WincacheEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/WincacheEngine.php
new file mode 100644
index 0000000..542172c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/WincacheEngine.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Wincache storage engine for cache.
+ *
+ * Supports wincache 1.1.0 and higher.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.4933
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Wincache storage engine for cache
+ *
+ * @package Cake.Cache.Engine
+ */
+class WincacheEngine extends CacheEngine {
+
+/**
+ * Contains the compiled group names
+ * (prefixed witht the global configuration prefix)
+ *
+ * @var array
+ **/
+ protected $_compiledGroupNames = array();
+
+/**
+ * Initialize the Cache Engine
+ *
+ * Called automatically by the cache frontend
+ * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
+ *
+ * @param array $settings array of setting for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ * @see CacheEngine::__defaults
+ */
+ public function init($settings = array()) {
+ if (!isset($settings['prefix'])) {
+ $settings['prefix'] = Inflector::slug(APP_DIR) . '_';
+ }
+ $settings += array('engine' => 'Wincache');
+ parent::init($settings);
+ return function_exists('wincache_ucache_info');
+ }
+
+/**
+ * Write data for key into cache
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached
+ * @param integer $duration How long to cache the data, in seconds
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ public function write($key, $value, $duration) {
+ $expires = time() + $duration;
+
+ $data = array(
+ $key . '_expires' => $expires,
+ $key => $value
+ );
+ $result = wincache_ucache_set($data, null, $duration);
+ return empty($result);
+ }
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if
+ * there was an error fetching it
+ */
+ public function read($key) {
+ $time = time();
+ $cachetime = intval(wincache_ucache_get($key . '_expires'));
+ if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) {
+ return false;
+ }
+ return wincache_ucache_get($key);
+ }
+
+/**
+ * Increments the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to increment
+ * @return New incremented value, false otherwise
+ */
+ public function increment($key, $offset = 1) {
+ return wincache_ucache_inc($key, $offset);
+ }
+
+/**
+ * Decrements the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @return New decremented value, false otherwise
+ */
+ public function decrement($key, $offset = 1) {
+ return wincache_ucache_dec($key, $offset);
+ }
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public function delete($key) {
+ return wincache_ucache_delete($key);
+ }
+
+/**
+ * Delete all keys from the cache. This will clear every
+ * item in the cache matching the cache config prefix.
+ *
+ * @param boolean $check If true, nothing will be cleared, as entries will
+ * naturally expire in wincache..
+ * @return boolean True Returns true.
+ */
+ public function clear($check) {
+ if ($check) {
+ return true;
+ }
+ $info = wincache_ucache_info();
+ $cacheKeys = $info['ucache_entries'];
+ unset($info);
+ foreach ($cacheKeys as $key) {
+ if (strpos($key['key_name'], $this->settings['prefix']) === 0) {
+ wincache_ucache_delete($key['key_name']);
+ }
+ }
+ return true;
+ }
+
+/**
+ * Returns the `group value` for each of the configured groups
+ * If the group initial value was not found, then it initializes
+ * the group accordingly.
+ *
+ * @return array
+ **/
+ public function groups() {
+ if (empty($this->_compiledGroupNames)) {
+ foreach ($this->settings['groups'] as $group) {
+ $this->_compiledGroupNames[] = $this->settings['prefix'] . $group;
+ }
+ }
+
+ $groups = wincache_ucache_get($this->_compiledGroupNames);
+ if (count($groups) !== count($this->settings['groups'])) {
+ foreach ($this->_compiledGroupNames as $group) {
+ if (!isset($groups[$group])) {
+ wincache_ucache_set($group, 1);
+ $groups[$group] = 1;
+ }
+ }
+ ksort($groups);
+ }
+
+ $result = array();
+ $groups = array_values($groups);
+ foreach ($this->settings['groups'] as $i => $group) {
+ $result[] = $group . $groups[$i];
+ }
+ return $result;
+ }
+
+/**
+ * Increments the group value to simulate deletion of all keys under a group
+ * old values will remain in storage until they expire.
+ *
+ * @return boolean success
+ **/
+ public function clearGroup($group) {
+ wincache_ucache_inc($this->settings['prefix'] . $group, 1, $success);
+ return $success;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/XcacheEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/XcacheEngine.php
new file mode 100644
index 0000000..8f5d229
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Cache/Engine/XcacheEngine.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ * Xcache storage engine for cache.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.4947
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Xcache storage engine for cache
+ *
+ * @link http://trac.lighttpd.net/xcache/ Xcache
+ * @package Cake.Cache.Engine
+ */
+class XcacheEngine extends CacheEngine {
+
+/**
+ * Settings
+ *
+ * - PHP_AUTH_USER = xcache.admin.user, default cake
+ * - PHP_AUTH_PW = xcache.admin.password, default cake
+ *
+ * @var array
+ */
+ public $settings = array();
+
+/**
+ * Initialize the Cache Engine
+ *
+ * Called automatically by the cache frontend
+ * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
+ *
+ * @param array $settings array of setting for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ */
+ public function init($settings = array()) {
+ if (php_sapi_name() !== 'cli') {
+ parent::init(array_merge(array(
+ 'engine' => 'Xcache',
+ 'prefix' => Inflector::slug(APP_DIR) . '_',
+ 'PHP_AUTH_USER' => 'user',
+ 'PHP_AUTH_PW' => 'password'
+ ), $settings)
+ );
+ return function_exists('xcache_info');
+ }
+ return false;
+ }
+
+/**
+ * Write data for key into cache
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached
+ * @param integer $duration How long to cache the data, in seconds
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ public function write($key, $value, $duration) {
+ $expires = time() + $duration;
+ xcache_set($key . '_expires', $expires, $duration);
+ return xcache_set($key, $value, $duration);
+ }
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
+ */
+ public function read($key) {
+ if (xcache_isset($key)) {
+ $time = time();
+ $cachetime = intval(xcache_get($key . '_expires'));
+ if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) {
+ return false;
+ }
+ return xcache_get($key);
+ }
+ return false;
+ }
+
+/**
+ * Increments the value of an integer cached key
+ * If the cache key is not an integer it will be treated as 0
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to increment
+ * @return New incremented value, false otherwise
+ */
+ public function increment($key, $offset = 1) {
+ return xcache_inc($key, $offset);
+ }
+
+/**
+ * Decrements the value of an integer cached key.
+ * If the cache key is not an integer it will be treated as 0
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @return New decremented value, false otherwise
+ */
+ public function decrement($key, $offset = 1) {
+ return xcache_dec($key, $offset);
+ }
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public function delete($key) {
+ return xcache_unset($key);
+ }
+
+/**
+ * Delete all keys from the cache
+ *
+ * @param boolean $check
+ * @return boolean True if the cache was successfully cleared, false otherwise
+ */
+ public function clear($check) {
+ $this->_auth();
+ $max = xcache_count(XC_TYPE_VAR);
+ for ($i = 0; $i < $max; $i++) {
+ xcache_clear_cache(XC_TYPE_VAR, $i);
+ }
+ $this->_auth(true);
+ return true;
+ }
+
+/**
+ * Returns the `group value` for each of the configured groups
+ * If the group initial value was not found, then it initializes
+ * the group accordingly.
+ *
+ * @return array
+ **/
+ public function groups() {
+ $result = array();
+ foreach ($this->settings['groups'] as $group) {
+ $value = xcache_get($this->settings['prefix'] . $group);
+ if (!$value) {
+ $value = 1;
+ xcache_set($this->settings['prefix'] . $group, $value, 0);
+ }
+ $result[] = $group . $value;
+ }
+ return $result;
+ }
+
+/**
+ * Increments the group value to simulate deletion of all keys under a group
+ * old values will remain in storage until they expire.
+ *
+ * @return boolean success
+ **/
+ public function clearGroup($group) {
+ return (bool)xcache_inc($this->settings['prefix'] . $group, 1);
+ }
+
+/**
+ * Populates and reverses $_SERVER authentication values
+ * Makes necessary changes (and reverting them back) in $_SERVER
+ *
+ * This has to be done because xcache_clear_cache() needs to pass Basic Http Auth
+ * (see xcache.admin configuration settings)
+ *
+ * @param boolean $reverse Revert changes
+ * @return void
+ */
+ protected function _auth($reverse = false) {
+ static $backup = array();
+ $keys = array('PHP_AUTH_USER' => 'user', 'PHP_AUTH_PW' => 'password');
+ foreach ($keys as $key => $setting) {
+ if ($reverse) {
+ if (isset($backup[$key])) {
+ $_SERVER[$key] = $backup[$key];
+ unset($backup[$key]);
+ } else {
+ unset($_SERVER[$key]);
+ }
+ } else {
+ $value = env($key);
+ if (!empty($value)) {
+ $backup[$key] = $value;
+ }
+ if (!empty($this->settings[$setting])) {
+ $_SERVER[$key] = $this->settings[$setting];
+ } elseif (!empty($this->settings[$key])) {
+ $_SERVER[$key] = $this->settings[$key];
+ } else {
+ $_SERVER[$key] = $value;
+ }
+ }
+ }
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/config.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/config.php
new file mode 100644
index 0000000..f8528e8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/config.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Core Configurations.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config
+ * @since CakePHP(tm) v 1.1.11.4062
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$versionFile = file(CAKE . 'VERSION.txt');
+$config['Cake.version'] = trim(array_pop($versionFile));
+return $config;
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/routes.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/routes.php
new file mode 100644
index 0000000..4667c42
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/routes.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Default routes that CakePHP provides as catch all routes.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Connects the default, built-in routes, including prefix and plugin routes. The following routes are created
+ * in the order below:
+ *
+ * For each of the Routing.prefixes the following routes are created. Routes containing `:plugin` are only
+ * created when your application has one or more plugins.
+ *
+ * - `/:prefix/:plugin` a plugin shortcut route.
+ * - `/:prefix/:plugin/:action/*` a plugin shortcut route.
+ * - `/:prefix/:plugin/:controller`
+ * - `/:prefix/:plugin/:controller/:action/*`
+ * - `/:prefix/:controller`
+ * - `/:prefix/:controller/:action/*`
+ *
+ * If plugins are found in your application the following routes are created:
+ *
+ * - `/:plugin` a plugin shortcut route.
+ * - `/:plugin/:action/*` a plugin shortcut route.
+ * - `/:plugin/:controller`
+ * - `/:plugin/:controller/:action/*`
+ *
+ * And lastly the following catch-all routes are connected.
+ *
+ * - `/:controller'
+ * - `/:controller/:action/*'
+ *
+ * You can disable the connection of default routes by deleting the require inside APP/Config/routes.php.
+ */
+$prefixes = Router::prefixes();
+
+if ($plugins = CakePlugin::loaded()) {
+ App::uses('PluginShortRoute', 'Routing/Route');
+ foreach ($plugins as $key => $value) {
+ $plugins[$key] = Inflector::underscore($value);
+ }
+ $pluginPattern = implode('|', $plugins);
+ $match = array('plugin' => $pluginPattern);
+ $shortParams = array('routeClass' => 'PluginShortRoute', 'plugin' => $pluginPattern);
+
+ foreach ($prefixes as $prefix) {
+ $params = array('prefix' => $prefix, $prefix => true);
+ $indexParams = $params + array('action' => 'index');
+ Router::connect("/{$prefix}/:plugin", $indexParams, $shortParams);
+ Router::connect("/{$prefix}/:plugin/:controller", $indexParams, $match);
+ Router::connect("/{$prefix}/:plugin/:controller/:action/*", $params, $match);
+ }
+ Router::connect('/:plugin', array('action' => 'index'), $shortParams);
+ Router::connect('/:plugin/:controller', array('action' => 'index'), $match);
+ Router::connect('/:plugin/:controller/:action/*', array(), $match);
+}
+
+foreach ($prefixes as $prefix) {
+ $params = array('prefix' => $prefix, $prefix => true);
+ $indexParams = $params + array('action' => 'index');
+ Router::connect("/{$prefix}/:controller", $indexParams);
+ Router::connect("/{$prefix}/:controller/:action/*", $params);
+}
+Router::connect('/:controller', array('action' => 'index'));
+Router::connect('/:controller/:action/*');
+
+$namedConfig = Router::namedConfig();
+if ($namedConfig['rules'] === false) {
+ Router::connectNamed(true);
+}
+
+unset($namedConfig, $params, $indexParams, $prefix, $prefixes, $shortParams, $match,
+ $pluginPattern, $plugins, $key, $value);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0080_00ff.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0080_00ff.php
new file mode 100644
index 0000000..542f47d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0080_00ff.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0080 through U+00FF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0080_00ff'][] = array('upper' => 181, 'status' => 'C', 'lower' => array(956));
+$config['0080_00ff'][] = array('upper' => 924, 'status' => 'C', 'lower' => array(181));
+$config['0080_00ff'][] = array('upper' => 192, 'status' => 'C', 'lower' => array(224)); /* LATIN CAPITAL LETTER A WITH GRAVE */
+$config['0080_00ff'][] = array('upper' => 193, 'status' => 'C', 'lower' => array(225)); /* LATIN CAPITAL LETTER A WITH ACUTE */
+$config['0080_00ff'][] = array('upper' => 194, 'status' => 'C', 'lower' => array(226)); /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+$config['0080_00ff'][] = array('upper' => 195, 'status' => 'C', 'lower' => array(227)); /* LATIN CAPITAL LETTER A WITH TILDE */
+$config['0080_00ff'][] = array('upper' => 196, 'status' => 'C', 'lower' => array(228)); /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+$config['0080_00ff'][] = array('upper' => 197, 'status' => 'C', 'lower' => array(229)); /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+$config['0080_00ff'][] = array('upper' => 198, 'status' => 'C', 'lower' => array(230)); /* LATIN CAPITAL LETTER AE */
+$config['0080_00ff'][] = array('upper' => 199, 'status' => 'C', 'lower' => array(231)); /* LATIN CAPITAL LETTER C WITH CEDILLA */
+$config['0080_00ff'][] = array('upper' => 200, 'status' => 'C', 'lower' => array(232)); /* LATIN CAPITAL LETTER E WITH GRAVE */
+$config['0080_00ff'][] = array('upper' => 201, 'status' => 'C', 'lower' => array(233)); /* LATIN CAPITAL LETTER E WITH ACUTE */
+$config['0080_00ff'][] = array('upper' => 202, 'status' => 'C', 'lower' => array(234)); /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+$config['0080_00ff'][] = array('upper' => 203, 'status' => 'C', 'lower' => array(235)); /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+$config['0080_00ff'][] = array('upper' => 204, 'status' => 'C', 'lower' => array(236)); /* LATIN CAPITAL LETTER I WITH GRAVE */
+$config['0080_00ff'][] = array('upper' => 205, 'status' => 'C', 'lower' => array(237)); /* LATIN CAPITAL LETTER I WITH ACUTE */
+$config['0080_00ff'][] = array('upper' => 206, 'status' => 'C', 'lower' => array(238)); /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+$config['0080_00ff'][] = array('upper' => 207, 'status' => 'C', 'lower' => array(239)); /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+$config['0080_00ff'][] = array('upper' => 208, 'status' => 'C', 'lower' => array(240)); /* LATIN CAPITAL LETTER ETH */
+$config['0080_00ff'][] = array('upper' => 209, 'status' => 'C', 'lower' => array(241)); /* LATIN CAPITAL LETTER N WITH TILDE */
+$config['0080_00ff'][] = array('upper' => 210, 'status' => 'C', 'lower' => array(242)); /* LATIN CAPITAL LETTER O WITH GRAVE */
+$config['0080_00ff'][] = array('upper' => 211, 'status' => 'C', 'lower' => array(243)); /* LATIN CAPITAL LETTER O WITH ACUTE */
+$config['0080_00ff'][] = array('upper' => 212, 'status' => 'C', 'lower' => array(244)); /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+$config['0080_00ff'][] = array('upper' => 213, 'status' => 'C', 'lower' => array(245)); /* LATIN CAPITAL LETTER O WITH TILDE */
+$config['0080_00ff'][] = array('upper' => 214, 'status' => 'C', 'lower' => array(246)); /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+$config['0080_00ff'][] = array('upper' => 216, 'status' => 'C', 'lower' => array(248)); /* LATIN CAPITAL LETTER O WITH STROKE */
+$config['0080_00ff'][] = array('upper' => 217, 'status' => 'C', 'lower' => array(249)); /* LATIN CAPITAL LETTER U WITH GRAVE */
+$config['0080_00ff'][] = array('upper' => 218, 'status' => 'C', 'lower' => array(250)); /* LATIN CAPITAL LETTER U WITH ACUTE */
+$config['0080_00ff'][] = array('upper' => 219, 'status' => 'C', 'lower' => array(251)); /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+$config['0080_00ff'][] = array('upper' => 220, 'status' => 'C', 'lower' => array(252)); /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+$config['0080_00ff'][] = array('upper' => 221, 'status' => 'C', 'lower' => array(253)); /* LATIN CAPITAL LETTER Y WITH ACUTE */
+$config['0080_00ff'][] = array('upper' => 222, 'status' => 'C', 'lower' => array(254)); /* LATIN CAPITAL LETTER THORN */
+$config['0080_00ff'][] = array('upper' => 223, 'status' => 'F', 'lower' => array(115, 115)); /* LATIN SMALL LETTER SHARP S */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0100_017f.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0100_017f.php
new file mode 100644
index 0000000..e8c3ff6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0100_017f.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0100 through U+017F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0100_017f'][] = array('upper' => 256, 'status' => 'C', 'lower' => array(257)); /* LATIN CAPITAL LETTER A WITH MACRON */
+$config['0100_017f'][] = array('upper' => 258, 'status' => 'C', 'lower' => array(259)); /* LATIN CAPITAL LETTER A WITH BREVE */
+$config['0100_017f'][] = array('upper' => 260, 'status' => 'C', 'lower' => array(261)); /* LATIN CAPITAL LETTER A WITH OGONEK */
+$config['0100_017f'][] = array('upper' => 262, 'status' => 'C', 'lower' => array(263)); /* LATIN CAPITAL LETTER C WITH ACUTE */
+$config['0100_017f'][] = array('upper' => 264, 'status' => 'C', 'lower' => array(265)); /* LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+$config['0100_017f'][] = array('upper' => 266, 'status' => 'C', 'lower' => array(267)); /* LATIN CAPITAL LETTER C WITH DOT ABOVE */
+$config['0100_017f'][] = array('upper' => 268, 'status' => 'C', 'lower' => array(269)); /* LATIN CAPITAL LETTER C WITH CARON */
+$config['0100_017f'][] = array('upper' => 270, 'status' => 'C', 'lower' => array(271)); /* LATIN CAPITAL LETTER D WITH CARON */
+$config['0100_017f'][] = array('upper' => 272, 'status' => 'C', 'lower' => array(273)); /* LATIN CAPITAL LETTER D WITH STROKE */
+$config['0100_017f'][] = array('upper' => 274, 'status' => 'C', 'lower' => array(275)); /* LATIN CAPITAL LETTER E WITH MACRON */
+$config['0100_017f'][] = array('upper' => 276, 'status' => 'C', 'lower' => array(277)); /* LATIN CAPITAL LETTER E WITH BREVE */
+$config['0100_017f'][] = array('upper' => 278, 'status' => 'C', 'lower' => array(279)); /* LATIN CAPITAL LETTER E WITH DOT ABOVE */
+$config['0100_017f'][] = array('upper' => 280, 'status' => 'C', 'lower' => array(281)); /* LATIN CAPITAL LETTER E WITH OGONEK */
+$config['0100_017f'][] = array('upper' => 282, 'status' => 'C', 'lower' => array(283)); /* LATIN CAPITAL LETTER E WITH CARON */
+$config['0100_017f'][] = array('upper' => 284, 'status' => 'C', 'lower' => array(285)); /* LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+$config['0100_017f'][] = array('upper' => 286, 'status' => 'C', 'lower' => array(287)); /* LATIN CAPITAL LETTER G WITH BREVE */
+$config['0100_017f'][] = array('upper' => 288, 'status' => 'C', 'lower' => array(289)); /* LATIN CAPITAL LETTER G WITH DOT ABOVE */
+$config['0100_017f'][] = array('upper' => 290, 'status' => 'C', 'lower' => array(291)); /* LATIN CAPITAL LETTER G WITH CEDILLA */
+$config['0100_017f'][] = array('upper' => 292, 'status' => 'C', 'lower' => array(293)); /* LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+$config['0100_017f'][] = array('upper' => 294, 'status' => 'C', 'lower' => array(295)); /* LATIN CAPITAL LETTER H WITH STROKE */
+$config['0100_017f'][] = array('upper' => 296, 'status' => 'C', 'lower' => array(297)); /* LATIN CAPITAL LETTER I WITH TILDE */
+$config['0100_017f'][] = array('upper' => 298, 'status' => 'C', 'lower' => array(299)); /* LATIN CAPITAL LETTER I WITH MACRON */
+$config['0100_017f'][] = array('upper' => 300, 'status' => 'C', 'lower' => array(301)); /* LATIN CAPITAL LETTER I WITH BREVE */
+$config['0100_017f'][] = array('upper' => 302, 'status' => 'C', 'lower' => array(303)); /* LATIN CAPITAL LETTER I WITH OGONEK */
+$config['0100_017f'][] = array('upper' => 304, 'status' => 'F', 'lower' => array(105, 775)); /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
+$config['0100_017f'][] = array('upper' => 304, 'status' => 'T', 'lower' => array(105)); /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
+$config['0100_017f'][] = array('upper' => 306, 'status' => 'C', 'lower' => array(307)); /* LATIN CAPITAL LIGATURE IJ */
+$config['0100_017f'][] = array('upper' => 308, 'status' => 'C', 'lower' => array(309)); /* LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+$config['0100_017f'][] = array('upper' => 310, 'status' => 'C', 'lower' => array(311)); /* LATIN CAPITAL LETTER K WITH CEDILLA */
+$config['0100_017f'][] = array('upper' => 313, 'status' => 'C', 'lower' => array(314)); /* LATIN CAPITAL LETTER L WITH ACUTE */
+$config['0100_017f'][] = array('upper' => 315, 'status' => 'C', 'lower' => array(316)); /* LATIN CAPITAL LETTER L WITH CEDILLA */
+$config['0100_017f'][] = array('upper' => 317, 'status' => 'C', 'lower' => array(318)); /* LATIN CAPITAL LETTER L WITH CARON */
+$config['0100_017f'][] = array('upper' => 319, 'status' => 'C', 'lower' => array(320)); /* LATIN CAPITAL LETTER L WITH MIDDLE DOT */
+$config['0100_017f'][] = array('upper' => 321, 'status' => 'C', 'lower' => array(322)); /* LATIN CAPITAL LETTER L WITH STROKE */
+$config['0100_017f'][] = array('upper' => 323, 'status' => 'C', 'lower' => array(324)); /* LATIN CAPITAL LETTER N WITH ACUTE */
+$config['0100_017f'][] = array('upper' => 325, 'status' => 'C', 'lower' => array(326)); /* LATIN CAPITAL LETTER N WITH CEDILLA */
+$config['0100_017f'][] = array('upper' => 327, 'status' => 'C', 'lower' => array(328)); /* LATIN CAPITAL LETTER N WITH CARON */
+$config['0100_017f'][] = array('upper' => 329, 'status' => 'F', 'lower' => array(700, 110)); /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */
+$config['0100_017f'][] = array('upper' => 330, 'status' => 'C', 'lower' => array(331)); /* LATIN CAPITAL LETTER ENG */
+$config['0100_017f'][] = array('upper' => 332, 'status' => 'C', 'lower' => array(333)); /* LATIN CAPITAL LETTER O WITH MACRON */
+$config['0100_017f'][] = array('upper' => 334, 'status' => 'C', 'lower' => array(335)); /* LATIN CAPITAL LETTER O WITH BREVE */
+$config['0100_017f'][] = array('upper' => 336, 'status' => 'C', 'lower' => array(337)); /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+$config['0100_017f'][] = array('upper' => 338, 'status' => 'C', 'lower' => array(339)); /* LATIN CAPITAL LIGATURE OE */
+$config['0100_017f'][] = array('upper' => 340, 'status' => 'C', 'lower' => array(341)); /* LATIN CAPITAL LETTER R WITH ACUTE */
+$config['0100_017f'][] = array('upper' => 342, 'status' => 'C', 'lower' => array(343)); /* LATIN CAPITAL LETTER R WITH CEDILLA */
+$config['0100_017f'][] = array('upper' => 344, 'status' => 'C', 'lower' => array(345)); /* LATIN CAPITAL LETTER R WITH CARON */
+$config['0100_017f'][] = array('upper' => 346, 'status' => 'C', 'lower' => array(347)); /* LATIN CAPITAL LETTER S WITH ACUTE */
+$config['0100_017f'][] = array('upper' => 348, 'status' => 'C', 'lower' => array(349)); /* LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+$config['0100_017f'][] = array('upper' => 350, 'status' => 'C', 'lower' => array(351)); /* LATIN CAPITAL LETTER S WITH CEDILLA */
+$config['0100_017f'][] = array('upper' => 352, 'status' => 'C', 'lower' => array(353)); /* LATIN CAPITAL LETTER S WITH CARON */
+$config['0100_017f'][] = array('upper' => 354, 'status' => 'C', 'lower' => array(355)); /* LATIN CAPITAL LETTER T WITH CEDILLA */
+$config['0100_017f'][] = array('upper' => 356, 'status' => 'C', 'lower' => array(357)); /* LATIN CAPITAL LETTER T WITH CARON */
+$config['0100_017f'][] = array('upper' => 358, 'status' => 'C', 'lower' => array(359)); /* LATIN CAPITAL LETTER T WITH STROKE */
+$config['0100_017f'][] = array('upper' => 360, 'status' => 'C', 'lower' => array(361)); /* LATIN CAPITAL LETTER U WITH TILDE */
+$config['0100_017f'][] = array('upper' => 362, 'status' => 'C', 'lower' => array(363)); /* LATIN CAPITAL LETTER U WITH MACRON */
+$config['0100_017f'][] = array('upper' => 364, 'status' => 'C', 'lower' => array(365)); /* LATIN CAPITAL LETTER U WITH BREVE */
+$config['0100_017f'][] = array('upper' => 366, 'status' => 'C', 'lower' => array(367)); /* LATIN CAPITAL LETTER U WITH RING ABOVE */
+$config['0100_017f'][] = array('upper' => 368, 'status' => 'C', 'lower' => array(369)); /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+$config['0100_017f'][] = array('upper' => 370, 'status' => 'C', 'lower' => array(371)); /* LATIN CAPITAL LETTER U WITH OGONEK */
+$config['0100_017f'][] = array('upper' => 372, 'status' => 'C', 'lower' => array(373)); /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
+$config['0100_017f'][] = array('upper' => 374, 'status' => 'C', 'lower' => array(375)); /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
+$config['0100_017f'][] = array('upper' => 376, 'status' => 'C', 'lower' => array(255)); /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+$config['0100_017f'][] = array('upper' => 377, 'status' => 'C', 'lower' => array(378)); /* LATIN CAPITAL LETTER Z WITH ACUTE */
+$config['0100_017f'][] = array('upper' => 379, 'status' => 'C', 'lower' => array(380)); /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+$config['0100_017f'][] = array('upper' => 381, 'status' => 'C', 'lower' => array(382)); /* LATIN CAPITAL LETTER Z WITH CARON */
+$config['0100_017f'][] = array('upper' => 383, 'status' => 'C', 'lower' => array(115)); /* LATIN SMALL LETTER LONG S */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0180_024F.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0180_024F.php
new file mode 100644
index 0000000..e8baaa3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0180_024F.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0180 through U+024F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0180_024F'][] = array('upper' => 385, 'status' => 'C', 'lower' => array(595)); /* LATIN CAPITAL LETTER B WITH HOOK */
+$config['0180_024F'][] = array('upper' => 386, 'status' => 'C', 'lower' => array(387)); /* LATIN CAPITAL LETTER B WITH TOPBAR */
+$config['0180_024F'][] = array('upper' => 388, 'status' => 'C', 'lower' => array(389)); /* LATIN CAPITAL LETTER TONE SIX */
+$config['0180_024F'][] = array('upper' => 390, 'status' => 'C', 'lower' => array(596)); /* LATIN CAPITAL LETTER OPEN O */
+$config['0180_024F'][] = array('upper' => 391, 'status' => 'C', 'lower' => array(392)); /* LATIN CAPITAL LETTER C WITH HOOK */
+$config['0180_024F'][] = array('upper' => 393, 'status' => 'C', 'lower' => array(598)); /* LATIN CAPITAL LETTER AFRICAN D */
+$config['0180_024F'][] = array('upper' => 394, 'status' => 'C', 'lower' => array(599)); /* LATIN CAPITAL LETTER D WITH HOOK */
+$config['0180_024F'][] = array('upper' => 395, 'status' => 'C', 'lower' => array(396)); /* LATIN CAPITAL LETTER D WITH TOPBAR */
+$config['0180_024F'][] = array('upper' => 398, 'status' => 'C', 'lower' => array(477)); /* LATIN CAPITAL LETTER REVERSED E */
+$config['0180_024F'][] = array('upper' => 399, 'status' => 'C', 'lower' => array(601)); /* LATIN CAPITAL LETTER SCHWA */
+$config['0180_024F'][] = array('upper' => 400, 'status' => 'C', 'lower' => array(603)); /* LATIN CAPITAL LETTER OPEN E */
+$config['0180_024F'][] = array('upper' => 401, 'status' => 'C', 'lower' => array(402)); /* LATIN CAPITAL LETTER F WITH HOOK */
+$config['0180_024F'][] = array('upper' => 403, 'status' => 'C', 'lower' => array(608)); /* LATIN CAPITAL LETTER G WITH HOOK */
+$config['0180_024F'][] = array('upper' => 404, 'status' => 'C', 'lower' => array(611)); /* LATIN CAPITAL LETTER GAMMA */
+$config['0180_024F'][] = array('upper' => 406, 'status' => 'C', 'lower' => array(617)); /* LATIN CAPITAL LETTER IOTA */
+$config['0180_024F'][] = array('upper' => 407, 'status' => 'C', 'lower' => array(616)); /* LATIN CAPITAL LETTER I WITH STROKE */
+$config['0180_024F'][] = array('upper' => 408, 'status' => 'C', 'lower' => array(409)); /* LATIN CAPITAL LETTER K WITH HOOK */
+$config['0180_024F'][] = array('upper' => 412, 'status' => 'C', 'lower' => array(623)); /* LATIN CAPITAL LETTER TURNED M */
+$config['0180_024F'][] = array('upper' => 413, 'status' => 'C', 'lower' => array(626)); /* LATIN CAPITAL LETTER N WITH LEFT HOOK */
+$config['0180_024F'][] = array('upper' => 415, 'status' => 'C', 'lower' => array(629)); /* LATIN CAPITAL LETTER O WITH MIDDLE TILDE */
+$config['0180_024F'][] = array('upper' => 416, 'status' => 'C', 'lower' => array(417)); /* LATIN CAPITAL LETTER O WITH HORN */
+$config['0180_024F'][] = array('upper' => 418, 'status' => 'C', 'lower' => array(419)); /* LATIN CAPITAL LETTER OI */
+$config['0180_024F'][] = array('upper' => 420, 'status' => 'C', 'lower' => array(421)); /* LATIN CAPITAL LETTER P WITH HOOK */
+$config['0180_024F'][] = array('upper' => 422, 'status' => 'C', 'lower' => array(640)); /* LATIN LETTER YR */
+$config['0180_024F'][] = array('upper' => 423, 'status' => 'C', 'lower' => array(424)); /* LATIN CAPITAL LETTER TONE TWO */
+$config['0180_024F'][] = array('upper' => 425, 'status' => 'C', 'lower' => array(643)); /* LATIN CAPITAL LETTER ESH */
+$config['0180_024F'][] = array('upper' => 428, 'status' => 'C', 'lower' => array(429)); /* LATIN CAPITAL LETTER T WITH HOOK */
+$config['0180_024F'][] = array('upper' => 430, 'status' => 'C', 'lower' => array(648)); /* LATIN CAPITAL LETTER T WITH RETROFLEX HOOK */
+$config['0180_024F'][] = array('upper' => 431, 'status' => 'C', 'lower' => array(432)); /* LATIN CAPITAL LETTER U WITH HORN */
+$config['0180_024F'][] = array('upper' => 433, 'status' => 'C', 'lower' => array(650)); /* LATIN CAPITAL LETTER UPSILON */
+$config['0180_024F'][] = array('upper' => 434, 'status' => 'C', 'lower' => array(651)); /* LATIN CAPITAL LETTER V WITH HOOK */
+$config['0180_024F'][] = array('upper' => 435, 'status' => 'C', 'lower' => array(436)); /* LATIN CAPITAL LETTER Y WITH HOOK */
+$config['0180_024F'][] = array('upper' => 437, 'status' => 'C', 'lower' => array(438)); /* LATIN CAPITAL LETTER Z WITH STROKE */
+$config['0180_024F'][] = array('upper' => 439, 'status' => 'C', 'lower' => array(658)); /* LATIN CAPITAL LETTER EZH */
+$config['0180_024F'][] = array('upper' => 440, 'status' => 'C', 'lower' => array(441)); /* LATIN CAPITAL LETTER EZH REVERSED */
+$config['0180_024F'][] = array('upper' => 444, 'status' => 'C', 'lower' => array(445)); /* LATIN CAPITAL LETTER TONE FIVE */
+$config['0180_024F'][] = array('upper' => 452, 'status' => 'C', 'lower' => array(454)); /* LATIN CAPITAL LETTER DZ WITH CARON */
+$config['0180_024F'][] = array('upper' => 453, 'status' => 'C', 'lower' => array(454)); /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON */
+$config['0180_024F'][] = array('upper' => 455, 'status' => 'C', 'lower' => array(457)); /* LATIN CAPITAL LETTER LJ */
+$config['0180_024F'][] = array('upper' => 456, 'status' => 'C', 'lower' => array(457)); /* LATIN CAPITAL LETTER L WITH SMALL LETTER J */
+$config['0180_024F'][] = array('upper' => 458, 'status' => 'C', 'lower' => array(460)); /* LATIN CAPITAL LETTER NJ */
+$config['0180_024F'][] = array('upper' => 459, 'status' => 'C', 'lower' => array(460)); /* LATIN CAPITAL LETTER N WITH SMALL LETTER J */
+$config['0180_024F'][] = array('upper' => 461, 'status' => 'C', 'lower' => array(462)); /* LATIN CAPITAL LETTER A WITH CARON */
+$config['0180_024F'][] = array('upper' => 463, 'status' => 'C', 'lower' => array(464)); /* LATIN CAPITAL LETTER I WITH CARON */
+$config['0180_024F'][] = array('upper' => 465, 'status' => 'C', 'lower' => array(466)); /* LATIN CAPITAL LETTER O WITH CARON */
+$config['0180_024F'][] = array('upper' => 467, 'status' => 'C', 'lower' => array(468)); /* LATIN CAPITAL LETTER U WITH CARON */
+$config['0180_024F'][] = array('upper' => 469, 'status' => 'C', 'lower' => array(470)); /* LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON */
+$config['0180_024F'][] = array('upper' => 471, 'status' => 'C', 'lower' => array(472)); /* LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE */
+$config['0180_024F'][] = array('upper' => 473, 'status' => 'C', 'lower' => array(474)); /* LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON */
+$config['0180_024F'][] = array('upper' => 475, 'status' => 'C', 'lower' => array(476)); /* LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE */
+$config['0180_024F'][] = array('upper' => 478, 'status' => 'C', 'lower' => array(479)); /* LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON */
+$config['0180_024F'][] = array('upper' => 480, 'status' => 'C', 'lower' => array(481)); /* LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON */
+$config['0180_024F'][] = array('upper' => 482, 'status' => 'C', 'lower' => array(483)); /* LATIN CAPITAL LETTER AE WITH MACRON */
+$config['0180_024F'][] = array('upper' => 484, 'status' => 'C', 'lower' => array(485)); /* LATIN CAPITAL LETTER G WITH STROKE */
+$config['0180_024F'][] = array('upper' => 486, 'status' => 'C', 'lower' => array(487)); /* LATIN CAPITAL LETTER G WITH CARON */
+$config['0180_024F'][] = array('upper' => 488, 'status' => 'C', 'lower' => array(489)); /* LATIN CAPITAL LETTER K WITH CARON */
+$config['0180_024F'][] = array('upper' => 490, 'status' => 'C', 'lower' => array(491)); /* LATIN CAPITAL LETTER O WITH OGONEK */
+$config['0180_024F'][] = array('upper' => 492, 'status' => 'C', 'lower' => array(493)); /* LATIN CAPITAL LETTER O WITH OGONEK AND MACRON */
+$config['0180_024F'][] = array('upper' => 494, 'status' => 'C', 'lower' => array(495)); /* LATIN CAPITAL LETTER EZH WITH CARON */
+$config['0180_024F'][] = array('upper' => 496, 'status' => 'F', 'lower' => array(106, 780)); /* LATIN SMALL LETTER J WITH CARON */
+$config['0180_024F'][] = array('upper' => 497, 'status' => 'C', 'lower' => array(499)); /* LATIN CAPITAL LETTER DZ */
+$config['0180_024F'][] = array('upper' => 498, 'status' => 'C', 'lower' => array(499)); /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z */
+$config['0180_024F'][] = array('upper' => 500, 'status' => 'C', 'lower' => array(501)); /* LATIN CAPITAL LETTER G WITH ACUTE */
+$config['0180_024F'][] = array('upper' => 502, 'status' => 'C', 'lower' => array(405)); /* LATIN CAPITAL LETTER HWAIR */
+$config['0180_024F'][] = array('upper' => 503, 'status' => 'C', 'lower' => array(447)); /* LATIN CAPITAL LETTER WYNN */
+$config['0180_024F'][] = array('upper' => 504, 'status' => 'C', 'lower' => array(505)); /* LATIN CAPITAL LETTER N WITH GRAVE */
+$config['0180_024F'][] = array('upper' => 506, 'status' => 'C', 'lower' => array(507)); /* LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE */
+$config['0180_024F'][] = array('upper' => 508, 'status' => 'C', 'lower' => array(509)); /* LATIN CAPITAL LETTER AE WITH ACUTE */
+$config['0180_024F'][] = array('upper' => 510, 'status' => 'C', 'lower' => array(511)); /* LATIN CAPITAL LETTER O WITH STROKE AND ACUTE */
+$config['0180_024F'][] = array('upper' => 512, 'status' => 'C', 'lower' => array(513)); /* LATIN CAPITAL LETTER A WITH DOUBLE GRAVE */
+$config['0180_024F'][] = array('upper' => 514, 'status' => 'C', 'lower' => array(515)); /* LATIN CAPITAL LETTER A WITH INVERTED BREVE */
+$config['0180_024F'][] = array('upper' => 516, 'status' => 'C', 'lower' => array(517)); /* LATIN CAPITAL LETTER E WITH DOUBLE GRAVE */
+$config['0180_024F'][] = array('upper' => 518, 'status' => 'C', 'lower' => array(519)); /* LATIN CAPITAL LETTER E WITH INVERTED BREVE */
+$config['0180_024F'][] = array('upper' => 520, 'status' => 'C', 'lower' => array(521)); /* LATIN CAPITAL LETTER I WITH DOUBLE GRAVE */
+$config['0180_024F'][] = array('upper' => 522, 'status' => 'C', 'lower' => array(523)); /* LATIN CAPITAL LETTER I WITH INVERTED BREVE */
+$config['0180_024F'][] = array('upper' => 524, 'status' => 'C', 'lower' => array(525)); /* LATIN CAPITAL LETTER O WITH DOUBLE GRAVE */
+$config['0180_024F'][] = array('upper' => 526, 'status' => 'C', 'lower' => array(527)); /* LATIN CAPITAL LETTER O WITH INVERTED BREVE */
+$config['0180_024F'][] = array('upper' => 528, 'status' => 'C', 'lower' => array(529)); /* LATIN CAPITAL LETTER R WITH DOUBLE GRAVE */
+$config['0180_024F'][] = array('upper' => 530, 'status' => 'C', 'lower' => array(531)); /* LATIN CAPITAL LETTER R WITH INVERTED BREVE */
+$config['0180_024F'][] = array('upper' => 532, 'status' => 'C', 'lower' => array(533)); /* LATIN CAPITAL LETTER U WITH DOUBLE GRAVE */
+$config['0180_024F'][] = array('upper' => 534, 'status' => 'C', 'lower' => array(535)); /* LATIN CAPITAL LETTER U WITH INVERTED BREVE */
+$config['0180_024F'][] = array('upper' => 536, 'status' => 'C', 'lower' => array(537)); /* LATIN CAPITAL LETTER S WITH COMMA BELOW */
+$config['0180_024F'][] = array('upper' => 538, 'status' => 'C', 'lower' => array(539)); /* LATIN CAPITAL LETTER T WITH COMMA BELOW */
+$config['0180_024F'][] = array('upper' => 540, 'status' => 'C', 'lower' => array(541)); /* LATIN CAPITAL LETTER YOGH */
+$config['0180_024F'][] = array('upper' => 542, 'status' => 'C', 'lower' => array(543)); /* LATIN CAPITAL LETTER H WITH CARON */
+$config['0180_024F'][] = array('upper' => 544, 'status' => 'C', 'lower' => array(414)); /* LATIN CAPITAL LETTER N WITH LONG RIGHT LEG */
+$config['0180_024F'][] = array('upper' => 546, 'status' => 'C', 'lower' => array(547)); /* LATIN CAPITAL LETTER OU */
+$config['0180_024F'][] = array('upper' => 548, 'status' => 'C', 'lower' => array(549)); /* LATIN CAPITAL LETTER Z WITH HOOK */
+$config['0180_024F'][] = array('upper' => 550, 'status' => 'C', 'lower' => array(551)); /* LATIN CAPITAL LETTER A WITH DOT ABOVE */
+$config['0180_024F'][] = array('upper' => 552, 'status' => 'C', 'lower' => array(553)); /* LATIN CAPITAL LETTER E WITH CEDILLA */
+$config['0180_024F'][] = array('upper' => 554, 'status' => 'C', 'lower' => array(555)); /* LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON */
+$config['0180_024F'][] = array('upper' => 556, 'status' => 'C', 'lower' => array(557)); /* LATIN CAPITAL LETTER O WITH TILDE AND MACRON */
+$config['0180_024F'][] = array('upper' => 558, 'status' => 'C', 'lower' => array(559)); /* LATIN CAPITAL LETTER O WITH DOT ABOVE */
+$config['0180_024F'][] = array('upper' => 560, 'status' => 'C', 'lower' => array(561)); /* LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON */
+$config['0180_024F'][] = array('upper' => 562, 'status' => 'C', 'lower' => array(563)); /* LATIN CAPITAL LETTER Y WITH MACRON */
+$config['0180_024F'][] = array('upper' => 570, 'status' => 'C', 'lower' => array(11365)); /* LATIN CAPITAL LETTER A WITH STROKE */
+$config['0180_024F'][] = array('upper' => 571, 'status' => 'C', 'lower' => array(572)); /* LATIN CAPITAL LETTER C WITH STROKE */
+$config['0180_024F'][] = array('upper' => 573, 'status' => 'C', 'lower' => array(410)); /* LATIN CAPITAL LETTER L WITH BAR */
+$config['0180_024F'][] = array('upper' => 574, 'status' => 'C', 'lower' => array(11366)); /* LATIN CAPITAL LETTER T WITH DIAGONAL STROKE */
+$config['0180_024F'][] = array('upper' => 577, 'status' => 'C', 'lower' => array(578)); /* LATIN CAPITAL LETTER GLOTTAL STOP */
+$config['0180_024F'][] = array('upper' => 579, 'status' => 'C', 'lower' => array(384)); /* LATIN CAPITAL LETTER B WITH STROKE */
+$config['0180_024F'][] = array('upper' => 580, 'status' => 'C', 'lower' => array(649)); /* LATIN CAPITAL LETTER U BAR */
+$config['0180_024F'][] = array('upper' => 581, 'status' => 'C', 'lower' => array(652)); /* LATIN CAPITAL LETTER TURNED V */
+$config['0180_024F'][] = array('upper' => 582, 'status' => 'C', 'lower' => array(583)); /* LATIN CAPITAL LETTER E WITH STROKE */
+$config['0180_024F'][] = array('upper' => 584, 'status' => 'C', 'lower' => array(585)); /* LATIN CAPITAL LETTER J WITH STROKE */
+$config['0180_024F'][] = array('upper' => 586, 'status' => 'C', 'lower' => array(587)); /* LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL */
+$config['0180_024F'][] = array('upper' => 588, 'status' => 'C', 'lower' => array(589)); /* LATIN CAPITAL LETTER R WITH STROKE */
+$config['0180_024F'][] = array('upper' => 590, 'status' => 'C', 'lower' => array(591)); /* LATIN CAPITAL LETTER Y WITH STROKE */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0250_02af.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0250_02af.php
new file mode 100644
index 0000000..6ffa59d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0250_02af.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0080 through U+00FF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.6833
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0250_02af'][] = array('upper' => 422, 'status' => 'C', 'lower' => array(640));
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0370_03ff.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0370_03ff.php
new file mode 100644
index 0000000..bb7ecde
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0370_03ff.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0370 through U+03FF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0370_03ff'][] = array('upper' => 902, 'status' => 'C', 'lower' => array(940)); /* GREEK CAPITAL LETTER ALPHA WITH TONOS */
+$config['0370_03ff'][] = array('upper' => 904, 'status' => 'C', 'lower' => array(941)); /* GREEK CAPITAL LETTER EPSILON WITH TONOS */
+$config['0370_03ff'][] = array('upper' => 905, 'status' => 'C', 'lower' => array(942)); /* GREEK CAPITAL LETTER ETA WITH TONOS */
+$config['0370_03ff'][] = array('upper' => 906, 'status' => 'C', 'lower' => array(943)); /* GREEK CAPITAL LETTER IOTA WITH TONOS */
+$config['0370_03ff'][] = array('upper' => 908, 'status' => 'C', 'lower' => array(972)); /* GREEK CAPITAL LETTER OMICRON WITH TONOS */
+$config['0370_03ff'][] = array('upper' => 910, 'status' => 'C', 'lower' => array(973)); /* GREEK CAPITAL LETTER UPSILON WITH TONOS */
+$config['0370_03ff'][] = array('upper' => 911, 'status' => 'C', 'lower' => array(974)); /* GREEK CAPITAL LETTER OMEGA WITH TONOS */
+//$config['0370_03ff'][] = array('upper' => 912, 'status' => 'F', 'lower' => array(953, 776, 769)); /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+$config['0370_03ff'][] = array('upper' => 913, 'status' => 'C', 'lower' => array(945)); /* GREEK CAPITAL LETTER ALPHA */
+$config['0370_03ff'][] = array('upper' => 914, 'status' => 'C', 'lower' => array(946)); /* GREEK CAPITAL LETTER BETA */
+$config['0370_03ff'][] = array('upper' => 915, 'status' => 'C', 'lower' => array(947)); /* GREEK CAPITAL LETTER GAMMA */
+$config['0370_03ff'][] = array('upper' => 916, 'status' => 'C', 'lower' => array(948)); /* GREEK CAPITAL LETTER DELTA */
+$config['0370_03ff'][] = array('upper' => 917, 'status' => 'C', 'lower' => array(949)); /* GREEK CAPITAL LETTER EPSILON */
+$config['0370_03ff'][] = array('upper' => 918, 'status' => 'C', 'lower' => array(950)); /* GREEK CAPITAL LETTER ZETA */
+$config['0370_03ff'][] = array('upper' => 919, 'status' => 'C', 'lower' => array(951)); /* GREEK CAPITAL LETTER ETA */
+$config['0370_03ff'][] = array('upper' => 920, 'status' => 'C', 'lower' => array(952)); /* GREEK CAPITAL LETTER THETA */
+$config['0370_03ff'][] = array('upper' => 921, 'status' => 'C', 'lower' => array(953)); /* GREEK CAPITAL LETTER IOTA */
+$config['0370_03ff'][] = array('upper' => 922, 'status' => 'C', 'lower' => array(954)); /* GREEK CAPITAL LETTER KAPPA */
+$config['0370_03ff'][] = array('upper' => 923, 'status' => 'C', 'lower' => array(955)); /* GREEK CAPITAL LETTER LAMDA */
+$config['0370_03ff'][] = array('upper' => 924, 'status' => 'C', 'lower' => array(956)); /* GREEK CAPITAL LETTER MU */
+$config['0370_03ff'][] = array('upper' => 925, 'status' => 'C', 'lower' => array(957)); /* GREEK CAPITAL LETTER NU */
+$config['0370_03ff'][] = array('upper' => 926, 'status' => 'C', 'lower' => array(958)); /* GREEK CAPITAL LETTER XI */
+$config['0370_03ff'][] = array('upper' => 927, 'status' => 'C', 'lower' => array(959)); /* GREEK CAPITAL LETTER OMICRON */
+$config['0370_03ff'][] = array('upper' => 928, 'status' => 'C', 'lower' => array(960)); /* GREEK CAPITAL LETTER PI */
+$config['0370_03ff'][] = array('upper' => 929, 'status' => 'C', 'lower' => array(961)); /* GREEK CAPITAL LETTER RHO */
+$config['0370_03ff'][] = array('upper' => 931, 'status' => 'C', 'lower' => array(963)); /* GREEK CAPITAL LETTER SIGMA */
+$config['0370_03ff'][] = array('upper' => 932, 'status' => 'C', 'lower' => array(964)); /* GREEK CAPITAL LETTER TAU */
+$config['0370_03ff'][] = array('upper' => 933, 'status' => 'C', 'lower' => array(965)); /* GREEK CAPITAL LETTER UPSILON */
+$config['0370_03ff'][] = array('upper' => 934, 'status' => 'C', 'lower' => array(966)); /* GREEK CAPITAL LETTER PHI */
+$config['0370_03ff'][] = array('upper' => 935, 'status' => 'C', 'lower' => array(967)); /* GREEK CAPITAL LETTER CHI */
+$config['0370_03ff'][] = array('upper' => 936, 'status' => 'C', 'lower' => array(968)); /* GREEK CAPITAL LETTER PSI */
+$config['0370_03ff'][] = array('upper' => 937, 'status' => 'C', 'lower' => array(969)); /* GREEK CAPITAL LETTER OMEGA */
+$config['0370_03ff'][] = array('upper' => 938, 'status' => 'C', 'lower' => array(970)); /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+$config['0370_03ff'][] = array('upper' => 939, 'status' => 'C', 'lower' => array(971)); /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+$config['0370_03ff'][] = array('upper' => 944, 'status' => 'F', 'lower' => array(965, 776, 769)); /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+$config['0370_03ff'][] = array('upper' => 962, 'status' => 'C', 'lower' => array(963)); /* GREEK SMALL LETTER FINAL SIGMA */
+$config['0370_03ff'][] = array('upper' => 976, 'status' => 'C', 'lower' => array(946)); /* GREEK BETA SYMBOL */
+$config['0370_03ff'][] = array('upper' => 977, 'status' => 'C', 'lower' => array(952)); /* GREEK THETA SYMBOL */
+$config['0370_03ff'][] = array('upper' => 981, 'status' => 'C', 'lower' => array(966)); /* GREEK PHI SYMBOL */
+$config['0370_03ff'][] = array('upper' => 982, 'status' => 'C', 'lower' => array(960)); /* GREEK PI SYMBOL */
+$config['0370_03ff'][] = array('upper' => 984, 'status' => 'C', 'lower' => array(985)); /* GREEK LETTER ARCHAIC KOPPA */
+$config['0370_03ff'][] = array('upper' => 986, 'status' => 'C', 'lower' => array(987)); /* GREEK LETTER STIGMA */
+$config['0370_03ff'][] = array('upper' => 988, 'status' => 'C', 'lower' => array(989)); /* GREEK LETTER DIGAMMA */
+$config['0370_03ff'][] = array('upper' => 990, 'status' => 'C', 'lower' => array(991)); /* GREEK LETTER KOPPA */
+$config['0370_03ff'][] = array('upper' => 992, 'status' => 'C', 'lower' => array(993)); /* GREEK LETTER SAMPI */
+$config['0370_03ff'][] = array('upper' => 994, 'status' => 'C', 'lower' => array(995)); /* COPTIC CAPITAL LETTER SHEI */
+$config['0370_03ff'][] = array('upper' => 996, 'status' => 'C', 'lower' => array(997)); /* COPTIC CAPITAL LETTER FEI */
+$config['0370_03ff'][] = array('upper' => 998, 'status' => 'C', 'lower' => array(999)); /* COPTIC CAPITAL LETTER KHEI */
+$config['0370_03ff'][] = array('upper' => 1000, 'status' => 'C', 'lower' => array(1001)); /* COPTIC CAPITAL LETTER HORI */
+$config['0370_03ff'][] = array('upper' => 1002, 'status' => 'C', 'lower' => array(1003)); /* COPTIC CAPITAL LETTER GANGIA */
+$config['0370_03ff'][] = array('upper' => 1004, 'status' => 'C', 'lower' => array(1005)); /* COPTIC CAPITAL LETTER SHIMA */
+$config['0370_03ff'][] = array('upper' => 1006, 'status' => 'C', 'lower' => array(1007)); /* COPTIC CAPITAL LETTER DEI */
+$config['0370_03ff'][] = array('upper' => 1008, 'status' => 'C', 'lower' => array(954)); /* GREEK KAPPA SYMBOL */
+$config['0370_03ff'][] = array('upper' => 1009, 'status' => 'C', 'lower' => array(961)); /* GREEK RHO SYMBOL */
+$config['0370_03ff'][] = array('upper' => 1012, 'status' => 'C', 'lower' => array(952)); /* GREEK CAPITAL THETA SYMBOL */
+$config['0370_03ff'][] = array('upper' => 1013, 'status' => 'C', 'lower' => array(949)); /* GREEK LUNATE EPSILON SYMBOL */
+$config['0370_03ff'][] = array('upper' => 1015, 'status' => 'C', 'lower' => array(1016)); /* GREEK CAPITAL LETTER SHO */
+$config['0370_03ff'][] = array('upper' => 1017, 'status' => 'C', 'lower' => array(1010)); /* GREEK CAPITAL LUNATE SIGMA SYMBOL */
+$config['0370_03ff'][] = array('upper' => 1018, 'status' => 'C', 'lower' => array(1019)); /* GREEK CAPITAL LETTER SAN */
+$config['0370_03ff'][] = array('upper' => 1021, 'status' => 'C', 'lower' => array(891)); /* GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL */
+$config['0370_03ff'][] = array('upper' => 1022, 'status' => 'C', 'lower' => array(892)); /* GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL */
+$config['0370_03ff'][] = array('upper' => 1023, 'status' => 'C', 'lower' => array(893)); /* GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0400_04ff.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0400_04ff.php
new file mode 100644
index 0000000..7a3f93a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0400_04ff.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0400 through U+04FF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0400_04ff'][] = array('upper' => 1024, 'status' => 'C', 'lower' => array(1104)); /* CYRILLIC CAPITAL LETTER IE WITH GRAVE */
+$config['0400_04ff'][] = array('upper' => 1025, 'status' => 'C', 'lower' => array(1105)); /* CYRILLIC CAPITAL LETTER IO */
+$config['0400_04ff'][] = array('upper' => 1026, 'status' => 'C', 'lower' => array(1106)); /* CYRILLIC CAPITAL LETTER DJE */
+$config['0400_04ff'][] = array('upper' => 1027, 'status' => 'C', 'lower' => array(1107)); /* CYRILLIC CAPITAL LETTER GJE */
+$config['0400_04ff'][] = array('upper' => 1028, 'status' => 'C', 'lower' => array(1108)); /* CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+$config['0400_04ff'][] = array('upper' => 1029, 'status' => 'C', 'lower' => array(1109)); /* CYRILLIC CAPITAL LETTER DZE */
+$config['0400_04ff'][] = array('upper' => 1030, 'status' => 'C', 'lower' => array(1110)); /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+$config['0400_04ff'][] = array('upper' => 1031, 'status' => 'C', 'lower' => array(1111)); /* CYRILLIC CAPITAL LETTER YI */
+$config['0400_04ff'][] = array('upper' => 1032, 'status' => 'C', 'lower' => array(1112)); /* CYRILLIC CAPITAL LETTER JE */
+$config['0400_04ff'][] = array('upper' => 1033, 'status' => 'C', 'lower' => array(1113)); /* CYRILLIC CAPITAL LETTER LJE */
+$config['0400_04ff'][] = array('upper' => 1034, 'status' => 'C', 'lower' => array(1114)); /* CYRILLIC CAPITAL LETTER NJE */
+$config['0400_04ff'][] = array('upper' => 1035, 'status' => 'C', 'lower' => array(1115)); /* CYRILLIC CAPITAL LETTER TSHE */
+$config['0400_04ff'][] = array('upper' => 1036, 'status' => 'C', 'lower' => array(1116)); /* CYRILLIC CAPITAL LETTER KJE */
+$config['0400_04ff'][] = array('upper' => 1037, 'status' => 'C', 'lower' => array(1117)); /* CYRILLIC CAPITAL LETTER I WITH GRAVE */
+$config['0400_04ff'][] = array('upper' => 1038, 'status' => 'C', 'lower' => array(1118)); /* CYRILLIC CAPITAL LETTER SHORT U */
+$config['0400_04ff'][] = array('upper' => 1039, 'status' => 'C', 'lower' => array(1119)); /* CYRILLIC CAPITAL LETTER DZHE */
+$config['0400_04ff'][] = array('upper' => 1040, 'status' => 'C', 'lower' => array(1072)); /* CYRILLIC CAPITAL LETTER A */
+$config['0400_04ff'][] = array('upper' => 1041, 'status' => 'C', 'lower' => array(1073)); /* CYRILLIC CAPITAL LETTER BE */
+$config['0400_04ff'][] = array('upper' => 1042, 'status' => 'C', 'lower' => array(1074)); /* CYRILLIC CAPITAL LETTER VE */
+$config['0400_04ff'][] = array('upper' => 1043, 'status' => 'C', 'lower' => array(1075)); /* CYRILLIC CAPITAL LETTER GHE */
+$config['0400_04ff'][] = array('upper' => 1044, 'status' => 'C', 'lower' => array(1076)); /* CYRILLIC CAPITAL LETTER DE */
+$config['0400_04ff'][] = array('upper' => 1045, 'status' => 'C', 'lower' => array(1077)); /* CYRILLIC CAPITAL LETTER IE */
+$config['0400_04ff'][] = array('upper' => 1046, 'status' => 'C', 'lower' => array(1078)); /* CYRILLIC CAPITAL LETTER ZHE */
+$config['0400_04ff'][] = array('upper' => 1047, 'status' => 'C', 'lower' => array(1079)); /* CYRILLIC CAPITAL LETTER ZE */
+$config['0400_04ff'][] = array('upper' => 1048, 'status' => 'C', 'lower' => array(1080)); /* CYRILLIC CAPITAL LETTER I */
+$config['0400_04ff'][] = array('upper' => 1049, 'status' => 'C', 'lower' => array(1081)); /* CYRILLIC CAPITAL LETTER SHORT I */
+$config['0400_04ff'][] = array('upper' => 1050, 'status' => 'C', 'lower' => array(1082)); /* CYRILLIC CAPITAL LETTER KA */
+$config['0400_04ff'][] = array('upper' => 1051, 'status' => 'C', 'lower' => array(1083)); /* CYRILLIC CAPITAL LETTER EL */
+$config['0400_04ff'][] = array('upper' => 1052, 'status' => 'C', 'lower' => array(1084)); /* CYRILLIC CAPITAL LETTER EM */
+$config['0400_04ff'][] = array('upper' => 1053, 'status' => 'C', 'lower' => array(1085)); /* CYRILLIC CAPITAL LETTER EN */
+$config['0400_04ff'][] = array('upper' => 1054, 'status' => 'C', 'lower' => array(1086)); /* CYRILLIC CAPITAL LETTER O */
+$config['0400_04ff'][] = array('upper' => 1055, 'status' => 'C', 'lower' => array(1087)); /* CYRILLIC CAPITAL LETTER PE */
+$config['0400_04ff'][] = array('upper' => 1056, 'status' => 'C', 'lower' => array(1088)); /* CYRILLIC CAPITAL LETTER ER */
+$config['0400_04ff'][] = array('upper' => 1057, 'status' => 'C', 'lower' => array(1089)); /* CYRILLIC CAPITAL LETTER ES */
+$config['0400_04ff'][] = array('upper' => 1058, 'status' => 'C', 'lower' => array(1090)); /* CYRILLIC CAPITAL LETTER TE */
+$config['0400_04ff'][] = array('upper' => 1059, 'status' => 'C', 'lower' => array(1091)); /* CYRILLIC CAPITAL LETTER U */
+$config['0400_04ff'][] = array('upper' => 1060, 'status' => 'C', 'lower' => array(1092)); /* CYRILLIC CAPITAL LETTER EF */
+$config['0400_04ff'][] = array('upper' => 1061, 'status' => 'C', 'lower' => array(1093)); /* CYRILLIC CAPITAL LETTER HA */
+$config['0400_04ff'][] = array('upper' => 1062, 'status' => 'C', 'lower' => array(1094)); /* CYRILLIC CAPITAL LETTER TSE */
+$config['0400_04ff'][] = array('upper' => 1063, 'status' => 'C', 'lower' => array(1095)); /* CYRILLIC CAPITAL LETTER CHE */
+$config['0400_04ff'][] = array('upper' => 1064, 'status' => 'C', 'lower' => array(1096)); /* CYRILLIC CAPITAL LETTER SHA */
+$config['0400_04ff'][] = array('upper' => 1065, 'status' => 'C', 'lower' => array(1097)); /* CYRILLIC CAPITAL LETTER SHCHA */
+$config['0400_04ff'][] = array('upper' => 1066, 'status' => 'C', 'lower' => array(1098)); /* CYRILLIC CAPITAL LETTER HARD SIGN */
+$config['0400_04ff'][] = array('upper' => 1067, 'status' => 'C', 'lower' => array(1099)); /* CYRILLIC CAPITAL LETTER YERU */
+$config['0400_04ff'][] = array('upper' => 1068, 'status' => 'C', 'lower' => array(1100)); /* CYRILLIC CAPITAL LETTER SOFT SIGN */
+$config['0400_04ff'][] = array('upper' => 1069, 'status' => 'C', 'lower' => array(1101)); /* CYRILLIC CAPITAL LETTER E */
+$config['0400_04ff'][] = array('upper' => 1070, 'status' => 'C', 'lower' => array(1102)); /* CYRILLIC CAPITAL LETTER YU */
+$config['0400_04ff'][] = array('upper' => 1071, 'status' => 'C', 'lower' => array(1103)); /* CYRILLIC CAPITAL LETTER YA */
+$config['0400_04ff'][] = array('upper' => 1120, 'status' => 'C', 'lower' => array(1121)); /* CYRILLIC CAPITAL LETTER OMEGA */
+$config['0400_04ff'][] = array('upper' => 1122, 'status' => 'C', 'lower' => array(1123)); /* CYRILLIC CAPITAL LETTER YAT */
+$config['0400_04ff'][] = array('upper' => 1124, 'status' => 'C', 'lower' => array(1125)); /* CYRILLIC CAPITAL LETTER IOTIFIED E */
+$config['0400_04ff'][] = array('upper' => 1126, 'status' => 'C', 'lower' => array(1127)); /* CYRILLIC CAPITAL LETTER LITTLE YUS */
+$config['0400_04ff'][] = array('upper' => 1128, 'status' => 'C', 'lower' => array(1129)); /* CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS */
+$config['0400_04ff'][] = array('upper' => 1130, 'status' => 'C', 'lower' => array(1131)); /* CYRILLIC CAPITAL LETTER BIG YUS */
+$config['0400_04ff'][] = array('upper' => 1132, 'status' => 'C', 'lower' => array(1133)); /* CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS */
+$config['0400_04ff'][] = array('upper' => 1134, 'status' => 'C', 'lower' => array(1135)); /* CYRILLIC CAPITAL LETTER KSI */
+$config['0400_04ff'][] = array('upper' => 1136, 'status' => 'C', 'lower' => array(1137)); /* CYRILLIC CAPITAL LETTER PSI */
+$config['0400_04ff'][] = array('upper' => 1138, 'status' => 'C', 'lower' => array(1139)); /* CYRILLIC CAPITAL LETTER FITA */
+$config['0400_04ff'][] = array('upper' => 1140, 'status' => 'C', 'lower' => array(1141)); /* CYRILLIC CAPITAL LETTER IZHITSA */
+$config['0400_04ff'][] = array('upper' => 1142, 'status' => 'C', 'lower' => array(1143)); /* CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
+$config['0400_04ff'][] = array('upper' => 1144, 'status' => 'C', 'lower' => array(1145)); /* CYRILLIC CAPITAL LETTER UK */
+$config['0400_04ff'][] = array('upper' => 1146, 'status' => 'C', 'lower' => array(1147)); /* CYRILLIC CAPITAL LETTER ROUND OMEGA */
+$config['0400_04ff'][] = array('upper' => 1148, 'status' => 'C', 'lower' => array(1149)); /* CYRILLIC CAPITAL LETTER OMEGA WITH TITLO */
+$config['0400_04ff'][] = array('upper' => 1150, 'status' => 'C', 'lower' => array(1151)); /* CYRILLIC CAPITAL LETTER OT */
+$config['0400_04ff'][] = array('upper' => 1152, 'status' => 'C', 'lower' => array(1153)); /* CYRILLIC CAPITAL LETTER KOPPA */
+$config['0400_04ff'][] = array('upper' => 1162, 'status' => 'C', 'lower' => array(1163)); /* CYRILLIC CAPITAL LETTER SHORT I WITH TAIL */
+$config['0400_04ff'][] = array('upper' => 1164, 'status' => 'C', 'lower' => array(1165)); /* CYRILLIC CAPITAL LETTER SEMISOFT SIGN */
+$config['0400_04ff'][] = array('upper' => 1166, 'status' => 'C', 'lower' => array(1167)); /* CYRILLIC CAPITAL LETTER ER WITH TICK */
+$config['0400_04ff'][] = array('upper' => 1168, 'status' => 'C', 'lower' => array(1169)); /* CYRILLIC CAPITAL LETTER GHE WITH UPTURN */
+$config['0400_04ff'][] = array('upper' => 1170, 'status' => 'C', 'lower' => array(1171)); /* CYRILLIC CAPITAL LETTER GHE WITH STROKE */
+$config['0400_04ff'][] = array('upper' => 1172, 'status' => 'C', 'lower' => array(1173)); /* CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK */
+$config['0400_04ff'][] = array('upper' => 1174, 'status' => 'C', 'lower' => array(1175)); /* CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1176, 'status' => 'C', 'lower' => array(1177)); /* CYRILLIC CAPITAL LETTER ZE WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1178, 'status' => 'C', 'lower' => array(1179)); /* CYRILLIC CAPITAL LETTER KA WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1180, 'status' => 'C', 'lower' => array(1181)); /* CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */
+$config['0400_04ff'][] = array('upper' => 1182, 'status' => 'C', 'lower' => array(1183)); /* CYRILLIC CAPITAL LETTER KA WITH STROKE */
+$config['0400_04ff'][] = array('upper' => 1184, 'status' => 'C', 'lower' => array(1185)); /* CYRILLIC CAPITAL LETTER BASHKIR KA */
+$config['0400_04ff'][] = array('upper' => 1186, 'status' => 'C', 'lower' => array(1187)); /* CYRILLIC CAPITAL LETTER EN WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1188, 'status' => 'C', 'lower' => array(1189)); /* CYRILLIC CAPITAL LIGATURE EN GHE */
+$config['0400_04ff'][] = array('upper' => 1190, 'status' => 'C', 'lower' => array(1191)); /* CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK */
+$config['0400_04ff'][] = array('upper' => 1192, 'status' => 'C', 'lower' => array(1193)); /* CYRILLIC CAPITAL LETTER ABKHASIAN HA */
+$config['0400_04ff'][] = array('upper' => 1194, 'status' => 'C', 'lower' => array(1195)); /* CYRILLIC CAPITAL LETTER ES WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1196, 'status' => 'C', 'lower' => array(1197)); /* CYRILLIC CAPITAL LETTER TE WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1198, 'status' => 'C', 'lower' => array(1199)); /* CYRILLIC CAPITAL LETTER STRAIGHT U */
+$config['0400_04ff'][] = array('upper' => 1200, 'status' => 'C', 'lower' => array(1201)); /* CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */
+$config['0400_04ff'][] = array('upper' => 1202, 'status' => 'C', 'lower' => array(1203)); /* CYRILLIC CAPITAL LETTER HA WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1204, 'status' => 'C', 'lower' => array(1205)); /* CYRILLIC CAPITAL LIGATURE TE TSE */
+$config['0400_04ff'][] = array('upper' => 1206, 'status' => 'C', 'lower' => array(1207)); /* CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1208, 'status' => 'C', 'lower' => array(1209)); /* CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */
+$config['0400_04ff'][] = array('upper' => 1210, 'status' => 'C', 'lower' => array(1211)); /* CYRILLIC CAPITAL LETTER SHHA */
+$config['0400_04ff'][] = array('upper' => 1212, 'status' => 'C', 'lower' => array(1213)); /* CYRILLIC CAPITAL LETTER ABKHASIAN CHE */
+$config['0400_04ff'][] = array('upper' => 1214, 'status' => 'C', 'lower' => array(1215)); /* CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1216, 'status' => 'C', 'lower' => array(1231)); /* CYRILLIC LETTER PALOCHKA */
+$config['0400_04ff'][] = array('upper' => 1217, 'status' => 'C', 'lower' => array(1218)); /* CYRILLIC CAPITAL LETTER ZHE WITH BREVE */
+$config['0400_04ff'][] = array('upper' => 1219, 'status' => 'C', 'lower' => array(1220)); /* CYRILLIC CAPITAL LETTER KA WITH HOOK */
+$config['0400_04ff'][] = array('upper' => 1221, 'status' => 'C', 'lower' => array(1222)); /* CYRILLIC CAPITAL LETTER EL WITH TAIL */
+$config['0400_04ff'][] = array('upper' => 1223, 'status' => 'C', 'lower' => array(1224)); /* CYRILLIC CAPITAL LETTER EN WITH HOOK */
+$config['0400_04ff'][] = array('upper' => 1225, 'status' => 'C', 'lower' => array(1226)); /* CYRILLIC CAPITAL LETTER EN WITH TAIL */
+$config['0400_04ff'][] = array('upper' => 1227, 'status' => 'C', 'lower' => array(1228)); /* CYRILLIC CAPITAL LETTER KHAKASSIAN CHE */
+$config['0400_04ff'][] = array('upper' => 1229, 'status' => 'C', 'lower' => array(1230)); /* CYRILLIC CAPITAL LETTER EM WITH TAIL */
+$config['0400_04ff'][] = array('upper' => 1232, 'status' => 'C', 'lower' => array(1233)); /* CYRILLIC CAPITAL LETTER A WITH BREVE */
+$config['0400_04ff'][] = array('upper' => 1234, 'status' => 'C', 'lower' => array(1235)); /* CYRILLIC CAPITAL LETTER A WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1236, 'status' => 'C', 'lower' => array(1237)); /* CYRILLIC CAPITAL LIGATURE A IE */
+$config['0400_04ff'][] = array('upper' => 1238, 'status' => 'C', 'lower' => array(1239)); /* CYRILLIC CAPITAL LETTER IE WITH BREVE */
+$config['0400_04ff'][] = array('upper' => 1240, 'status' => 'C', 'lower' => array(1241)); /* CYRILLIC CAPITAL LETTER SCHWA */
+$config['0400_04ff'][] = array('upper' => 1242, 'status' => 'C', 'lower' => array(1243)); /* CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1244, 'status' => 'C', 'lower' => array(1245)); /* CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1246, 'status' => 'C', 'lower' => array(1247)); /* CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1248, 'status' => 'C', 'lower' => array(1249)); /* CYRILLIC CAPITAL LETTER ABKHASIAN DZE */
+$config['0400_04ff'][] = array('upper' => 1250, 'status' => 'C', 'lower' => array(1251)); /* CYRILLIC CAPITAL LETTER I WITH MACRON */
+$config['0400_04ff'][] = array('upper' => 1252, 'status' => 'C', 'lower' => array(1253)); /* CYRILLIC CAPITAL LETTER I WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1254, 'status' => 'C', 'lower' => array(1255)); /* CYRILLIC CAPITAL LETTER O WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1256, 'status' => 'C', 'lower' => array(1257)); /* CYRILLIC CAPITAL LETTER BARRED O */
+$config['0400_04ff'][] = array('upper' => 1258, 'status' => 'C', 'lower' => array(1259)); /* CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1260, 'status' => 'C', 'lower' => array(1261)); /* CYRILLIC CAPITAL LETTER E WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1262, 'status' => 'C', 'lower' => array(1263)); /* CYRILLIC CAPITAL LETTER U WITH MACRON */
+$config['0400_04ff'][] = array('upper' => 1264, 'status' => 'C', 'lower' => array(1265)); /* CYRILLIC CAPITAL LETTER U WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1266, 'status' => 'C', 'lower' => array(1267)); /* CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE */
+$config['0400_04ff'][] = array('upper' => 1268, 'status' => 'C', 'lower' => array(1269)); /* CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1270, 'status' => 'C', 'lower' => array(1271)); /* CYRILLIC CAPITAL LETTER GHE WITH DESCENDER */
+$config['0400_04ff'][] = array('upper' => 1272, 'status' => 'C', 'lower' => array(1273)); /* CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS */
+$config['0400_04ff'][] = array('upper' => 1274, 'status' => 'C', 'lower' => array(1275)); /* CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK */
+$config['0400_04ff'][] = array('upper' => 1276, 'status' => 'C', 'lower' => array(1277)); /* CYRILLIC CAPITAL LETTER HA WITH HOOK */
+$config['0400_04ff'][] = array('upper' => 1278, 'status' => 'C', 'lower' => array(1279)); /* CYRILLIC CAPITAL LETTER HA WITH STROKE */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0500_052f.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0500_052f.php
new file mode 100644
index 0000000..73b81fa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0500_052f.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0500 through U+052F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0500_052f'][] = array('upper' => 1280, 'status' => 'C', 'lower' => array(1281)); /* CYRILLIC CAPITAL LETTER KOMI DE */
+$config['0500_052f'][] = array('upper' => 1282, 'status' => 'C', 'lower' => array(1283)); /* CYRILLIC CAPITAL LETTER KOMI DJE */
+$config['0500_052f'][] = array('upper' => 1284, 'status' => 'C', 'lower' => array(1285)); /* CYRILLIC CAPITAL LETTER KOMI ZJE */
+$config['0500_052f'][] = array('upper' => 1286, 'status' => 'C', 'lower' => array(1287)); /* CYRILLIC CAPITAL LETTER KOMI DZJE */
+$config['0500_052f'][] = array('upper' => 1288, 'status' => 'C', 'lower' => array(1289)); /* CYRILLIC CAPITAL LETTER KOMI LJE */
+$config['0500_052f'][] = array('upper' => 1290, 'status' => 'C', 'lower' => array(1291)); /* CYRILLIC CAPITAL LETTER KOMI NJE */
+$config['0500_052f'][] = array('upper' => 1292, 'status' => 'C', 'lower' => array(1293)); /* CYRILLIC CAPITAL LETTER KOMI SJE */
+$config['0500_052f'][] = array('upper' => 1294, 'status' => 'C', 'lower' => array(1295)); /* CYRILLIC CAPITAL LETTER KOMI TJE */
+$config['0500_052f'][] = array('upper' => 1296, 'status' => 'C', 'lower' => array(1297)); /* CYRILLIC CAPITAL LETTER ZE */
+$config['0500_052f'][] = array('upper' => 1298, 'status' => 'C', 'lower' => array(1299)); /* CYRILLIC CAPITAL LETTER El with hook */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0530_058f.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0530_058f.php
new file mode 100644
index 0000000..4ffb553
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/0530_058f.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+0530 through U+058F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['0530_058f'][] = array('upper' => 1329, 'status' => 'C', 'lower' => array(1377)); /* ARMENIAN CAPITAL LETTER AYB */
+$config['0530_058f'][] = array('upper' => 1330, 'status' => 'C', 'lower' => array(1378)); /* ARMENIAN CAPITAL LETTER BEN */
+$config['0530_058f'][] = array('upper' => 1331, 'status' => 'C', 'lower' => array(1379)); /* ARMENIAN CAPITAL LETTER GIM */
+$config['0530_058f'][] = array('upper' => 1332, 'status' => 'C', 'lower' => array(1380)); /* ARMENIAN CAPITAL LETTER DA */
+$config['0530_058f'][] = array('upper' => 1333, 'status' => 'C', 'lower' => array(1381)); /* ARMENIAN CAPITAL LETTER ECH */
+$config['0530_058f'][] = array('upper' => 1334, 'status' => 'C', 'lower' => array(1382)); /* ARMENIAN CAPITAL LETTER ZA */
+$config['0530_058f'][] = array('upper' => 1335, 'status' => 'C', 'lower' => array(1383)); /* ARMENIAN CAPITAL LETTER EH */
+$config['0530_058f'][] = array('upper' => 1336, 'status' => 'C', 'lower' => array(1384)); /* ARMENIAN CAPITAL LETTER ET */
+$config['0530_058f'][] = array('upper' => 1337, 'status' => 'C', 'lower' => array(1385)); /* ARMENIAN CAPITAL LETTER TO */
+$config['0530_058f'][] = array('upper' => 1338, 'status' => 'C', 'lower' => array(1386)); /* ARMENIAN CAPITAL LETTER ZHE */
+$config['0530_058f'][] = array('upper' => 1339, 'status' => 'C', 'lower' => array(1387)); /* ARMENIAN CAPITAL LETTER INI */
+$config['0530_058f'][] = array('upper' => 1340, 'status' => 'C', 'lower' => array(1388)); /* ARMENIAN CAPITAL LETTER LIWN */
+$config['0530_058f'][] = array('upper' => 1341, 'status' => 'C', 'lower' => array(1389)); /* ARMENIAN CAPITAL LETTER XEH */
+$config['0530_058f'][] = array('upper' => 1342, 'status' => 'C', 'lower' => array(1390)); /* ARMENIAN CAPITAL LETTER CA */
+$config['0530_058f'][] = array('upper' => 1343, 'status' => 'C', 'lower' => array(1391)); /* ARMENIAN CAPITAL LETTER KEN */
+$config['0530_058f'][] = array('upper' => 1344, 'status' => 'C', 'lower' => array(1392)); /* ARMENIAN CAPITAL LETTER HO */
+$config['0530_058f'][] = array('upper' => 1345, 'status' => 'C', 'lower' => array(1393)); /* ARMENIAN CAPITAL LETTER JA */
+$config['0530_058f'][] = array('upper' => 1346, 'status' => 'C', 'lower' => array(1394)); /* ARMENIAN CAPITAL LETTER GHAD */
+$config['0530_058f'][] = array('upper' => 1347, 'status' => 'C', 'lower' => array(1395)); /* ARMENIAN CAPITAL LETTER CHEH */
+$config['0530_058f'][] = array('upper' => 1348, 'status' => 'C', 'lower' => array(1396)); /* ARMENIAN CAPITAL LETTER MEN */
+$config['0530_058f'][] = array('upper' => 1349, 'status' => 'C', 'lower' => array(1397)); /* ARMENIAN CAPITAL LETTER YI */
+$config['0530_058f'][] = array('upper' => 1350, 'status' => 'C', 'lower' => array(1398)); /* ARMENIAN CAPITAL LETTER NOW */
+$config['0530_058f'][] = array('upper' => 1351, 'status' => 'C', 'lower' => array(1399)); /* ARMENIAN CAPITAL LETTER SHA */
+$config['0530_058f'][] = array('upper' => 1352, 'status' => 'C', 'lower' => array(1400)); /* ARMENIAN CAPITAL LETTER VO */
+$config['0530_058f'][] = array('upper' => 1353, 'status' => 'C', 'lower' => array(1401)); /* ARMENIAN CAPITAL LETTER CHA */
+$config['0530_058f'][] = array('upper' => 1354, 'status' => 'C', 'lower' => array(1402)); /* ARMENIAN CAPITAL LETTER PEH */
+$config['0530_058f'][] = array('upper' => 1355, 'status' => 'C', 'lower' => array(1403)); /* ARMENIAN CAPITAL LETTER JHEH */
+$config['0530_058f'][] = array('upper' => 1356, 'status' => 'C', 'lower' => array(1404)); /* ARMENIAN CAPITAL LETTER RA */
+$config['0530_058f'][] = array('upper' => 1357, 'status' => 'C', 'lower' => array(1405)); /* ARMENIAN CAPITAL LETTER SEH */
+$config['0530_058f'][] = array('upper' => 1358, 'status' => 'C', 'lower' => array(1406)); /* ARMENIAN CAPITAL LETTER VEW */
+$config['0530_058f'][] = array('upper' => 1359, 'status' => 'C', 'lower' => array(1407)); /* ARMENIAN CAPITAL LETTER TIWN */
+$config['0530_058f'][] = array('upper' => 1360, 'status' => 'C', 'lower' => array(1408)); /* ARMENIAN CAPITAL LETTER REH */
+$config['0530_058f'][] = array('upper' => 1361, 'status' => 'C', 'lower' => array(1409)); /* ARMENIAN CAPITAL LETTER CO */
+$config['0530_058f'][] = array('upper' => 1362, 'status' => 'C', 'lower' => array(1410)); /* ARMENIAN CAPITAL LETTER YIWN */
+$config['0530_058f'][] = array('upper' => 1363, 'status' => 'C', 'lower' => array(1411)); /* ARMENIAN CAPITAL LETTER PIWR */
+$config['0530_058f'][] = array('upper' => 1364, 'status' => 'C', 'lower' => array(1412)); /* ARMENIAN CAPITAL LETTER KEH */
+$config['0530_058f'][] = array('upper' => 1365, 'status' => 'C', 'lower' => array(1413)); /* ARMENIAN CAPITAL LETTER OH */
+$config['0530_058f'][] = array('upper' => 1366, 'status' => 'C', 'lower' => array(1414)); /* ARMENIAN CAPITAL LETTER FEH */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1e00_1eff.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1e00_1eff.php
new file mode 100644
index 0000000..5b534a3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1e00_1eff.php
@@ -0,0 +1,168 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+1E00 through U+1EFF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['1e00_1eff'][] = array('upper' => 7680, 'status' => 'C', 'lower' => array(7681)); /* LATIN CAPITAL LETTER A WITH RING BELOW */
+$config['1e00_1eff'][] = array('upper' => 7682, 'status' => 'C', 'lower' => array(7683)); /* LATIN CAPITAL LETTER B WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7684, 'status' => 'C', 'lower' => array(7685)); /* LATIN CAPITAL LETTER B WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7686, 'status' => 'C', 'lower' => array(7687)); /* LATIN CAPITAL LETTER B WITH LINE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7688, 'status' => 'C', 'lower' => array(7689)); /* LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7690, 'status' => 'C', 'lower' => array(7691)); /* LATIN CAPITAL LETTER D WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7692, 'status' => 'C', 'lower' => array(7693)); /* LATIN CAPITAL LETTER D WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7694, 'status' => 'C', 'lower' => array(7695)); /* LATIN CAPITAL LETTER D WITH LINE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7696, 'status' => 'C', 'lower' => array(7697)); /* LATIN CAPITAL LETTER D WITH CEDILLA */
+$config['1e00_1eff'][] = array('upper' => 7698, 'status' => 'C', 'lower' => array(7699)); /* LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW */
+$config['1e00_1eff'][] = array('upper' => 7700, 'status' => 'C', 'lower' => array(7701)); /* LATIN CAPITAL LETTER E WITH MACRON AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7702, 'status' => 'C', 'lower' => array(7703)); /* LATIN CAPITAL LETTER E WITH MACRON AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7704, 'status' => 'C', 'lower' => array(7705)); /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW */
+$config['1e00_1eff'][] = array('upper' => 7706, 'status' => 'C', 'lower' => array(7707)); /* LATIN CAPITAL LETTER E WITH TILDE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7708, 'status' => 'C', 'lower' => array(7709)); /* LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE */
+$config['1e00_1eff'][] = array('upper' => 7710, 'status' => 'C', 'lower' => array(7711)); /* LATIN CAPITAL LETTER F WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7712, 'status' => 'C', 'lower' => array(7713)); /* LATIN CAPITAL LETTER G WITH MACRON */
+$config['1e00_1eff'][] = array('upper' => 7714, 'status' => 'C', 'lower' => array(7715)); /* LATIN CAPITAL LETTER H WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7716, 'status' => 'C', 'lower' => array(7717)); /* LATIN CAPITAL LETTER H WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7718, 'status' => 'C', 'lower' => array(7719)); /* LATIN CAPITAL LETTER H WITH DIAERESIS */
+$config['1e00_1eff'][] = array('upper' => 7720, 'status' => 'C', 'lower' => array(7721)); /* LATIN CAPITAL LETTER H WITH CEDILLA */
+$config['1e00_1eff'][] = array('upper' => 7722, 'status' => 'C', 'lower' => array(7723)); /* LATIN CAPITAL LETTER H WITH BREVE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7724, 'status' => 'C', 'lower' => array(7725)); /* LATIN CAPITAL LETTER I WITH TILDE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7726, 'status' => 'C', 'lower' => array(7727)); /* LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7728, 'status' => 'C', 'lower' => array(7729)); /* LATIN CAPITAL LETTER K WITH ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7730, 'status' => 'C', 'lower' => array(7731)); /* LATIN CAPITAL LETTER K WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7732, 'status' => 'C', 'lower' => array(7733)); /* LATIN CAPITAL LETTER K WITH LINE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7734, 'status' => 'C', 'lower' => array(7735)); /* LATIN CAPITAL LETTER L WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7736, 'status' => 'C', 'lower' => array(7737)); /* LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON */
+$config['1e00_1eff'][] = array('upper' => 7738, 'status' => 'C', 'lower' => array(7739)); /* LATIN CAPITAL LETTER L WITH LINE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7740, 'status' => 'C', 'lower' => array(7741)); /* LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW */
+$config['1e00_1eff'][] = array('upper' => 7742, 'status' => 'C', 'lower' => array(7743)); /* LATIN CAPITAL LETTER M WITH ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7744, 'status' => 'C', 'lower' => array(7745)); /* LATIN CAPITAL LETTER M WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7746, 'status' => 'C', 'lower' => array(7747)); /* LATIN CAPITAL LETTER M WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7748, 'status' => 'C', 'lower' => array(7749)); /* LATIN CAPITAL LETTER N WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7750, 'status' => 'C', 'lower' => array(7751)); /* LATIN CAPITAL LETTER N WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7752, 'status' => 'C', 'lower' => array(7753)); /* LATIN CAPITAL LETTER N WITH LINE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7754, 'status' => 'C', 'lower' => array(7755)); /* LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW */
+$config['1e00_1eff'][] = array('upper' => 7756, 'status' => 'C', 'lower' => array(7757)); /* LATIN CAPITAL LETTER O WITH TILDE AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7758, 'status' => 'C', 'lower' => array(7759)); /* LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS */
+$config['1e00_1eff'][] = array('upper' => 7760, 'status' => 'C', 'lower' => array(7761)); /* LATIN CAPITAL LETTER O WITH MACRON AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7762, 'status' => 'C', 'lower' => array(7763)); /* LATIN CAPITAL LETTER O WITH MACRON AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7764, 'status' => 'C', 'lower' => array(7765)); /* LATIN CAPITAL LETTER P WITH ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7766, 'status' => 'C', 'lower' => array(7767)); /* LATIN CAPITAL LETTER P WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7768, 'status' => 'C', 'lower' => array(7769)); /* LATIN CAPITAL LETTER R WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7770, 'status' => 'C', 'lower' => array(7771)); /* LATIN CAPITAL LETTER R WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7772, 'status' => 'C', 'lower' => array(7773)); /* LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON */
+$config['1e00_1eff'][] = array('upper' => 7774, 'status' => 'C', 'lower' => array(7775)); /* LATIN CAPITAL LETTER R WITH LINE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7776, 'status' => 'C', 'lower' => array(7777)); /* LATIN CAPITAL LETTER S WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7778, 'status' => 'C', 'lower' => array(7779)); /* LATIN CAPITAL LETTER S WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7780, 'status' => 'C', 'lower' => array(7781)); /* LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7782, 'status' => 'C', 'lower' => array(7783)); /* LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7784, 'status' => 'C', 'lower' => array(7785)); /* LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7786, 'status' => 'C', 'lower' => array(7787)); /* LATIN CAPITAL LETTER T WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7788, 'status' => 'C', 'lower' => array(7789)); /* LATIN CAPITAL LETTER T WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7790, 'status' => 'C', 'lower' => array(7791)); /* LATIN CAPITAL LETTER T WITH LINE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7792, 'status' => 'C', 'lower' => array(7793)); /* LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW */
+$config['1e00_1eff'][] = array('upper' => 7794, 'status' => 'C', 'lower' => array(7795)); /* LATIN CAPITAL LETTER U WITH DIAERESIS BELOW */
+$config['1e00_1eff'][] = array('upper' => 7796, 'status' => 'C', 'lower' => array(7797)); /* LATIN CAPITAL LETTER U WITH TILDE BELOW */
+$config['1e00_1eff'][] = array('upper' => 7798, 'status' => 'C', 'lower' => array(7799)); /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW */
+$config['1e00_1eff'][] = array('upper' => 7800, 'status' => 'C', 'lower' => array(7801)); /* LATIN CAPITAL LETTER U WITH TILDE AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7802, 'status' => 'C', 'lower' => array(7803)); /* LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS */
+$config['1e00_1eff'][] = array('upper' => 7804, 'status' => 'C', 'lower' => array(7805)); /* LATIN CAPITAL LETTER V WITH TILDE */
+$config['1e00_1eff'][] = array('upper' => 7806, 'status' => 'C', 'lower' => array(7807)); /* LATIN CAPITAL LETTER V WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7808, 'status' => 'C', 'lower' => array(7809)); /* LATIN CAPITAL LETTER W WITH GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7810, 'status' => 'C', 'lower' => array(7811)); /* LATIN CAPITAL LETTER W WITH ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7812, 'status' => 'C', 'lower' => array(7813)); /* LATIN CAPITAL LETTER W WITH DIAERESIS */
+$config['1e00_1eff'][] = array('upper' => 7814, 'status' => 'C', 'lower' => array(7815)); /* LATIN CAPITAL LETTER W WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7816, 'status' => 'C', 'lower' => array(7817)); /* LATIN CAPITAL LETTER W WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7818, 'status' => 'C', 'lower' => array(7819)); /* LATIN CAPITAL LETTER X WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7820, 'status' => 'C', 'lower' => array(7821)); /* LATIN CAPITAL LETTER X WITH DIAERESIS */
+$config['1e00_1eff'][] = array('upper' => 7822, 'status' => 'C', 'lower' => array(7823)); /* LATIN CAPITAL LETTER Y WITH DOT ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7824, 'status' => 'C', 'lower' => array(7825)); /* LATIN CAPITAL LETTER Z WITH CIRCUMFLEX */
+$config['1e00_1eff'][] = array('upper' => 7826, 'status' => 'C', 'lower' => array(7827)); /* LATIN CAPITAL LETTER Z WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7828, 'status' => 'C', 'lower' => array(7829)); /* LATIN CAPITAL LETTER Z WITH LINE BELOW */
+
+//$config['1e00_1eff'][] = array('upper' => 7830, 'status' => 'F', 'lower' => array(104, 817)); /* LATIN SMALL LETTER H WITH LINE BELOW */
+//$config['1e00_1eff'][] = array('upper' => 7831, 'status' => 'F', 'lower' => array(116, 776)); /* LATIN SMALL LETTER T WITH DIAERESIS */
+//$config['1e00_1eff'][] = array('upper' => 7832, 'status' => 'F', 'lower' => array(119, 778)); /* LATIN SMALL LETTER W WITH RING ABOVE */
+//$config['1e00_1eff'][] = array('upper' => 7833, 'status' => 'F', 'lower' => array(121, 778)); /* LATIN SMALL LETTER Y WITH RING ABOVE */
+//$config['1e00_1eff'][] = array('upper' => 7834, 'status' => 'F', 'lower' => array(97, 702)); /* LATIN SMALL LETTER A WITH RIGHT HALF RING */
+//$config['1e00_1eff'][] = array('upper' => 7835, 'status' => 'C', 'lower' => array(7777)); /* LATIN SMALL LETTER LONG S WITH DOT ABOVE */
+
+$config['1e00_1eff'][] = array('upper' => 7840, 'status' => 'C', 'lower' => array(7841)); /* LATIN CAPITAL LETTER A WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7842, 'status' => 'C', 'lower' => array(7843)); /* LATIN CAPITAL LETTER A WITH HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7844, 'status' => 'C', 'lower' => array(7845)); /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7846, 'status' => 'C', 'lower' => array(7847)); /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7848, 'status' => 'C', 'lower' => array(7849)); /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7850, 'status' => 'C', 'lower' => array(7851)); /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
+$config['1e00_1eff'][] = array('upper' => 7852, 'status' => 'C', 'lower' => array(7853)); /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7854, 'status' => 'C', 'lower' => array(7855)); /* LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7856, 'status' => 'C', 'lower' => array(7857)); /* LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7858, 'status' => 'C', 'lower' => array(7859)); /* LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7860, 'status' => 'C', 'lower' => array(7861)); /* LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
+$config['1e00_1eff'][] = array('upper' => 7862, 'status' => 'C', 'lower' => array(7863)); /* LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7864, 'status' => 'C', 'lower' => array(7865)); /* LATIN CAPITAL LETTER E WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7866, 'status' => 'C', 'lower' => array(7867)); /* LATIN CAPITAL LETTER E WITH HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7868, 'status' => 'C', 'lower' => array(7869)); /* LATIN CAPITAL LETTER E WITH TILDE */
+$config['1e00_1eff'][] = array('upper' => 7870, 'status' => 'C', 'lower' => array(7871)); /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7872, 'status' => 'C', 'lower' => array(7873)); /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7874, 'status' => 'C', 'lower' => array(7875)); /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7876, 'status' => 'C', 'lower' => array(7877)); /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
+$config['1e00_1eff'][] = array('upper' => 7878, 'status' => 'C', 'lower' => array(7879)); /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7880, 'status' => 'C', 'lower' => array(7881)); /* LATIN CAPITAL LETTER I WITH HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7882, 'status' => 'C', 'lower' => array(7883)); /* LATIN CAPITAL LETTER I WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7884, 'status' => 'C', 'lower' => array(7885)); /* LATIN CAPITAL LETTER O WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7886, 'status' => 'C', 'lower' => array(7887)); /* LATIN CAPITAL LETTER O WITH HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7888, 'status' => 'C', 'lower' => array(7889)); /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7890, 'status' => 'C', 'lower' => array(7891)); /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7892, 'status' => 'C', 'lower' => array(7893)); /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7894, 'status' => 'C', 'lower' => array(7895)); /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
+$config['1e00_1eff'][] = array('upper' => 7896, 'status' => 'C', 'lower' => array(7897)); /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7898, 'status' => 'C', 'lower' => array(7899)); /* LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7900, 'status' => 'C', 'lower' => array(7901)); /* LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7902, 'status' => 'C', 'lower' => array(7903)); /* LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7904, 'status' => 'C', 'lower' => array(7905)); /* LATIN CAPITAL LETTER O WITH HORN AND TILDE */
+$config['1e00_1eff'][] = array('upper' => 7906, 'status' => 'C', 'lower' => array(7907)); /* LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7908, 'status' => 'C', 'lower' => array(7909)); /* LATIN CAPITAL LETTER U WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7910, 'status' => 'C', 'lower' => array(7911)); /* LATIN CAPITAL LETTER U WITH HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7912, 'status' => 'C', 'lower' => array(7913)); /* LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
+$config['1e00_1eff'][] = array('upper' => 7914, 'status' => 'C', 'lower' => array(7915)); /* LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7916, 'status' => 'C', 'lower' => array(7917)); /* LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7918, 'status' => 'C', 'lower' => array(7919)); /* LATIN CAPITAL LETTER U WITH HORN AND TILDE */
+$config['1e00_1eff'][] = array('upper' => 7920, 'status' => 'C', 'lower' => array(7921)); /* LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7922, 'status' => 'C', 'lower' => array(7923)); /* LATIN CAPITAL LETTER Y WITH GRAVE */
+$config['1e00_1eff'][] = array('upper' => 7924, 'status' => 'C', 'lower' => array(7925)); /* LATIN CAPITAL LETTER Y WITH DOT BELOW */
+$config['1e00_1eff'][] = array('upper' => 7926, 'status' => 'C', 'lower' => array(7927)); /* LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
+$config['1e00_1eff'][] = array('upper' => 7928, 'status' => 'C', 'lower' => array(7929)); /* LATIN CAPITAL LETTER Y WITH TILDE */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1f00_1fff.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1f00_1fff.php
new file mode 100644
index 0000000..be09aa5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/1f00_1fff.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+1F00 through U+1FFF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['1f00_1fff'][] = array('upper' => 7944, 'status' => 'C', 'lower' => array(7936, 953)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 7945, 'status' => 'C', 'lower' => array(7937)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 7946, 'status' => 'C', 'lower' => array(7938)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7947, 'status' => 'C', 'lower' => array(7939)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7948, 'status' => 'C', 'lower' => array(7940)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7949, 'status' => 'C', 'lower' => array(7941)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7950, 'status' => 'C', 'lower' => array(7942)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 7951, 'status' => 'C', 'lower' => array(7943)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 7960, 'status' => 'C', 'lower' => array(7952)); /* GREEK CAPITAL LETTER EPSILON WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 7961, 'status' => 'C', 'lower' => array(7953)); /* GREEK CAPITAL LETTER EPSILON WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 7962, 'status' => 'C', 'lower' => array(7954)); /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7963, 'status' => 'C', 'lower' => array(7955)); /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7964, 'status' => 'C', 'lower' => array(7956)); /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7965, 'status' => 'C', 'lower' => array(7957)); /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7976, 'status' => 'C', 'lower' => array(7968)); /* GREEK CAPITAL LETTER ETA WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 7977, 'status' => 'C', 'lower' => array(7969)); /* GREEK CAPITAL LETTER ETA WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 7978, 'status' => 'C', 'lower' => array(7970)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7979, 'status' => 'C', 'lower' => array(7971)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7980, 'status' => 'C', 'lower' => array(7972)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7981, 'status' => 'C', 'lower' => array(7973)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7982, 'status' => 'C', 'lower' => array(7974)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 7983, 'status' => 'C', 'lower' => array(7975)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 7992, 'status' => 'C', 'lower' => array(7984)); /* GREEK CAPITAL LETTER IOTA WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 7993, 'status' => 'C', 'lower' => array(7985)); /* GREEK CAPITAL LETTER IOTA WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 7994, 'status' => 'C', 'lower' => array(7986)); /* GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7995, 'status' => 'C', 'lower' => array(7987)); /* GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 7996, 'status' => 'C', 'lower' => array(7988)); /* GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7997, 'status' => 'C', 'lower' => array(7989)); /* GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 7998, 'status' => 'C', 'lower' => array(7990)); /* GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 7999, 'status' => 'C', 'lower' => array(7991)); /* GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8008, 'status' => 'C', 'lower' => array(8000)); /* GREEK CAPITAL LETTER OMICRON WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 8009, 'status' => 'C', 'lower' => array(8001)); /* GREEK CAPITAL LETTER OMICRON WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 8010, 'status' => 'C', 'lower' => array(8002)); /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8011, 'status' => 'C', 'lower' => array(8003)); /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8012, 'status' => 'C', 'lower' => array(8004)); /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8013, 'status' => 'C', 'lower' => array(8005)); /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8016, 'status' => 'F', 'lower' => array(965, 787)); /* GREEK SMALL LETTER UPSILON WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 8018, 'status' => 'F', 'lower' => array(965, 787, 768)); /* GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8020, 'status' => 'F', 'lower' => array(965, 787, 769)); /* GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8022, 'status' => 'F', 'lower' => array(965, 787, 834)); /* GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8025, 'status' => 'C', 'lower' => array(8017)); /* GREEK CAPITAL LETTER UPSILON WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 8027, 'status' => 'C', 'lower' => array(8019)); /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8029, 'status' => 'C', 'lower' => array(8021)); /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8031, 'status' => 'C', 'lower' => array(8023)); /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8040, 'status' => 'C', 'lower' => array(8032)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 8041, 'status' => 'C', 'lower' => array(8033)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 8042, 'status' => 'C', 'lower' => array(8034)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8043, 'status' => 'C', 'lower' => array(8035)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8044, 'status' => 'C', 'lower' => array(8036)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8045, 'status' => 'C', 'lower' => array(8037)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8046, 'status' => 'C', 'lower' => array(8038)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8047, 'status' => 'C', 'lower' => array(8039)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8064, 'status' => 'F', 'lower' => array(7936, 953)); /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8065, 'status' => 'F', 'lower' => array(7937, 953)); /* GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8066, 'status' => 'F', 'lower' => array(7938, 953)); /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8067, 'status' => 'F', 'lower' => array(7939, 953)); /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8068, 'status' => 'F', 'lower' => array(7940, 953)); /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8069, 'status' => 'F', 'lower' => array(7941, 953)); /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8070, 'status' => 'F', 'lower' => array(7942, 953)); /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8071, 'status' => 'F', 'lower' => array(7943, 953)); /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8072, 'status' => 'F', 'lower' => array(7936, 953)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8072, 'status' => 'S', 'lower' => array(8064)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8073, 'status' => 'F', 'lower' => array(7937, 953)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8073, 'status' => 'S', 'lower' => array(8065)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8074, 'status' => 'F', 'lower' => array(7938, 953)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8074, 'status' => 'S', 'lower' => array(8066)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8075, 'status' => 'F', 'lower' => array(7939, 953)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8075, 'status' => 'S', 'lower' => array(8067)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8076, 'status' => 'F', 'lower' => array(7940, 953)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8076, 'status' => 'S', 'lower' => array(8068)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8077, 'status' => 'F', 'lower' => array(7941, 953)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8077, 'status' => 'S', 'lower' => array(8069)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8078, 'status' => 'F', 'lower' => array(7942, 953)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8078, 'status' => 'S', 'lower' => array(8070)); /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8079, 'status' => 'F', 'lower' => array(7943, 953)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8079, 'status' => 'S', 'lower' => array(8071)); /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8080, 'status' => 'F', 'lower' => array(7968, 953)); /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8081, 'status' => 'F', 'lower' => array(7969, 953)); /* GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8082, 'status' => 'F', 'lower' => array(7970, 953)); /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8083, 'status' => 'F', 'lower' => array(7971, 953)); /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8084, 'status' => 'F', 'lower' => array(7972, 953)); /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8085, 'status' => 'F', 'lower' => array(7973, 953)); /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8086, 'status' => 'F', 'lower' => array(7974, 953)); /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8087, 'status' => 'F', 'lower' => array(7975, 953)); /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8088, 'status' => 'F', 'lower' => array(7968, 953)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8088, 'status' => 'S', 'lower' => array(8080)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8089, 'status' => 'F', 'lower' => array(7969, 953)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8089, 'status' => 'S', 'lower' => array(8081)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8090, 'status' => 'F', 'lower' => array(7970, 953)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8090, 'status' => 'S', 'lower' => array(8082)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8091, 'status' => 'F', 'lower' => array(7971, 953)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8091, 'status' => 'S', 'lower' => array(8083)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8092, 'status' => 'F', 'lower' => array(7972, 953)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8092, 'status' => 'S', 'lower' => array(8084)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8093, 'status' => 'F', 'lower' => array(7973, 953)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8093, 'status' => 'S', 'lower' => array(8085)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8094, 'status' => 'F', 'lower' => array(7974, 953)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8094, 'status' => 'S', 'lower' => array(8086)); /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8095, 'status' => 'F', 'lower' => array(7975, 953)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8095, 'status' => 'S', 'lower' => array(8087)); /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8096, 'status' => 'F', 'lower' => array(8032, 953)); /* GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8097, 'status' => 'F', 'lower' => array(8033, 953)); /* GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8098, 'status' => 'F', 'lower' => array(8034, 953)); /* GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8099, 'status' => 'F', 'lower' => array(8035, 953)); /* GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8100, 'status' => 'F', 'lower' => array(8036, 953)); /* GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8101, 'status' => 'F', 'lower' => array(8037, 953)); /* GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8102, 'status' => 'F', 'lower' => array(8038, 953)); /* GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8103, 'status' => 'F', 'lower' => array(8039, 953)); /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8104, 'status' => 'F', 'lower' => array(8032, 953)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8104, 'status' => 'S', 'lower' => array(8096)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8105, 'status' => 'F', 'lower' => array(8033, 953)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8105, 'status' => 'S', 'lower' => array(8097)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8106, 'status' => 'F', 'lower' => array(8034, 953)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8106, 'status' => 'S', 'lower' => array(8098)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8107, 'status' => 'F', 'lower' => array(8035, 953)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8107, 'status' => 'S', 'lower' => array(8099)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8108, 'status' => 'F', 'lower' => array(8036, 953)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8108, 'status' => 'S', 'lower' => array(8100)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8109, 'status' => 'F', 'lower' => array(8037, 953)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8109, 'status' => 'S', 'lower' => array(8101)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8110, 'status' => 'F', 'lower' => array(8038, 953)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8110, 'status' => 'S', 'lower' => array(8102)); /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8111, 'status' => 'F', 'lower' => array(8039, 953)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8111, 'status' => 'S', 'lower' => array(8103)); /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8114, 'status' => 'F', 'lower' => array(8048, 953)); /* GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8115, 'status' => 'F', 'lower' => array(945, 953)); /* GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8116, 'status' => 'F', 'lower' => array(940, 953)); /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8118, 'status' => 'F', 'lower' => array(945, 834)); /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8119, 'status' => 'F', 'lower' => array(945, 834, 953)); /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8120, 'status' => 'C', 'lower' => array(8112)); /* GREEK CAPITAL LETTER ALPHA WITH VRACHY */
+$config['1f00_1fff'][] = array('upper' => 8121, 'status' => 'C', 'lower' => array(8113)); /* GREEK CAPITAL LETTER ALPHA WITH MACRON */
+$config['1f00_1fff'][] = array('upper' => 8122, 'status' => 'C', 'lower' => array(8048)); /* GREEK CAPITAL LETTER ALPHA WITH VARIA */
+$config['1f00_1fff'][] = array('upper' => 8123, 'status' => 'C', 'lower' => array(8049)); /* GREEK CAPITAL LETTER ALPHA WITH OXIA */
+$config['1f00_1fff'][] = array('upper' => 8124, 'status' => 'F', 'lower' => array(945, 953)); /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8124, 'status' => 'S', 'lower' => array(8115)); /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8126, 'status' => 'C', 'lower' => array(953)); /* GREEK PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8130, 'status' => 'F', 'lower' => array(8052, 953)); /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8131, 'status' => 'F', 'lower' => array(951, 953)); /* GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8132, 'status' => 'F', 'lower' => array(942, 953)); /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8134, 'status' => 'F', 'lower' => array(951, 834)); /* GREEK SMALL LETTER ETA WITH PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8135, 'status' => 'F', 'lower' => array(951, 834, 953)); /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8136, 'status' => 'C', 'lower' => array(8050)); /* GREEK CAPITAL LETTER EPSILON WITH VARIA */
+$config['1f00_1fff'][] = array('upper' => 8137, 'status' => 'C', 'lower' => array(8051)); /* GREEK CAPITAL LETTER EPSILON WITH OXIA */
+$config['1f00_1fff'][] = array('upper' => 8138, 'status' => 'C', 'lower' => array(8052)); /* GREEK CAPITAL LETTER ETA WITH VARIA */
+$config['1f00_1fff'][] = array('upper' => 8139, 'status' => 'C', 'lower' => array(8053)); /* GREEK CAPITAL LETTER ETA WITH OXIA */
+$config['1f00_1fff'][] = array('upper' => 8140, 'status' => 'F', 'lower' => array(951, 953)); /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8140, 'status' => 'S', 'lower' => array(8131)); /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8146, 'status' => 'F', 'lower' => array(953, 776, 768)); /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8147, 'status' => 'F', 'lower' => array(953, 776, 769)); /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8150, 'status' => 'F', 'lower' => array(953, 834)); /* GREEK SMALL LETTER IOTA WITH PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8151, 'status' => 'F', 'lower' => array(953, 776, 834)); /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8152, 'status' => 'C', 'lower' => array(8144)); /* GREEK CAPITAL LETTER IOTA WITH VRACHY */
+$config['1f00_1fff'][] = array('upper' => 8153, 'status' => 'C', 'lower' => array(8145)); /* GREEK CAPITAL LETTER IOTA WITH MACRON */
+$config['1f00_1fff'][] = array('upper' => 8154, 'status' => 'C', 'lower' => array(8054)); /* GREEK CAPITAL LETTER IOTA WITH VARIA */
+$config['1f00_1fff'][] = array('upper' => 8155, 'status' => 'C', 'lower' => array(8055)); /* GREEK CAPITAL LETTER IOTA WITH OXIA */
+$config['1f00_1fff'][] = array('upper' => 8162, 'status' => 'F', 'lower' => array(965, 776, 768)); /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA */
+$config['1f00_1fff'][] = array('upper' => 8163, 'status' => 'F', 'lower' => array(965, 776, 769)); /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA */
+$config['1f00_1fff'][] = array('upper' => 8164, 'status' => 'F', 'lower' => array(961, 787)); /* GREEK SMALL LETTER RHO WITH PSILI */
+$config['1f00_1fff'][] = array('upper' => 8166, 'status' => 'F', 'lower' => array(965, 834)); /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8167, 'status' => 'F', 'lower' => array(965, 776, 834)); /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8168, 'status' => 'C', 'lower' => array(8160)); /* GREEK CAPITAL LETTER UPSILON WITH VRACHY */
+$config['1f00_1fff'][] = array('upper' => 8169, 'status' => 'C', 'lower' => array(8161)); /* GREEK CAPITAL LETTER UPSILON WITH MACRON */
+$config['1f00_1fff'][] = array('upper' => 8170, 'status' => 'C', 'lower' => array(8058)); /* GREEK CAPITAL LETTER UPSILON WITH VARIA */
+$config['1f00_1fff'][] = array('upper' => 8171, 'status' => 'C', 'lower' => array(8059)); /* GREEK CAPITAL LETTER UPSILON WITH OXIA */
+$config['1f00_1fff'][] = array('upper' => 8172, 'status' => 'C', 'lower' => array(8165)); /* GREEK CAPITAL LETTER RHO WITH DASIA */
+$config['1f00_1fff'][] = array('upper' => 8178, 'status' => 'F', 'lower' => array(8060, 953)); /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8179, 'status' => 'F', 'lower' => array(969, 953)); /* GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8180, 'status' => 'F', 'lower' => array(974, 953)); /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8182, 'status' => 'F', 'lower' => array(969, 834)); /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI */
+$config['1f00_1fff'][] = array('upper' => 8183, 'status' => 'F', 'lower' => array(969, 834, 953)); /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8184, 'status' => 'C', 'lower' => array(8056)); /* GREEK CAPITAL LETTER OMICRON WITH VARIA */
+$config['1f00_1fff'][] = array('upper' => 8185, 'status' => 'C', 'lower' => array(8057)); /* GREEK CAPITAL LETTER OMICRON WITH OXIA */
+$config['1f00_1fff'][] = array('upper' => 8186, 'status' => 'C', 'lower' => array(8060)); /* GREEK CAPITAL LETTER OMEGA WITH VARIA */
+$config['1f00_1fff'][] = array('upper' => 8187, 'status' => 'C', 'lower' => array(8061)); /* GREEK CAPITAL LETTER OMEGA WITH OXIA */
+$config['1f00_1fff'][] = array('upper' => 8188, 'status' => 'F', 'lower' => array(969, 953)); /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */
+$config['1f00_1fff'][] = array('upper' => 8188, 'status' => 'S', 'lower' => array(8179)); /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2100_214f.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2100_214f.php
new file mode 100644
index 0000000..77705ed
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2100_214f.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+2100 through U+214F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['2100_214f'][] = array('upper' => 8486, 'status' => 'C', 'lower' => array(969)); /* OHM SIGN */
+$config['2100_214f'][] = array('upper' => 8490, 'status' => 'C', 'lower' => array(107)); /* KELVIN SIGN */
+$config['2100_214f'][] = array('upper' => 8491, 'status' => 'C', 'lower' => array(229)); /* ANGSTROM SIGN */
+$config['2100_214f'][] = array('upper' => 8498, 'status' => 'C', 'lower' => array(8526)); /* TURNED CAPITAL F */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2150_218f.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2150_218f.php
new file mode 100644
index 0000000..8821fbd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2150_218f.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+2150 through U+218F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['2150_218f'][] = array('upper' => 8544, 'status' => 'C', 'lower' => array(8560)); /* ROMAN NUMERAL ONE */
+$config['2150_218f'][] = array('upper' => 8545, 'status' => 'C', 'lower' => array(8561)); /* ROMAN NUMERAL TWO */
+$config['2150_218f'][] = array('upper' => 8546, 'status' => 'C', 'lower' => array(8562)); /* ROMAN NUMERAL THREE */
+$config['2150_218f'][] = array('upper' => 8547, 'status' => 'C', 'lower' => array(8563)); /* ROMAN NUMERAL FOUR */
+$config['2150_218f'][] = array('upper' => 8548, 'status' => 'C', 'lower' => array(8564)); /* ROMAN NUMERAL FIVE */
+$config['2150_218f'][] = array('upper' => 8549, 'status' => 'C', 'lower' => array(8565)); /* ROMAN NUMERAL SIX */
+$config['2150_218f'][] = array('upper' => 8550, 'status' => 'C', 'lower' => array(8566)); /* ROMAN NUMERAL SEVEN */
+$config['2150_218f'][] = array('upper' => 8551, 'status' => 'C', 'lower' => array(8567)); /* ROMAN NUMERAL EIGHT */
+$config['2150_218f'][] = array('upper' => 8552, 'status' => 'C', 'lower' => array(8568)); /* ROMAN NUMERAL NINE */
+$config['2150_218f'][] = array('upper' => 8553, 'status' => 'C', 'lower' => array(8569)); /* ROMAN NUMERAL TEN */
+$config['2150_218f'][] = array('upper' => 8554, 'status' => 'C', 'lower' => array(8570)); /* ROMAN NUMERAL ELEVEN */
+$config['2150_218f'][] = array('upper' => 8555, 'status' => 'C', 'lower' => array(8571)); /* ROMAN NUMERAL TWELVE */
+$config['2150_218f'][] = array('upper' => 8556, 'status' => 'C', 'lower' => array(8572)); /* ROMAN NUMERAL FIFTY */
+$config['2150_218f'][] = array('upper' => 8557, 'status' => 'C', 'lower' => array(8573)); /* ROMAN NUMERAL ONE HUNDRED */
+$config['2150_218f'][] = array('upper' => 8558, 'status' => 'C', 'lower' => array(8574)); /* ROMAN NUMERAL FIVE HUNDRED */
+$config['2150_218f'][] = array('upper' => 8559, 'status' => 'C', 'lower' => array(8575)); /* ROMAN NUMERAL ONE THOUSAND */
+$config['2150_218f'][] = array('upper' => 8579, 'status' => 'C', 'lower' => array(8580)); /* ROMAN NUMERAL REVERSED ONE HUNDRED */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2460_24ff.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2460_24ff.php
new file mode 100644
index 0000000..08b2615
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2460_24ff.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+2460 through U+24FF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['2460_24ff'][] = array('upper' => 9398, 'status' => 'C', 'lower' => array(9424)); /* CIRCLED LATIN CAPITAL LETTER A */
+$config['2460_24ff'][] = array('upper' => 9399, 'status' => 'C', 'lower' => array(9425)); /* CIRCLED LATIN CAPITAL LETTER B */
+$config['2460_24ff'][] = array('upper' => 9400, 'status' => 'C', 'lower' => array(9426)); /* CIRCLED LATIN CAPITAL LETTER C */
+$config['2460_24ff'][] = array('upper' => 9401, 'status' => 'C', 'lower' => array(9427)); /* CIRCLED LATIN CAPITAL LETTER D */
+$config['2460_24ff'][] = array('upper' => 9402, 'status' => 'C', 'lower' => array(9428)); /* CIRCLED LATIN CAPITAL LETTER E */
+$config['2460_24ff'][] = array('upper' => 9403, 'status' => 'C', 'lower' => array(9429)); /* CIRCLED LATIN CAPITAL LETTER F */
+$config['2460_24ff'][] = array('upper' => 9404, 'status' => 'C', 'lower' => array(9430)); /* CIRCLED LATIN CAPITAL LETTER G */
+$config['2460_24ff'][] = array('upper' => 9405, 'status' => 'C', 'lower' => array(9431)); /* CIRCLED LATIN CAPITAL LETTER H */
+$config['2460_24ff'][] = array('upper' => 9406, 'status' => 'C', 'lower' => array(9432)); /* CIRCLED LATIN CAPITAL LETTER I */
+$config['2460_24ff'][] = array('upper' => 9407, 'status' => 'C', 'lower' => array(9433)); /* CIRCLED LATIN CAPITAL LETTER J */
+$config['2460_24ff'][] = array('upper' => 9408, 'status' => 'C', 'lower' => array(9434)); /* CIRCLED LATIN CAPITAL LETTER K */
+$config['2460_24ff'][] = array('upper' => 9409, 'status' => 'C', 'lower' => array(9435)); /* CIRCLED LATIN CAPITAL LETTER L */
+$config['2460_24ff'][] = array('upper' => 9410, 'status' => 'C', 'lower' => array(9436)); /* CIRCLED LATIN CAPITAL LETTER M */
+$config['2460_24ff'][] = array('upper' => 9411, 'status' => 'C', 'lower' => array(9437)); /* CIRCLED LATIN CAPITAL LETTER N */
+$config['2460_24ff'][] = array('upper' => 9412, 'status' => 'C', 'lower' => array(9438)); /* CIRCLED LATIN CAPITAL LETTER O */
+$config['2460_24ff'][] = array('upper' => 9413, 'status' => 'C', 'lower' => array(9439)); /* CIRCLED LATIN CAPITAL LETTER P */
+$config['2460_24ff'][] = array('upper' => 9414, 'status' => 'C', 'lower' => array(9440)); /* CIRCLED LATIN CAPITAL LETTER Q */
+$config['2460_24ff'][] = array('upper' => 9415, 'status' => 'C', 'lower' => array(9441)); /* CIRCLED LATIN CAPITAL LETTER R */
+$config['2460_24ff'][] = array('upper' => 9416, 'status' => 'C', 'lower' => array(9442)); /* CIRCLED LATIN CAPITAL LETTER S */
+$config['2460_24ff'][] = array('upper' => 9417, 'status' => 'C', 'lower' => array(9443)); /* CIRCLED LATIN CAPITAL LETTER T */
+$config['2460_24ff'][] = array('upper' => 9418, 'status' => 'C', 'lower' => array(9444)); /* CIRCLED LATIN CAPITAL LETTER U */
+$config['2460_24ff'][] = array('upper' => 9419, 'status' => 'C', 'lower' => array(9445)); /* CIRCLED LATIN CAPITAL LETTER V */
+$config['2460_24ff'][] = array('upper' => 9420, 'status' => 'C', 'lower' => array(9446)); /* CIRCLED LATIN CAPITAL LETTER W */
+$config['2460_24ff'][] = array('upper' => 9421, 'status' => 'C', 'lower' => array(9447)); /* CIRCLED LATIN CAPITAL LETTER X */
+$config['2460_24ff'][] = array('upper' => 9422, 'status' => 'C', 'lower' => array(9448)); /* CIRCLED LATIN CAPITAL LETTER Y */
+$config['2460_24ff'][] = array('upper' => 9423, 'status' => 'C', 'lower' => array(9449)); /* CIRCLED LATIN CAPITAL LETTER Z */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php
new file mode 100644
index 0000000..185f390
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c00_2c5f.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+2C00 through U+2C5F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['2c00_2c5f'][] = array('upper' => 11264, 'status' => 'C', 'lower' => array(11312)); /* GLAGOLITIC CAPITAL LETTER AZU */
+$config['2c00_2c5f'][] = array('upper' => 11265, 'status' => 'C', 'lower' => array(11313)); /* GLAGOLITIC CAPITAL LETTER BUKY */
+$config['2c00_2c5f'][] = array('upper' => 11266, 'status' => 'C', 'lower' => array(11314)); /* GLAGOLITIC CAPITAL LETTER VEDE */
+$config['2c00_2c5f'][] = array('upper' => 11267, 'status' => 'C', 'lower' => array(11315)); /* GLAGOLITIC CAPITAL LETTER GLAGOLI */
+$config['2c00_2c5f'][] = array('upper' => 11268, 'status' => 'C', 'lower' => array(11316)); /* GLAGOLITIC CAPITAL LETTER DOBRO */
+$config['2c00_2c5f'][] = array('upper' => 11269, 'status' => 'C', 'lower' => array(11317)); /* GLAGOLITIC CAPITAL LETTER YESTU */
+$config['2c00_2c5f'][] = array('upper' => 11270, 'status' => 'C', 'lower' => array(11318)); /* GLAGOLITIC CAPITAL LETTER ZHIVETE */
+$config['2c00_2c5f'][] = array('upper' => 11271, 'status' => 'C', 'lower' => array(11319)); /* GLAGOLITIC CAPITAL LETTER DZELO */
+$config['2c00_2c5f'][] = array('upper' => 11272, 'status' => 'C', 'lower' => array(11320)); /* GLAGOLITIC CAPITAL LETTER ZEMLJA */
+$config['2c00_2c5f'][] = array('upper' => 11273, 'status' => 'C', 'lower' => array(11321)); /* GLAGOLITIC CAPITAL LETTER IZHE */
+$config['2c00_2c5f'][] = array('upper' => 11274, 'status' => 'C', 'lower' => array(11322)); /* GLAGOLITIC CAPITAL LETTER INITIAL IZHE */
+$config['2c00_2c5f'][] = array('upper' => 11275, 'status' => 'C', 'lower' => array(11323)); /* GLAGOLITIC CAPITAL LETTER I */
+$config['2c00_2c5f'][] = array('upper' => 11276, 'status' => 'C', 'lower' => array(11324)); /* GLAGOLITIC CAPITAL LETTER DJERVI */
+$config['2c00_2c5f'][] = array('upper' => 11277, 'status' => 'C', 'lower' => array(11325)); /* GLAGOLITIC CAPITAL LETTER KAKO */
+$config['2c00_2c5f'][] = array('upper' => 11278, 'status' => 'C', 'lower' => array(11326)); /* GLAGOLITIC CAPITAL LETTER LJUDIJE */
+$config['2c00_2c5f'][] = array('upper' => 11279, 'status' => 'C', 'lower' => array(11327)); /* GLAGOLITIC CAPITAL LETTER MYSLITE */
+$config['2c00_2c5f'][] = array('upper' => 11280, 'status' => 'C', 'lower' => array(11328)); /* GLAGOLITIC CAPITAL LETTER NASHI */
+$config['2c00_2c5f'][] = array('upper' => 11281, 'status' => 'C', 'lower' => array(11329)); /* GLAGOLITIC CAPITAL LETTER ONU */
+$config['2c00_2c5f'][] = array('upper' => 11282, 'status' => 'C', 'lower' => array(11330)); /* GLAGOLITIC CAPITAL LETTER POKOJI */
+$config['2c00_2c5f'][] = array('upper' => 11283, 'status' => 'C', 'lower' => array(11331)); /* GLAGOLITIC CAPITAL LETTER RITSI */
+$config['2c00_2c5f'][] = array('upper' => 11284, 'status' => 'C', 'lower' => array(11332)); /* GLAGOLITIC CAPITAL LETTER SLOVO */
+$config['2c00_2c5f'][] = array('upper' => 11285, 'status' => 'C', 'lower' => array(11333)); /* GLAGOLITIC CAPITAL LETTER TVRIDO */
+$config['2c00_2c5f'][] = array('upper' => 11286, 'status' => 'C', 'lower' => array(11334)); /* GLAGOLITIC CAPITAL LETTER UKU */
+$config['2c00_2c5f'][] = array('upper' => 11287, 'status' => 'C', 'lower' => array(11335)); /* GLAGOLITIC CAPITAL LETTER FRITU */
+$config['2c00_2c5f'][] = array('upper' => 11288, 'status' => 'C', 'lower' => array(11336)); /* GLAGOLITIC CAPITAL LETTER HERU */
+$config['2c00_2c5f'][] = array('upper' => 11289, 'status' => 'C', 'lower' => array(11337)); /* GLAGOLITIC CAPITAL LETTER OTU */
+$config['2c00_2c5f'][] = array('upper' => 11290, 'status' => 'C', 'lower' => array(11338)); /* GLAGOLITIC CAPITAL LETTER PE */
+$config['2c00_2c5f'][] = array('upper' => 11291, 'status' => 'C', 'lower' => array(11339)); /* GLAGOLITIC CAPITAL LETTER SHTA */
+$config['2c00_2c5f'][] = array('upper' => 11292, 'status' => 'C', 'lower' => array(11340)); /* GLAGOLITIC CAPITAL LETTER TSI */
+$config['2c00_2c5f'][] = array('upper' => 11293, 'status' => 'C', 'lower' => array(11341)); /* GLAGOLITIC CAPITAL LETTER CHRIVI */
+$config['2c00_2c5f'][] = array('upper' => 11294, 'status' => 'C', 'lower' => array(11342)); /* GLAGOLITIC CAPITAL LETTER SHA */
+$config['2c00_2c5f'][] = array('upper' => 11295, 'status' => 'C', 'lower' => array(11343)); /* GLAGOLITIC CAPITAL LETTER YERU */
+$config['2c00_2c5f'][] = array('upper' => 11296, 'status' => 'C', 'lower' => array(11344)); /* GLAGOLITIC CAPITAL LETTER YERI */
+$config['2c00_2c5f'][] = array('upper' => 11297, 'status' => 'C', 'lower' => array(11345)); /* GLAGOLITIC CAPITAL LETTER YATI */
+$config['2c00_2c5f'][] = array('upper' => 11298, 'status' => 'C', 'lower' => array(11346)); /* GLAGOLITIC CAPITAL LETTER SPIDERY HA */
+$config['2c00_2c5f'][] = array('upper' => 11299, 'status' => 'C', 'lower' => array(11347)); /* GLAGOLITIC CAPITAL LETTER YU */
+$config['2c00_2c5f'][] = array('upper' => 11300, 'status' => 'C', 'lower' => array(11348)); /* GLAGOLITIC CAPITAL LETTER SMALL YUS */
+$config['2c00_2c5f'][] = array('upper' => 11301, 'status' => 'C', 'lower' => array(11349)); /* GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL */
+$config['2c00_2c5f'][] = array('upper' => 11302, 'status' => 'C', 'lower' => array(11350)); /* GLAGOLITIC CAPITAL LETTER YO */
+$config['2c00_2c5f'][] = array('upper' => 11303, 'status' => 'C', 'lower' => array(11351)); /* GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS */
+$config['2c00_2c5f'][] = array('upper' => 11304, 'status' => 'C', 'lower' => array(11352)); /* GLAGOLITIC CAPITAL LETTER BIG YUS */
+$config['2c00_2c5f'][] = array('upper' => 11305, 'status' => 'C', 'lower' => array(11353)); /* GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS */
+$config['2c00_2c5f'][] = array('upper' => 11306, 'status' => 'C', 'lower' => array(11354)); /* GLAGOLITIC CAPITAL LETTER FITA */
+$config['2c00_2c5f'][] = array('upper' => 11307, 'status' => 'C', 'lower' => array(11355)); /* GLAGOLITIC CAPITAL LETTER IZHITSA */
+$config['2c00_2c5f'][] = array('upper' => 11308, 'status' => 'C', 'lower' => array(11356)); /* GLAGOLITIC CAPITAL LETTER SHTAPIC */
+$config['2c00_2c5f'][] = array('upper' => 11309, 'status' => 'C', 'lower' => array(11357)); /* GLAGOLITIC CAPITAL LETTER TROKUTASTI A */
+$config['2c00_2c5f'][] = array('upper' => 11310, 'status' => 'C', 'lower' => array(11358)); /* GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php
new file mode 100644
index 0000000..f0f1e90
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c60_2c7f.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+2C60 through U+2C7F
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['2c60_2c7f'][] = array('upper' => 11360, 'status' => 'C', 'lower' => array(11361)); /* LATIN CAPITAL LETTER L WITH DOUBLE BAR */
+$config['2c60_2c7f'][] = array('upper' => 11362, 'status' => 'C', 'lower' => array(619)); /* LATIN CAPITAL LETTER L WITH MIDDLE TILDE */
+$config['2c60_2c7f'][] = array('upper' => 11363, 'status' => 'C', 'lower' => array(7549)); /* LATIN CAPITAL LETTER P WITH STROKE */
+$config['2c60_2c7f'][] = array('upper' => 11364, 'status' => 'C', 'lower' => array(637)); /* LATIN CAPITAL LETTER R WITH TAIL */
+$config['2c60_2c7f'][] = array('upper' => 11367, 'status' => 'C', 'lower' => array(11368)); /* LATIN CAPITAL LETTER H WITH DESCENDER */
+$config['2c60_2c7f'][] = array('upper' => 11369, 'status' => 'C', 'lower' => array(11370)); /* LATIN CAPITAL LETTER K WITH DESCENDER */
+$config['2c60_2c7f'][] = array('upper' => 11371, 'status' => 'C', 'lower' => array(11372)); /* LATIN CAPITAL LETTER Z WITH DESCENDER */
+$config['2c60_2c7f'][] = array('upper' => 11381, 'status' => 'C', 'lower' => array(11382)); /* LATIN CAPITAL LETTER HALF H */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c80_2cff.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c80_2cff.php
new file mode 100644
index 0000000..c073a53
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/2c80_2cff.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+2C80 through U+2CFF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['2c80_2cff'][] = array('upper' => 11392, 'status' => 'C', 'lower' => array(11393)); /* COPTIC CAPITAL LETTER ALFA */
+$config['2c80_2cff'][] = array('upper' => 11394, 'status' => 'C', 'lower' => array(11395)); /* COPTIC CAPITAL LETTER VIDA */
+$config['2c80_2cff'][] = array('upper' => 11396, 'status' => 'C', 'lower' => array(11397)); /* COPTIC CAPITAL LETTER GAMMA */
+$config['2c80_2cff'][] = array('upper' => 11398, 'status' => 'C', 'lower' => array(11399)); /* COPTIC CAPITAL LETTER DALDA */
+$config['2c80_2cff'][] = array('upper' => 11400, 'status' => 'C', 'lower' => array(11401)); /* COPTIC CAPITAL LETTER EIE */
+$config['2c80_2cff'][] = array('upper' => 11402, 'status' => 'C', 'lower' => array(11403)); /* COPTIC CAPITAL LETTER SOU */
+$config['2c80_2cff'][] = array('upper' => 11404, 'status' => 'C', 'lower' => array(11405)); /* COPTIC CAPITAL LETTER ZATA */
+$config['2c80_2cff'][] = array('upper' => 11406, 'status' => 'C', 'lower' => array(11407)); /* COPTIC CAPITAL LETTER HATE */
+$config['2c80_2cff'][] = array('upper' => 11408, 'status' => 'C', 'lower' => array(11409)); /* COPTIC CAPITAL LETTER THETHE */
+$config['2c80_2cff'][] = array('upper' => 11410, 'status' => 'C', 'lower' => array(11411)); /* COPTIC CAPITAL LETTER IAUDA */
+$config['2c80_2cff'][] = array('upper' => 11412, 'status' => 'C', 'lower' => array(11413)); /* COPTIC CAPITAL LETTER KAPA */
+$config['2c80_2cff'][] = array('upper' => 11414, 'status' => 'C', 'lower' => array(11415)); /* COPTIC CAPITAL LETTER LAULA */
+$config['2c80_2cff'][] = array('upper' => 11416, 'status' => 'C', 'lower' => array(11417)); /* COPTIC CAPITAL LETTER MI */
+$config['2c80_2cff'][] = array('upper' => 11418, 'status' => 'C', 'lower' => array(11419)); /* COPTIC CAPITAL LETTER NI */
+$config['2c80_2cff'][] = array('upper' => 11420, 'status' => 'C', 'lower' => array(11421)); /* COPTIC CAPITAL LETTER KSI */
+$config['2c80_2cff'][] = array('upper' => 11422, 'status' => 'C', 'lower' => array(11423)); /* COPTIC CAPITAL LETTER O */
+$config['2c80_2cff'][] = array('upper' => 11424, 'status' => 'C', 'lower' => array(11425)); /* COPTIC CAPITAL LETTER PI */
+$config['2c80_2cff'][] = array('upper' => 11426, 'status' => 'C', 'lower' => array(11427)); /* COPTIC CAPITAL LETTER RO */
+$config['2c80_2cff'][] = array('upper' => 11428, 'status' => 'C', 'lower' => array(11429)); /* COPTIC CAPITAL LETTER SIMA */
+$config['2c80_2cff'][] = array('upper' => 11430, 'status' => 'C', 'lower' => array(11431)); /* COPTIC CAPITAL LETTER TAU */
+$config['2c80_2cff'][] = array('upper' => 11432, 'status' => 'C', 'lower' => array(11433)); /* COPTIC CAPITAL LETTER UA */
+$config['2c80_2cff'][] = array('upper' => 11434, 'status' => 'C', 'lower' => array(11435)); /* COPTIC CAPITAL LETTER FI */
+$config['2c80_2cff'][] = array('upper' => 11436, 'status' => 'C', 'lower' => array(11437)); /* COPTIC CAPITAL LETTER KHI */
+$config['2c80_2cff'][] = array('upper' => 11438, 'status' => 'C', 'lower' => array(11439)); /* COPTIC CAPITAL LETTER PSI */
+$config['2c80_2cff'][] = array('upper' => 11440, 'status' => 'C', 'lower' => array(11441)); /* COPTIC CAPITAL LETTER OOU */
+$config['2c80_2cff'][] = array('upper' => 11442, 'status' => 'C', 'lower' => array(11443)); /* COPTIC CAPITAL LETTER DIALECT-P ALEF */
+$config['2c80_2cff'][] = array('upper' => 11444, 'status' => 'C', 'lower' => array(11445)); /* COPTIC CAPITAL LETTER OLD COPTIC AIN */
+$config['2c80_2cff'][] = array('upper' => 11446, 'status' => 'C', 'lower' => array(11447)); /* COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE */
+$config['2c80_2cff'][] = array('upper' => 11448, 'status' => 'C', 'lower' => array(11449)); /* COPTIC CAPITAL LETTER DIALECT-P KAPA */
+$config['2c80_2cff'][] = array('upper' => 11450, 'status' => 'C', 'lower' => array(11451)); /* COPTIC CAPITAL LETTER DIALECT-P NI */
+$config['2c80_2cff'][] = array('upper' => 11452, 'status' => 'C', 'lower' => array(11453)); /* COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI */
+$config['2c80_2cff'][] = array('upper' => 11454, 'status' => 'C', 'lower' => array(11455)); /* COPTIC CAPITAL LETTER OLD COPTIC OOU */
+$config['2c80_2cff'][] = array('upper' => 11456, 'status' => 'C', 'lower' => array(11457)); /* COPTIC CAPITAL LETTER SAMPI */
+$config['2c80_2cff'][] = array('upper' => 11458, 'status' => 'C', 'lower' => array(11459)); /* COPTIC CAPITAL LETTER CROSSED SHEI */
+$config['2c80_2cff'][] = array('upper' => 11460, 'status' => 'C', 'lower' => array(11461)); /* COPTIC CAPITAL LETTER OLD COPTIC SHEI */
+$config['2c80_2cff'][] = array('upper' => 11462, 'status' => 'C', 'lower' => array(11463)); /* COPTIC CAPITAL LETTER OLD COPTIC ESH */
+$config['2c80_2cff'][] = array('upper' => 11464, 'status' => 'C', 'lower' => array(11465)); /* COPTIC CAPITAL LETTER AKHMIMIC KHEI */
+$config['2c80_2cff'][] = array('upper' => 11466, 'status' => 'C', 'lower' => array(11467)); /* COPTIC CAPITAL LETTER DIALECT-P HORI */
+$config['2c80_2cff'][] = array('upper' => 11468, 'status' => 'C', 'lower' => array(11469)); /* COPTIC CAPITAL LETTER OLD COPTIC HORI */
+$config['2c80_2cff'][] = array('upper' => 11470, 'status' => 'C', 'lower' => array(11471)); /* COPTIC CAPITAL LETTER OLD COPTIC HA */
+$config['2c80_2cff'][] = array('upper' => 11472, 'status' => 'C', 'lower' => array(11473)); /* COPTIC CAPITAL LETTER L-SHAPED HA */
+$config['2c80_2cff'][] = array('upper' => 11474, 'status' => 'C', 'lower' => array(11475)); /* COPTIC CAPITAL LETTER OLD COPTIC HEI */
+$config['2c80_2cff'][] = array('upper' => 11476, 'status' => 'C', 'lower' => array(11477)); /* COPTIC CAPITAL LETTER OLD COPTIC HAT */
+$config['2c80_2cff'][] = array('upper' => 11478, 'status' => 'C', 'lower' => array(11479)); /* COPTIC CAPITAL LETTER OLD COPTIC GANGIA */
+$config['2c80_2cff'][] = array('upper' => 11480, 'status' => 'C', 'lower' => array(11481)); /* COPTIC CAPITAL LETTER OLD COPTIC DJA */
+$config['2c80_2cff'][] = array('upper' => 11482, 'status' => 'C', 'lower' => array(11483)); /* COPTIC CAPITAL LETTER OLD COPTIC SHIMA */
+$config['2c80_2cff'][] = array('upper' => 11484, 'status' => 'C', 'lower' => array(11485)); /* COPTIC CAPITAL LETTER OLD NUBIAN SHIMA */
+$config['2c80_2cff'][] = array('upper' => 11486, 'status' => 'C', 'lower' => array(11487)); /* COPTIC CAPITAL LETTER OLD NUBIAN NGI */
+$config['2c80_2cff'][] = array('upper' => 11488, 'status' => 'C', 'lower' => array(11489)); /* COPTIC CAPITAL LETTER OLD NUBIAN NYI */
+$config['2c80_2cff'][] = array('upper' => 11490, 'status' => 'C', 'lower' => array(11491)); /* COPTIC CAPITAL LETTER OLD NUBIAN WAU */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/ff00_ffef.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/ff00_ffef.php
new file mode 100644
index 0000000..22d7a2d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Config/unicode/casefolding/ff00_ffef.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Case Folding Properties.
+ *
+ * Provides case mapping of Unicode characters for code points U+FF00 through U+FFEF
+ *
+ * @see http://www.unicode.org/Public/UNIDATA/UCD.html
+ * @see http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+ * @see http://www.unicode.org/reports/tr21/tr21-5.html
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Config.unicode.casefolding
+ * @since CakePHP(tm) v 1.2.0.5691
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * The upper field is the decimal value of the upper case character
+ *
+ * The lower filed is an array of the decimal values that form the lower case version of a character.
+ *
+ * The status field is:
+ * C: common case folding, common mappings shared by both simple and full mappings.
+ * F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+ * S: simple case folding, mappings to single characters where different from F.
+ * T: special case for uppercase I and dotted uppercase I
+ * - For non-Turkic languages, this mapping is normally not used.
+ * - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+ * Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+ * See the discussions of case mapping in the Unicode Standard for more information.
+ */
+$config['ff00_ffef'][] = array('upper' => 65313, 'status' => 'C', 'lower' => array(65345)); /* FULLWIDTH LATIN CAPITAL LETTER A */
+$config['ff00_ffef'][] = array('upper' => 65314, 'status' => 'C', 'lower' => array(65346)); /* FULLWIDTH LATIN CAPITAL LETTER B */
+$config['ff00_ffef'][] = array('upper' => 65315, 'status' => 'C', 'lower' => array(65347)); /* FULLWIDTH LATIN CAPITAL LETTER C */
+$config['ff00_ffef'][] = array('upper' => 65316, 'status' => 'C', 'lower' => array(65348)); /* FULLWIDTH LATIN CAPITAL LETTER D */
+$config['ff00_ffef'][] = array('upper' => 65317, 'status' => 'C', 'lower' => array(65349)); /* FULLWIDTH LATIN CAPITAL LETTER E */
+$config['ff00_ffef'][] = array('upper' => 65318, 'status' => 'C', 'lower' => array(65350)); /* FULLWIDTH LATIN CAPITAL LETTER F */
+$config['ff00_ffef'][] = array('upper' => 65319, 'status' => 'C', 'lower' => array(65351)); /* FULLWIDTH LATIN CAPITAL LETTER G */
+$config['ff00_ffef'][] = array('upper' => 65320, 'status' => 'C', 'lower' => array(65352)); /* FULLWIDTH LATIN CAPITAL LETTER H */
+$config['ff00_ffef'][] = array('upper' => 65321, 'status' => 'C', 'lower' => array(65353)); /* FULLWIDTH LATIN CAPITAL LETTER I */
+$config['ff00_ffef'][] = array('upper' => 65322, 'status' => 'C', 'lower' => array(65354)); /* FULLWIDTH LATIN CAPITAL LETTER J */
+$config['ff00_ffef'][] = array('upper' => 65323, 'status' => 'C', 'lower' => array(65355)); /* FULLWIDTH LATIN CAPITAL LETTER K */
+$config['ff00_ffef'][] = array('upper' => 65324, 'status' => 'C', 'lower' => array(65356)); /* FULLWIDTH LATIN CAPITAL LETTER L */
+$config['ff00_ffef'][] = array('upper' => 65325, 'status' => 'C', 'lower' => array(65357)); /* FULLWIDTH LATIN CAPITAL LETTER M */
+$config['ff00_ffef'][] = array('upper' => 65326, 'status' => 'C', 'lower' => array(65358)); /* FULLWIDTH LATIN CAPITAL LETTER N */
+$config['ff00_ffef'][] = array('upper' => 65327, 'status' => 'C', 'lower' => array(65359)); /* FULLWIDTH LATIN CAPITAL LETTER O */
+$config['ff00_ffef'][] = array('upper' => 65328, 'status' => 'C', 'lower' => array(65360)); /* FULLWIDTH LATIN CAPITAL LETTER P */
+$config['ff00_ffef'][] = array('upper' => 65329, 'status' => 'C', 'lower' => array(65361)); /* FULLWIDTH LATIN CAPITAL LETTER Q */
+$config['ff00_ffef'][] = array('upper' => 65330, 'status' => 'C', 'lower' => array(65362)); /* FULLWIDTH LATIN CAPITAL LETTER R */
+$config['ff00_ffef'][] = array('upper' => 65331, 'status' => 'C', 'lower' => array(65363)); /* FULLWIDTH LATIN CAPITAL LETTER S */
+$config['ff00_ffef'][] = array('upper' => 65332, 'status' => 'C', 'lower' => array(65364)); /* FULLWIDTH LATIN CAPITAL LETTER T */
+$config['ff00_ffef'][] = array('upper' => 65333, 'status' => 'C', 'lower' => array(65365)); /* FULLWIDTH LATIN CAPITAL LETTER U */
+$config['ff00_ffef'][] = array('upper' => 65334, 'status' => 'C', 'lower' => array(65366)); /* FULLWIDTH LATIN CAPITAL LETTER V */
+$config['ff00_ffef'][] = array('upper' => 65335, 'status' => 'C', 'lower' => array(65367)); /* FULLWIDTH LATIN CAPITAL LETTER W */
+$config['ff00_ffef'][] = array('upper' => 65336, 'status' => 'C', 'lower' => array(65368)); /* FULLWIDTH LATIN CAPITAL LETTER X */
+$config['ff00_ffef'][] = array('upper' => 65337, 'status' => 'C', 'lower' => array(65369)); /* FULLWIDTH LATIN CAPITAL LETTER Y */
+$config['ff00_ffef'][] = array('upper' => 65338, 'status' => 'C', 'lower' => array(65370)); /* FULLWIDTH LATIN CAPITAL LETTER Z */
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/ConfigReaderInterface.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/ConfigReaderInterface.php
new file mode 100644
index 0000000..f137355
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/ConfigReaderInterface.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Core
+ * @since CakePHP(tm) v 1.0.0.2363
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * An interface for creating objects compatible with Configure::load()
+ *
+ * @package Cake.Core
+ */
+interface ConfigReaderInterface {
+
+/**
+ * Read method is used for reading configuration information from sources.
+ * These sources can either be static resources like files, or dynamic ones like
+ * a database, or other datasource.
+ *
+ * @param string $key
+ * @return array An array of data to merge into the runtime configuration
+ */
+ public function read($key);
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/IniReader.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/IniReader.php
new file mode 100644
index 0000000..debd685
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/IniReader.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * IniReader
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Configure
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Hash', 'Utility');
+
+/**
+ * Ini file configuration engine.
+ *
+ * Since IniReader uses parse_ini_file underneath, you should be aware that this
+ * class shares the same behavior, especially with regards to boolean and null values.
+ *
+ * In addition to the native `parse_ini_file` features, IniReader also allows you
+ * to create nested array structures through usage of `.` delimited names. This allows
+ * you to create nested arrays structures in an ini config file. For example:
+ *
+ * `db.password = secret` would turn into `array('db' => array('password' => 'secret'))`
+ *
+ * You can nest properties as deeply as needed using `.`'s. In addition to using `.` you
+ * can use standard ini section notation to create nested structures:
+ *
+ * {{{
+ * [section]
+ * key = value
+ * }}}
+ *
+ * Once loaded into Configure, the above would be accessed using:
+ *
+ * `Configure::read('section.key');
+ *
+ * You can combine `.` separated values with sections to create more deeply
+ * nested structures.
+ *
+ * IniReader also manipulates how the special ini values of
+ * 'yes', 'no', 'on', 'off', 'null' are handled. These values will be
+ * converted to their boolean equivalents.
+ *
+ * @package Cake.Configure
+ * @see http://php.net/parse_ini_file
+ */
+class IniReader implements ConfigReaderInterface {
+
+/**
+ * The path to read ini files from.
+ *
+ * @var array
+ */
+ protected $_path;
+
+/**
+ * The section to read, if null all sections will be read.
+ *
+ * @var string
+ */
+ protected $_section;
+
+/**
+ * Build and construct a new ini file parser. The parser can be used to read
+ * ini files that are on the filesystem.
+ *
+ * @param string $path Path to load ini config files from.
+ * @param string $section Only get one section, leave null to parse and fetch
+ * all sections in the ini file.
+ */
+ public function __construct($path, $section = null) {
+ $this->_path = $path;
+ $this->_section = $section;
+ }
+
+/**
+ * Read an ini file and return the results as an array.
+ *
+ * @param string $file Name of the file to read. The chosen file
+ * must be on the reader's path.
+ * @return array
+ * @throws ConfigureException
+ */
+ public function read($file) {
+ $filename = $this->_path . $file;
+ if (!file_exists($filename)) {
+ $filename .= '.ini';
+ if (!file_exists($filename)) {
+ throw new ConfigureException(__d('cake_dev', 'Could not load configuration files: %s or %s', substr($filename, 0, -4), $filename));
+ }
+ }
+ $contents = parse_ini_file($filename, true);
+ if (!empty($this->_section) && isset($contents[$this->_section])) {
+ $values = $this->_parseNestedValues($contents[$this->_section]);
+ } else {
+ $values = array();
+ foreach ($contents as $section => $attribs) {
+ if (is_array($attribs)) {
+ $values[$section] = $this->_parseNestedValues($attribs);
+ } else {
+ $parse = $this->_parseNestedValues(array($attribs));
+ $values[$section] = array_shift($parse);
+ }
+ }
+ }
+ return $values;
+ }
+
+/**
+ * parses nested values out of keys.
+ *
+ * @param array $values Values to be exploded.
+ * @return array Array of values exploded
+ */
+ protected function _parseNestedValues($values) {
+ foreach ($values as $key => $value) {
+ if ($value === '1') {
+ $value = true;
+ }
+ if ($value === '') {
+ $value = false;
+ }
+ unset($values[$key]);
+ if (strpos($key, '.') !== false) {
+ $values = Hash::insert($values, $key, $value);
+ } else {
+ $values[$key] = $value;
+ }
+ }
+ return $values;
+ }
+
+/**
+ * Dumps the state of Configure data into an ini formatted string.
+ *
+ * @param string $filename The filename on $this->_path to save into.
+ * @param array $data The data to convert to ini file.
+ * @return int Bytes saved.
+ */
+ public function dump($filename, $data) {
+ $result = array();
+ foreach ($data as $key => $value) {
+ if ($key[0] != '[') {
+ $result[] = "[$key]";
+ }
+ if (is_array($value)) {
+ $keyValues = Hash::flatten($value, '.');
+ foreach ($keyValues as $k => $v) {
+ $result[] = "$k = " . $this->_value($v);
+ }
+ }
+ }
+ $contents = join("\n", $result);
+ return file_put_contents($this->_path . $filename, $contents);
+ }
+
+/**
+ * Converts a value into the ini equivalent
+ *
+ * @param mixed $value to export.
+ * @return string String value for ini file.
+ */
+ protected function _value($val) {
+ if ($val === null) {
+ return 'null';
+ }
+ if ($val === true) {
+ return 'true';
+ }
+ if ($val === false) {
+ return 'false';
+ }
+ return (string)$val;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/PhpReader.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/PhpReader.php
new file mode 100644
index 0000000..f5d9619
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Configure/PhpReader.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * PhpReader file
+ *
+ * PHP 5
+ *
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/configuration.html#loading-configuration-files CakePHP(tm) Configuration
+ * @package Cake.Configure
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * PHP Reader allows Configure to load configuration values from
+ * files containing simple PHP arrays.
+ *
+ * Files compatible with PhpReader should define a `$config` variable, that
+ * contains all of the configuration data contained in the file.
+ *
+ * @package Cake.Configure
+ */
+class PhpReader implements ConfigReaderInterface {
+
+/**
+ * The path this reader finds files on.
+ *
+ * @var string
+ */
+ protected $_path = null;
+
+/**
+ * Constructor for PHP Config file reading.
+ *
+ * @param string $path The path to read config files from. Defaults to APP . 'Config' . DS
+ */
+ public function __construct($path = null) {
+ if (!$path) {
+ $path = APP . 'Config' . DS;
+ }
+ $this->_path = $path;
+ }
+
+/**
+ * Read a config file and return its contents.
+ *
+ * Files with `.` in the name will be treated as values in plugins. Instead of reading from
+ * the initialized path, plugin keys will be located using App::pluginPath().
+ *
+ * @param string $key The identifier to read from. If the key has a . it will be treated
+ * as a plugin prefix.
+ * @return array Parsed configuration values.
+ * @throws ConfigureException when files don't exist or they don't contain `$config`.
+ * Or when files contain '..' as this could lead to abusive reads.
+ */
+ public function read($key) {
+ if (strpos($key, '..') !== false) {
+ throw new ConfigureException(__d('cake_dev', 'Cannot load configuration files with ../ in them.'));
+ }
+ if (substr($key, -4) === '.php') {
+ $key = substr($key, 0, -4);
+ }
+ list($plugin, $key) = pluginSplit($key);
+
+ if ($plugin) {
+ $file = App::pluginPath($plugin) . 'Config' . DS . $key;
+ } else {
+ $file = $this->_path . $key;
+ }
+ $file .= '.php';
+ if (!is_file($file)) {
+ if (!is_file(substr($file, 0, -4))) {
+ throw new ConfigureException(__d('cake_dev', 'Could not load configuration files: %s or %s', $file, substr($file, 0, -4)));
+ }
+ }
+ include $file;
+ if (!isset($config)) {
+ throw new ConfigureException(
+ sprintf(__d('cake_dev', 'No variable $config found in %s.php'), $file)
+ );
+ }
+ return $config;
+ }
+
+/**
+ * Converts the provided $data into a string of PHP code that can
+ * be used saved into a file and loaded later.
+ *
+ * @param string $filename The filename to create on $this->_path.
+ * @param array $data Data to dump.
+ * @return int Bytes saved.
+ */
+ public function dump($filename, $data) {
+ $contents = '<?php' . "\n" . '$config = ' . var_export($data, true) . ';';
+ return file_put_contents($this->_path . $filename, $contents);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AclShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AclShell.php
new file mode 100644
index 0000000..8fa17c2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AclShell.php
@@ -0,0 +1,610 @@
+<?php
+/**
+ * Acl Shell provides Acl access in the CLI environment
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5012
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('Controller', 'Controller');
+App::uses('ComponentCollection', 'Controller');
+App::uses('AclComponent', 'Controller/Component');
+App::uses('DbAcl', 'Model');
+App::uses('Hash', 'Utility');
+
+/**
+ * Shell for ACL management. This console is known to have issues with zend.ze1_compatibility_mode
+ * being enabled. Be sure to turn it off when using this shell.
+ *
+ * @package Cake.Console.Command
+ */
+class AclShell extends AppShell {
+
+/**
+ * Contains instance of AclComponent
+ *
+ * @var AclComponent
+ */
+ public $Acl;
+
+/**
+ * Contains arguments parsed from the command line.
+ *
+ * @var array
+ */
+ public $args;
+
+/**
+ * Contains database source to use
+ *
+ * @var string
+ */
+ public $connection = 'default';
+
+/**
+ * Contains tasks to load and instantiate
+ *
+ * @var array
+ */
+ public $tasks = array('DbConfig');
+
+/**
+ * Override startup of the Shell
+ *
+ * @return void
+ */
+ public function startup() {
+ parent::startup();
+ if (isset($this->params['connection'])) {
+ $this->connection = $this->params['connection'];
+ }
+
+ if (!in_array(Configure::read('Acl.classname'), array('DbAcl', 'DB_ACL'))) {
+ $out = "--------------------------------------------------\n";
+ $out .= __d('cake_console', 'Error: Your current Cake configuration is set to an ACL implementation other than DB.') . "\n";
+ $out .= __d('cake_console', 'Please change your core config to reflect your decision to use DbAcl before attempting to use this script') . "\n";
+ $out .= "--------------------------------------------------\n";
+ $out .= __d('cake_console', 'Current ACL Classname: %s', Configure::read('Acl.classname')) . "\n";
+ $out .= "--------------------------------------------------\n";
+ $this->err($out);
+ $this->_stop();
+ }
+
+ if ($this->command) {
+ if (!config('database')) {
+ $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.'), true);
+ $this->args = null;
+ return $this->DbConfig->execute();
+ }
+ require_once (APP . 'Config' . DS . 'database.php');
+
+ if (!in_array($this->command, array('initdb'))) {
+ $collection = new ComponentCollection();
+ $this->Acl = new AclComponent($collection);
+ $controller = new Controller();
+ $this->Acl->startup($controller);
+ }
+ }
+ }
+
+/**
+ * Override main() for help message hook
+ *
+ * @return void
+ */
+ public function main() {
+ $this->out($this->OptionParser->help());
+ }
+
+/**
+ * Creates an ARO/ACO node
+ *
+ * @return void
+ */
+ public function create() {
+ extract($this->_dataVars());
+
+ $class = ucfirst($this->args[0]);
+ $parent = $this->parseIdentifier($this->args[1]);
+
+ if (!empty($parent) && $parent != '/' && $parent != 'root') {
+ $parent = $this->_getNodeId($class, $parent);
+ } else {
+ $parent = null;
+ }
+
+ $data = $this->parseIdentifier($this->args[2]);
+ if (is_string($data) && $data != '/') {
+ $data = array('alias' => $data);
+ } elseif (is_string($data)) {
+ $this->error(__d('cake_console', '/ can not be used as an alias!') . __d('cake_console', " / is the root, please supply a sub alias"));
+ }
+
+ $data['parent_id'] = $parent;
+ $this->Acl->{$class}->create();
+ if ($this->Acl->{$class}->save($data)) {
+ $this->out(__d('cake_console', "<success>New %s</success> '%s' created.", $class, $this->args[2]), 2);
+ } else {
+ $this->err(__d('cake_console', "There was a problem creating a new %s '%s'.", $class, $this->args[2]));
+ }
+ }
+
+/**
+ * Delete an ARO/ACO node.
+ *
+ * @return void
+ */
+ public function delete() {
+ extract($this->_dataVars());
+
+ $identifier = $this->parseIdentifier($this->args[1]);
+ $nodeId = $this->_getNodeId($class, $identifier);
+
+ if (!$this->Acl->{$class}->delete($nodeId)) {
+ $this->error(__d('cake_console', 'Node Not Deleted') . __d('cake_console', 'There was an error deleting the %s. Check that the node exists.', $class) . "\n");
+ }
+ $this->out(__d('cake_console', '<success>%s deleted.</success>', $class), 2);
+ }
+
+/**
+ * Set parent for an ARO/ACO node.
+ *
+ * @return void
+ */
+ public function setParent() {
+ extract($this->_dataVars());
+ $target = $this->parseIdentifier($this->args[1]);
+ $parent = $this->parseIdentifier($this->args[2]);
+
+ $data = array(
+ $class => array(
+ 'id' => $this->_getNodeId($class, $target),
+ 'parent_id' => $this->_getNodeId($class, $parent)
+ )
+ );
+ $this->Acl->{$class}->create();
+ if (!$this->Acl->{$class}->save($data)) {
+ $this->out(__d('cake_console', 'Error in setting new parent. Please make sure the parent node exists, and is not a descendant of the node specified.'), true);
+ } else {
+ $this->out(__d('cake_console', 'Node parent set to %s', $this->args[2]) . "\n", true);
+ }
+ }
+
+/**
+ * Get path to specified ARO/ACO node.
+ *
+ * @return void
+ */
+ public function getPath() {
+ extract($this->_dataVars());
+ $identifier = $this->parseIdentifier($this->args[1]);
+
+ $id = $this->_getNodeId($class, $identifier);
+ $nodes = $this->Acl->{$class}->getPath($id);
+
+ if (empty($nodes)) {
+ $this->error(
+ __d('cake_console', "Supplied Node '%s' not found", $this->args[1]),
+ __d('cake_console', 'No tree returned.')
+ );
+ }
+ $this->out(__d('cake_console', 'Path:'));
+ $this->hr();
+ for ($i = 0, $len = count($nodes); $i < $len; $i++) {
+ $this->_outputNode($class, $nodes[$i], $i);
+ }
+ }
+
+/**
+ * Outputs a single node, Either using the alias or Model.key
+ *
+ * @param string $class Class name that is being used.
+ * @param array $node Array of node information.
+ * @param integer $indent indent level.
+ * @return void
+ */
+ protected function _outputNode($class, $node, $indent) {
+ $indent = str_repeat(' ', $indent);
+ $data = $node[$class];
+ if ($data['alias']) {
+ $this->out($indent . "[" . $data['id'] . "] " . $data['alias']);
+ } else {
+ $this->out($indent . "[" . $data['id'] . "] " . $data['model'] . '.' . $data['foreign_key']);
+ }
+ }
+
+/**
+ * Check permission for a given ARO to a given ACO.
+ *
+ * @return void
+ */
+ public function check() {
+ extract($this->_getParams());
+
+ if ($this->Acl->check($aro, $aco, $action)) {
+ $this->out(__d('cake_console', '%s is <success>allowed</success>.', $aroName), true);
+ } else {
+ $this->out(__d('cake_console', '%s is <error>not allowed</error>.', $aroName), true);
+ }
+ }
+
+/**
+ * Grant permission for a given ARO to a given ACO.
+ *
+ * @return void
+ */
+ public function grant() {
+ extract($this->_getParams());
+
+ if ($this->Acl->allow($aro, $aco, $action)) {
+ $this->out(__d('cake_console', 'Permission <success>granted</success>.'), true);
+ } else {
+ $this->out(__d('cake_console', 'Permission was <error>not granted</error>.'), true);
+ }
+ }
+
+/**
+ * Deny access for an ARO to an ACO.
+ *
+ * @return void
+ */
+ public function deny() {
+ extract($this->_getParams());
+
+ if ($this->Acl->deny($aro, $aco, $action)) {
+ $this->out(__d('cake_console', 'Permission denied.'), true);
+ } else {
+ $this->out(__d('cake_console', 'Permission was not denied.'), true);
+ }
+ }
+
+/**
+ * Set an ARO to inherit permission to an ACO.
+ *
+ * @return void
+ */
+ public function inherit() {
+ extract($this->_getParams());
+
+ if ($this->Acl->inherit($aro, $aco, $action)) {
+ $this->out(__d('cake_console', 'Permission inherited.'), true);
+ } else {
+ $this->out(__d('cake_console', 'Permission was not inherited.'), true);
+ }
+ }
+
+/**
+ * Show a specific ARO/ACO node.
+ *
+ * @return void
+ */
+ public function view() {
+ extract($this->_dataVars());
+
+ if (isset($this->args[1])) {
+ $identity = $this->parseIdentifier($this->args[1]);
+
+ $topNode = $this->Acl->{$class}->find('first', array(
+ 'conditions' => array($class . '.id' => $this->_getNodeId($class, $identity))
+ ));
+
+ $nodes = $this->Acl->{$class}->find('all', array(
+ 'conditions' => array(
+ $class . '.lft >=' => $topNode[$class]['lft'],
+ $class . '.lft <=' => $topNode[$class]['rght']
+ ),
+ 'order' => $class . '.lft ASC'
+ ));
+ } else {
+ $nodes = $this->Acl->{$class}->find('all', array('order' => $class . '.lft ASC'));
+ }
+
+ if (empty($nodes)) {
+ if (isset($this->args[1])) {
+ $this->error(__d('cake_console', '%s not found', $this->args[1]), __d('cake_console', 'No tree returned.'));
+ } elseif (isset($this->args[0])) {
+ $this->error(__d('cake_console', '%s not found', $this->args[0]), __d('cake_console', 'No tree returned.'));
+ }
+ }
+ $this->out($class . ' tree:');
+ $this->hr();
+
+ $stack = array();
+ $last = null;
+
+ foreach ($nodes as $n) {
+ $stack[] = $n;
+ if (!empty($last)) {
+ $end = end($stack);
+ if ($end[$class]['rght'] > $last) {
+ foreach ($stack as $k => $v) {
+ $end = end($stack);
+ if ($v[$class]['rght'] < $end[$class]['rght']) {
+ unset($stack[$k]);
+ }
+ }
+ }
+ }
+ $last = $n[$class]['rght'];
+ $count = count($stack);
+
+ $this->_outputNode($class, $n, $count);
+ }
+ $this->hr();
+ }
+
+/**
+ * Initialize ACL database.
+ *
+ * @return mixed
+ */
+ public function initdb() {
+ return $this->dispatchShell('schema create DbAcl');
+ }
+
+/**
+ * Get the option parser.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+
+ $type = array(
+ 'choices' => array('aro', 'aco'),
+ 'required' => true,
+ 'help' => __d('cake_console', 'Type of node to create.')
+ );
+
+ $parser->description(
+ __d('cake_console', 'A console tool for managing the DbAcl')
+ )->addSubcommand('create', array(
+ 'help' => __d('cake_console', 'Create a new ACL node'),
+ 'parser' => array(
+ 'description' => __d('cake_console', 'Creates a new ACL object <node> under the parent'),
+ 'arguments' => array(
+ 'type' => $type,
+ 'parent' => array(
+ 'help' => __d('cake_console', 'The node selector for the parent.'),
+ 'required' => true
+ ),
+ 'alias' => array(
+ 'help' => __d('cake_console', 'The alias to use for the newly created node.'),
+ 'required' => true
+ )
+ )
+ )
+ ))->addSubcommand('delete', array(
+ 'help' => __d('cake_console', 'Deletes the ACL object with the given <node> reference'),
+ 'parser' => array(
+ 'description' => __d('cake_console', 'Delete an ACL node.'),
+ 'arguments' => array(
+ 'type' => $type,
+ 'node' => array(
+ 'help' => __d('cake_console', 'The node identifier to delete.'),
+ 'required' => true,
+ )
+ )
+ )
+ ))->addSubcommand('setparent', array(
+ 'help' => __d('cake_console', 'Moves the ACL node under a new parent.'),
+ 'parser' => array(
+ 'description' => __d('cake_console', 'Moves the ACL object specified by <node> beneath <parent>'),
+ 'arguments' => array(
+ 'type' => $type,
+ 'node' => array(
+ 'help' => __d('cake_console', 'The node to move'),
+ 'required' => true,
+ ),
+ 'parent' => array(
+ 'help' => __d('cake_console', 'The new parent for <node>.'),
+ 'required' => true
+ )
+ )
+ )
+ ))->addSubcommand('getpath', array(
+ 'help' => __d('cake_console', 'Print out the path to an ACL node.'),
+ 'parser' => array(
+ 'description' => array(
+ __d('cake_console', "Returns the path to the ACL object specified by <node>."),
+ __d('cake_console', "This command is useful in determining the inheritance of permissions for a certain object in the tree.")
+ ),
+ 'arguments' => array(
+ 'type' => $type,
+ 'node' => array(
+ 'help' => __d('cake_console', 'The node to get the path of'),
+ 'required' => true,
+ )
+ )
+ )
+ ))->addSubcommand('check', array(
+ 'help' => __d('cake_console', 'Check the permissions between an ACO and ARO.'),
+ 'parser' => array(
+ 'description' => array(
+ __d('cake_console', 'Use this command to check ACL permissions.')
+ ),
+ 'arguments' => array(
+ 'aro' => array('help' => __d('cake_console', 'ARO to check.'), 'required' => true),
+ 'aco' => array('help' => __d('cake_console', 'ACO to check.'), 'required' => true),
+ 'action' => array('help' => __d('cake_console', 'Action to check'), 'default' => 'all')
+ )
+ )
+ ))->addSubcommand('grant', array(
+ 'help' => __d('cake_console', 'Grant an ARO permissions to an ACO.'),
+ 'parser' => array(
+ 'description' => array(
+ __d('cake_console', 'Use this command to grant ACL permissions. Once executed, the ARO specified (and its children, if any) will have ALLOW access to the specified ACO action (and the ACO\'s children, if any).')
+ ),
+ 'arguments' => array(
+ 'aro' => array('help' => __d('cake_console', 'ARO to grant permission to.'), 'required' => true),
+ 'aco' => array('help' => __d('cake_console', 'ACO to grant access to.'), 'required' => true),
+ 'action' => array('help' => __d('cake_console', 'Action to grant'), 'default' => 'all')
+ )
+ )
+ ))->addSubcommand('deny', array(
+ 'help' => __d('cake_console', 'Deny an ARO permissions to an ACO.'),
+ 'parser' => array(
+ 'description' => array(
+ __d('cake_console', 'Use this command to deny ACL permissions. Once executed, the ARO specified (and its children, if any) will have DENY access to the specified ACO action (and the ACO\'s children, if any).')
+ ),
+ 'arguments' => array(
+ 'aro' => array('help' => __d('cake_console', 'ARO to deny.'), 'required' => true),
+ 'aco' => array('help' => __d('cake_console', 'ACO to deny.'), 'required' => true),
+ 'action' => array('help' => __d('cake_console', 'Action to deny'), 'default' => 'all')
+ )
+ )
+ ))->addSubcommand('inherit', array(
+ 'help' => __d('cake_console', 'Inherit an ARO\'s parent permissions.'),
+ 'parser' => array(
+ 'description' => array(
+ __d('cake_console', "Use this command to force a child ARO object to inherit its permissions settings from its parent.")
+ ),
+ 'arguments' => array(
+ 'aro' => array('help' => __d('cake_console', 'ARO to have permissions inherit.'), 'required' => true),
+ 'aco' => array('help' => __d('cake_console', 'ACO to inherit permissions on.'), 'required' => true),
+ 'action' => array('help' => __d('cake_console', 'Action to inherit'), 'default' => 'all')
+ )
+ )
+ ))->addSubcommand('view', array(
+ 'help' => __d('cake_console', 'View a tree or a single node\'s subtree.'),
+ 'parser' => array(
+ 'description' => array(
+ __d('cake_console', "The view command will return the ARO or ACO tree."),
+ __d('cake_console', "The optional node parameter allows you to return"),
+ __d('cake_console', "only a portion of the requested tree.")
+ ),
+ 'arguments' => array(
+ 'type' => $type,
+ 'node' => array('help' => __d('cake_console', 'The optional node to view the subtree of.'))
+ )
+ )
+ ))->addSubcommand('initdb', array(
+ 'help' => __d('cake_console', 'Initialize the DbAcl tables. Uses this command : cake schema create DbAcl')
+ ))->epilog(
+ array(
+ 'Node and parent arguments can be in one of the following formats:',
+ '',
+ ' - <model>.<id> - The node will be bound to a specific record of the given model.',
+ '',
+ ' - <alias> - The node will be given a string alias (or path, in the case of <parent>)',
+ " i.e. 'John'. When used with <parent>, this takes the form of an alias path,",
+ " i.e. <group>/<subgroup>/<parent>.",
+ '',
+ "To add a node at the root level, enter 'root' or '/' as the <parent> parameter."
+ )
+ );
+ return $parser;
+ }
+
+/**
+ * Checks that given node exists
+ *
+ * @return boolean Success
+ */
+ public function nodeExists() {
+ if (!isset($this->args[0]) || !isset($this->args[1])) {
+ return false;
+ }
+ $dataVars = $this->_dataVars($this->args[0]);
+ extract($dataVars);
+ $key = is_numeric($this->args[1]) ? $dataVars['secondary_id'] : 'alias';
+ $conditions = array($class . '.' . $key => $this->args[1]);
+ $possibility = $this->Acl->{$class}->find('all', compact('conditions'));
+ if (empty($possibility)) {
+ $this->error(__d('cake_console', '%s not found', $this->args[1]), __d('cake_console', 'No tree returned.'));
+ }
+ return $possibility;
+ }
+
+/**
+ * Parse an identifier into Model.foreignKey or an alias.
+ * Takes an identifier determines its type and returns the result as used by other methods.
+ *
+ * @param string $identifier Identifier to parse
+ * @return mixed a string for aliases, and an array for model.foreignKey
+ */
+ public function parseIdentifier($identifier) {
+ if (preg_match('/^([\w]+)\.(.*)$/', $identifier, $matches)) {
+ return array(
+ 'model' => $matches[1],
+ 'foreign_key' => $matches[2],
+ );
+ }
+ return $identifier;
+ }
+
+/**
+ * Get the node for a given identifier. $identifier can either be a string alias
+ * or an array of properties to use in AcoNode::node()
+ *
+ * @param string $class Class type you want (Aro/Aco)
+ * @param string|array $identifier A mixed identifier for finding the node.
+ * @return integer Integer of NodeId. Will trigger an error if nothing is found.
+ */
+ protected function _getNodeId($class, $identifier) {
+ $node = $this->Acl->{$class}->node($identifier);
+ if (empty($node)) {
+ if (is_array($identifier)) {
+ $identifier = var_export($identifier, true);
+ }
+ $this->error(__d('cake_console', 'Could not find node using reference "%s"', $identifier));
+ return;
+ }
+ return Hash::get($node, "0.{$class}.id");
+ }
+
+/**
+ * get params for standard Acl methods
+ *
+ * @return array aro, aco, action
+ */
+ protected function _getParams() {
+ $aro = is_numeric($this->args[0]) ? intval($this->args[0]) : $this->args[0];
+ $aco = is_numeric($this->args[1]) ? intval($this->args[1]) : $this->args[1];
+ $aroName = $aro;
+ $acoName = $aco;
+
+ if (is_string($aro)) {
+ $aro = $this->parseIdentifier($aro);
+ }
+ if (is_string($aco)) {
+ $aco = $this->parseIdentifier($aco);
+ }
+ $action = '*';
+ if (isset($this->args[2]) && !in_array($this->args[2], array('', 'all'))) {
+ $action = $this->args[2];
+ }
+ return compact('aro', 'aco', 'action', 'aroName', 'acoName');
+ }
+
+/**
+ * Build data parameters based on node type
+ *
+ * @param string $type Node type (ARO/ACO)
+ * @return array Variables
+ */
+ protected function _dataVars($type = null) {
+ if ($type == null) {
+ $type = $this->args[0];
+ }
+ $vars = array();
+ $class = ucwords($type);
+ $vars['secondary_id'] = (strtolower($class) == 'aro') ? 'foreign_key' : 'object_id';
+ $vars['data_name'] = $type;
+ $vars['table_name'] = $type . 's';
+ $vars['class'] = $class;
+ return $vars;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ApiShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ApiShell.php
new file mode 100644
index 0000000..8ba50e7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ApiShell.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * API shell to get CakePHP core method signatures.
+ *
+ * Implementation of a Cake Shell to show CakePHP core method signatures.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5012
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('File', 'Utility');
+
+/**
+ * API shell to show method signatures of CakePHP core classes.
+ *
+ * Implementation of a Cake Shell to show CakePHP core method signatures.
+ *
+ * @package Cake.Console.Command
+ */
+class ApiShell extends AppShell {
+
+/**
+ * Map between short name for paths and real paths.
+ *
+ * @var array
+ */
+ public $paths = array();
+
+/**
+ * Override initialize of the Shell
+ *
+ * @return void
+ */
+ public function initialize() {
+ $this->paths = array_merge($this->paths, array(
+ 'behavior' => CAKE . 'Model' . DS . 'Behavior' . DS,
+ 'cache' => CAKE . 'Cache' . DS,
+ 'controller' => CAKE . 'Controller' . DS,
+ 'component' => CAKE . 'Controller' . DS . 'Component' . DS,
+ 'helper' => CAKE . 'View' . DS . 'Helper' . DS,
+ 'model' => CAKE . 'Model' . DS,
+ 'view' => CAKE . 'View' . DS,
+ 'core' => CAKE
+ ));
+ }
+
+/**
+ * Override main() to handle action
+ *
+ * @return void
+ */
+ public function main() {
+ if (empty($this->args)) {
+ return $this->out($this->OptionParser->help());
+ }
+
+ $type = strtolower($this->args[0]);
+
+ if (isset($this->paths[$type])) {
+ $path = $this->paths[$type];
+ } else {
+ $path = $this->paths['core'];
+ }
+
+ if (count($this->args) == 1) {
+ $file = $type;
+ $class = Inflector::camelize($type);
+ } elseif (count($this->args) > 1) {
+ $file = Inflector::underscore($this->args[1]);
+ $class = Inflector::camelize($this->args[1]);
+ }
+ $objects = App::objects('class', $path);
+ if (in_array($class, $objects)) {
+ if (in_array($type, array('behavior', 'component', 'helper')) && $type !== $file) {
+ if (!preg_match('/' . Inflector::camelize($type) . '$/', $class)) {
+ $class .= Inflector::camelize($type);
+ }
+ }
+
+ } else {
+ $this->error(__d('cake_console', '%s not found', $class));
+ }
+
+ $parsed = $this->_parseClass($path . $class . '.php', $class);
+
+ if (!empty($parsed)) {
+ if (isset($this->params['method'])) {
+ if (!isset($parsed[$this->params['method']])) {
+ $this->err(__d('cake_console', '%s::%s() could not be found', $class, $this->params['method']));
+ $this->_stop();
+ }
+ $method = $parsed[$this->params['method']];
+ $this->out($class . '::' . $method['method'] . $method['parameters']);
+ $this->hr();
+ $this->out($method['comment'], true);
+ } else {
+ $this->out(ucwords($class));
+ $this->hr();
+ $i = 0;
+ foreach ($parsed as $method) {
+ $list[] = ++$i . ". " . $method['method'] . $method['parameters'];
+ }
+ $this->out($list);
+
+ $methods = array_keys($parsed);
+ while ($number = strtolower($this->in(__d('cake_console', 'Select a number to see the more information about a specific method. q to quit. l to list.'), null, 'q'))) {
+ if ($number === 'q') {
+ $this->out(__d('cake_console', 'Done'));
+ return $this->_stop();
+ }
+
+ if ($number === 'l') {
+ $this->out($list);
+ }
+
+ if (isset($methods[--$number])) {
+ $method = $parsed[$methods[$number]];
+ $this->hr();
+ $this->out($class . '::' . $method['method'] . $method['parameters']);
+ $this->hr();
+ $this->out($method['comment'], true);
+ }
+ }
+ }
+ }
+ }
+
+/**
+ * Get and configure the optionparser.
+ *
+ * @return ConsoleOptionParser
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ $parser->addArgument('type', array(
+ 'help' => __d('cake_console', 'Either a full path or type of class (model, behavior, controller, component, view, helper)')
+ ))->addArgument('className', array(
+ 'help' => __d('cake_console', 'A CakePHP core class name (e.g: Component, HtmlHelper).')
+ ))->addOption('method', array(
+ 'short' => 'm',
+ 'help' => __d('cake_console', 'The specific method you want help on.')
+ ))->description(__d('cake_console', 'Lookup doc block comments for classes in CakePHP.'));
+ return $parser;
+ }
+
+/**
+ * Show help for this shell.
+ *
+ * @return void
+ */
+ public function help() {
+ $head = "Usage: cake api [<type>] <className> [-m <method>]\n";
+ $head .= "-----------------------------------------------\n";
+ $head .= "Parameters:\n\n";
+
+ $commands = array(
+ 'path' => "\t<type>\n" .
+ "\t\tEither a full path or type of class (model, behavior, controller, component, view, helper).\n" .
+ "\t\tAvailable values:\n\n" .
+ "\t\tbehavior\tLook for class in CakePHP behavior path\n" .
+ "\t\tcache\tLook for class in CakePHP cache path\n" .
+ "\t\tcontroller\tLook for class in CakePHP controller path\n" .
+ "\t\tcomponent\tLook for class in CakePHP component path\n" .
+ "\t\thelper\tLook for class in CakePHP helper path\n" .
+ "\t\tmodel\tLook for class in CakePHP model path\n" .
+ "\t\tview\tLook for class in CakePHP view path\n",
+ 'className' => "\t<className>\n" .
+ "\t\tA CakePHP core class name (e.g: Component, HtmlHelper).\n"
+ );
+
+ $this->out($head);
+ if (!isset($this->args[1])) {
+ foreach ($commands as $cmd) {
+ $this->out("{$cmd}\n\n");
+ }
+ } elseif (isset($commands[strtolower($this->args[1])])) {
+ $this->out($commands[strtolower($this->args[1])] . "\n\n");
+ } else {
+ $this->out(__d('cake_console', 'Command %s not found', $this->args[1]));
+ }
+ }
+
+/**
+ * Parse a given class (located on given file) and get public methods and their
+ * signatures.
+ *
+ * @param string $path File path
+ * @param string $class Class name
+ * @return array Methods and signatures indexed by method name
+ */
+ protected function _parseClass($path, $class) {
+ $parsed = array();
+
+ if (!class_exists($class)) {
+ if (!include_once $path) {
+ $this->err(__d('cake_console', '%s could not be found', $path));
+ }
+ }
+
+ $reflection = new ReflectionClass($class);
+
+ foreach ($reflection->getMethods() as $method) {
+ if (!$method->isPublic() || strpos($method->getName(), '_') === 0) {
+ continue;
+ }
+ if ($method->getDeclaringClass()->getName() != $class) {
+ continue;
+ }
+ $args = array();
+ foreach ($method->getParameters() as $param) {
+ $paramString = '$' . $param->getName();
+ if ($param->isDefaultValueAvailable()) {
+ $paramString .= ' = ' . str_replace("\n", '', var_export($param->getDefaultValue(), true));
+ }
+ $args[] = $paramString;
+ }
+ $parsed[$method->getName()] = array(
+ 'comment' => str_replace(array('/*', '*/', '*'), '', $method->getDocComment()),
+ 'method' => $method->getName(),
+ 'parameters' => '(' . implode(', ', $args) . ')'
+ );
+ }
+ ksort($parsed);
+ return $parsed;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AppShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AppShell.php
new file mode 100644
index 0000000..5cc915f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/AppShell.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * AppShell file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Shell', 'Console');
+
+/**
+ * Application Shell
+ *
+ * Add your application-wide methods in the class below, your shells
+ * will inherit them.
+ *
+ * @package app.Console.Command
+ */
+class AppShell extends Shell {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/BakeShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/BakeShell.php
new file mode 100644
index 0000000..853074c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/BakeShell.php
@@ -0,0 +1,248 @@
+<?php
+/**
+ * Command-line code generation utility to automate programmer chores.
+ *
+ * Bake is CakePHP's code generation script, which can help you kickstart
+ * application development by writing fully functional skeleton controllers,
+ * models, and views. Going further, Bake can also write Unit Tests for you.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5012
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('Model', 'Model');
+
+/**
+ * Command-line code generation utility to automate programmer chores.
+ *
+ * Bake is CakePHP's code generation script, which can help you kickstart
+ * application development by writing fully functional skeleton controllers,
+ * models, and views. Going further, Bake can also write Unit Tests for you.
+ *
+ * @package Cake.Console.Command
+ * @link http://book.cakephp.org/2.0/en/console-and-shells/code-generation-with-bake.html
+ */
+class BakeShell extends AppShell {
+
+/**
+ * Contains tasks to load and instantiate
+ *
+ * @var array
+ */
+ public $tasks = array('Project', 'DbConfig', 'Model', 'Controller', 'View', 'Plugin', 'Fixture', 'Test');
+
+/**
+ * The connection being used.
+ *
+ * @var string
+ */
+ public $connection = 'default';
+
+/**
+ * Assign $this->connection to the active task if a connection param is set.
+ *
+ * @return void
+ */
+ public function startup() {
+ parent::startup();
+ Configure::write('debug', 2);
+ Configure::write('Cache.disable', 1);
+
+ $task = Inflector::classify($this->command);
+ if (isset($this->{$task}) && !in_array($task, array('Project', 'DbConfig'))) {
+ if (isset($this->params['connection'])) {
+ $this->{$task}->connection = $this->params['connection'];
+ }
+ }
+ }
+
+/**
+ * Override main() to handle action
+ *
+ * @return mixed
+ */
+ public function main() {
+ if (!is_dir($this->DbConfig->path)) {
+ $path = $this->Project->execute();
+ if (!empty($path)) {
+ $this->DbConfig->path = $path . 'Config' . DS;
+ } else {
+ return false;
+ }
+ }
+
+ if (!config('database')) {
+ $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.'));
+ $this->args = null;
+ return $this->DbConfig->execute();
+ }
+ $this->out(__d('cake_console', 'Interactive Bake Shell'));
+ $this->hr();
+ $this->out(__d('cake_console', '[D]atabase Configuration'));
+ $this->out(__d('cake_console', '[M]odel'));
+ $this->out(__d('cake_console', '[V]iew'));
+ $this->out(__d('cake_console', '[C]ontroller'));
+ $this->out(__d('cake_console', '[P]roject'));
+ $this->out(__d('cake_console', '[F]ixture'));
+ $this->out(__d('cake_console', '[T]est case'));
+ $this->out(__d('cake_console', '[Q]uit'));
+
+ $classToBake = strtoupper($this->in(__d('cake_console', 'What would you like to Bake?'), array('D', 'M', 'V', 'C', 'P', 'F', 'T', 'Q')));
+ switch ($classToBake) {
+ case 'D':
+ $this->DbConfig->execute();
+ break;
+ case 'M':
+ $this->Model->execute();
+ break;
+ case 'V':
+ $this->View->execute();
+ break;
+ case 'C':
+ $this->Controller->execute();
+ break;
+ case 'P':
+ $this->Project->execute();
+ break;
+ case 'F':
+ $this->Fixture->execute();
+ break;
+ case 'T':
+ $this->Test->execute();
+ break;
+ case 'Q':
+ exit(0);
+ break;
+ default:
+ $this->out(__d('cake_console', 'You have made an invalid selection. Please choose a type of class to Bake by entering D, M, V, F, T, or C.'));
+ }
+ $this->hr();
+ $this->main();
+ }
+
+/**
+ * Quickly bake the MVC
+ *
+ * @return void
+ */
+ public function all() {
+ $this->out('Bake All');
+ $this->hr();
+
+ if (!isset($this->params['connection']) && empty($this->connection)) {
+ $this->connection = $this->DbConfig->getConfig();
+ }
+
+ if (empty($this->args)) {
+ $this->Model->interactive = true;
+ $name = $this->Model->getName($this->connection);
+ }
+
+ foreach (array('Model', 'Controller', 'View') as $task) {
+ $this->{$task}->connection = $this->connection;
+ $this->{$task}->interactive = false;
+ }
+
+ if (!empty($this->args[0])) {
+ $name = $this->args[0];
+ }
+
+ $modelExists = false;
+ $model = $this->_modelName($name);
+
+ App::uses('AppModel', 'Model');
+ App::uses($model, 'Model');
+ if (class_exists($model)) {
+ $object = new $model();
+ $modelExists = true;
+ } else {
+ $object = new Model(array('name' => $name, 'ds' => $this->connection));
+ }
+
+ $modelBaked = $this->Model->bake($object, false);
+
+ if ($modelBaked && $modelExists === false) {
+ if ($this->_checkUnitTest()) {
+ $this->Model->bakeFixture($model);
+ $this->Model->bakeTest($model);
+ }
+ $modelExists = true;
+ }
+
+ if ($modelExists === true) {
+ $controller = $this->_controllerName($name);
+ if ($this->Controller->bake($controller, $this->Controller->bakeActions($controller))) {
+ if ($this->_checkUnitTest()) {
+ $this->Controller->bakeTest($controller);
+ }
+ }
+ App::uses($controller . 'Controller', 'Controller');
+ if (class_exists($controller . 'Controller')) {
+ $this->View->args = array($name);
+ $this->View->execute();
+ }
+ $this->out('', 1, Shell::QUIET);
+ $this->out(__d('cake_console', '<success>Bake All complete</success>'), 1, Shell::QUIET);
+ array_shift($this->args);
+ } else {
+ $this->error(__d('cake_console', 'Bake All could not continue without a valid model'));
+ }
+ return $this->_stop();
+ }
+
+/**
+ * get the option parser.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(__d('cake_console',
+ 'The Bake script generates controllers, views and models for your application.' .
+ ' If run with no command line arguments, Bake guides the user through the class creation process.' .
+ ' You can customize the generation process by telling Bake where different parts of your application are using command line arguments.'
+ ))->addSubcommand('all', array(
+ 'help' => __d('cake_console', 'Bake a complete MVC. optional <name> of a Model'),
+ ))->addSubcommand('project', array(
+ 'help' => __d('cake_console', 'Bake a new app folder in the path supplied or in current directory if no path is specified'),
+ 'parser' => $this->Project->getOptionParser()
+ ))->addSubcommand('plugin', array(
+ 'help' => __d('cake_console', 'Bake a new plugin folder in the path supplied or in current directory if no path is specified.'),
+ 'parser' => $this->Plugin->getOptionParser()
+ ))->addSubcommand('db_config', array(
+ 'help' => __d('cake_console', 'Bake a database.php file in config directory.'),
+ 'parser' => $this->DbConfig->getOptionParser()
+ ))->addSubcommand('model', array(
+ 'help' => __d('cake_console', 'Bake a model.'),
+ 'parser' => $this->Model->getOptionParser()
+ ))->addSubcommand('view', array(
+ 'help' => __d('cake_console', 'Bake views for controllers.'),
+ 'parser' => $this->View->getOptionParser()
+ ))->addSubcommand('controller', array(
+ 'help' => __d('cake_console', 'Bake a controller.'),
+ 'parser' => $this->Controller->getOptionParser()
+ ))->addSubcommand('fixture', array(
+ 'help' => __d('cake_console', 'Bake a fixture.'),
+ 'parser' => $this->Fixture->getOptionParser()
+ ))->addSubcommand('test', array(
+ 'help' => __d('cake_console', 'Bake a unit test.'),
+ 'parser' => $this->Test->getOptionParser()
+ ))->addOption('connection', array(
+ 'help' => __d('cake_console', 'Database connection to use in conjunction with `bake all`.'),
+ 'short' => 'c',
+ 'default' => 'default'
+ ));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/CommandListShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/CommandListShell.php
new file mode 100644
index 0000000..512349c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/CommandListShell.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Console.Command
+ * @since CakePHP v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('Inflector', 'Utility');
+
+/**
+ * Shows a list of commands available from the console.
+ *
+ * @package Cake.Console.Command
+ */
+class CommandListShell extends AppShell {
+
+/**
+ * startup
+ *
+ * @return void
+ */
+ public function startup() {
+ if (empty($this->params['xml'])) {
+ parent::startup();
+ }
+ }
+
+/**
+ * Main function Prints out the list of shells.
+ *
+ * @return void
+ */
+ public function main() {
+ if (empty($this->params['xml'])) {
+ $this->out(__d('cake_console', "<info>Current Paths:</info>"), 2);
+ $this->out(" -app: " . APP_DIR);
+ $this->out(" -working: " . rtrim(APP, DS));
+ $this->out(" -root: " . rtrim(ROOT, DS));
+ $this->out(" -core: " . rtrim(CORE_PATH, DS));
+ $this->out("");
+ $this->out(__d('cake_console', "<info>Changing Paths:</info>"), 2);
+ $this->out(__d('cake_console', "Your working path should be the same as your application path to change your path use the '-app' param."));
+ $this->out(__d('cake_console', "Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp"), 2);
+
+ $this->out(__d('cake_console', "<info>Available Shells:</info>"), 2);
+ }
+
+ $shellList = $this->_getShellList();
+ if (empty($shellList)) {
+ return;
+ }
+
+ if (empty($this->params['xml'])) {
+ $this->_asText($shellList);
+ } else {
+ $this->_asXml($shellList);
+ }
+ }
+
+/**
+ * Gets the shell command listing.
+ *
+ * @return array
+ */
+ protected function _getShellList() {
+ $skipFiles = array('AppShell');
+
+ $plugins = CakePlugin::loaded();
+ $shellList = array_fill_keys($plugins, null) + array('CORE' => null, 'app' => null);
+
+ $corePath = App::core('Console/Command');
+ $shells = App::objects('file', $corePath[0]);
+ $shells = array_diff($shells, $skipFiles);
+ $this->_appendShells('CORE', $shells, $shellList);
+
+ $appShells = App::objects('Console/Command', null, false);
+ $appShells = array_diff($appShells, $shells, $skipFiles);
+ $this->_appendShells('app', $appShells, $shellList);
+
+ foreach ($plugins as $plugin) {
+ $pluginShells = App::objects($plugin . '.Console/Command');
+ $this->_appendShells($plugin, $pluginShells, $shellList);
+ }
+
+ return array_filter($shellList);
+ }
+
+/**
+ * Scan the provided paths for shells, and append them into $shellList
+ *
+ * @param string $type
+ * @param array $shells
+ * @param array $shellList
+ * @return array
+ */
+ protected function _appendShells($type, $shells, &$shellList) {
+ foreach ($shells as $shell) {
+ $shellList[$type][] = Inflector::underscore(str_replace('Shell', '', $shell));
+ }
+ }
+
+/**
+ * Output text.
+ *
+ * @param array $shellList
+ * @return void
+ */
+ protected function _asText($shellList) {
+ foreach ($shellList as $plugin => $commands) {
+ sort($commands);
+ $this->out(sprintf('[<info>%s</info>] %s', $plugin, implode(', ', $commands)));
+ $this->out();
+ }
+
+ $this->out(__d('cake_console', "To run an app or core command, type <info>cake shell_name [args]</info>"));
+ $this->out(__d('cake_console', "To run a plugin command, type <info>cake Plugin.shell_name [args]</info>"));
+ $this->out(__d('cake_console', "To get help on a specific command, type <info>cake shell_name --help</info>"), 2);
+ }
+
+/**
+ * Output as XML
+ *
+ * @param array $shellList
+ * @return void
+ */
+ protected function _asXml($shellList) {
+ $plugins = CakePlugin::loaded();
+ $shells = new SimpleXmlElement('<shells></shells>');
+ foreach ($shellList as $plugin => $commands) {
+ foreach ($commands as $command) {
+ $callable = $command;
+ if (in_array($plugin, $plugins)) {
+ $callable = Inflector::camelize($plugin) . '.' . $command;
+ }
+
+ $shell = $shells->addChild('shell');
+ $shell->addAttribute('name', $command);
+ $shell->addAttribute('call_as', $callable);
+ $shell->addAttribute('provider', $plugin);
+ $shell->addAttribute('help', $callable . ' -h');
+ }
+ }
+ $this->stdout->outputAs(ConsoleOutput::RAW);
+ $this->out($shells->saveXml());
+ }
+
+/**
+ * get the option parser
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(__d('cake_console', 'Get the list of available shells for this CakePHP application.'))
+ ->addOption('sort', array(
+ 'help' => __d('cake_console', 'Does nothing (deprecated)'),
+ 'boolean' => true
+ ))
+ ->addOption('xml', array(
+ 'help' => __d('cake_console', 'Get the listing as XML.'),
+ 'boolean' => true
+ ));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ConsoleShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ConsoleShell.php
new file mode 100644
index 0000000..ee8f07d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/ConsoleShell.php
@@ -0,0 +1,359 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5012
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+
+/**
+ * Provides a very basic 'interactive' console for CakePHP apps.
+ *
+ * @package Cake.Console.Command
+ */
+class ConsoleShell extends AppShell {
+
+/**
+ * Available binding types
+ *
+ * @var array
+ */
+ public $associations = array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany');
+
+/**
+ * Chars that describe invalid commands
+ *
+ * @var array
+ */
+ public $badCommandChars = array('$', ';');
+
+/**
+ * Available models
+ *
+ * @var array
+ */
+ public $models = array();
+
+/**
+ * Override startup of the Shell
+ *
+ * @return void
+ */
+ public function startup() {
+ App::uses('Dispatcher', 'Routing');
+ $this->Dispatcher = new Dispatcher();
+ $this->models = App::objects('Model');
+
+ foreach ($this->models as $model) {
+ $class = $model;
+ $this->models[$model] = $class;
+ App::uses($class, 'Model');
+ $this->{$class} = new $class();
+ }
+ $this->out(__d('cake_console', 'Model classes:'));
+ $this->hr();
+
+ foreach ($this->models as $model) {
+ $this->out(" - {$model}");
+ }
+ $this->_loadRoutes();
+ }
+
+/**
+ * Prints the help message
+ *
+ * @return void
+ */
+ public function help() {
+ $out = 'Console help:';
+ $out .= '-------------';
+ $out .= 'The interactive console is a tool for testing parts of your app before you';
+ $out .= 'write code.';
+ $out .= "\n";
+ $out .= 'Model testing:';
+ $out .= 'To test model results, use the name of your model without a leading $';
+ $out .= 'e.g. Foo->find("all")';
+ $out .= "\n";
+ $out .= 'To dynamically set associations, you can do the following:';
+ $out .= "\tModelA bind <association> ModelB";
+ $out .= "where the supported associations are hasOne, hasMany, belongsTo, hasAndBelongsToMany";
+ $out .= "\n";
+ $out .= 'To dynamically remove associations, you can do the following:';
+ $out .= "\t ModelA unbind <association> ModelB";
+ $out .= "where the supported associations are the same as above";
+ $out .= "\n";
+ $out .= "To save a new field in a model, you can do the following:";
+ $out .= "\tModelA->save(array('foo' => 'bar', 'baz' => 0))";
+ $out .= "where you are passing a hash of data to be saved in the format";
+ $out .= "of field => value pairs";
+ $out .= "\n";
+ $out .= "To get column information for a model, use the following:";
+ $out .= "\tModelA columns";
+ $out .= "which returns a list of columns and their type";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= 'Route testing:';
+ $out .= "\n";
+ $out .= 'To test URLs against your app\'s route configuration, type:';
+ $out .= "\n";
+ $out .= "\tRoute <url>";
+ $out .= "\n";
+ $out .= "where url is the path to your your action plus any query parameters,";
+ $out .= "minus the application's base path. For example:";
+ $out .= "\n";
+ $out .= "\tRoute /posts/view/1";
+ $out .= "\n";
+ $out .= "will return something like the following:";
+ $out .= "\n";
+ $out .= "\tarray(";
+ $out .= "\t [...]";
+ $out .= "\t 'controller' => 'posts',";
+ $out .= "\t 'action' => 'view',";
+ $out .= "\t [...]";
+ $out .= "\t)";
+ $out .= "\n";
+ $out .= 'Alternatively, you can use simple array syntax to test reverse';
+ $out .= 'To reload your routes config (Config/routes.php), do the following:';
+ $out .= "\n";
+ $out .= "\tRoutes reload";
+ $out .= "\n";
+ $out .= 'To show all connected routes, do the following:';
+ $out .= "\tRoutes show";
+ $this->out($out);
+ }
+
+/**
+ * Override main() to handle action
+ *
+ * @param string $command
+ * @return void
+ */
+ public function main($command = null) {
+ while (true) {
+ if (empty($command)) {
+ $command = trim($this->in(''));
+ }
+
+ switch ($command) {
+ case 'help':
+ $this->help();
+ break;
+ case 'quit':
+ case 'exit':
+ return true;
+ break;
+ case 'models':
+ $this->out(__d('cake_console', 'Model classes:'));
+ $this->hr();
+ foreach ($this->models as $model) {
+ $this->out(" - {$model}");
+ }
+ break;
+ case (preg_match("/^(\w+) bind (\w+) (\w+)/", $command, $tmp) == true):
+ foreach ($tmp as $data) {
+ $data = strip_tags($data);
+ $data = str_replace($this->badCommandChars, "", $data);
+ }
+
+ $modelA = $tmp[1];
+ $association = $tmp[2];
+ $modelB = $tmp[3];
+
+ if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations)) {
+ $this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false);
+ $this->out(__d('cake_console', "Created %s association between %s and %s",
+ $association, $modelA, $modelB));
+ } else {
+ $this->out(__d('cake_console', "Please verify you are using valid models and association types"));
+ }
+ break;
+ case (preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp) == true):
+ foreach ($tmp as $data) {
+ $data = strip_tags($data);
+ $data = str_replace($this->badCommandChars, "", $data);
+ }
+
+ $modelA = $tmp[1];
+ $association = $tmp[2];
+ $modelB = $tmp[3];
+
+ // Verify that there is actually an association to unbind
+ $currentAssociations = $this->{$modelA}->getAssociated();
+ $validCurrentAssociation = false;
+
+ foreach ($currentAssociations as $model => $currentAssociation) {
+ if ($model == $modelB && $association == $currentAssociation) {
+ $validCurrentAssociation = true;
+ }
+ }
+
+ if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) {
+ $this->{$modelA}->unbindModel(array($association => array($modelB)));
+ $this->out(__d('cake_console', "Removed %s association between %s and %s",
+ $association, $modelA, $modelB));
+ } else {
+ $this->out(__d('cake_console', "Please verify you are using valid models, valid current association, and valid association types"));
+ }
+ break;
+ case (strpos($command, "->find") > 0):
+ // Remove any bad info
+ $command = strip_tags($command);
+ $command = str_replace($this->badCommandChars, "", $command);
+
+ // Do we have a valid model?
+ list($modelToCheck, $tmp) = explode('->', $command);
+
+ if ($this->_isValidModel($modelToCheck)) {
+ $findCommand = "\$data = \$this->$command;";
+ @eval($findCommand);
+
+ if (is_array($data)) {
+ foreach ($data as $idx => $results) {
+ if (is_numeric($idx)) { // findAll() output
+ foreach ($results as $modelName => $result) {
+ $this->out("$modelName");
+
+ foreach ($result as $field => $value) {
+ if (is_array($value)) {
+ foreach ($value as $field2 => $value2) {
+ $this->out("\t$field2: $value2");
+ }
+
+ $this->out();
+ } else {
+ $this->out("\t$field: $value");
+ }
+ }
+ }
+ } else { // find() output
+ $this->out($idx);
+
+ foreach ($results as $field => $value) {
+ if (is_array($value)) {
+ foreach ($value as $field2 => $value2) {
+ $this->out("\t$field2: $value2");
+ }
+
+ $this->out();
+ } else {
+ $this->out("\t$field: $value");
+ }
+ }
+ }
+ }
+ } else {
+ $this->out();
+ $this->out(__d('cake_console', "No result set found"));
+ }
+ } else {
+ $this->out(__d('cake_console', "%s is not a valid model", $modelToCheck));
+ }
+
+ break;
+ case (strpos($command, '->save') > 0):
+ // Validate the model we're trying to save here
+ $command = strip_tags($command);
+ $command = str_replace($this->badCommandChars, "", $command);
+ list($modelToSave, $tmp) = explode("->", $command);
+
+ if ($this->_isValidModel($modelToSave)) {
+ // Extract the array of data we are trying to build
+ list($foo, $data) = explode("->save", $command);
+ $data = preg_replace('/^\(*(array)?\(*(.+?)\)*$/i', '\\2', $data);
+ $saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));";
+ @eval($saveCommand);
+ $this->out(__d('cake_console', 'Saved record for %s', $modelToSave));
+ }
+ break;
+ case (preg_match("/^(\w+) columns/", $command, $tmp) == true):
+ $modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1]));
+
+ if ($this->_isValidModel($modelToCheck)) {
+ // Get the column info for this model
+ $fieldsCommand = "\$data = \$this->{$modelToCheck}->getColumnTypes();";
+ @eval($fieldsCommand);
+
+ if (is_array($data)) {
+ foreach ($data as $field => $type) {
+ $this->out("\t{$field}: {$type}");
+ }
+ }
+ } else {
+ $this->out(__d('cake_console', "Please verify that you selected a valid model"));
+ }
+ break;
+ case (preg_match("/^routes\s+reload/i", $command, $tmp) == true):
+ $router = Router::getInstance();
+ if (!$this->_loadRoutes()) {
+ $this->out(__d('cake_console', "There was an error loading the routes config. Please check that the file exists and is free of parse errors."));
+ break;
+ }
+ $this->out(__d('cake_console', "Routes configuration reloaded, %d routes connected", count($router->routes)));
+ break;
+ case (preg_match("/^routes\s+show/i", $command, $tmp) == true):
+ $router = Router::getInstance();
+ $this->out(implode("\n", Hash::extract($router->routes, '{n}.0')));
+ break;
+ case (preg_match("/^route\s+(\(.*\))$/i", $command, $tmp) == true):
+ if ($url = eval('return array' . $tmp[1] . ';')) {
+ $this->out(Router::url($url));
+ }
+ break;
+ case (preg_match("/^route\s+(.*)/i", $command, $tmp) == true):
+ $this->out(var_export(Router::parse($tmp[1]), true));
+ break;
+ default:
+ $this->out(__d('cake_console', "Invalid command"));
+ $this->out();
+ break;
+ }
+ $command = '';
+ }
+ }
+
+/**
+ * Tells if the specified model is included in the list of available models
+ *
+ * @param string $modelToCheck
+ * @return boolean true if is an available model, false otherwise
+ */
+ protected function _isValidModel($modelToCheck) {
+ return in_array($modelToCheck, $this->models);
+ }
+
+/**
+ * Reloads the routes configuration from app/Config/routes.php, and compiles
+ * all routes found
+ *
+ * @return boolean True if config reload was a success, otherwise false
+ */
+ protected function _loadRoutes() {
+ Router::reload();
+ extract(Router::getNamedExpressions());
+
+ if (!@include APP . 'Config' . DS . 'routes.php') {
+ return false;
+ }
+ CakePlugin::routes();
+
+ Router::parse('/');
+
+ foreach (array_keys(Router::getNamedExpressions()) as $var) {
+ unset(${$var});
+ }
+
+ foreach (Router::$routes as $route) {
+ $route->compile();
+ }
+ return true;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/I18nShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/I18nShell.php
new file mode 100644
index 0000000..73e67a2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/I18nShell.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Internationalization Management Shell
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+
+/**
+ * Shell for I18N management.
+ *
+ * @package Cake.Console.Command
+ */
+class I18nShell extends AppShell {
+
+/**
+ * Contains database source to use
+ *
+ * @var string
+ */
+ public $dataSource = 'default';
+
+/**
+ * Contains tasks to load and instantiate
+ *
+ * @var array
+ */
+ public $tasks = array('DbConfig', 'Extract');
+
+/**
+ * Override startup of the Shell
+ *
+ * @return mixed
+ */
+ public function startup() {
+ $this->_welcome();
+ if (isset($this->params['datasource'])) {
+ $this->dataSource = $this->params['datasource'];
+ }
+
+ if ($this->command && !in_array($this->command, array('help'))) {
+ if (!config('database')) {
+ $this->out(__d('cake_console', 'Your database configuration was not found. Take a moment to create one.'), true);
+ return $this->DbConfig->execute();
+ }
+ }
+ }
+
+/**
+ * Override main() for help message hook
+ *
+ * @return void
+ */
+ public function main() {
+ $this->out(__d('cake_console', '<info>I18n Shell</info>'));
+ $this->hr();
+ $this->out(__d('cake_console', '[E]xtract POT file from sources'));
+ $this->out(__d('cake_console', '[I]nitialize i18n database table'));
+ $this->out(__d('cake_console', '[H]elp'));
+ $this->out(__d('cake_console', '[Q]uit'));
+
+ $choice = strtolower($this->in(__d('cake_console', 'What would you like to do?'), array('E', 'I', 'H', 'Q')));
+ switch ($choice) {
+ case 'e':
+ $this->Extract->execute();
+ break;
+ case 'i':
+ $this->initdb();
+ break;
+ case 'h':
+ $this->out($this->OptionParser->help());
+ break;
+ case 'q':
+ exit(0);
+ break;
+ default:
+ $this->out(__d('cake_console', 'You have made an invalid selection. Please choose a command to execute by entering E, I, H, or Q.'));
+ }
+ $this->hr();
+ $this->main();
+ }
+
+/**
+ * Initialize I18N database.
+ *
+ * @return void
+ */
+ public function initdb() {
+ $this->dispatchShell('schema create i18n');
+ }
+
+/**
+ * Get and configure the Option parser
+ *
+ * @return ConsoleOptionParser
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(
+ __d('cake_console', 'I18n Shell initializes i18n database table for your application and generates .pot files(s) with translations.')
+ )->addSubcommand('initdb', array(
+ 'help' => __d('cake_console', 'Initialize the i18n table.')
+ ))->addSubcommand('extract', array(
+ 'help' => __d('cake_console', 'Extract the po translations from your application'),
+ 'parser' => $this->Extract->getOptionParser()
+ ));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/SchemaShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/SchemaShell.php
new file mode 100644
index 0000000..eb33215
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/SchemaShell.php
@@ -0,0 +1,533 @@
+<?php
+/**
+ * Command-line database management utility to automate programmer chores.
+ *
+ * Schema is CakePHP's database management utility. This helps you maintain versions of
+ * of your database.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5550
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('File', 'Utility');
+App::uses('Folder', 'Utility');
+App::uses('CakeSchema', 'Model');
+
+/**
+ * Schema is a command-line database management utility for automating programmer chores.
+ *
+ * Schema is CakePHP's database management utility. This helps you maintain versions of
+ * of your database.
+ *
+ * @package Cake.Console.Command
+ * @link http://book.cakephp.org/2.0/en/console-and-shells/schema-management-and-migrations.html
+ */
+class SchemaShell extends AppShell {
+
+/**
+ * Schema class being used.
+ *
+ * @var CakeSchema
+ */
+ public $Schema;
+
+/**
+ * is this a dry run?
+ *
+ * @var boolean
+ */
+ protected $_dry = null;
+
+/**
+ * Override startup
+ *
+ * @return void
+ */
+ public function startup() {
+ $this->_welcome();
+ $this->out('Cake Schema Shell');
+ $this->hr();
+
+ $name = $path = $connection = $plugin = null;
+ if (!empty($this->params['name'])) {
+ $name = $this->params['name'];
+ } elseif (!empty($this->args[0]) && $this->args[0] !== 'snapshot') {
+ $name = $this->params['name'] = $this->args[0];
+ }
+
+ if (strpos($name, '.')) {
+ list($this->params['plugin'], $splitName) = pluginSplit($name);
+ $name = $this->params['name'] = $splitName;
+ }
+
+ if ($name) {
+ $this->params['file'] = Inflector::underscore($name);
+ }
+
+ if (empty($this->params['file'])) {
+ $this->params['file'] = 'schema.php';
+ }
+ if (strpos($this->params['file'], '.php') === false) {
+ $this->params['file'] .= '.php';
+ }
+ $file = $this->params['file'];
+
+ if (!empty($this->params['path'])) {
+ $path = $this->params['path'];
+ }
+
+ if (!empty($this->params['connection'])) {
+ $connection = $this->params['connection'];
+ }
+ if (!empty($this->params['plugin'])) {
+ $plugin = $this->params['plugin'];
+ if (empty($name)) {
+ $name = $plugin;
+ }
+ }
+ $this->Schema = new CakeSchema(compact('name', 'path', 'file', 'connection', 'plugin'));
+ }
+
+/**
+ * Read and output contents of schema object
+ * path to read as second arg
+ *
+ * @return void
+ */
+ public function view() {
+ $File = new File($this->Schema->path . DS . $this->params['file']);
+ if ($File->exists()) {
+ $this->out($File->read());
+ $this->_stop();
+ } else {
+ $file = $this->Schema->path . DS . $this->params['file'];
+ $this->err(__d('cake_console', 'Schema file (%s) could not be found.', $file));
+ $this->_stop();
+ }
+ }
+
+/**
+ * Read database and Write schema object
+ * accepts a connection as first arg or path to save as second arg
+ *
+ * @return void
+ */
+ public function generate() {
+ $this->out(__d('cake_console', 'Generating Schema...'));
+ $options = array();
+ if ($this->params['force']) {
+ $options = array('models' => false);
+ }
+
+ $snapshot = false;
+ if (isset($this->args[0]) && $this->args[0] === 'snapshot') {
+ $snapshot = true;
+ }
+
+ if (!$snapshot && file_exists($this->Schema->path . DS . $this->params['file'])) {
+ $snapshot = true;
+ $prompt = __d('cake_console', "Schema file exists.\n [O]verwrite\n [S]napshot\n [Q]uit\nWould you like to do?");
+ $result = strtolower($this->in($prompt, array('o', 's', 'q'), 's'));
+ if ($result === 'q') {
+ return $this->_stop();
+ }
+ if ($result === 'o') {
+ $snapshot = false;
+ }
+ }
+
+ $cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', true);
+
+ $content = $this->Schema->read($options);
+ $content['file'] = $this->params['file'];
+
+ Configure::write('Cache.disable', $cacheDisable);
+
+ if ($snapshot === true) {
+ $fileName = rtrim($this->params['file'], '.php');
+ $Folder = new Folder($this->Schema->path);
+ $result = $Folder->read();
+
+ $numToUse = false;
+ if (isset($this->params['snapshot'])) {
+ $numToUse = $this->params['snapshot'];
+ }
+
+ $count = 0;
+ if (!empty($result[1])) {
+ foreach ($result[1] as $file) {
+ if (preg_match('/' . preg_quote($fileName) . '(?:[_\d]*)?\.php$/', $file)) {
+ $count++;
+ }
+ }
+ }
+
+ if ($numToUse !== false) {
+ if ($numToUse > $count) {
+ $count = $numToUse;
+ }
+ }
+
+ $content['file'] = $fileName . '_' . $count . '.php';
+ }
+
+ if ($this->Schema->write($content)) {
+ $this->out(__d('cake_console', 'Schema file: %s generated', $content['file']));
+ $this->_stop();
+ } else {
+ $this->err(__d('cake_console', 'Schema file: %s generated'));
+ $this->_stop();
+ }
+ }
+
+/**
+ * Dump Schema object to sql file
+ * Use the `write` param to enable and control SQL file output location.
+ * Simply using -write will write the sql file to the same dir as the schema file.
+ * If -write contains a full path name the file will be saved there. If -write only
+ * contains no DS, that will be used as the file name, in the same dir as the schema file.
+ *
+ * @return string
+ */
+ public function dump() {
+ $write = false;
+ $Schema = $this->Schema->load();
+ if (!$Schema) {
+ $this->err(__d('cake_console', 'Schema could not be loaded'));
+ $this->_stop();
+ }
+ if (!empty($this->params['write'])) {
+ if ($this->params['write'] == 1) {
+ $write = Inflector::underscore($this->Schema->name);
+ } else {
+ $write = $this->params['write'];
+ }
+ }
+ $db = ConnectionManager::getDataSource($this->Schema->connection);
+ $contents = "\n\n" . $db->dropSchema($Schema) . "\n\n" . $db->createSchema($Schema);
+
+ if ($write) {
+ if (strpos($write, '.sql') === false) {
+ $write .= '.sql';
+ }
+ if (strpos($write, DS) !== false) {
+ $File = new File($write, true);
+ } else {
+ $File = new File($this->Schema->path . DS . $write, true);
+ }
+
+ if ($File->write($contents)) {
+ $this->out(__d('cake_console', 'SQL dump file created in %s', $File->pwd()));
+ $this->_stop();
+ } else {
+ $this->err(__d('cake_console', 'SQL dump could not be created'));
+ $this->_stop();
+ }
+ }
+ $this->out($contents);
+ return $contents;
+ }
+
+/**
+ * Run database create commands. Alias for run create.
+ *
+ * @return void
+ */
+ public function create() {
+ list($Schema, $table) = $this->_loadSchema();
+ $this->_create($Schema, $table);
+ }
+
+/**
+ * Run database create commands. Alias for run create.
+ *
+ * @return void
+ */
+ public function update() {
+ list($Schema, $table) = $this->_loadSchema();
+ $this->_update($Schema, $table);
+ }
+
+/**
+ * Prepares the Schema objects for database operations.
+ *
+ * @return void
+ */
+ protected function _loadSchema() {
+ $name = $plugin = null;
+ if (!empty($this->params['name'])) {
+ $name = $this->params['name'];
+ }
+ if (!empty($this->params['plugin'])) {
+ $plugin = $this->params['plugin'];
+ }
+
+ if (!empty($this->params['dry'])) {
+ $this->_dry = true;
+ $this->out(__d('cake_console', 'Performing a dry run.'));
+ }
+
+ $options = array('name' => $name, 'plugin' => $plugin);
+ if (!empty($this->params['snapshot'])) {
+ $fileName = rtrim($this->Schema->file, '.php');
+ $options['file'] = $fileName . '_' . $this->params['snapshot'] . '.php';
+ }
+
+ $Schema = $this->Schema->load($options);
+
+ if (!$Schema) {
+ $this->err(__d('cake_console', '%s could not be loaded', $this->Schema->path . DS . $this->Schema->file));
+ $this->_stop();
+ }
+ $table = null;
+ if (isset($this->args[1])) {
+ $table = $this->args[1];
+ }
+ return array(&$Schema, $table);
+ }
+
+/**
+ * Create database from Schema object
+ * Should be called via the run method
+ *
+ * @param CakeSchema $Schema
+ * @param string $table
+ * @return void
+ */
+ protected function _create($Schema, $table = null) {
+ $db = ConnectionManager::getDataSource($this->Schema->connection);
+
+ $drop = $create = array();
+
+ if (!$table) {
+ foreach ($Schema->tables as $table => $fields) {
+ $drop[$table] = $db->dropSchema($Schema, $table);
+ $create[$table] = $db->createSchema($Schema, $table);
+ }
+ } elseif (isset($Schema->tables[$table])) {
+ $drop[$table] = $db->dropSchema($Schema, $table);
+ $create[$table] = $db->createSchema($Schema, $table);
+ }
+ if (empty($drop) || empty($create)) {
+ $this->out(__d('cake_console', 'Schema is up to date.'));
+ $this->_stop();
+ }
+
+ $this->out("\n" . __d('cake_console', 'The following table(s) will be dropped.'));
+ $this->out(array_keys($drop));
+
+ if ('y' == $this->in(__d('cake_console', 'Are you sure you want to drop the table(s)?'), array('y', 'n'), 'n')) {
+ $this->out(__d('cake_console', 'Dropping table(s).'));
+ $this->_run($drop, 'drop', $Schema);
+ }
+
+ $this->out("\n" . __d('cake_console', 'The following table(s) will be created.'));
+ $this->out(array_keys($create));
+
+ if ('y' == $this->in(__d('cake_console', 'Are you sure you want to create the table(s)?'), array('y', 'n'), 'y')) {
+ $this->out(__d('cake_console', 'Creating table(s).'));
+ $this->_run($create, 'create', $Schema);
+ }
+ $this->out(__d('cake_console', 'End create.'));
+ }
+
+/**
+ * Update database with Schema object
+ * Should be called via the run method
+ *
+ * @param CakeSchema $Schema
+ * @param string $table
+ * @return void
+ */
+ protected function _update(&$Schema, $table = null) {
+ $db = ConnectionManager::getDataSource($this->Schema->connection);
+
+ $this->out(__d('cake_console', 'Comparing Database to Schema...'));
+ $options = array();
+ if (isset($this->params['force'])) {
+ $options['models'] = false;
+ }
+ $Old = $this->Schema->read($options);
+ $compare = $this->Schema->compare($Old, $Schema);
+
+ $contents = array();
+
+ if (empty($table)) {
+ foreach ($compare as $table => $changes) {
+ $contents[$table] = $db->alterSchema(array($table => $changes), $table);
+ }
+ } elseif (isset($compare[$table])) {
+ $contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table);
+ }
+
+ if (empty($contents)) {
+ $this->out(__d('cake_console', 'Schema is up to date.'));
+ $this->_stop();
+ }
+
+ $this->out("\n" . __d('cake_console', 'The following statements will run.'));
+ $this->out(array_map('trim', $contents));
+ if ('y' == $this->in(__d('cake_console', 'Are you sure you want to alter the tables?'), array('y', 'n'), 'n')) {
+ $this->out();
+ $this->out(__d('cake_console', 'Updating Database...'));
+ $this->_run($contents, 'update', $Schema);
+ }
+
+ $this->out(__d('cake_console', 'End update.'));
+ }
+
+/**
+ * Runs sql from _create() or _update()
+ *
+ * @param array $contents
+ * @param string $event
+ * @param CakeSchema $Schema
+ * @return void
+ */
+ protected function _run($contents, $event, &$Schema) {
+ if (empty($contents)) {
+ $this->err(__d('cake_console', 'Sql could not be run'));
+ return;
+ }
+ Configure::write('debug', 2);
+ $db = ConnectionManager::getDataSource($this->Schema->connection);
+
+ foreach ($contents as $table => $sql) {
+ if (empty($sql)) {
+ $this->out(__d('cake_console', '%s is up to date.', $table));
+ } else {
+ if ($this->_dry === true) {
+ $this->out(__d('cake_console', 'Dry run for %s :', $table));
+ $this->out($sql);
+ } else {
+ if (!$Schema->before(array($event => $table))) {
+ return false;
+ }
+ $error = null;
+ try {
+ $db->execute($sql);
+ } catch (PDOException $e) {
+ $error = $table . ': ' . $e->getMessage();
+ }
+
+ $Schema->after(array($event => $table, 'errors' => $error));
+
+ if (!empty($error)) {
+ $this->err($error);
+ } else {
+ $this->out(__d('cake_console', '%s updated.', $table));
+ }
+ }
+ }
+ }
+ }
+
+/**
+ * get the option parser
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $plugin = array(
+ 'short' => 'p',
+ 'help' => __d('cake_console', 'The plugin to use.'),
+ );
+ $connection = array(
+ 'short' => 'c',
+ 'help' => __d('cake_console', 'Set the db config to use.'),
+ 'default' => 'default'
+ );
+ $path = array(
+ 'help' => __d('cake_console', 'Path to read and write schema.php'),
+ 'default' => APP . 'Config' . DS . 'Schema'
+ );
+ $file = array(
+ 'help' => __d('cake_console', 'File name to read and write.'),
+ 'default' => 'schema.php'
+ );
+ $name = array(
+ 'help' => __d('cake_console', 'Classname to use. If its Plugin.class, both name and plugin options will be set.')
+ );
+ $snapshot = array(
+ 'short' => 's',
+ 'help' => __d('cake_console', 'Snapshot number to use/make.')
+ );
+ $dry = array(
+ 'help' => __d('cake_console', 'Perform a dry run on create and update commands. Queries will be output instead of run.'),
+ 'boolean' => true
+ );
+ $force = array(
+ 'short' => 'f',
+ 'help' => __d('cake_console', 'Force "generate" to create a new schema'),
+ 'boolean' => true
+ );
+ $write = array(
+ 'help' => __d('cake_console', 'Write the dumped SQL to a file.')
+ );
+
+ $parser = parent::getOptionParser();
+ $parser->description(
+ __d('cake_console', 'The Schema Shell generates a schema object from the database and updates the database from the schema.')
+ )->addSubcommand('view', array(
+ 'help' => __d('cake_console', 'Read and output the contents of a schema file'),
+ 'parser' => array(
+ 'options' => compact('plugin', 'path', 'file', 'name', 'connection'),
+ 'arguments' => compact('name')
+ )
+ ))->addSubcommand('generate', array(
+ 'help' => __d('cake_console', 'Reads from --connection and writes to --path. Generate snapshots with -s'),
+ 'parser' => array(
+ 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force'),
+ 'arguments' => array(
+ 'snapshot' => array('help' => __d('cake_console', 'Generate a snapshot.'))
+ )
+ )
+ ))->addSubcommand('dump', array(
+ 'help' => __d('cake_console', 'Dump database SQL based on a schema file to stdout.'),
+ 'parser' => array(
+ 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'write'),
+ 'arguments' => compact('name')
+ )
+ ))->addSubcommand('create', array(
+ 'help' => __d('cake_console', 'Drop and create tables based on the schema file.'),
+ 'parser' => array(
+ 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot'),
+ 'args' => array(
+ 'name' => array(
+ 'help' => __d('cake_console', 'Name of schema to use.')
+ ),
+ 'table' => array(
+ 'help' => __d('cake_console', 'Only create the specified table.')
+ )
+ )
+ )
+ ))->addSubcommand('update', array(
+ 'help' => __d('cake_console', 'Alter the tables based on the schema file.'),
+ 'parser' => array(
+ 'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'dry', 'snapshot', 'force'),
+ 'args' => array(
+ 'name' => array(
+ 'help' => __d('cake_console', 'Name of schema to use.')
+ ),
+ 'table' => array(
+ 'help' => __d('cake_console', 'Only create the specified table.')
+ )
+ )
+ )
+ ));
+ return $parser;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/BakeTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/BakeTask.php
new file mode 100644
index 0000000..e32e253
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/BakeTask.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Base class for Bake Tasks.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+
+/**
+ * Base class for Bake Tasks.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class BakeTask extends AppShell {
+
+/**
+ * Name of plugin
+ *
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * The db connection being used for baking
+ *
+ * @var string
+ */
+ public $connection = null;
+
+/**
+ * Flag for interactive mode
+ *
+ * @var boolean
+ */
+ public $interactive = false;
+
+/**
+ * Disable caching and enable debug for baking.
+ * This forces the most current database schema to be used.
+ *
+ * @return void
+ */
+ public function startup() {
+ Configure::write('debug', 2);
+ Configure::write('Cache.disable', 1);
+ parent::startup();
+ }
+
+/**
+ * Gets the path for output. Checks the plugin property
+ * and returns the correct path.
+ *
+ * @return string Path to output.
+ */
+ public function getPath() {
+ $path = $this->path;
+ if (isset($this->plugin)) {
+ $path = $this->_pluginPath($this->plugin) . $this->name . DS;
+ }
+ return $path;
+ }
+
+/**
+ * Base execute method parses some parameters and sets some properties on the bake tasks.
+ * call when overriding execute()
+ *
+ * @return void
+ */
+ public function execute() {
+ foreach ($this->args as $i => $arg) {
+ if (strpos($arg, '.')) {
+ list($this->params['plugin'], $this->args[$i]) = pluginSplit($arg);
+ break;
+ }
+ }
+ if (isset($this->params['plugin'])) {
+ $this->plugin = $this->params['plugin'];
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ControllerTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ControllerTask.php
new file mode 100644
index 0000000..8feecc1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ControllerTask.php
@@ -0,0 +1,471 @@
+<?php
+/**
+ * The ControllerTask handles creating and updating controller files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('BakeTask', 'Console/Command/Task');
+App::uses('AppModel', 'Model');
+
+/**
+ * Task class for creating and updating controller files.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class ControllerTask extends BakeTask {
+
+/**
+ * Tasks to be loaded by this Task
+ *
+ * @var array
+ */
+ public $tasks = array('Model', 'Test', 'Template', 'DbConfig', 'Project');
+
+/**
+ * path to Controller directory
+ *
+ * @var array
+ */
+ public $path = null;
+
+/**
+ * Override initialize
+ *
+ * @return void
+ */
+ public function initialize() {
+ $this->path = current(App::path('Controller'));
+ }
+
+/**
+ * Execution method always used for tasks
+ *
+ * @return void
+ */
+ public function execute() {
+ parent::execute();
+ if (empty($this->args)) {
+ return $this->_interactive();
+ }
+
+ if (isset($this->args[0])) {
+ if (!isset($this->connection)) {
+ $this->connection = 'default';
+ }
+ if (strtolower($this->args[0]) == 'all') {
+ return $this->all();
+ }
+
+ $controller = $this->_controllerName($this->args[0]);
+ $actions = '';
+
+ if (!empty($this->params['public'])) {
+ $this->out(__d('cake_console', 'Baking basic crud methods for ') . $controller);
+ $actions .= $this->bakeActions($controller);
+ }
+ if (!empty($this->params['admin'])) {
+ $admin = $this->Project->getPrefix();
+ if ($admin) {
+ $this->out(__d('cake_console', 'Adding %s methods', $admin));
+ $actions .= "\n" . $this->bakeActions($controller, $admin);
+ }
+ }
+ if (empty($actions)) {
+ $actions = 'scaffold';
+ }
+
+ if ($this->bake($controller, $actions)) {
+ if ($this->_checkUnitTest()) {
+ $this->bakeTest($controller);
+ }
+ }
+ }
+ }
+
+/**
+ * Bake All the controllers at once. Will only bake controllers for models that exist.
+ *
+ * @return void
+ */
+ public function all() {
+ $this->interactive = false;
+ $this->listAll($this->connection, false);
+ ClassRegistry::config('Model', array('ds' => $this->connection));
+ $unitTestExists = $this->_checkUnitTest();
+ foreach ($this->__tables as $table) {
+ $model = $this->_modelName($table);
+ $controller = $this->_controllerName($model);
+ App::uses($model, 'Model');
+ if (class_exists($model)) {
+ $actions = $this->bakeActions($controller);
+ if ($this->bake($controller, $actions) && $unitTestExists) {
+ $this->bakeTest($controller);
+ }
+ }
+ }
+ }
+
+/**
+ * Interactive
+ *
+ * @return void
+ */
+ protected function _interactive() {
+ $this->interactive = true;
+ $this->hr();
+ $this->out(__d('cake_console', "Bake Controller\nPath: %s", $this->getPath()));
+ $this->hr();
+
+ if (empty($this->connection)) {
+ $this->connection = $this->DbConfig->getConfig();
+ }
+
+ $controllerName = $this->getName();
+ $this->hr();
+ $this->out(__d('cake_console', 'Baking %sController', $controllerName));
+ $this->hr();
+
+ $helpers = $components = array();
+ $actions = '';
+ $wannaUseSession = 'y';
+ $wannaBakeAdminCrud = 'n';
+ $useDynamicScaffold = 'n';
+ $wannaBakeCrud = 'y';
+
+ $question[] = __d('cake_console', "Would you like to build your controller interactively?");
+ if (file_exists($this->path . $controllerName . 'Controller.php')) {
+ $question[] = __d('cake_console', "Warning: Choosing no will overwrite the %sController.", $controllerName);
+ }
+ $doItInteractive = $this->in(implode("\n", $question), array('y', 'n'), 'y');
+
+ if (strtolower($doItInteractive) == 'y') {
+ $this->interactive = true;
+ $useDynamicScaffold = $this->in(
+ __d('cake_console', "Would you like to use dynamic scaffolding?"), array('y', 'n'), 'n'
+ );
+
+ if (strtolower($useDynamicScaffold) == 'y') {
+ $wannaBakeCrud = 'n';
+ $actions = 'scaffold';
+ } else {
+ list($wannaBakeCrud, $wannaBakeAdminCrud) = $this->_askAboutMethods();
+
+ $helpers = $this->doHelpers();
+ $components = $this->doComponents();
+
+ $wannaUseSession = $this->in(
+ __d('cake_console', "Would you like to use Session flash messages?"), array('y','n'), 'y'
+ );
+ }
+ } else {
+ list($wannaBakeCrud, $wannaBakeAdminCrud) = $this->_askAboutMethods();
+ }
+
+ if (strtolower($wannaBakeCrud) == 'y') {
+ $actions = $this->bakeActions($controllerName, null, strtolower($wannaUseSession) == 'y');
+ }
+ if (strtolower($wannaBakeAdminCrud) == 'y') {
+ $admin = $this->Project->getPrefix();
+ $actions .= $this->bakeActions($controllerName, $admin, strtolower($wannaUseSession) == 'y');
+ }
+
+ $baked = false;
+ if ($this->interactive === true) {
+ $this->confirmController($controllerName, $useDynamicScaffold, $helpers, $components);
+ $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y','n'), 'y');
+
+ if (strtolower($looksGood) == 'y') {
+ $baked = $this->bake($controllerName, $actions, $helpers, $components);
+ if ($baked && $this->_checkUnitTest()) {
+ $this->bakeTest($controllerName);
+ }
+ }
+ } else {
+ $baked = $this->bake($controllerName, $actions, $helpers, $components);
+ if ($baked && $this->_checkUnitTest()) {
+ $this->bakeTest($controllerName);
+ }
+ }
+ return $baked;
+ }
+
+/**
+ * Confirm a to be baked controller with the user
+ *
+ * @param string $controllerName
+ * @param string $useDynamicScaffold
+ * @param array $helpers
+ * @param array $components
+ * @return void
+ */
+ public function confirmController($controllerName, $useDynamicScaffold, $helpers, $components) {
+ $this->out();
+ $this->hr();
+ $this->out(__d('cake_console', 'The following controller will be created:'));
+ $this->hr();
+ $this->out(__d('cake_console', "Controller Name:\n\t%s", $controllerName));
+
+ if (strtolower($useDynamicScaffold) == 'y') {
+ $this->out("public \$scaffold;");
+ }
+
+ $properties = array(
+ 'helpers' => __d('cake_console', 'Helpers:'),
+ 'components' => __d('cake_console', 'Components:'),
+ );
+
+ foreach ($properties as $var => $title) {
+ if (count($$var)) {
+ $output = '';
+ $length = count($$var);
+ foreach ($$var as $i => $propElement) {
+ if ($i != $length - 1) {
+ $output .= ucfirst($propElement) . ', ';
+ } else {
+ $output .= ucfirst($propElement);
+ }
+ }
+ $this->out($title . "\n\t" . $output);
+ }
+ }
+ $this->hr();
+ }
+
+/**
+ * Interact with the user and ask about which methods (admin or regular they want to bake)
+ *
+ * @return array Array containing (bakeRegular, bakeAdmin) answers
+ */
+ protected function _askAboutMethods() {
+ $wannaBakeCrud = $this->in(
+ __d('cake_console', "Would you like to create some basic class methods \n(index(), add(), view(), edit())?"),
+ array('y','n'), 'n'
+ );
+ $wannaBakeAdminCrud = $this->in(
+ __d('cake_console', "Would you like to create the basic class methods for admin routing?"),
+ array('y','n'), 'n'
+ );
+ return array($wannaBakeCrud, $wannaBakeAdminCrud);
+ }
+
+/**
+ * Bake scaffold actions
+ *
+ * @param string $controllerName Controller name
+ * @param string $admin Admin route to use
+ * @param boolean $wannaUseSession Set to true to use sessions, false otherwise
+ * @return string Baked actions
+ */
+ public function bakeActions($controllerName, $admin = null, $wannaUseSession = true) {
+ $currentModelName = $modelImport = $this->_modelName($controllerName);
+ $plugin = $this->plugin;
+ if ($plugin) {
+ $plugin .= '.';
+ }
+ App::uses($modelImport, $plugin . 'Model');
+ if (!class_exists($modelImport)) {
+ $this->err(__d('cake_console', 'You must have a model for this class to build basic methods. Please try again.'));
+ $this->_stop();
+ }
+
+ $modelObj = ClassRegistry::init($currentModelName);
+ $controllerPath = $this->_controllerPath($controllerName);
+ $pluralName = $this->_pluralName($currentModelName);
+ $singularName = Inflector::variable($currentModelName);
+ $singularHumanName = $this->_singularHumanName($controllerName);
+ $pluralHumanName = $this->_pluralName($controllerName);
+ $displayField = $modelObj->displayField;
+ $primaryKey = $modelObj->primaryKey;
+
+ $this->Template->set(compact(
+ 'plugin', 'admin', 'controllerPath', 'pluralName', 'singularName',
+ 'singularHumanName', 'pluralHumanName', 'modelObj', 'wannaUseSession', 'currentModelName',
+ 'displayField', 'primaryKey'
+ ));
+ $actions = $this->Template->generate('actions', 'controller_actions');
+ return $actions;
+ }
+
+/**
+ * Assembles and writes a Controller file
+ *
+ * @param string $controllerName Controller name already pluralized and correctly cased.
+ * @param string $actions Actions to add, or set the whole controller to use $scaffold (set $actions to 'scaffold')
+ * @param array $helpers Helpers to use in controller
+ * @param array $components Components to use in controller
+ * @return string Baked controller
+ */
+ public function bake($controllerName, $actions = '', $helpers = null, $components = null) {
+ $this->out("\n" . __d('cake_console', 'Baking controller class for %s...', $controllerName), 1, Shell::QUIET);
+
+ $isScaffold = ($actions === 'scaffold') ? true : false;
+
+ $this->Template->set(array(
+ 'plugin' => $this->plugin,
+ 'pluginPath' => empty($this->plugin) ? '' : $this->plugin . '.'
+ ));
+ $this->Template->set(compact('controllerName', 'actions', 'helpers', 'components', 'isScaffold'));
+ $contents = $this->Template->generate('classes', 'controller');
+
+ $path = $this->getPath();
+ $filename = $path . $controllerName . 'Controller.php';
+ if ($this->createFile($filename, $contents)) {
+ return $contents;
+ }
+ return false;
+ }
+
+/**
+ * Assembles and writes a unit test file
+ *
+ * @param string $className Controller class name
+ * @return string Baked test
+ */
+ public function bakeTest($className) {
+ $this->Test->plugin = $this->plugin;
+ $this->Test->connection = $this->connection;
+ $this->Test->interactive = $this->interactive;
+ return $this->Test->bake('Controller', $className);
+ }
+
+/**
+ * Interact with the user and get a list of additional helpers
+ *
+ * @return array Helpers that the user wants to use.
+ */
+ public function doHelpers() {
+ return $this->_doPropertyChoices(
+ __d('cake_console', "Would you like this controller to use other helpers\nbesides HtmlHelper and FormHelper?"),
+ __d('cake_console', "Please provide a comma separated list of the other\nhelper names you'd like to use.\nExample: 'Ajax, Javascript, Time'")
+ );
+ }
+
+/**
+ * Interact with the user and get a list of additional components
+ *
+ * @return array Components the user wants to use.
+ */
+ public function doComponents() {
+ return $this->_doPropertyChoices(
+ __d('cake_console', "Would you like this controller to use any components?"),
+ __d('cake_console', "Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, Security, RequestHandler'")
+ );
+ }
+
+/**
+ * Common code for property choice handling.
+ *
+ * @param string $prompt A yes/no question to precede the list
+ * @param string $example A question for a comma separated list, with examples.
+ * @return array Array of values for property.
+ */
+ protected function _doPropertyChoices($prompt, $example) {
+ $proceed = $this->in($prompt, array('y','n'), 'n');
+ $property = array();
+ if (strtolower($proceed) == 'y') {
+ $propertyList = $this->in($example);
+ $propertyListTrimmed = str_replace(' ', '', $propertyList);
+ $property = explode(',', $propertyListTrimmed);
+ }
+ return array_filter($property);
+ }
+
+/**
+ * Outputs and gets the list of possible controllers from database
+ *
+ * @param string $useDbConfig Database configuration name
+ * @return array Set of controllers
+ */
+ public function listAll($useDbConfig = null) {
+ if (is_null($useDbConfig)) {
+ $useDbConfig = $this->connection;
+ }
+ $this->__tables = $this->Model->getAllTables($useDbConfig);
+
+ if ($this->interactive == true) {
+ $this->out(__d('cake_console', 'Possible Controllers based on your current database:'));
+ $this->hr();
+ $this->_controllerNames = array();
+ $count = count($this->__tables);
+ for ($i = 0; $i < $count; $i++) {
+ $this->_controllerNames[] = $this->_controllerName($this->_modelName($this->__tables[$i]));
+ $this->out(sprintf("%2d. %s", $i + 1, $this->_controllerNames[$i]));
+ }
+ return $this->_controllerNames;
+ }
+ return $this->__tables;
+ }
+
+/**
+ * Forces the user to specify the controller he wants to bake, and returns the selected controller name.
+ *
+ * @param string $useDbConfig Connection name to get a controller name for.
+ * @return string Controller name
+ */
+ public function getName($useDbConfig = null) {
+ $controllers = $this->listAll($useDbConfig);
+ $enteredController = '';
+
+ while ($enteredController == '') {
+ $enteredController = $this->in(__d('cake_console', "Enter a number from the list above,\ntype in the name of another controller, or 'q' to exit"), null, 'q');
+ if ($enteredController === 'q') {
+ $this->out(__d('cake_console', 'Exit'));
+ return $this->_stop();
+ }
+
+ if ($enteredController == '' || intval($enteredController) > count($controllers)) {
+ $this->err(__d('cake_console', "The Controller name you supplied was empty,\nor the number you selected was not an option. Please try again."));
+ $enteredController = '';
+ }
+ }
+
+ if (intval($enteredController) > 0 && intval($enteredController) <= count($controllers) ) {
+ $controllerName = $controllers[intval($enteredController) - 1];
+ } else {
+ $controllerName = Inflector::camelize($enteredController);
+ }
+ return $controllerName;
+ }
+
+/**
+ * get the option parser.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(
+ __d('cake_console', 'Bake a controller for a model. Using options you can bake public, admin or both.')
+ )->addArgument('name', array(
+ 'help' => __d('cake_console', 'Name of the controller to bake. Can use Plugin.name to bake controllers into plugins.')
+ ))->addOption('public', array(
+ 'help' => __d('cake_console', 'Bake a controller with basic crud actions (index, view, add, edit, delete).'),
+ 'boolean' => true
+ ))->addOption('admin', array(
+ 'help' => __d('cake_console', 'Bake a controller with crud actions for one of the Routing.prefixes.'),
+ 'boolean' => true
+ ))->addOption('plugin', array(
+ 'short' => 'p',
+ 'help' => __d('cake_console', 'Plugin to bake the controller into.')
+ ))->addOption('connection', array(
+ 'short' => 'c',
+ 'help' => __d('cake_console', 'The connection the controller\'s model is on.')
+ ))->addSubcommand('all', array(
+ 'help' => __d('cake_console', 'Bake all controllers with CRUD methods.')
+ ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/DbConfigTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/DbConfigTask.php
new file mode 100644
index 0000000..b9778a5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/DbConfigTask.php
@@ -0,0 +1,384 @@
+<?php
+/**
+ * The DbConfig Task handles creating and updating the database.php
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+
+/**
+ * Task class for creating and updating the database configuration file.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class DbConfigTask extends AppShell {
+
+/**
+ * path to CONFIG directory
+ *
+ * @var string
+ */
+ public $path = null;
+
+/**
+ * Default configuration settings to use
+ *
+ * @var array
+ */
+ protected $_defaultConfig = array(
+ 'name' => 'default',
+ 'datasource' => 'Database/Mysql',
+ 'persistent' => 'false',
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => 'password',
+ 'database' => 'project_name',
+ 'schema' => null,
+ 'prefix' => null,
+ 'encoding' => null,
+ 'port' => null
+ );
+
+/**
+ * String name of the database config class name.
+ * Used for testing.
+ *
+ * @var string
+ */
+ public $databaseClassName = 'DATABASE_CONFIG';
+
+/**
+ * initialization callback
+ *
+ * @return void
+ */
+ public function initialize() {
+ $this->path = APP . 'Config' . DS;
+ }
+
+/**
+ * Execution method always used for tasks
+ *
+ * @return void
+ */
+ public function execute() {
+ if (empty($this->args)) {
+ $this->_interactive();
+ $this->_stop();
+ }
+ }
+
+/**
+ * Interactive interface
+ *
+ * @return void
+ */
+ protected function _interactive() {
+ $this->hr();
+ $this->out(__d('cake_console', 'Database Configuration:'));
+ $this->hr();
+ $done = false;
+ $dbConfigs = array();
+
+ while ($done == false) {
+ $name = '';
+
+ while ($name == '') {
+ $name = $this->in(__d('cake_console', "Name:"), null, 'default');
+ if (preg_match('/[^a-z0-9_]/i', $name)) {
+ $name = '';
+ $this->out(__d('cake_console', 'The name may only contain unaccented latin characters, numbers or underscores'));
+ } elseif (preg_match('/^[^a-z_]/i', $name)) {
+ $name = '';
+ $this->out(__d('cake_console', 'The name must start with an unaccented latin character or an underscore'));
+ }
+ }
+
+ $datasource = $this->in(__d('cake_console', 'Datasource:'), array('Mysql', 'Postgres', 'Sqlite', 'Sqlserver'), 'Mysql');
+
+ $persistent = $this->in(__d('cake_console', 'Persistent Connection?'), array('y', 'n'), 'n');
+ if (strtolower($persistent) == 'n') {
+ $persistent = 'false';
+ } else {
+ $persistent = 'true';
+ }
+
+ $host = '';
+ while ($host == '') {
+ $host = $this->in(__d('cake_console', 'Database Host:'), null, 'localhost');
+ }
+
+ $port = '';
+ while ($port == '') {
+ $port = $this->in(__d('cake_console', 'Port?'), null, 'n');
+ }
+
+ if (strtolower($port) == 'n') {
+ $port = null;
+ }
+
+ $login = '';
+ while ($login == '') {
+ $login = $this->in(__d('cake_console', 'User:'), null, 'root');
+ }
+ $password = '';
+ $blankPassword = false;
+
+ while ($password == '' && $blankPassword == false) {
+ $password = $this->in(__d('cake_console', 'Password:'));
+
+ if ($password == '') {
+ $blank = $this->in(__d('cake_console', 'The password you supplied was empty. Use an empty password?'), array('y', 'n'), 'n');
+ if ($blank == 'y') {
+ $blankPassword = true;
+ }
+ }
+ }
+
+ $database = '';
+ while ($database == '') {
+ $database = $this->in(__d('cake_console', 'Database Name:'), null, 'cake');
+ }
+
+ $prefix = '';
+ while ($prefix == '') {
+ $prefix = $this->in(__d('cake_console', 'Table Prefix?'), null, 'n');
+ }
+ if (strtolower($prefix) == 'n') {
+ $prefix = null;
+ }
+
+ $encoding = '';
+ while ($encoding == '') {
+ $encoding = $this->in(__d('cake_console', 'Table encoding?'), null, 'n');
+ }
+ if (strtolower($encoding) == 'n') {
+ $encoding = null;
+ }
+
+ $schema = '';
+ if ($datasource == 'postgres') {
+ while ($schema == '') {
+ $schema = $this->in(__d('cake_console', 'Table schema?'), null, 'n');
+ }
+ }
+ if (strtolower($schema) == 'n') {
+ $schema = null;
+ }
+
+ $config = compact('name', 'datasource', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema');
+
+ while ($this->_verify($config) == false) {
+ $this->_interactive();
+ }
+
+ $dbConfigs[] = $config;
+ $doneYet = $this->in(__d('cake_console', 'Do you wish to add another database configuration?'), null, 'n');
+
+ if (strtolower($doneYet == 'n')) {
+ $done = true;
+ }
+ }
+
+ $this->bake($dbConfigs);
+ config('database');
+ return true;
+ }
+
+/**
+ * Output verification message and bake if it looks good
+ *
+ * @param array $config
+ * @return boolean True if user says it looks good, false otherwise
+ */
+ protected function _verify($config) {
+ $config = array_merge($this->_defaultConfig, $config);
+ extract($config);
+ $this->out();
+ $this->hr();
+ $this->out(__d('cake_console', 'The following database configuration will be created:'));
+ $this->hr();
+ $this->out(__d('cake_console', "Name: %s", $name));
+ $this->out(__d('cake_console', "Datasource: %s", $datasource));
+ $this->out(__d('cake_console', "Persistent: %s", $persistent));
+ $this->out(__d('cake_console', "Host: %s", $host));
+
+ if ($port) {
+ $this->out(__d('cake_console', "Port: %s", $port));
+ }
+
+ $this->out(__d('cake_console', "User: %s", $login));
+ $this->out(__d('cake_console', "Pass: %s", str_repeat('*', strlen($password))));
+ $this->out(__d('cake_console', "Database: %s", $database));
+
+ if ($prefix) {
+ $this->out(__d('cake_console', "Table prefix: %s", $prefix));
+ }
+
+ if ($schema) {
+ $this->out(__d('cake_console', "Schema: %s", $schema));
+ }
+
+ if ($encoding) {
+ $this->out(__d('cake_console', "Encoding: %s", $encoding));
+ }
+
+ $this->hr();
+ $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y');
+
+ if (strtolower($looksGood) == 'y') {
+ return $config;
+ }
+ return false;
+ }
+
+/**
+ * Assembles and writes database.php
+ *
+ * @param array $configs Configuration settings to use
+ * @return boolean Success
+ */
+ public function bake($configs) {
+ if (!is_dir($this->path)) {
+ $this->err(__d('cake_console', '%s not found', $this->path));
+ return false;
+ }
+
+ $filename = $this->path . 'database.php';
+ $oldConfigs = array();
+
+ if (file_exists($filename)) {
+ config('database');
+ $db = new $this->databaseClassName;
+ $temp = get_class_vars(get_class($db));
+
+ foreach ($temp as $configName => $info) {
+ $info = array_merge($this->_defaultConfig, $info);
+
+ if (!isset($info['schema'])) {
+ $info['schema'] = null;
+ }
+ if (!isset($info['encoding'])) {
+ $info['encoding'] = null;
+ }
+ if (!isset($info['port'])) {
+ $info['port'] = null;
+ }
+
+ if ($info['persistent'] === false) {
+ $info['persistent'] = 'false';
+ } else {
+ $info['persistent'] = ($info['persistent'] == true) ? 'true' : 'false';
+ }
+
+ $oldConfigs[] = array(
+ 'name' => $configName,
+ 'datasource' => $info['datasource'],
+ 'persistent' => $info['persistent'],
+ 'host' => $info['host'],
+ 'port' => $info['port'],
+ 'login' => $info['login'],
+ 'password' => $info['password'],
+ 'database' => $info['database'],
+ 'prefix' => $info['prefix'],
+ 'schema' => $info['schema'],
+ 'encoding' => $info['encoding']
+ );
+ }
+ }
+
+ foreach ($oldConfigs as $key => $oldConfig) {
+ foreach ($configs as $k => $config) {
+ if ($oldConfig['name'] == $config['name']) {
+ unset($oldConfigs[$key]);
+ }
+ }
+ }
+
+ $configs = array_merge($oldConfigs, $configs);
+ $out = "<?php\n";
+ $out .= "class DATABASE_CONFIG {\n\n";
+
+ foreach ($configs as $config) {
+ $config = array_merge($this->_defaultConfig, $config);
+ extract($config);
+
+ $out .= "\tpublic \${$name} = array(\n";
+ $out .= "\t\t'datasource' => 'Database/{$datasource}',\n";
+ $out .= "\t\t'persistent' => {$persistent},\n";
+ $out .= "\t\t'host' => '{$host}',\n";
+
+ if ($port) {
+ $out .= "\t\t'port' => {$port},\n";
+ }
+
+ $out .= "\t\t'login' => '{$login}',\n";
+ $out .= "\t\t'password' => '{$password}',\n";
+ $out .= "\t\t'database' => '{$database}',\n";
+
+ if ($schema) {
+ $out .= "\t\t'schema' => '{$schema}',\n";
+ }
+
+ if ($prefix) {
+ $out .= "\t\t'prefix' => '{$prefix}',\n";
+ }
+
+ if ($encoding) {
+ $out .= "\t\t'encoding' => '{$encoding}'\n";
+ }
+
+ $out .= "\t);\n";
+ }
+
+ $out .= "}\n";
+ $filename = $this->path . 'database.php';
+ return $this->createFile($filename, $out);
+ }
+
+/**
+ * Get a user specified Connection name
+ *
+ * @return void
+ */
+ public function getConfig() {
+ App::uses('ConnectionManager', 'Model');
+ $configs = ConnectionManager::enumConnectionObjects();
+
+ $useDbConfig = key($configs);
+ if (!is_array($configs) || empty($configs)) {
+ return $this->execute();
+ }
+ $connections = array_keys($configs);
+
+ if (count($connections) > 1) {
+ $useDbConfig = $this->in(__d('cake_console', 'Use Database Config') . ':', $connections, $useDbConfig);
+ }
+ return $useDbConfig;
+ }
+
+/**
+ * get the option parser
+ *
+ * @return ConsoleOptionParser
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(
+ __d('cake_console', 'Bake new database configuration settings.')
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ExtractTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ExtractTask.php
new file mode 100644
index 0000000..8d0777b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ExtractTask.php
@@ -0,0 +1,754 @@
+<?php
+/**
+ * Language string extractor
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5012
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('File', 'Utility');
+App::uses('Folder', 'Utility');
+App::uses('Hash', 'Utility');
+
+/**
+ * Language string extractor
+ *
+ * @package Cake.Console.Command.Task
+ */
+class ExtractTask extends AppShell {
+
+/**
+ * Paths to use when looking for strings
+ *
+ * @var string
+ */
+ protected $_paths = array();
+
+/**
+ * Files from where to extract
+ *
+ * @var array
+ */
+ protected $_files = array();
+
+/**
+ * Merge all domains string into the default.pot file
+ *
+ * @var boolean
+ */
+ protected $_merge = false;
+
+/**
+ * Current file being processed
+ *
+ * @var string
+ */
+ protected $_file = null;
+
+/**
+ * Contains all content waiting to be write
+ *
+ * @var string
+ */
+ protected $_storage = array();
+
+/**
+ * Extracted tokens
+ *
+ * @var array
+ */
+ protected $_tokens = array();
+
+/**
+ * Extracted strings indexed by domain.
+ *
+ * @var array
+ */
+ protected $_translations = array();
+
+/**
+ * Destination path
+ *
+ * @var string
+ */
+ protected $_output = null;
+
+/**
+ * An array of directories to exclude.
+ *
+ * @var array
+ */
+ protected $_exclude = array();
+
+/**
+ * Holds whether this call should extract model validation messages
+ *
+ * @var boolean
+ */
+ protected $_extractValidation = true;
+
+/**
+ * Holds the validation string domain to use for validation messages when extracting
+ *
+ * @var boolean
+ */
+ protected $_validationDomain = 'default';
+
+/**
+ * Holds whether this call should extract the CakePHP Lib messages
+ *
+ * @var boolean
+ */
+ protected $_extractCore = false;
+
+/**
+ * Method to interact with the User and get path selections.
+ *
+ * @return void
+ */
+ protected function _getPaths() {
+ $defaultPath = APP;
+ while (true) {
+ $currentPaths = count($this->_paths) > 0 ? $this->_paths : array('None');
+ $message = __d(
+ 'cake_console',
+ "Current paths: %s\nWhat is the path you would like to extract?\n[Q]uit [D]one",
+ implode(', ', $currentPaths)
+ );
+ $response = $this->in($message, null, $defaultPath);
+ if (strtoupper($response) === 'Q') {
+ $this->out(__d('cake_console', 'Extract Aborted'));
+ return $this->_stop();
+ } elseif (strtoupper($response) === 'D' && count($this->_paths)) {
+ $this->out();
+ return;
+ } elseif (strtoupper($response) === 'D') {
+ $this->err(__d('cake_console', '<warning>No directories selected.</warning> Please choose a directory.'));
+ } elseif (is_dir($response)) {
+ $this->_paths[] = $response;
+ $defaultPath = 'D';
+ } else {
+ $this->err(__d('cake_console', 'The directory path you supplied was not found. Please try again.'));
+ }
+ $this->out();
+ }
+ }
+
+/**
+ * Execution method always used for tasks
+ *
+ * @return void
+ */
+ public function execute() {
+ if (!empty($this->params['exclude'])) {
+ $this->_exclude = explode(',', $this->params['exclude']);
+ }
+ if (isset($this->params['files']) && !is_array($this->params['files'])) {
+ $this->_files = explode(',', $this->params['files']);
+ }
+ if (isset($this->params['paths'])) {
+ $this->_paths = explode(',', $this->params['paths']);
+ } elseif (isset($this->params['plugin'])) {
+ $plugin = Inflector::camelize($this->params['plugin']);
+ if (!CakePlugin::loaded($plugin)) {
+ CakePlugin::load($plugin);
+ }
+ $this->_paths = array(CakePlugin::path($plugin));
+ $this->params['plugin'] = $plugin;
+ } else {
+ $this->_getPaths();
+ }
+
+ if (isset($this->params['extract-core'])) {
+ $this->_extractCore = !(strtolower($this->params['extract-core']) === 'no');
+ } else {
+ $response = $this->in(__d('cake_console', 'Would you like to extract the messages from the CakePHP core?'), array('y', 'n'), 'n');
+ $this->_extractCore = strtolower($response) === 'y';
+ }
+
+ if ($this->_extractCore) {
+ $this->_paths[] = CAKE;
+ $this->_exclude = array_merge($this->_exclude, array(
+ CAKE . 'Test',
+ CAKE . 'Console' . DS . 'Templates'
+ ));
+ }
+
+ if (!empty($this->params['exclude-plugins']) && $this->_isExtractingApp()) {
+ $this->_exclude = array_merge($this->_exclude, App::path('plugins'));
+ }
+
+ if (!empty($this->params['ignore-model-validation']) || (!$this->_isExtractingApp() && empty($plugin))) {
+ $this->_extractValidation = false;
+ }
+ if (!empty($this->params['validation-domain'])) {
+ $this->_validationDomain = $this->params['validation-domain'];
+ }
+
+ if (isset($this->params['output'])) {
+ $this->_output = $this->params['output'];
+ } elseif (isset($this->params['plugin'])) {
+ $this->_output = $this->_paths[0] . DS . 'Locale';
+ } else {
+ $message = __d('cake_console', "What is the path you would like to output?\n[Q]uit", $this->_paths[0] . DS . 'Locale');
+ while (true) {
+ $response = $this->in($message, null, rtrim($this->_paths[0], DS) . DS . 'Locale');
+ if (strtoupper($response) === 'Q') {
+ $this->out(__d('cake_console', 'Extract Aborted'));
+ $this->_stop();
+ } elseif (is_dir($response)) {
+ $this->_output = $response . DS;
+ break;
+ } else {
+ $this->err(__d('cake_console', 'The directory path you supplied was not found. Please try again.'));
+ }
+ $this->out();
+ }
+ }
+
+ if (isset($this->params['merge'])) {
+ $this->_merge = !(strtolower($this->params['merge']) === 'no');
+ } else {
+ $this->out();
+ $response = $this->in(__d('cake_console', 'Would you like to merge all domains strings into the default.pot file?'), array('y', 'n'), 'n');
+ $this->_merge = strtolower($response) === 'y';
+ }
+
+ if (empty($this->_files)) {
+ $this->_searchFiles();
+ }
+ $this->_output = rtrim($this->_output, DS) . DS;
+ $this->_extract();
+ }
+
+/**
+ * Add a translation to the internal translations property
+ *
+ * Takes care of duplicate translations
+ *
+ * @param string $domain
+ * @param string $msgid
+ * @param array $details
+ */
+ protected function _addTranslation($domain, $msgid, $details = array()) {
+ if (empty($this->_translations[$domain][$msgid])) {
+ $this->_translations[$domain][$msgid] = array(
+ 'msgid_plural' => false
+ );
+ }
+
+ if (isset($details['msgid_plural'])) {
+ $this->_translations[$domain][$msgid]['msgid_plural'] = $details['msgid_plural'];
+ }
+
+ if (isset($details['file'])) {
+ $line = 0;
+ if (isset($details['line'])) {
+ $line = $details['line'];
+ }
+ $this->_translations[$domain][$msgid]['references'][$details['file']][] = $line;
+ }
+ }
+
+/**
+ * Extract text
+ *
+ * @return void
+ */
+ protected function _extract() {
+ $this->out();
+ $this->out();
+ $this->out(__d('cake_console', 'Extracting...'));
+ $this->hr();
+ $this->out(__d('cake_console', 'Paths:'));
+ foreach ($this->_paths as $path) {
+ $this->out(' ' . $path);
+ }
+ $this->out(__d('cake_console', 'Output Directory: ') . $this->_output);
+ $this->hr();
+ $this->_extractTokens();
+ $this->_extractValidationMessages();
+ $this->_buildFiles();
+ $this->_writeFiles();
+ $this->_paths = $this->_files = $this->_storage = array();
+ $this->_translations = $this->_tokens = array();
+ $this->_extractValidation = true;
+ $this->out();
+ $this->out(__d('cake_console', 'Done.'));
+ }
+
+/**
+ * Get & configure the option parser
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(__d('cake_console', 'CakePHP Language String Extraction:'))
+ ->addOption('app', array('help' => __d('cake_console', 'Directory where your application is located.')))
+ ->addOption('paths', array('help' => __d('cake_console', 'Comma separated list of paths.')))
+ ->addOption('merge', array(
+ 'help' => __d('cake_console', 'Merge all domain strings into the default.po file.'),
+ 'choices' => array('yes', 'no')
+ ))
+ ->addOption('output', array('help' => __d('cake_console', 'Full path to output directory.')))
+ ->addOption('files', array('help' => __d('cake_console', 'Comma separated list of files.')))
+ ->addOption('exclude-plugins', array(
+ 'boolean' => true,
+ 'default' => true,
+ 'help' => __d('cake_console', 'Ignores all files in plugins if this command is run inside from the same app directory.')
+ ))
+ ->addOption('plugin', array(
+ 'help' => __d('cake_console', 'Extracts tokens only from the plugin specified and puts the result in the plugin\'s Locale directory.')
+ ))
+ ->addOption('ignore-model-validation', array(
+ 'boolean' => true,
+ 'default' => false,
+ 'help' => __d('cake_console', 'Ignores validation messages in the $validate property.' .
+ ' If this flag is not set and the command is run from the same app directory,' .
+ ' all messages in model validation rules will be extracted as tokens.')
+ ))
+ ->addOption('validation-domain', array(
+ 'help' => __d('cake_console', 'If set to a value, the localization domain to be used for model validation messages.')
+ ))
+ ->addOption('exclude', array(
+ 'help' => __d('cake_console', 'Comma separated list of directories to exclude.' .
+ ' Any path containing a path segment with the provided values will be skipped. E.g. test,vendors')
+ ))
+ ->addOption('overwrite', array(
+ 'boolean' => true,
+ 'default' => false,
+ 'help' => __d('cake_console', 'Always overwrite existing .pot files.')
+ ))
+ ->addOption('extract-core', array(
+ 'help' => __d('cake_console', 'Extract messages from the CakePHP core libs.'),
+ 'choices' => array('yes', 'no')
+ ));
+ }
+
+/**
+ * Extract tokens out of all files to be processed
+ *
+ * @return void
+ */
+ protected function _extractTokens() {
+ foreach ($this->_files as $file) {
+ $this->_file = $file;
+ $this->out(__d('cake_console', 'Processing %s...', $file));
+
+ $code = file_get_contents($file);
+ $allTokens = token_get_all($code);
+
+ $this->_tokens = array();
+ foreach ($allTokens as $token) {
+ if (!is_array($token) || ($token[0] != T_WHITESPACE && $token[0] != T_INLINE_HTML)) {
+ $this->_tokens[] = $token;
+ }
+ }
+ unset($allTokens);
+ $this->_parse('__', array('singular'));
+ $this->_parse('__n', array('singular', 'plural'));
+ $this->_parse('__d', array('domain', 'singular'));
+ $this->_parse('__c', array('singular'));
+ $this->_parse('__dc', array('domain', 'singular'));
+ $this->_parse('__dn', array('domain', 'singular', 'plural'));
+ $this->_parse('__dcn', array('domain', 'singular', 'plural'));
+ }
+ }
+
+/**
+ * Parse tokens
+ *
+ * @param string $functionName Function name that indicates translatable string (e.g: '__')
+ * @param array $map Array containing what variables it will find (e.g: domain, singular, plural)
+ * @return void
+ */
+ protected function _parse($functionName, $map) {
+ $count = 0;
+ $tokenCount = count($this->_tokens);
+
+ while (($tokenCount - $count) > 1) {
+ $countToken = $this->_tokens[$count];
+ $firstParenthesis = $this->_tokens[$count + 1];
+ if (!is_array($countToken)) {
+ $count++;
+ continue;
+ }
+
+ list($type, $string, $line) = $countToken;
+ if (($type == T_STRING) && ($string == $functionName) && ($firstParenthesis == '(')) {
+ $position = $count;
+ $depth = 0;
+
+ while ($depth == 0) {
+ if ($this->_tokens[$position] == '(') {
+ $depth++;
+ } elseif ($this->_tokens[$position] == ')') {
+ $depth--;
+ }
+ $position++;
+ }
+
+ $mapCount = count($map);
+ $strings = $this->_getStrings($position, $mapCount);
+
+ if ($mapCount == count($strings)) {
+ extract(array_combine($map, $strings));
+ $domain = isset($domain) ? $domain : 'default';
+ $details = array(
+ 'file' => $this->_file,
+ 'line' => $line,
+ );
+ if (isset($plural)) {
+ $details['msgid_plural'] = $plural;
+ }
+ $this->_addTranslation($domain, $singular, $details);
+ } else {
+ $this->_markerError($this->_file, $line, $functionName, $count);
+ }
+ }
+ $count++;
+ }
+ }
+
+/**
+ * Looks for models in the application and extracts the validation messages
+ * to be added to the translation map
+ *
+ * @return void
+ */
+ protected function _extractValidationMessages() {
+ if (!$this->_extractValidation) {
+ return;
+ }
+
+ App::uses('AppModel', 'Model');
+ $plugin = null;
+ if (!empty($this->params['plugin'])) {
+ App::uses($this->params['plugin'] . 'AppModel', $this->params['plugin'] . '.Model');
+ $plugin = $this->params['plugin'] . '.';
+ }
+ $models = App::objects($plugin . 'Model', null, false);
+
+ foreach ($models as $model) {
+ App::uses($model, $plugin . 'Model');
+ $reflection = new ReflectionClass($model);
+ if (!$reflection->isSubClassOf('Model')) {
+ continue;
+ }
+ $properties = $reflection->getDefaultProperties();
+ $validate = $properties['validate'];
+ if (empty($validate)) {
+ continue;
+ }
+
+ $file = $reflection->getFileName();
+ $domain = $this->_validationDomain;
+ if (!empty($properties['validationDomain'])) {
+ $domain = $properties['validationDomain'];
+ }
+ foreach ($validate as $field => $rules) {
+ $this->_processValidationRules($field, $rules, $file, $domain);
+ }
+ }
+ }
+
+/**
+ * Process a validation rule for a field and looks for a message to be added
+ * to the translation map
+ *
+ * @param string $field the name of the field that is being processed
+ * @param array $rules the set of validation rules for the field
+ * @param string $file the file name where this validation rule was found
+ * @param string $domain default domain to bind the validations to
+ * @return void
+ */
+ protected function _processValidationRules($field, $rules, $file, $domain) {
+ if (!is_array($rules)) {
+ return;
+ }
+
+ $dims = Hash::dimensions($rules);
+ if ($dims == 1 || ($dims == 2 && isset($rules['message']))) {
+ $rules = array($rules);
+ }
+
+ foreach ($rules as $rule => $validateProp) {
+ $msgid = null;
+ if (isset($validateProp['message'])) {
+ if (is_array($validateProp['message'])) {
+ $msgid = $validateProp['message'][0];
+ } else {
+ $msgid = $validateProp['message'];
+ }
+ } elseif (is_string($rule)) {
+ $msgid = $rule;
+ }
+ if ($msgid) {
+ $details = array(
+ 'file' => $file,
+ 'line' => 'validation for field ' . $field
+ );
+ $this->_addTranslation($domain, $msgid, $details);
+ }
+ }
+ }
+
+/**
+ * Build the translate template file contents out of obtained strings
+ *
+ * @return void
+ */
+ protected function _buildFiles() {
+ $paths = $this->_paths;
+ $paths[] = realpath(APP) . DS;
+ foreach ($this->_translations as $domain => $translations) {
+ foreach ($translations as $msgid => $details) {
+ $plural = $details['msgid_plural'];
+ $files = $details['references'];
+ $occurrences = array();
+ foreach ($files as $file => $lines) {
+ $lines = array_unique($lines);
+ $occurrences[] = $file . ':' . implode(';', $lines);
+ }
+ $occurrences = implode("\n#: ", $occurrences);
+ $header = '#: ' . str_replace($paths, '', $occurrences) . "\n";
+
+ if ($plural === false) {
+ $sentence = "msgid \"{$msgid}\"\n";
+ $sentence .= "msgstr \"\"\n\n";
+ } else {
+ $sentence = "msgid \"{$msgid}\"\n";
+ $sentence .= "msgid_plural \"{$plural}\"\n";
+ $sentence .= "msgstr[0] \"\"\n";
+ $sentence .= "msgstr[1] \"\"\n\n";
+ }
+
+ $this->_store($domain, $header, $sentence);
+ if ($domain != 'default' && $this->_merge) {
+ $this->_store('default', $header, $sentence);
+ }
+ }
+ }
+ }
+
+/**
+ * Prepare a file to be stored
+ *
+ * @param string $domain
+ * @param string $header
+ * @param string $sentence
+ * @return void
+ */
+ protected function _store($domain, $header, $sentence) {
+ if (!isset($this->_storage[$domain])) {
+ $this->_storage[$domain] = array();
+ }
+ if (!isset($this->_storage[$domain][$sentence])) {
+ $this->_storage[$domain][$sentence] = $header;
+ } else {
+ $this->_storage[$domain][$sentence] .= $header;
+ }
+ }
+
+/**
+ * Write the files that need to be stored
+ *
+ * @return void
+ */
+ protected function _writeFiles() {
+ $overwriteAll = false;
+ if (!empty($this->params['overwrite'])) {
+ $overwriteAll = true;
+ }
+
+ foreach ($this->_storage as $domain => $sentences) {
+ $output = $this->_writeHeader();
+ foreach ($sentences as $sentence => $header) {
+ $output .= $header . $sentence;
+ }
+
+ $filename = $domain . '.pot';
+ $File = new File($this->_output . $filename);
+ $response = '';
+ while ($overwriteAll === false && $File->exists() && strtoupper($response) !== 'Y') {
+ $this->out();
+ $response = $this->in(
+ __d('cake_console', 'Error: %s already exists in this location. Overwrite? [Y]es, [N]o, [A]ll', $filename),
+ array('y', 'n', 'a'),
+ 'y'
+ );
+ if (strtoupper($response) === 'N') {
+ $response = '';
+ while ($response == '') {
+ $response = $this->in(__d('cake_console', "What would you like to name this file?"), null, 'new_' . $filename);
+ $File = new File($this->_output . $response);
+ $filename = $response;
+ }
+ } elseif (strtoupper($response) === 'A') {
+ $overwriteAll = true;
+ }
+ }
+ $File->write($output);
+ $File->close();
+ }
+ }
+
+/**
+ * Build the translation template header
+ *
+ * @return string Translation template header
+ */
+ protected function _writeHeader() {
+ $output = "# LANGUAGE translation of CakePHP Application\n";
+ $output .= "# Copyright YEAR NAME <EMAIL@ADDRESS>\n";
+ $output .= "#\n";
+ $output .= "#, fuzzy\n";
+ $output .= "msgid \"\"\n";
+ $output .= "msgstr \"\"\n";
+ $output .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
+ $output .= "\"POT-Creation-Date: " . date("Y-m-d H:iO") . "\\n\"\n";
+ $output .= "\"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\\n\"\n";
+ $output .= "\"Last-Translator: NAME <EMAIL@ADDRESS>\\n\"\n";
+ $output .= "\"Language-Team: LANGUAGE <EMAIL@ADDRESS>\\n\"\n";
+ $output .= "\"MIME-Version: 1.0\\n\"\n";
+ $output .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
+ $output .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
+ $output .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n\n";
+ return $output;
+ }
+
+/**
+ * Get the strings from the position forward
+ *
+ * @param integer $position Actual position on tokens array
+ * @param integer $target Number of strings to extract
+ * @return array Strings extracted
+ */
+ protected function _getStrings(&$position, $target) {
+ $strings = array();
+ $count = count($strings);
+ while ($count < $target && ($this->_tokens[$position] == ',' || $this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING)) {
+ $count = count($strings);
+ if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING && $this->_tokens[$position + 1] == '.') {
+ $string = '';
+ while ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING || $this->_tokens[$position] == '.') {
+ if ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) {
+ $string .= $this->_formatString($this->_tokens[$position][1]);
+ }
+ $position++;
+ }
+ $strings[] = $string;
+ } elseif ($this->_tokens[$position][0] == T_CONSTANT_ENCAPSED_STRING) {
+ $strings[] = $this->_formatString($this->_tokens[$position][1]);
+ }
+ $position++;
+ }
+ return $strings;
+ }
+
+/**
+ * Format a string to be added as a translatable string
+ *
+ * @param string $string String to format
+ * @return string Formatted string
+ */
+ protected function _formatString($string) {
+ $quote = substr($string, 0, 1);
+ $string = substr($string, 1, -1);
+ if ($quote == '"') {
+ $string = stripcslashes($string);
+ } else {
+ $string = strtr($string, array("\\'" => "'", "\\\\" => "\\"));
+ }
+ $string = str_replace("\r\n", "\n", $string);
+ return addcslashes($string, "\0..\37\\\"");
+ }
+
+/**
+ * Indicate an invalid marker on a processed file
+ *
+ * @param string $file File where invalid marker resides
+ * @param integer $line Line number
+ * @param string $marker Marker found
+ * @param integer $count Count
+ * @return void
+ */
+ protected function _markerError($file, $line, $marker, $count) {
+ $this->out(__d('cake_console', "Invalid marker content in %s:%s\n* %s(", $file, $line, $marker), true);
+ $count += 2;
+ $tokenCount = count($this->_tokens);
+ $parenthesis = 1;
+
+ while ((($tokenCount - $count) > 0) && $parenthesis) {
+ if (is_array($this->_tokens[$count])) {
+ $this->out($this->_tokens[$count][1], false);
+ } else {
+ $this->out($this->_tokens[$count], false);
+ if ($this->_tokens[$count] == '(') {
+ $parenthesis++;
+ }
+
+ if ($this->_tokens[$count] == ')') {
+ $parenthesis--;
+ }
+ }
+ $count++;
+ }
+ $this->out("\n", true);
+ }
+
+/**
+ * Search files that may contain translatable strings
+ *
+ * @return void
+ */
+ protected function _searchFiles() {
+ $pattern = false;
+ if (!empty($this->_exclude)) {
+ $exclude = array();
+ foreach ($this->_exclude as $e) {
+ if (DS !== '\\' && $e[0] !== DS) {
+ $e = DS . $e;
+ }
+ $exclude[] = preg_quote($e, '/');
+ }
+ $pattern = '/' . implode('|', $exclude) . '/';
+ }
+ foreach ($this->_paths as $path) {
+ $Folder = new Folder($path);
+ $files = $Folder->findRecursive('.*\.(php|ctp|thtml|inc|tpl)', true);
+ if (!empty($pattern)) {
+ foreach ($files as $i => $file) {
+ if (preg_match($pattern, $file)) {
+ unset($files[$i]);
+ }
+ }
+ $files = array_values($files);
+ }
+ $this->_files = array_merge($this->_files, $files);
+ }
+ }
+
+/**
+ * Returns whether this execution is meant to extract string only from directories in folder represented by the
+ * APP constant, i.e. this task is extracting strings from same application.
+ *
+ * @return boolean
+ */
+ protected function _isExtractingApp() {
+ return $this->_paths === array(APP);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/FixtureTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/FixtureTask.php
new file mode 100644
index 0000000..92e5154
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/FixtureTask.php
@@ -0,0 +1,421 @@
+<?php
+/**
+ * The FixtureTask handles creating and updating fixture files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('BakeTask', 'Console/Command/Task');
+App::uses('Model', 'Model');
+
+/**
+ * Task class for creating and updating fixtures files.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class FixtureTask extends BakeTask {
+
+/**
+ * Tasks to be loaded by this Task
+ *
+ * @var array
+ */
+ public $tasks = array('DbConfig', 'Model', 'Template');
+
+/**
+ * path to fixtures directory
+ *
+ * @var string
+ */
+ public $path = null;
+
+/**
+ * Schema instance
+ *
+ * @var CakeSchema
+ */
+ protected $_Schema = null;
+
+/**
+ * Override initialize
+ *
+ * @param ConsoleOutput $stdout A ConsoleOutput object for stdout.
+ * @param ConsoleOutput $stderr A ConsoleOutput object for stderr.
+ * @param ConsoleInput $stdin A ConsoleInput object for stdin.
+ */
+ public function __construct($stdout = null, $stderr = null, $stdin = null) {
+ parent::__construct($stdout, $stderr, $stdin);
+ $this->path = APP . 'Test' . DS . 'Fixture' . DS;
+ }
+
+/**
+ * get the option parser.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(
+ __d('cake_console', 'Generate fixtures for use with the test suite. You can use `bake fixture all` to bake all fixtures.')
+ )->addArgument('name', array(
+ 'help' => __d('cake_console', 'Name of the fixture to bake. Can use Plugin.name to bake plugin fixtures.')
+ ))->addOption('count', array(
+ 'help' => __d('cake_console', 'When using generated data, the number of records to include in the fixture(s).'),
+ 'short' => 'n',
+ 'default' => 10
+ ))->addOption('connection', array(
+ 'help' => __d('cake_console', 'Which database configuration to use for baking.'),
+ 'short' => 'c',
+ 'default' => 'default'
+ ))->addOption('plugin', array(
+ 'help' => __d('cake_console', 'CamelCased name of the plugin to bake fixtures for.'),
+ 'short' => 'p',
+ ))->addOption('records', array(
+ 'help' => __d('cake_console', 'Used with --count and <name>/all commands to pull [n] records from the live tables, where [n] is either --count or the default of 10'),
+ 'short' => 'r',
+ 'boolean' => true
+ ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
+ }
+
+/**
+ * Execution method always used for tasks
+ * Handles dispatching to interactive, named, or all processes.
+ *
+ * @return void
+ */
+ public function execute() {
+ parent::execute();
+ if (empty($this->args)) {
+ $this->_interactive();
+ }
+
+ if (isset($this->args[0])) {
+ $this->interactive = false;
+ if (!isset($this->connection)) {
+ $this->connection = 'default';
+ }
+ if (strtolower($this->args[0]) == 'all') {
+ return $this->all();
+ }
+ $model = $this->_modelName($this->args[0]);
+ $this->bake($model);
+ }
+ }
+
+/**
+ * Bake All the Fixtures at once. Will only bake fixtures for models that exist.
+ *
+ * @return void
+ */
+ public function all() {
+ $this->interactive = false;
+ $this->Model->interactive = false;
+ $tables = $this->Model->listAll($this->connection, false);
+ foreach ($tables as $table) {
+ $model = $this->_modelName($table);
+ $this->bake($model);
+ }
+ }
+
+/**
+ * Interactive baking function
+ *
+ * @return void
+ */
+ protected function _interactive() {
+ $this->DbConfig->interactive = $this->Model->interactive = $this->interactive = true;
+ $this->hr();
+ $this->out(__d('cake_console', "Bake Fixture\nPath: %s", $this->getPath()));
+ $this->hr();
+
+ if (!isset($this->connection)) {
+ $this->connection = $this->DbConfig->getConfig();
+ }
+ $modelName = $this->Model->getName($this->connection);
+ $useTable = $this->Model->getTable($modelName, $this->connection);
+ $importOptions = $this->importOptions($modelName);
+ $this->bake($modelName, $useTable, $importOptions);
+ }
+
+/**
+ * Interacts with the User to setup an array of import options. For a fixture.
+ *
+ * @param string $modelName Name of model you are dealing with.
+ * @return array Array of import options.
+ */
+ public function importOptions($modelName) {
+ $options = array();
+ $doSchema = $this->in(__d('cake_console', 'Would you like to import schema for this fixture?'), array('y', 'n'), 'n');
+ if ($doSchema == 'y') {
+ $options['schema'] = $modelName;
+ }
+ $doRecords = $this->in(__d('cake_console', 'Would you like to use record importing for this fixture?'), array('y', 'n'), 'n');
+ if ($doRecords == 'y') {
+ $options['records'] = true;
+ }
+ if ($doRecords == 'n') {
+ $prompt = __d('cake_console', "Would you like to build this fixture with data from %s's table?", $modelName);
+ $fromTable = $this->in($prompt, array('y', 'n'), 'n');
+ if (strtolower($fromTable) == 'y') {
+ $options['fromTable'] = true;
+ }
+ }
+ return $options;
+ }
+
+/**
+ * Assembles and writes a Fixture file
+ *
+ * @param string $model Name of model to bake.
+ * @param string $useTable Name of table to use.
+ * @param array $importOptions Options for public $import
+ * @return string Baked fixture content
+ */
+ public function bake($model, $useTable = false, $importOptions = array()) {
+ App::uses('CakeSchema', 'Model');
+ $table = $schema = $records = $import = $modelImport = null;
+ $importBits = array();
+
+ if (!$useTable) {
+ $useTable = Inflector::tableize($model);
+ } elseif ($useTable != Inflector::tableize($model)) {
+ $table = $useTable;
+ }
+
+ if (!empty($importOptions)) {
+ if (isset($importOptions['schema'])) {
+ $modelImport = true;
+ $importBits[] = "'model' => '{$importOptions['schema']}'";
+ }
+ if (isset($importOptions['records'])) {
+ $importBits[] = "'records' => true";
+ }
+ if ($this->connection != 'default') {
+ $importBits[] .= "'connection' => '{$this->connection}'";
+ }
+ if (!empty($importBits)) {
+ $import = sprintf("array(%s)", implode(', ', $importBits));
+ }
+ }
+
+ $this->_Schema = new CakeSchema();
+ $data = $this->_Schema->read(array('models' => false, 'connection' => $this->connection));
+ if (!isset($data['tables'][$useTable])) {
+ $this->err('Could not find your selected table ' . $useTable);
+ return false;
+ }
+
+ $tableInfo = $data['tables'][$useTable];
+ if (is_null($modelImport)) {
+ $schema = $this->_generateSchema($tableInfo);
+ }
+
+ if (empty($importOptions['records']) && !isset($importOptions['fromTable'])) {
+ $recordCount = 1;
+ if (isset($this->params['count'])) {
+ $recordCount = $this->params['count'];
+ }
+ $records = $this->_makeRecordString($this->_generateRecords($tableInfo, $recordCount));
+ }
+ if (!empty($this->params['records']) || isset($importOptions['fromTable'])) {
+ $records = $this->_makeRecordString($this->_getRecordsFromTable($model, $useTable));
+ }
+ $out = $this->generateFixtureFile($model, compact('records', 'table', 'schema', 'import', 'fields'));
+ return $out;
+ }
+
+/**
+ * Generate the fixture file, and write to disk
+ *
+ * @param string $model name of the model being generated
+ * @param string $otherVars Contents of the fixture file.
+ * @return string Content saved into fixture file.
+ */
+ public function generateFixtureFile($model, $otherVars) {
+ $defaults = array('table' => null, 'schema' => null, 'records' => null, 'import' => null, 'fields' => null);
+ $vars = array_merge($defaults, $otherVars);
+
+ $path = $this->getPath();
+ $filename = Inflector::camelize($model) . 'Fixture.php';
+
+ $this->Template->set('model', $model);
+ $this->Template->set($vars);
+ $content = $this->Template->generate('classes', 'fixture');
+
+ $this->out("\n" . __d('cake_console', 'Baking test fixture for %s...', $model), 1, Shell::QUIET);
+ $this->createFile($path . $filename, $content);
+ return $content;
+ }
+
+/**
+ * Get the path to the fixtures.
+ *
+ * @return string Path for the fixtures
+ */
+ public function getPath() {
+ $path = $this->path;
+ if (isset($this->plugin)) {
+ $path = $this->_pluginPath($this->plugin) . 'Test' . DS . 'Fixture' . DS;
+ }
+ return $path;
+ }
+
+/**
+ * Generates a string representation of a schema.
+ *
+ * @param array $tableInfo Table schema array
+ * @return string fields definitions
+ */
+ protected function _generateSchema($tableInfo) {
+ $schema = $this->_Schema->generateTable('f', $tableInfo);
+ return substr($schema, 13, -2);
+ }
+
+/**
+ * Generate String representation of Records
+ *
+ * @param array $tableInfo Table schema array
+ * @param integer $recordCount
+ * @return array Array of records to use in the fixture.
+ */
+ protected function _generateRecords($tableInfo, $recordCount = 1) {
+ $records = array();
+ for ($i = 0; $i < $recordCount; $i++) {
+ $record = array();
+ foreach ($tableInfo as $field => $fieldInfo) {
+ if (empty($fieldInfo['type'])) {
+ continue;
+ }
+ switch ($fieldInfo['type']) {
+ case 'integer':
+ case 'float':
+ $insert = $i + 1;
+ break;
+ case 'string':
+ case 'binary':
+ $isPrimaryUuid = (
+ isset($fieldInfo['key']) && strtolower($fieldInfo['key']) == 'primary' &&
+ isset($fieldInfo['length']) && $fieldInfo['length'] == 36
+ );
+ if ($isPrimaryUuid) {
+ $insert = String::uuid();
+ } else {
+ $insert = "Lorem ipsum dolor sit amet";
+ if (!empty($fieldInfo['length'])) {
+ $insert = substr($insert, 0, (int)$fieldInfo['length'] - 2);
+ }
+ }
+ break;
+ case 'timestamp':
+ $insert = time();
+ break;
+ case 'datetime':
+ $insert = date('Y-m-d H:i:s');
+ break;
+ case 'date':
+ $insert = date('Y-m-d');
+ break;
+ case 'time':
+ $insert = date('H:i:s');
+ break;
+ case 'boolean':
+ $insert = 1;
+ break;
+ case 'text':
+ $insert = "Lorem ipsum dolor sit amet, aliquet feugiat.";
+ $insert .= " Convallis morbi fringilla gravida,";
+ $insert .= " phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin";
+ $insert .= " venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla";
+ $insert .= " vestibulum massa neque ut et, id hendrerit sit,";
+ $insert .= " feugiat in taciti enim proin nibh, tempor dignissim, rhoncus";
+ $insert .= " duis vestibulum nunc mattis convallis.";
+ break;
+ }
+ $record[$field] = $insert;
+ }
+ $records[] = $record;
+ }
+ return $records;
+ }
+
+/**
+ * Convert a $records array into a a string.
+ *
+ * @param array $records Array of records to be converted to string
+ * @return string A string value of the $records array.
+ */
+ protected function _makeRecordString($records) {
+ $out = "array(\n";
+ foreach ($records as $record) {
+ $values = array();
+ foreach ($record as $field => $value) {
+ $val = var_export($value, true);
+ if ($val === 'NULL') {
+ $val = 'null';
+ }
+ $values[] = "\t\t\t'$field' => $val";
+ }
+ $out .= "\t\tarray(\n";
+ $out .= implode(",\n", $values);
+ $out .= "\n\t\t),\n";
+ }
+ $out .= "\t)";
+ return $out;
+ }
+
+/**
+ * Interact with the user to get a custom SQL condition and use that to extract data
+ * to build a fixture.
+ *
+ * @param string $modelName name of the model to take records from.
+ * @param string $useTable Name of table to use.
+ * @return array Array of records.
+ */
+ protected function _getRecordsFromTable($modelName, $useTable = null) {
+ if ($this->interactive) {
+ $condition = null;
+ $prompt = __d('cake_console', "Please provide a SQL fragment to use as conditions\nExample: WHERE 1=1");
+ while (!$condition) {
+ $condition = $this->in($prompt, null, 'WHERE 1=1');
+ }
+ $prompt = __d('cake_console', "How many records do you want to import?");
+ $recordCount = $this->in($prompt, null, 10);
+ } else {
+ $condition = 'WHERE 1=1';
+ $recordCount = (isset($this->params['count']) ? $this->params['count'] : 10);
+ }
+ $modelObject = new Model(array('name' => $modelName, 'table' => $useTable, 'ds' => $this->connection));
+ $records = $modelObject->find('all', array(
+ 'conditions' => $condition,
+ 'recursive' => -1,
+ 'limit' => $recordCount
+ ));
+ $db = $modelObject->getDatasource();
+ $schema = $modelObject->schema(true);
+ $out = array();
+ foreach ($records as $record) {
+ $row = array();
+ foreach ($record[$modelObject->alias] as $field => $value) {
+ if ($schema[$field]['type'] === 'boolean') {
+ $value = (int)(bool)$value;
+ }
+ $row[$field] = $value;
+ }
+ $out[] = $row;
+ }
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ModelTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ModelTask.php
new file mode 100644
index 0000000..b308454
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ModelTask.php
@@ -0,0 +1,996 @@
+<?php
+/**
+ * The ModelTask handles creating and updating models files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('BakeTask', 'Console/Command/Task');
+App::uses('ConnectionManager', 'Model');
+App::uses('Model', 'Model');
+App::uses('Validation', 'Utility');
+
+/**
+ * Task class for creating and updating model files.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class ModelTask extends BakeTask {
+
+/**
+ * path to Model directory
+ *
+ * @var string
+ */
+ public $path = null;
+
+/**
+ * tasks
+ *
+ * @var array
+ */
+ public $tasks = array('DbConfig', 'Fixture', 'Test', 'Template');
+
+/**
+ * Tables to skip when running all()
+ *
+ * @var array
+ */
+ public $skipTables = array('i18n');
+
+/**
+ * Holds tables found on connection.
+ *
+ * @var array
+ */
+ protected $_tables = array();
+
+/**
+ * Holds the model names
+ *
+ * @var array
+ */
+ protected $_modelNames = array();
+
+/**
+ * Holds validation method map.
+ *
+ * @var array
+ */
+ protected $_validations = array();
+
+/**
+ * Override initialize
+ *
+ * @return void
+ */
+ public function initialize() {
+ $this->path = current(App::path('Model'));
+ }
+
+/**
+ * Execution method always used for tasks
+ *
+ * @return void
+ */
+ public function execute() {
+ parent::execute();
+
+ if (empty($this->args)) {
+ $this->_interactive();
+ }
+
+ if (!empty($this->args[0])) {
+ $this->interactive = false;
+ if (!isset($this->connection)) {
+ $this->connection = 'default';
+ }
+ if (strtolower($this->args[0]) == 'all') {
+ return $this->all();
+ }
+ $model = $this->_modelName($this->args[0]);
+ $this->listAll($this->connection);
+ $useTable = $this->getTable($model);
+ $object = $this->_getModelObject($model, $useTable);
+ if ($this->bake($object, false)) {
+ if ($this->_checkUnitTest()) {
+ $this->bakeFixture($model, $useTable);
+ $this->bakeTest($model);
+ }
+ }
+ }
+ }
+
+/**
+ * Bake all models at once.
+ *
+ * @return void
+ */
+ public function all() {
+ $this->listAll($this->connection, false);
+ $unitTestExists = $this->_checkUnitTest();
+ foreach ($this->_tables as $table) {
+ if (in_array($table, $this->skipTables)) {
+ continue;
+ }
+ $modelClass = Inflector::classify($table);
+ $this->out(__d('cake_console', 'Baking %s', $modelClass));
+ $object = $this->_getModelObject($modelClass, $table);
+ if ($this->bake($object, false) && $unitTestExists) {
+ $this->bakeFixture($modelClass, $table);
+ $this->bakeTest($modelClass);
+ }
+ }
+ }
+
+/**
+ * Get a model object for a class name.
+ *
+ * @param string $className Name of class you want model to be.
+ * @param string $table Table name
+ * @return Model Model instance
+ */
+ protected function _getModelObject($className, $table = null) {
+ if (!$table) {
+ $table = Inflector::tableize($className);
+ }
+ $object = new Model(array('name' => $className, 'table' => $table, 'ds' => $this->connection));
+ $fields = $object->schema(true);
+ foreach ($fields as $name => $field) {
+ if (isset($field['key']) && $field['key'] == 'primary') {
+ $object->primaryKey = $name;
+ break;
+ }
+ }
+ return $object;
+ }
+
+/**
+ * Generate a key value list of options and a prompt.
+ *
+ * @param array $options Array of options to use for the selections. indexes must start at 0
+ * @param string $prompt Prompt to use for options list.
+ * @param integer $default The default option for the given prompt.
+ * @return integer result of user choice.
+ */
+ public function inOptions($options, $prompt = null, $default = null) {
+ $valid = false;
+ $max = count($options);
+ while (!$valid) {
+ $len = strlen(count($options) + 1);
+ foreach ($options as $i => $option) {
+ $this->out(sprintf("%${len}d. %s", $i + 1, $option));
+ }
+ if (empty($prompt)) {
+ $prompt = __d('cake_console', 'Make a selection from the choices above');
+ }
+ $choice = $this->in($prompt, null, $default);
+ if (intval($choice) > 0 && intval($choice) <= $max) {
+ $valid = true;
+ }
+ }
+ return $choice - 1;
+ }
+
+/**
+ * Handles interactive baking
+ *
+ * @return boolean
+ */
+ protected function _interactive() {
+ $this->hr();
+ $this->out(__d('cake_console', "Bake Model\nPath: %s", $this->getPath()));
+ $this->hr();
+ $this->interactive = true;
+
+ $primaryKey = 'id';
+ $validate = $associations = array();
+
+ if (empty($this->connection)) {
+ $this->connection = $this->DbConfig->getConfig();
+ }
+ $currentModelName = $this->getName();
+ $useTable = $this->getTable($currentModelName);
+ $db = ConnectionManager::getDataSource($this->connection);
+ $fullTableName = $db->fullTableName($useTable);
+ if (!in_array($useTable, $this->_tables)) {
+ $prompt = __d('cake_console', "The table %s doesn't exist or could not be automatically detected\ncontinue anyway?", $useTable);
+ $continue = $this->in($prompt, array('y', 'n'));
+ if (strtolower($continue) == 'n') {
+ return false;
+ }
+ }
+
+ $tempModel = new Model(array('name' => $currentModelName, 'table' => $useTable, 'ds' => $this->connection));
+
+ $knownToExist = false;
+ try {
+ $fields = $tempModel->schema(true);
+ $knownToExist = true;
+ } catch (Exception $e) {
+ $fields = array($tempModel->primaryKey);
+ }
+ if (!array_key_exists('id', $fields)) {
+ $primaryKey = $this->findPrimaryKey($fields);
+ }
+
+ if ($knownToExist) {
+ $displayField = $tempModel->hasField(array('name', 'title'));
+ if (!$displayField) {
+ $displayField = $this->findDisplayField($tempModel->schema());
+ }
+
+ $prompt = __d('cake_console', "Would you like to supply validation criteria \nfor the fields in your model?");
+ $wannaDoValidation = $this->in($prompt, array('y','n'), 'y');
+ if (array_search($useTable, $this->_tables) !== false && strtolower($wannaDoValidation) == 'y') {
+ $validate = $this->doValidation($tempModel);
+ }
+
+ $prompt = __d('cake_console', "Would you like to define model associations\n(hasMany, hasOne, belongsTo, etc.)?");
+ $wannaDoAssoc = $this->in($prompt, array('y','n'), 'y');
+ if (strtolower($wannaDoAssoc) == 'y') {
+ $associations = $this->doAssociations($tempModel);
+ }
+ }
+
+ $this->out();
+ $this->hr();
+ $this->out(__d('cake_console', 'The following Model will be created:'));
+ $this->hr();
+ $this->out(__d('cake_console', "Name: %s", $currentModelName));
+
+ if ($this->connection !== 'default') {
+ $this->out(__d('cake_console', "DB Config: %s", $this->connection));
+ }
+ if ($fullTableName !== Inflector::tableize($currentModelName)) {
+ $this->out(__d('cake_console', 'DB Table: %s', $fullTableName));
+ }
+ if ($primaryKey != 'id') {
+ $this->out(__d('cake_console', 'Primary Key: %s', $primaryKey));
+ }
+ if (!empty($validate)) {
+ $this->out(__d('cake_console', 'Validation: %s', print_r($validate, true)));
+ }
+ if (!empty($associations)) {
+ $this->out(__d('cake_console', 'Associations:'));
+ $assocKeys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+ foreach ($assocKeys as $assocKey) {
+ $this->_printAssociation($currentModelName, $assocKey, $associations);
+ }
+ }
+
+ $this->hr();
+ $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y');
+
+ if (strtolower($looksGood) == 'y') {
+ $vars = compact('associations', 'validate', 'primaryKey', 'useTable', 'displayField');
+ $vars['useDbConfig'] = $this->connection;
+ if ($this->bake($currentModelName, $vars)) {
+ if ($this->_checkUnitTest()) {
+ $this->bakeFixture($currentModelName, $useTable);
+ $this->bakeTest($currentModelName, $useTable, $associations);
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+
+/**
+ * Print out all the associations of a particular type
+ *
+ * @param string $modelName Name of the model relations belong to.
+ * @param string $type Name of association you want to see. i.e. 'belongsTo'
+ * @param string $associations Collection of associations.
+ * @return void
+ */
+ protected function _printAssociation($modelName, $type, $associations) {
+ if (!empty($associations[$type])) {
+ for ($i = 0, $len = count($associations[$type]); $i < $len; $i++) {
+ $out = "\t" . $modelName . ' ' . $type . ' ' . $associations[$type][$i]['alias'];
+ $this->out($out);
+ }
+ }
+ }
+
+/**
+ * Finds a primary Key in a list of fields.
+ *
+ * @param array $fields Array of fields that might have a primary key.
+ * @return string Name of field that is a primary key.
+ */
+ public function findPrimaryKey($fields) {
+ $name = 'id';
+ foreach ($fields as $name => $field) {
+ if (isset($field['key']) && $field['key'] == 'primary') {
+ break;
+ }
+ }
+ return $this->in(__d('cake_console', 'What is the primaryKey?'), null, $name);
+ }
+
+/**
+ * interact with the user to find the displayField value for a model.
+ *
+ * @param array $fields Array of fields to look for and choose as a displayField
+ * @return mixed Name of field to use for displayField or false if the user declines to choose
+ */
+ public function findDisplayField($fields) {
+ $fieldNames = array_keys($fields);
+ $prompt = __d('cake_console', "A displayField could not be automatically detected\nwould you like to choose one?");
+ $continue = $this->in($prompt, array('y', 'n'));
+ if (strtolower($continue) == 'n') {
+ return false;
+ }
+ $prompt = __d('cake_console', 'Choose a field from the options above:');
+ $choice = $this->inOptions($fieldNames, $prompt);
+ return $fieldNames[$choice];
+ }
+
+/**
+ * Handles Generation and user interaction for creating validation.
+ *
+ * @param Model $model Model to have validations generated for.
+ * @return array $validate Array of user selected validations.
+ */
+ public function doValidation($model) {
+ if (!is_object($model)) {
+ return false;
+ }
+ $fields = $model->schema();
+
+ if (empty($fields)) {
+ return false;
+ }
+ $validate = array();
+ $this->initValidations();
+ foreach ($fields as $fieldName => $field) {
+ $validation = $this->fieldValidation($fieldName, $field, $model->primaryKey);
+ if (!empty($validation)) {
+ $validate[$fieldName] = $validation;
+ }
+ }
+ return $validate;
+ }
+
+/**
+ * Populate the _validations array
+ *
+ * @return void
+ */
+ public function initValidations() {
+ $options = $choices = array();
+ if (class_exists('Validation')) {
+ $options = get_class_methods('Validation');
+ }
+ sort($options);
+ $default = 1;
+ foreach ($options as $key => $option) {
+ if ($option{0} != '_') {
+ $choices[$default] = strtolower($option);
+ $default++;
+ }
+ }
+ $choices[$default] = 'none'; // Needed since index starts at 1
+ $this->_validations = $choices;
+ return $choices;
+ }
+
+/**
+ * Does individual field validation handling.
+ *
+ * @param string $fieldName Name of field to be validated.
+ * @param array $metaData metadata for field
+ * @param string $primaryKey
+ * @return array Array of validation for the field.
+ */
+ public function fieldValidation($fieldName, $metaData, $primaryKey = 'id') {
+ $defaultChoice = count($this->_validations);
+ $validate = $alreadyChosen = array();
+
+ $anotherValidator = 'y';
+ while ($anotherValidator == 'y') {
+ if ($this->interactive) {
+ $this->out();
+ $this->out(__d('cake_console', 'Field: <info>%s</info>', $fieldName));
+ $this->out(__d('cake_console', 'Type: <info>%s</info>', $metaData['type']));
+ $this->hr();
+ $this->out(__d('cake_console', 'Please select one of the following validation options:'));
+ $this->hr();
+
+ $optionText = '';
+ for ($i = 1, $m = $defaultChoice / 2; $i < $m; $i++) {
+ $line = sprintf("%2d. %s", $i, $this->_validations[$i]);
+ $optionText .= $line . str_repeat(" ", 31 - strlen($line));
+ $optionText .= sprintf("%2d. %s\n", $m + $i, $this->_validations[$m + $i]);
+ }
+ $this->out($optionText);
+ $this->out(__d('cake_console', "%s - Do not do any validation on this field.", $defaultChoice));
+ $this->hr();
+ }
+
+ $prompt = __d('cake_console', "... or enter in a valid regex validation string.\n");
+ $methods = array_flip($this->_validations);
+ $guess = $defaultChoice;
+ if ($metaData['null'] != 1 && !in_array($fieldName, array($primaryKey, 'created', 'modified', 'updated'))) {
+ if ($fieldName == 'email') {
+ $guess = $methods['email'];
+ } elseif ($metaData['type'] == 'string' && $metaData['length'] == 36) {
+ $guess = $methods['uuid'];
+ } elseif ($metaData['type'] == 'string') {
+ $guess = $methods['notempty'];
+ } elseif ($metaData['type'] == 'text') {
+ $guess = $methods['notempty'];
+ } elseif ($metaData['type'] == 'integer') {
+ $guess = $methods['numeric'];
+ } elseif ($metaData['type'] == 'boolean') {
+ $guess = $methods['boolean'];
+ } elseif ($metaData['type'] == 'date') {
+ $guess = $methods['date'];
+ } elseif ($metaData['type'] == 'time') {
+ $guess = $methods['time'];
+ } elseif ($metaData['type'] == 'datetime') {
+ $guess = $methods['datetime'];
+ } elseif ($metaData['type'] == 'inet') {
+ $guess = $methods['ip'];
+ }
+ }
+
+ if ($this->interactive === true) {
+ $choice = $this->in($prompt, null, $guess);
+ if (in_array($choice, $alreadyChosen)) {
+ $this->out(__d('cake_console', "You have already chosen that validation rule,\nplease choose again"));
+ continue;
+ }
+ if (!isset($this->_validations[$choice]) && is_numeric($choice)) {
+ $this->out(__d('cake_console', 'Please make a valid selection.'));
+ continue;
+ }
+ $alreadyChosen[] = $choice;
+ } else {
+ $choice = $guess;
+ }
+
+ if (isset($this->_validations[$choice])) {
+ $validatorName = $this->_validations[$choice];
+ } else {
+ $validatorName = Inflector::slug($choice);
+ }
+
+ if ($choice != $defaultChoice) {
+ if (is_numeric($choice) && isset($this->_validations[$choice])) {
+ $validate[$validatorName] = $this->_validations[$choice];
+ } else {
+ $validate[$validatorName] = $choice;
+ }
+ }
+ if ($this->interactive == true && $choice != $defaultChoice) {
+ $anotherValidator = $this->in(__d('cake_console', 'Would you like to add another validation rule?'), array('y', 'n'), 'n');
+ } else {
+ $anotherValidator = 'n';
+ }
+ }
+ return $validate;
+ }
+
+/**
+ * Handles associations
+ *
+ * @param Model $model
+ * @return array $associations
+ */
+ public function doAssociations($model) {
+ if (!is_object($model)) {
+ return false;
+ }
+ if ($this->interactive === true) {
+ $this->out(__d('cake_console', 'One moment while the associations are detected.'));
+ }
+
+ $fields = $model->schema(true);
+ if (empty($fields)) {
+ return array();
+ }
+
+ if (empty($this->_tables)) {
+ $this->_tables = (array)$this->getAllTables();
+ }
+
+ $associations = array(
+ 'belongsTo' => array(),
+ 'hasMany' => array(),
+ 'hasOne' => array(),
+ 'hasAndBelongsToMany' => array()
+ );
+
+ $associations = $this->findBelongsTo($model, $associations);
+ $associations = $this->findHasOneAndMany($model, $associations);
+ $associations = $this->findHasAndBelongsToMany($model, $associations);
+
+ if ($this->interactive !== true) {
+ unset($associations['hasOne']);
+ }
+
+ if ($this->interactive === true) {
+ $this->hr();
+ if (empty($associations)) {
+ $this->out(__d('cake_console', 'None found.'));
+ } else {
+ $this->out(__d('cake_console', 'Please confirm the following associations:'));
+ $this->hr();
+ $associations = $this->confirmAssociations($model, $associations);
+ }
+ $associations = $this->doMoreAssociations($model, $associations);
+ }
+ return $associations;
+ }
+
+/**
+ * Find belongsTo relations and add them to the associations list.
+ *
+ * @param Model $model Model instance of model being generated.
+ * @param array $associations Array of in progress associations
+ * @return array $associations with belongsTo added in.
+ */
+ public function findBelongsTo(Model $model, $associations) {
+ $fields = $model->schema(true);
+ foreach ($fields as $fieldName => $field) {
+ $offset = strpos($fieldName, '_id');
+ if ($fieldName != $model->primaryKey && $fieldName != 'parent_id' && $offset !== false) {
+ $tmpModelName = $this->_modelNameFromKey($fieldName);
+ $associations['belongsTo'][] = array(
+ 'alias' => $tmpModelName,
+ 'className' => $tmpModelName,
+ 'foreignKey' => $fieldName,
+ );
+ } elseif ($fieldName == 'parent_id') {
+ $associations['belongsTo'][] = array(
+ 'alias' => 'Parent' . $model->name,
+ 'className' => $model->name,
+ 'foreignKey' => $fieldName,
+ );
+ }
+ }
+ return $associations;
+ }
+
+/**
+ * Find the hasOne and HasMany relations and add them to associations list
+ *
+ * @param Model $model Model instance being generated
+ * @param array $associations Array of in progress associations
+ * @return array $associations with hasOne and hasMany added in.
+ */
+ public function findHasOneAndMany(Model $model, $associations) {
+ $foreignKey = $this->_modelKey($model->name);
+ foreach ($this->_tables as $otherTable) {
+ $tempOtherModel = $this->_getModelObject($this->_modelName($otherTable), $otherTable);
+ $modelFieldsTemp = $tempOtherModel->schema(true);
+
+ $pattern = '/_' . preg_quote($model->table, '/') . '|' . preg_quote($model->table, '/') . '_/';
+ $possibleJoinTable = preg_match($pattern, $otherTable);
+ if ($possibleJoinTable == true) {
+ continue;
+ }
+ foreach ($modelFieldsTemp as $fieldName => $field) {
+ $assoc = false;
+ if ($fieldName != $model->primaryKey && $fieldName == $foreignKey) {
+ $assoc = array(
+ 'alias' => $tempOtherModel->name,
+ 'className' => $tempOtherModel->name,
+ 'foreignKey' => $fieldName
+ );
+ } elseif ($otherTable == $model->table && $fieldName == 'parent_id') {
+ $assoc = array(
+ 'alias' => 'Child' . $model->name,
+ 'className' => $model->name,
+ 'foreignKey' => $fieldName
+ );
+ }
+ if ($assoc) {
+ $associations['hasOne'][] = $assoc;
+ $associations['hasMany'][] = $assoc;
+ }
+
+ }
+ }
+ return $associations;
+ }
+
+/**
+ * Find the hasAndBelongsToMany relations and add them to associations list
+ *
+ * @param Model $model Model instance being generated
+ * @param array $associations Array of in-progress associations
+ * @return array $associations with hasAndBelongsToMany added in.
+ */
+ public function findHasAndBelongsToMany(Model $model, $associations) {
+ $foreignKey = $this->_modelKey($model->name);
+ foreach ($this->_tables as $otherTable) {
+ $tempOtherModel = $this->_getModelObject($this->_modelName($otherTable), $otherTable);
+ $modelFieldsTemp = $tempOtherModel->schema(true);
+
+ $offset = strpos($otherTable, $model->table . '_');
+ $otherOffset = strpos($otherTable, '_' . $model->table);
+
+ if ($offset !== false) {
+ $offset = strlen($model->table . '_');
+ $habtmName = $this->_modelName(substr($otherTable, $offset));
+ $associations['hasAndBelongsToMany'][] = array(
+ 'alias' => $habtmName,
+ 'className' => $habtmName,
+ 'foreignKey' => $foreignKey,
+ 'associationForeignKey' => $this->_modelKey($habtmName),
+ 'joinTable' => $otherTable
+ );
+ } elseif ($otherOffset !== false) {
+ $habtmName = $this->_modelName(substr($otherTable, 0, $otherOffset));
+ $associations['hasAndBelongsToMany'][] = array(
+ 'alias' => $habtmName,
+ 'className' => $habtmName,
+ 'foreignKey' => $foreignKey,
+ 'associationForeignKey' => $this->_modelKey($habtmName),
+ 'joinTable' => $otherTable
+ );
+ }
+ }
+ return $associations;
+ }
+
+/**
+ * Interact with the user and confirm associations.
+ *
+ * @param array $model Temporary Model instance.
+ * @param array $associations Array of associations to be confirmed.
+ * @return array Array of confirmed associations
+ */
+ public function confirmAssociations(Model $model, $associations) {
+ foreach ($associations as $type => $settings) {
+ if (!empty($associations[$type])) {
+ foreach ($associations[$type] as $i => $assoc) {
+ $prompt = "{$model->name} {$type} {$assoc['alias']}?";
+ $response = $this->in($prompt, array('y', 'n'), 'y');
+
+ if ('n' == strtolower($response)) {
+ unset($associations[$type][$i]);
+ } elseif ($type == 'hasMany') {
+ unset($associations['hasOne'][$i]);
+ }
+ }
+ $associations[$type] = array_merge($associations[$type]);
+ }
+ }
+ return $associations;
+ }
+
+/**
+ * Interact with the user and generate additional non-conventional associations
+ *
+ * @param Model $model Temporary model instance
+ * @param array $associations Array of associations.
+ * @return array Array of associations.
+ */
+ public function doMoreAssociations(Model $model, $associations) {
+ $prompt = __d('cake_console', 'Would you like to define some additional model associations?');
+ $wannaDoMoreAssoc = $this->in($prompt, array('y', 'n'), 'n');
+ $possibleKeys = $this->_generatePossibleKeys();
+ while (strtolower($wannaDoMoreAssoc) == 'y') {
+ $assocs = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+ $this->out(__d('cake_console', 'What is the association type?'));
+ $assocType = intval($this->inOptions($assocs, __d('cake_console', 'Enter a number')));
+
+ $this->out(__d('cake_console', "For the following options be very careful to match your setup exactly.\n" .
+ "Any spelling mistakes will cause errors."));
+ $this->hr();
+
+ $alias = $this->in(__d('cake_console', 'What is the alias for this association?'));
+ $className = $this->in(__d('cake_console', 'What className will %s use?', $alias), null, $alias );
+
+ if ($assocType == 0) {
+ if (!empty($possibleKeys[$model->table])) {
+ $showKeys = $possibleKeys[$model->table];
+ } else {
+ $showKeys = null;
+ }
+ $suggestedForeignKey = $this->_modelKey($alias);
+ } else {
+ $otherTable = Inflector::tableize($className);
+ if (in_array($otherTable, $this->_tables)) {
+ if ($assocType < 3) {
+ if (!empty($possibleKeys[$otherTable])) {
+ $showKeys = $possibleKeys[$otherTable];
+ } else {
+ $showKeys = null;
+ }
+ } else {
+ $showKeys = null;
+ }
+ } else {
+ $otherTable = $this->in(__d('cake_console', 'What is the table for this model?'));
+ $showKeys = $possibleKeys[$otherTable];
+ }
+ $suggestedForeignKey = $this->_modelKey($model->name);
+ }
+ if (!empty($showKeys)) {
+ $this->out(__d('cake_console', 'A helpful List of possible keys'));
+ $foreignKey = $this->inOptions($showKeys, __d('cake_console', 'What is the foreignKey?'));
+ $foreignKey = $showKeys[intval($foreignKey)];
+ }
+ if (!isset($foreignKey)) {
+ $foreignKey = $this->in(__d('cake_console', 'What is the foreignKey? Specify your own.'), null, $suggestedForeignKey);
+ }
+ if ($assocType == 3) {
+ $associationForeignKey = $this->in(__d('cake_console', 'What is the associationForeignKey?'), null, $this->_modelKey($model->name));
+ $joinTable = $this->in(__d('cake_console', 'What is the joinTable?'));
+ }
+ $associations[$assocs[$assocType]] = array_values((array)$associations[$assocs[$assocType]]);
+ $count = count($associations[$assocs[$assocType]]);
+ $i = ($count > 0) ? $count : 0;
+ $associations[$assocs[$assocType]][$i]['alias'] = $alias;
+ $associations[$assocs[$assocType]][$i]['className'] = $className;
+ $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
+ if ($assocType == 3) {
+ $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
+ $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
+ }
+ $wannaDoMoreAssoc = $this->in(__d('cake_console', 'Define another association?'), array('y', 'n'), 'y');
+ }
+ return $associations;
+ }
+
+/**
+ * Finds all possible keys to use on custom associations.
+ *
+ * @return array array of tables and possible keys
+ */
+ protected function _generatePossibleKeys() {
+ $possible = array();
+ foreach ($this->_tables as $otherTable) {
+ $tempOtherModel = new Model(array('table' => $otherTable, 'ds' => $this->connection));
+ $modelFieldsTemp = $tempOtherModel->schema(true);
+ foreach ($modelFieldsTemp as $fieldName => $field) {
+ if ($field['type'] == 'integer' || $field['type'] == 'string') {
+ $possible[$otherTable][] = $fieldName;
+ }
+ }
+ }
+ return $possible;
+ }
+
+/**
+ * Assembles and writes a Model file.
+ *
+ * @param string|object $name Model name or object
+ * @param array|boolean $data if array and $name is not an object assume bake data, otherwise boolean.
+ * @return string
+ */
+ public function bake($name, $data = array()) {
+ if (is_object($name)) {
+ if ($data == false) {
+ $data = array();
+ $data['associations'] = $this->doAssociations($name);
+ $data['validate'] = $this->doValidation($name);
+ }
+ $data['primaryKey'] = $name->primaryKey;
+ $data['useTable'] = $name->table;
+ $data['useDbConfig'] = $name->useDbConfig;
+ $data['name'] = $name = $name->name;
+ } else {
+ $data['name'] = $name;
+ }
+ $defaults = array(
+ 'associations' => array(),
+ 'validate' => array(),
+ 'primaryKey' => 'id',
+ 'useTable' => null,
+ 'useDbConfig' => 'default',
+ 'displayField' => null
+ );
+ $data = array_merge($defaults, $data);
+
+ $pluginPath = '';
+ if ($this->plugin) {
+ $pluginPath = $this->plugin . '.';
+ }
+
+ $this->Template->set($data);
+ $this->Template->set(array(
+ 'plugin' => $this->plugin,
+ 'pluginPath' => $pluginPath
+ ));
+ $out = $this->Template->generate('classes', 'model');
+
+ $path = $this->getPath();
+ $filename = $path . $name . '.php';
+ $this->out("\n" . __d('cake_console', 'Baking model class for %s...', $name), 1, Shell::QUIET);
+ $this->createFile($filename, $out);
+ ClassRegistry::flush();
+ return $out;
+ }
+
+/**
+ * Assembles and writes a unit test file
+ *
+ * @param string $className Model class name
+ * @return string
+ */
+ public function bakeTest($className) {
+ $this->Test->interactive = $this->interactive;
+ $this->Test->plugin = $this->plugin;
+ $this->Test->connection = $this->connection;
+ return $this->Test->bake('Model', $className);
+ }
+
+/**
+ * outputs the a list of possible models or controllers from database
+ *
+ * @param string $useDbConfig Database configuration name
+ * @return array
+ */
+ public function listAll($useDbConfig = null) {
+ $this->_tables = (array)$this->getAllTables($useDbConfig);
+
+ $this->_modelNames = array();
+ $count = count($this->_tables);
+ for ($i = 0; $i < $count; $i++) {
+ $this->_modelNames[] = $this->_modelName($this->_tables[$i]);
+ }
+ if ($this->interactive === true) {
+ $this->out(__d('cake_console', 'Possible Models based on your current database:'));
+ $len = strlen($count + 1);
+ for ($i = 0; $i < $count; $i++) {
+ $this->out(sprintf("%${len}d. %s", $i + 1, $this->_modelNames[$i]));
+ }
+ }
+ return $this->_tables;
+ }
+
+/**
+ * Interact with the user to determine the table name of a particular model
+ *
+ * @param string $modelName Name of the model you want a table for.
+ * @param string $useDbConfig Name of the database config you want to get tables from.
+ * @return string Table name
+ */
+ public function getTable($modelName, $useDbConfig = null) {
+ $useTable = Inflector::tableize($modelName);
+ if (in_array($modelName, $this->_modelNames)) {
+ $modelNames = array_flip($this->_modelNames);
+ $useTable = $this->_tables[$modelNames[$modelName]];
+ }
+
+ if ($this->interactive === true) {
+ if (!isset($useDbConfig)) {
+ $useDbConfig = $this->connection;
+ }
+ $db = ConnectionManager::getDataSource($useDbConfig);
+ $fullTableName = $db->fullTableName($useTable, false);
+ $tableIsGood = false;
+ if (array_search($useTable, $this->_tables) === false) {
+ $this->out();
+ $this->out(__d('cake_console', "Given your model named '%s',\nCake would expect a database table named '%s'", $modelName, $fullTableName));
+ $tableIsGood = $this->in(__d('cake_console', 'Do you want to use this table?'), array('y', 'n'), 'y');
+ }
+ if (strtolower($tableIsGood) == 'n') {
+ $useTable = $this->in(__d('cake_console', 'What is the name of the table?'));
+ }
+ }
+ return $useTable;
+ }
+
+/**
+ * Get an Array of all the tables in the supplied connection
+ * will halt the script if no tables are found.
+ *
+ * @param string $useDbConfig Connection name to scan.
+ * @return array Array of tables in the database.
+ */
+ public function getAllTables($useDbConfig = null) {
+ if (!isset($useDbConfig)) {
+ $useDbConfig = $this->connection;
+ }
+
+ $tables = array();
+ $db = ConnectionManager::getDataSource($useDbConfig);
+ $db->cacheSources = false;
+ $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
+ if ($usePrefix) {
+ foreach ($db->listSources() as $table) {
+ if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
+ $tables[] = substr($table, strlen($usePrefix));
+ }
+ }
+ } else {
+ $tables = $db->listSources();
+ }
+ if (empty($tables)) {
+ $this->err(__d('cake_console', 'Your database does not have any tables.'));
+ $this->_stop();
+ }
+ return $tables;
+ }
+
+/**
+ * Forces the user to specify the model he wants to bake, and returns the selected model name.
+ *
+ * @param string $useDbConfig Database config name
+ * @return string the model name
+ */
+ public function getName($useDbConfig = null) {
+ $this->listAll($useDbConfig);
+
+ $enteredModel = '';
+
+ while ($enteredModel == '') {
+ $enteredModel = $this->in(__d('cake_console', "Enter a number from the list above,\n" .
+ "type in the name of another model, or 'q' to exit"), null, 'q');
+
+ if ($enteredModel === 'q') {
+ $this->out(__d('cake_console', 'Exit'));
+ $this->_stop();
+ }
+
+ if ($enteredModel == '' || intval($enteredModel) > count($this->_modelNames)) {
+ $this->err(__d('cake_console', "The model name you supplied was empty,\n" .
+ "or the number you selected was not an option. Please try again."));
+ $enteredModel = '';
+ }
+ }
+ if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->_modelNames)) {
+ $currentModelName = $this->_modelNames[intval($enteredModel) - 1];
+ } else {
+ $currentModelName = $enteredModel;
+ }
+ return $currentModelName;
+ }
+
+/**
+ * get the option parser.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(
+ __d('cake_console', 'Bake models.')
+ )->addArgument('name', array(
+ 'help' => __d('cake_console', 'Name of the model to bake. Can use Plugin.name to bake plugin models.')
+ ))->addSubcommand('all', array(
+ 'help' => __d('cake_console', 'Bake all model files with associations and validation.')
+ ))->addOption('plugin', array(
+ 'short' => 'p',
+ 'help' => __d('cake_console', 'Plugin to bake the model into.')
+ ))->addOption('connection', array(
+ 'short' => 'c',
+ 'help' => __d('cake_console', 'The connection the model table is on.')
+ ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
+ }
+
+/**
+ * Interact with FixtureTask to automatically bake fixtures when baking models.
+ *
+ * @param string $className Name of class to bake fixture for
+ * @param string $useTable Optional table name for fixture to use.
+ * @return void
+ * @see FixtureTask::bake
+ */
+ public function bakeFixture($className, $useTable = null) {
+ $this->Fixture->interactive = $this->interactive;
+ $this->Fixture->connection = $this->connection;
+ $this->Fixture->plugin = $this->plugin;
+ $this->Fixture->bake($className, $useTable);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/PluginTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/PluginTask.php
new file mode 100644
index 0000000..2f972b6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/PluginTask.php
@@ -0,0 +1,225 @@
+<?php
+/**
+ * The Plugin Task handles creating an empty plugin, ready to be used
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('File', 'Utility');
+App::uses('Folder', 'Utility');
+
+/**
+ * The Plugin Task handles creating an empty plugin, ready to be used
+ *
+ * @package Cake.Console.Command.Task
+ */
+class PluginTask extends AppShell {
+
+/**
+ * path to plugins directory
+ *
+ * @var array
+ */
+ public $path = null;
+
+/**
+ * Path to the bootstrap file. Changed in tests.
+ *
+ * @var string
+ */
+ public $bootstrap = null;
+
+/**
+ * initialize
+ *
+ * @return void
+ */
+ public function initialize() {
+ $this->path = current(App::path('plugins'));
+ $this->bootstrap = APP . 'Config' . DS . 'bootstrap.php';
+ }
+
+/**
+ * Execution method always used for tasks
+ *
+ * @return void
+ */
+ public function execute() {
+ if (isset($this->args[0])) {
+ $plugin = Inflector::camelize($this->args[0]);
+ $pluginPath = $this->_pluginPath($plugin);
+ if (is_dir($pluginPath)) {
+ $this->out(__d('cake_console', 'Plugin: %s already exists, no action taken', $plugin));
+ $this->out(__d('cake_console', 'Path: %s', $pluginPath));
+ return false;
+ } else {
+ $this->_interactive($plugin);
+ }
+ } else {
+ return $this->_interactive();
+ }
+ }
+
+/**
+ * Interactive interface
+ *
+ * @param string $plugin
+ * @return void
+ */
+ protected function _interactive($plugin = null) {
+ while ($plugin === null) {
+ $plugin = $this->in(__d('cake_console', 'Enter the name of the plugin in CamelCase format'));
+ }
+
+ if (!$this->bake($plugin)) {
+ $this->error(__d('cake_console', "An error occurred trying to bake: %s in %s", $plugin, $this->path . $plugin));
+ }
+ }
+
+/**
+ * Bake the plugin, create directories and files
+ *
+ * @param string $plugin Name of the plugin in CamelCased format
+ * @return boolean
+ */
+ public function bake($plugin) {
+ $pathOptions = App::path('plugins');
+ if (count($pathOptions) > 1) {
+ $this->findPath($pathOptions);
+ }
+ $this->hr();
+ $this->out(__d('cake_console', "<info>Plugin Name:</info> %s", $plugin));
+ $this->out(__d('cake_console', "<info>Plugin Directory:</info> %s", $this->path . $plugin));
+ $this->hr();
+
+ $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n', 'q'), 'y');
+
+ if (strtolower($looksGood) == 'y') {
+ $Folder = new Folder($this->path . $plugin);
+ $directories = array(
+ 'Config' . DS . 'Schema',
+ 'Model' . DS . 'Behavior',
+ 'Model' . DS . 'Datasource',
+ 'Console' . DS . 'Command' . DS . 'Task',
+ 'Controller' . DS . 'Component',
+ 'Lib',
+ 'View' . DS . 'Helper',
+ 'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component',
+ 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper',
+ 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior',
+ 'Test' . DS . 'Fixture',
+ 'Vendor',
+ 'webroot'
+ );
+
+ foreach ($directories as $directory) {
+ $dirPath = $this->path . $plugin . DS . $directory;
+ $Folder->create($dirPath);
+ $File = new File($dirPath . DS . 'empty', true);
+ }
+
+ foreach ($Folder->messages() as $message) {
+ $this->out($message, 1, Shell::VERBOSE);
+ }
+
+ $errors = $Folder->errors();
+ if (!empty($errors)) {
+ foreach ($errors as $message) {
+ $this->error($message);
+ }
+ return false;
+ }
+
+ $controllerFileName = $plugin . 'AppController.php';
+
+ $out = "<?php\n\n";
+ $out .= "class {$plugin}AppController extends AppController {\n\n";
+ $out .= "}\n\n";
+ $this->createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out);
+
+ $modelFileName = $plugin . 'AppModel.php';
+
+ $out = "<?php\n\n";
+ $out .= "class {$plugin}AppModel extends AppModel {\n\n";
+ $out .= "}\n\n";
+ $this->createFile($this->path . $plugin . DS . 'Model' . DS . $modelFileName, $out);
+
+ $this->_modifyBootstrap($plugin);
+
+ $this->hr();
+ $this->out(__d('cake_console', '<success>Created:</success> %s in %s', $plugin, $this->path . $plugin), 2);
+ }
+
+ return true;
+ }
+
+/**
+ * Update the app's bootstrap.php file.
+ *
+ * @return void
+ */
+ protected function _modifyBootstrap($plugin) {
+ $bootstrap = new File($this->bootstrap, false);
+ $contents = $bootstrap->read();
+ if (!preg_match("@\n\s*CakePlugin::loadAll@", $contents)) {
+ $bootstrap->append("\nCakePlugin::load('$plugin', array('bootstrap' => false, 'routes' => false));\n");
+ $this->out('');
+ $this->out(__d('cake_dev', '%s modified', $this->bootstrap));
+ }
+ }
+
+/**
+ * find and change $this->path to the user selection
+ *
+ * @param array $pathOptions
+ * @return string plugin path
+ */
+ public function findPath($pathOptions) {
+ $valid = false;
+ foreach ($pathOptions as $i => $path) {
+ if (!is_dir($path)) {
+ array_splice($pathOptions, $i, 1);
+ }
+ }
+ $max = count($pathOptions);
+ while (!$valid) {
+ foreach ($pathOptions as $i => $option) {
+ $this->out($i + 1 . '. ' . $option);
+ }
+ $prompt = __d('cake_console', 'Choose a plugin path from the paths above.');
+ $choice = $this->in($prompt, null, 1);
+ if (intval($choice) > 0 && intval($choice) <= $max) {
+ $valid = true;
+ }
+ }
+ $this->path = $pathOptions[$choice - 1];
+ }
+
+/**
+ * get the option parser for the plugin task
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(__d('cake_console',
+ 'Create the directory structure, AppModel and AppController classes for a new plugin. ' .
+ 'Can create plugins in any of your bootstrapped plugin paths.'
+ ))->addArgument('name', array(
+ 'help' => __d('cake_console', 'CamelCased name of the plugin to create.')
+ ));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ProjectTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ProjectTask.php
new file mode 100644
index 0000000..ebfe4e9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ProjectTask.php
@@ -0,0 +1,421 @@
+<?php
+/**
+ * The Project Task handles creating the base application
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('File', 'Utility');
+App::uses('Folder', 'Utility');
+App::uses('String', 'Utility');
+App::uses('Security', 'Utility');
+
+/**
+ * Task class for creating new project apps and plugins
+ *
+ * @package Cake.Console.Command.Task
+ */
+class ProjectTask extends AppShell {
+
+/**
+ * configs path (used in testing).
+ *
+ * @var string
+ */
+ public $configPath = null;
+
+/**
+ * Checks that given project path does not already exist, and
+ * finds the app directory in it. Then it calls bake() with that information.
+ *
+ * @return mixed
+ */
+ public function execute() {
+ $project = null;
+ if (isset($this->args[0])) {
+ $project = $this->args[0];
+ } else {
+ $appContents = array_diff(scandir(APP), array('.', '..'));
+ if (empty($appContents)) {
+ $suggestedPath = rtrim(APP, DS);
+ } else {
+ $suggestedPath = APP . 'myapp';
+ }
+ }
+
+ while (!$project) {
+ $prompt = __d('cake_console', "What is the path to the project you want to bake?");
+ $project = $this->in($prompt, null, $suggestedPath);
+ }
+
+ if ($project && !Folder::isAbsolute($project) && isset($_SERVER['PWD'])) {
+ $project = $_SERVER['PWD'] . DS . $project;
+ }
+
+ $response = false;
+ while ($response == false && is_dir($project) === true && file_exists($project . 'Config' . 'core.php')) {
+ $prompt = __d('cake_console', '<warning>A project already exists in this location:</warning> %s Overwrite?', $project);
+ $response = $this->in($prompt, array('y', 'n'), 'n');
+ if (strtolower($response) === 'n') {
+ $response = $project = false;
+ }
+ }
+
+ $success = true;
+ if ($this->bake($project)) {
+ $path = Folder::slashTerm($project);
+
+ if ($this->securitySalt($path) === true) {
+ $this->out(__d('cake_console', ' * Random hash key created for \'Security.salt\''));
+ } else {
+ $this->err(__d('cake_console', 'Unable to generate random hash for \'Security.salt\', you should change it in %s', APP . 'Config' . DS . 'core.php'));
+ $success = false;
+ }
+
+ if ($this->securityCipherSeed($path) === true) {
+ $this->out(__d('cake_console', ' * Random seed created for \'Security.cipherSeed\''));
+ } else {
+ $this->err(__d('cake_console', 'Unable to generate random seed for \'Security.cipherSeed\', you should change it in %s', APP . 'Config' . DS . 'core.php'));
+ $success = false;
+ }
+
+ if ($this->consolePath($path) === true) {
+ $this->out(__d('cake_console', ' * app/Console/cake.php path set.'));
+ } else {
+ $this->err(__d('cake_console', 'Unable to set console path for app/Console.'));
+ $success = false;
+ }
+
+ $hardCode = false;
+ if ($this->cakeOnIncludePath()) {
+ $this->out(__d('cake_console', '<info>CakePHP is on your `include_path`. CAKE_CORE_INCLUDE_PATH will be set, but commented out.</info>'));
+ } else {
+ $this->out(__d('cake_console', '<warning>CakePHP is not on your `include_path`, CAKE_CORE_INCLUDE_PATH will be hard coded.</warning>'));
+ $this->out(__d('cake_console', 'You can fix this by adding CakePHP to your `include_path`.'));
+ $hardCode = true;
+ }
+ $success = $this->corePath($path, $hardCode) === true;
+ if ($success) {
+ $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in webroot/index.php', CAKE_CORE_INCLUDE_PATH));
+ $this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in webroot/test.php', CAKE_CORE_INCLUDE_PATH));
+ } else {
+ $this->err(__d('cake_console', 'Unable to set CAKE_CORE_INCLUDE_PATH, you should change it in %s', $path . 'webroot' . DS . 'index.php'));
+ $success = false;
+ }
+ if ($success && $hardCode) {
+ $this->out(__d('cake_console', ' * <warning>Remember to check these values after moving to production server</warning>'));
+ }
+
+ $Folder = new Folder($path);
+ if (!$Folder->chmod($path . 'tmp', 0777)) {
+ $this->err(__d('cake_console', 'Could not set permissions on %s', $path . DS . 'tmp'));
+ $this->out(__d('cake_console', 'chmod -R 0777 %s', $path . DS . 'tmp'));
+ $success = false;
+ }
+ if ($success) {
+ $this->out(__d('cake_console', '<success>Project baked successfully!</success>'));
+ } else {
+ $this->out(__d('cake_console', 'Project baked but with <warning>some issues.</warning>.'));
+ }
+ return $path;
+ }
+ }
+
+/**
+ * Checks PHP's include_path for CakePHP.
+ *
+ * @return boolean Indicates whether or not CakePHP exists on include_path
+ */
+ public function cakeOnIncludePath() {
+ $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
+ foreach ($paths as $path) {
+ if (file_exists($path . DS . 'Cake' . DS . 'bootstrap.php')) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Looks for a skeleton template of a Cake application,
+ * and if not found asks the user for a path. When there is a path
+ * this method will make a deep copy of the skeleton to the project directory.
+ *
+ * @param string $path Project path
+ * @param string $skel Path to copy from
+ * @param string $skip array of directories to skip when copying
+ * @return mixed
+ */
+ public function bake($path, $skel = null, $skip = array('empty')) {
+ if (!$skel && !empty($this->params['skel'])) {
+ $skel = $this->params['skel'];
+ }
+ while (!$skel) {
+ $skel = $this->in(
+ __d('cake_console', "What is the path to the directory layout you wish to copy?"),
+ null,
+ CAKE . 'Console' . DS . 'Templates' . DS . 'skel'
+ );
+ if (!$skel) {
+ $this->err(__d('cake_console', 'The directory path you supplied was empty. Please try again.'));
+ } else {
+ while (is_dir($skel) === false) {
+ $skel = $this->in(
+ __d('cake_console', 'Directory path does not exist please choose another:'),
+ null,
+ CAKE . 'Console' . DS . 'Templates' . DS . 'skel'
+ );
+ }
+ }
+ }
+
+ $app = basename($path);
+
+ $this->out(__d('cake_console', '<info>Skel Directory</info>: ') . $skel);
+ $this->out(__d('cake_console', '<info>Will be copied to</info>: ') . $path);
+ $this->hr();
+
+ $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n', 'q'), 'y');
+
+ switch (strtolower($looksGood)) {
+ case 'y':
+ $Folder = new Folder($skel);
+ if (!empty($this->params['empty'])) {
+ $skip = array();
+ }
+
+ if ($Folder->copy(array('to' => $path, 'skip' => $skip))) {
+ $this->hr();
+ $this->out(__d('cake_console', '<success>Created:</success> %s in %s', $app, $path));
+ $this->hr();
+ } else {
+ $this->err(__d('cake_console', "<error>Could not create</error> '%s' properly.", $app));
+ return false;
+ }
+
+ foreach ($Folder->messages() as $message) {
+ $this->out(String::wrap(' * ' . $message), 1, Shell::VERBOSE);
+ }
+
+ return true;
+ case 'n':
+ unset($this->args[0]);
+ $this->execute();
+ return false;
+ case 'q':
+ $this->out(__d('cake_console', '<error>Bake Aborted.</error>'));
+ return false;
+ }
+ }
+
+/**
+ * Generates the correct path to the CakePHP libs that are generating the project
+ * and points app/console/cake.php to the right place
+ *
+ * @param string $path Project path.
+ * @return boolean success
+ */
+ public function consolePath($path) {
+ $File = new File($path . 'Console' . DS . 'cake.php');
+ $contents = $File->read();
+ if (preg_match('/(__CAKE_PATH__)/', $contents, $match)) {
+ $root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " \$ds . '" : "'";
+ $replacement = $root . str_replace(DS, "' . \$ds . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'";
+ $result = str_replace($match[0], $replacement, $contents);
+ if ($File->write($result)) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+/**
+ * Generates and writes 'Security.salt'
+ *
+ * @param string $path Project path
+ * @return boolean Success
+ */
+ public function securitySalt($path) {
+ $File = new File($path . 'Config' . DS . 'core.php');
+ $contents = $File->read();
+ if (preg_match('/([\s]*Configure::write\(\'Security.salt\',[\s\'A-z0-9]*\);)/', $contents, $match)) {
+ $string = Security::generateAuthKey();
+ $result = str_replace($match[0], "\t" . 'Configure::write(\'Security.salt\', \'' . $string . '\');', $contents);
+ if ($File->write($result)) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+/**
+ * Generates and writes 'Security.cipherSeed'
+ *
+ * @param string $path Project path
+ * @return boolean Success
+ */
+ public function securityCipherSeed($path) {
+ $File = new File($path . 'Config' . DS . 'core.php');
+ $contents = $File->read();
+ if (preg_match('/([\s]*Configure::write\(\'Security.cipherSeed\',[\s\'A-z0-9]*\);)/', $contents, $match)) {
+ App::uses('Security', 'Utility');
+ $string = substr(bin2hex(Security::generateAuthKey()), 0, 30);
+ $result = str_replace($match[0], "\t" . 'Configure::write(\'Security.cipherSeed\', \'' . $string . '\');', $contents);
+ if ($File->write($result)) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
+/**
+ * Generates and writes CAKE_CORE_INCLUDE_PATH
+ *
+ * @param string $path Project path
+ * @param boolean $hardCode Wether or not define calls should be hardcoded.
+ * @return boolean Success
+ */
+ public function corePath($path, $hardCode = true) {
+ if (dirname($path) !== CAKE_CORE_INCLUDE_PATH) {
+ $filename = $path . 'webroot' . DS . 'index.php';
+ if (!$this->_replaceCorePath($filename, $hardCode)) {
+ return false;
+ }
+ $filename = $path . 'webroot' . DS . 'test.php';
+ if (!$this->_replaceCorePath($filename, $hardCode)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+/**
+ * Replaces the __CAKE_PATH__ placeholder in the template files.
+ *
+ * @param string $filename The filename to operate on.
+ * @param boolean $hardCode Whether or not the define should be uncommented.
+ * @return boolean Success
+ */
+ protected function _replaceCorePath($filename, $hardCode) {
+ $contents = file_get_contents($filename);
+
+ $root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " DS . '" : "'";
+ $corePath = $root . str_replace(DS, "' . DS . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'";
+
+ $result = str_replace('__CAKE_PATH__', $corePath, $contents, $count);
+ if ($hardCode) {
+ $result = str_replace('//define(\'CAKE_CORE', 'define(\'CAKE_CORE', $result);
+ }
+ if (!file_put_contents($filename, $result)) {
+ return false;
+ }
+ if ($count == 0) {
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Enables Configure::read('Routing.prefixes') in /app/Config/core.php
+ *
+ * @param string $name Name to use as admin routing
+ * @return boolean Success
+ */
+ public function cakeAdmin($name) {
+ $path = (empty($this->configPath)) ? APP . 'Config' . DS : $this->configPath;
+ $File = new File($path . 'core.php');
+ $contents = $File->read();
+ if (preg_match('%(\s*[/]*Configure::write\(\'Routing.prefixes\',[\s\'a-z,\)\(]*\);)%', $contents, $match)) {
+ $result = str_replace($match[0], "\n" . 'Configure::write(\'Routing.prefixes\', array(\'' . $name . '\'));', $contents);
+ if ($File->write($result)) {
+ Configure::write('Routing.prefixes', array($name));
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+/**
+ * Checks for Configure::read('Routing.prefixes') and forces user to input it if not enabled
+ *
+ * @return string Admin route to use
+ */
+ public function getPrefix() {
+ $admin = '';
+ $prefixes = Configure::read('Routing.prefixes');
+ if (!empty($prefixes)) {
+ if (count($prefixes) == 1) {
+ return $prefixes[0] . '_';
+ }
+ if ($this->interactive) {
+ $this->out();
+ $this->out(__d('cake_console', 'You have more than one routing prefix configured'));
+ }
+ $options = array();
+ foreach ($prefixes as $i => $prefix) {
+ $options[] = $i + 1;
+ if ($this->interactive) {
+ $this->out($i + 1 . '. ' . $prefix);
+ }
+ }
+ $selection = $this->in(__d('cake_console', 'Please choose a prefix to bake with.'), $options, 1);
+ return $prefixes[$selection - 1] . '_';
+ }
+ if ($this->interactive) {
+ $this->hr();
+ $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/Config/core.php to use prefix routing.'));
+ $this->out(__d('cake_console', 'What would you like the prefix route to be?'));
+ $this->out(__d('cake_console', 'Example: www.example.com/admin/controller'));
+ while ($admin == '') {
+ $admin = $this->in(__d('cake_console', 'Enter a routing prefix:'), null, 'admin');
+ }
+ if ($this->cakeAdmin($admin) !== true) {
+ $this->out(__d('cake_console', '<error>Unable to write to</error> /app/Config/core.php.'));
+ $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/Config/core.php to use prefix routing.'));
+ $this->_stop();
+ }
+ return $admin . '_';
+ }
+ return '';
+ }
+
+/**
+ * get the option parser.
+ *
+ * @return ConsoleOptionParser
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(
+ __d('cake_console', 'Generate a new CakePHP project skeleton.')
+ )->addArgument('name', array(
+ 'help' => __d('cake_console', 'Application directory to make, if it starts with "/" the path is absolute.')
+ ))->addOption('empty', array(
+ 'boolean' => true,
+ 'help' => __d('cake_console', 'Create empty files in each of the directories. Good if you are using git')
+ ))->addOption('skel', array(
+ 'default' => current(App::core('Console')) . 'Templates' . DS . 'skel',
+ 'help' => __d('cake_console', 'The directory layout to use for the new application skeleton. Defaults to cake/Console/Templates/skel of CakePHP used to create the project.')
+ ));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TemplateTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TemplateTask.php
new file mode 100644
index 0000000..ffe993c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TemplateTask.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * Template Task can generate templated output Used in other Tasks
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('Folder', 'Utility');
+
+/**
+ * Template Task can generate templated output Used in other Tasks.
+ * Acts like a simplified View class.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class TemplateTask extends AppShell {
+
+/**
+ * variables to add to template scope
+ *
+ * @var array
+ */
+ public $templateVars = array();
+
+/**
+ * Paths to look for templates on.
+ * Contains a list of $theme => $path
+ *
+ * @var array
+ */
+ public $templatePaths = array();
+
+/**
+ * Initialize callback. Setup paths for the template task.
+ *
+ * @return void
+ */
+ public function initialize() {
+ $this->templatePaths = $this->_findThemes();
+ }
+
+/**
+ * Find the paths to all the installed shell themes in the app.
+ *
+ * Bake themes are directories not named `skel` inside a `Console/Templates` path.
+ * They are listed in this order: app -> plugin -> default
+ *
+ * @return array Array of bake themes that are installed.
+ */
+ protected function _findThemes() {
+ $paths = App::path('Console');
+
+ $plugins = App::objects('plugin');
+ foreach ($plugins as $plugin) {
+ $paths[] = $this->_pluginPath($plugin) . 'Console' . DS;
+ }
+
+ $core = current(App::core('Console'));
+ $separator = DS === '/' ? '/' : '\\\\';
+ $core = preg_replace('#shells' . $separator . '$#', '', $core);
+
+ $Folder = new Folder($core . 'Templates' . DS . 'default');
+
+ $contents = $Folder->read();
+ $themeFolders = $contents[0];
+
+ $paths[] = $core;
+
+ // TEMPORARY TODO remove when all paths are DS terminated
+ foreach ($paths as $i => $path) {
+ $paths[$i] = rtrim($path, DS) . DS;
+ }
+
+ $themes = array();
+ foreach ($paths as $path) {
+ $Folder = new Folder($path . 'Templates', false);
+ $contents = $Folder->read();
+ $subDirs = $contents[0];
+ foreach ($subDirs as $dir) {
+ if (empty($dir) || preg_match('@^skel$|_skel$@', $dir)) {
+ continue;
+ }
+ $Folder = new Folder($path . 'Templates' . DS . $dir);
+ $contents = $Folder->read();
+ $subDirs = $contents[0];
+ if (array_intersect($contents[0], $themeFolders)) {
+ $templateDir = $path . 'Templates' . DS . $dir . DS;
+ $themes[$dir] = $templateDir;
+ }
+ }
+ }
+ return $themes;
+ }
+
+/**
+ * Set variable values to the template scope
+ *
+ * @param string|array $one A string or an array of data.
+ * @param string|array $two Value in case $one is a string (which then works as the key).
+ * Unused if $one is an associative array, otherwise serves as the values to $one's keys.
+ * @return void
+ */
+ public function set($one, $two = null) {
+ if (is_array($one)) {
+ if (is_array($two)) {
+ $data = array_combine($one, $two);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($one => $two);
+ }
+
+ if ($data == null) {
+ return false;
+ }
+ $this->templateVars = $data + $this->templateVars;
+ }
+
+/**
+ * Runs the template
+ *
+ * @param string $directory directory / type of thing you want
+ * @param string $filename template name
+ * @param array $vars Additional vars to set to template scope.
+ * @return string contents of generated code template
+ */
+ public function generate($directory, $filename, $vars = null) {
+ if ($vars !== null) {
+ $this->set($vars);
+ }
+ if (empty($this->templatePaths)) {
+ $this->initialize();
+ }
+ $themePath = $this->getThemePath();
+ $templateFile = $this->_findTemplate($themePath, $directory, $filename);
+ if ($templateFile) {
+ extract($this->templateVars);
+ ob_start();
+ ob_implicit_flush(0);
+ include $templateFile;
+ $content = ob_get_clean();
+ return $content;
+ }
+ return '';
+ }
+
+/**
+ * Find the theme name for the current operation.
+ * If there is only one theme in $templatePaths it will be used.
+ * If there is a -theme param in the cli args, it will be used.
+ * If there is more than one installed theme user interaction will happen
+ *
+ * @return string returns the path to the selected theme.
+ */
+ public function getThemePath() {
+ if (count($this->templatePaths) == 1) {
+ $paths = array_values($this->templatePaths);
+ return $paths[0];
+ }
+ if (!empty($this->params['theme']) && isset($this->templatePaths[$this->params['theme']])) {
+ return $this->templatePaths[$this->params['theme']];
+ }
+
+ $this->hr();
+ $this->out(__d('cake_console', 'You have more than one set of templates installed.'));
+ $this->out(__d('cake_console', 'Please choose the template set you wish to use:'));
+ $this->hr();
+
+ $i = 1;
+ $indexedPaths = array();
+ foreach ($this->templatePaths as $key => $path) {
+ $this->out($i . '. ' . $key);
+ $indexedPaths[$i] = $path;
+ $i++;
+ }
+ $index = $this->in(__d('cake_console', 'Which bake theme would you like to use?'), range(1, $i - 1), 1);
+ $themeNames = array_keys($this->templatePaths);
+ $this->params['theme'] = $themeNames[$index - 1];
+ return $indexedPaths[$index];
+ }
+
+/**
+ * Find a template inside a directory inside a path.
+ * Will scan all other theme dirs if the template is not found in the first directory.
+ *
+ * @param string $path The initial path to look for the file on. If it is not found fallbacks will be used.
+ * @param string $directory Subdirectory to look for ie. 'views', 'objects'
+ * @param string $filename lower_case_underscored filename you want.
+ * @return string filename will exit program if template is not found.
+ */
+ protected function _findTemplate($path, $directory, $filename) {
+ $themeFile = $path . $directory . DS . $filename . '.ctp';
+ if (file_exists($themeFile)) {
+ return $themeFile;
+ }
+ foreach ($this->templatePaths as $path) {
+ $templatePath = $path . $directory . DS . $filename . '.ctp';
+ if (file_exists($templatePath)) {
+ return $templatePath;
+ }
+ }
+ $this->err(__d('cake_console', 'Could not find template for %s', $filename));
+ return false;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TestTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TestTask.php
new file mode 100644
index 0000000..b5b6c50
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/TestTask.php
@@ -0,0 +1,537 @@
+<?php
+/**
+ * The TestTask handles creating and updating test files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('BakeTask', 'Console/Command/Task');
+App::uses('ClassRegistry', 'Utility');
+
+/**
+ * Task class for creating and updating test files.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class TestTask extends BakeTask {
+
+/**
+ * path to TESTS directory
+ *
+ * @var string
+ */
+ public $path = TESTS;
+
+/**
+ * Tasks used.
+ *
+ * @var array
+ */
+ public $tasks = array('Template');
+
+/**
+ * class types that methods can be generated for
+ *
+ * @var array
+ */
+ public $classTypes = array(
+ 'Model' => 'Model',
+ 'Controller' => 'Controller',
+ 'Component' => 'Controller/Component',
+ 'Behavior' => 'Model/Behavior',
+ 'Helper' => 'View/Helper'
+ );
+
+/**
+ * Internal list of fixtures that have been added so far.
+ *
+ * @var array
+ */
+ protected $_fixtures = array();
+
+/**
+ * Execution method always used for tasks
+ *
+ * @return void
+ */
+ public function execute() {
+ parent::execute();
+ if (empty($this->args)) {
+ $this->_interactive();
+ }
+
+ if (count($this->args) == 1) {
+ $this->_interactive($this->args[0]);
+ }
+
+ if (count($this->args) > 1) {
+ $type = Inflector::classify($this->args[0]);
+ if ($this->bake($type, $this->args[1])) {
+ $this->out('<success>Done</success>');
+ }
+ }
+ }
+
+/**
+ * Handles interactive baking
+ *
+ * @param string $type
+ * @return string|boolean
+ */
+ protected function _interactive($type = null) {
+ $this->interactive = true;
+ $this->hr();
+ $this->out(__d('cake_console', 'Bake Tests'));
+ $this->out(__d('cake_console', 'Path: %s', $this->getPath()));
+ $this->hr();
+
+ if ($type) {
+ $type = Inflector::camelize($type);
+ if (!isset($this->classTypes[$type])) {
+ $this->error(__d('cake_console', 'Incorrect type provided. Please choose one of %s', implode(', ', array_keys($this->classTypes))));
+ }
+ } else {
+ $type = $this->getObjectType();
+ }
+ $className = $this->getClassName($type);
+ return $this->bake($type, $className);
+ }
+
+/**
+ * Completes final steps for generating data to create test case.
+ *
+ * @param string $type Type of object to bake test case for ie. Model, Controller
+ * @param string $className the 'cake name' for the class ie. Posts for the PostsController
+ * @return string|boolean
+ */
+ public function bake($type, $className) {
+ $plugin = null;
+ if ($this->plugin) {
+ $plugin = $this->plugin . '.';
+ }
+
+ $realType = $this->mapType($type, $plugin);
+ $fullClassName = $this->getRealClassName($type, $className);
+
+ if ($this->typeCanDetectFixtures($type) && $this->isLoadableClass($realType, $fullClassName)) {
+ $this->out(__d('cake_console', 'Bake is detecting possible fixtures...'));
+ $testSubject = $this->buildTestSubject($type, $className);
+ $this->generateFixtureList($testSubject);
+ } elseif ($this->interactive) {
+ $this->getUserFixtures();
+ }
+ App::uses($fullClassName, $realType);
+
+ $methods = array();
+ if (class_exists($fullClassName)) {
+ $methods = $this->getTestableMethods($fullClassName);
+ }
+ $mock = $this->hasMockClass($type, $fullClassName);
+ list($preConstruct, $construction, $postConstruct) = $this->generateConstructor($type, $fullClassName, $plugin);
+ $uses = $this->generateUses($type, $realType, $fullClassName);
+
+ $this->out("\n" . __d('cake_console', 'Baking test case for %s %s ...', $className, $type), 1, Shell::QUIET);
+
+ $this->Template->set('fixtures', $this->_fixtures);
+ $this->Template->set('plugin', $plugin);
+ $this->Template->set(compact(
+ 'className', 'methods', 'type', 'fullClassName', 'mock',
+ 'realType', 'preConstruct', 'postConstruct', 'construction',
+ 'uses'
+ ));
+ $out = $this->Template->generate('classes', 'test');
+
+ $filename = $this->testCaseFileName($type, $className);
+ $made = $this->createFile($filename, $out);
+ if ($made) {
+ return $out;
+ }
+ return false;
+ }
+
+/**
+ * Interact with the user and get their chosen type. Can exit the script.
+ *
+ * @return string Users chosen type.
+ */
+ public function getObjectType() {
+ $this->hr();
+ $this->out(__d('cake_console', 'Select an object type:'));
+ $this->hr();
+
+ $keys = array();
+ $i = 0;
+ foreach ($this->classTypes as $option => $package) {
+ $this->out(++$i . '. ' . $option);
+ $keys[] = $i;
+ }
+ $keys[] = 'q';
+ $selection = $this->in(__d('cake_console', 'Enter the type of object to bake a test for or (q)uit'), $keys, 'q');
+ if ($selection == 'q') {
+ return $this->_stop();
+ }
+ $types = array_keys($this->classTypes);
+ return $types[$selection - 1];
+ }
+
+/**
+ * Get the user chosen Class name for the chosen type
+ *
+ * @param string $objectType Type of object to list classes for i.e. Model, Controller.
+ * @return string Class name the user chose.
+ */
+ public function getClassName($objectType) {
+ $type = ucfirst(strtolower($objectType));
+ $typeLength = strlen($type);
+ $type = $this->classTypes[$type];
+ if ($this->plugin) {
+ $plugin = $this->plugin . '.';
+ $options = App::objects($plugin . $type);
+ } else {
+ $options = App::objects($type);
+ }
+ $this->out(__d('cake_console', 'Choose a %s class', $objectType));
+ $keys = array();
+ foreach ($options as $key => $option) {
+ $this->out(++$key . '. ' . $option);
+ $keys[] = $key;
+ }
+ while (empty($selection)) {
+ $selection = $this->in(__d('cake_console', 'Choose an existing class, or enter the name of a class that does not exist'));
+ if (is_numeric($selection) && isset($options[$selection - 1])) {
+ $selection = $options[$selection - 1];
+ }
+ if ($type !== 'Model') {
+ $selection = substr($selection, 0, $typeLength * - 1);
+ }
+ }
+ return $selection;
+ }
+
+/**
+ * Checks whether the chosen type can find its own fixtures.
+ * Currently only model, and controller are supported
+ *
+ * @param string $type The Type of object you are generating tests for eg. controller
+ * @return boolean
+ */
+ public function typeCanDetectFixtures($type) {
+ $type = strtolower($type);
+ return in_array($type, array('controller', 'model'));
+ }
+
+/**
+ * Check if a class with the given package is loaded or can be loaded.
+ *
+ * @param string $package The package of object you are generating tests for eg. controller
+ * @param string $class the Classname of the class the test is being generated for.
+ * @return boolean
+ */
+ public function isLoadableClass($package, $class) {
+ App::uses($class, $package);
+ list($plugin, $ns) = pluginSplit($package);
+ if ($plugin) {
+ App::uses("{$plugin}AppController", $package);
+ App::uses("{$plugin}AppModel", $package);
+ App::uses("{$plugin}AppHelper", $package);
+ }
+ return class_exists($class);
+ }
+
+/**
+ * Construct an instance of the class to be tested.
+ * So that fixtures can be detected
+ *
+ * @param string $type The Type of object you are generating tests for eg. controller
+ * @param string $class the Classname of the class the test is being generated for.
+ * @return object And instance of the class that is going to be tested.
+ */
+ public function &buildTestSubject($type, $class) {
+ ClassRegistry::flush();
+ App::import($type, $class);
+ $class = $this->getRealClassName($type, $class);
+ if (strtolower($type) == 'model') {
+ $instance = ClassRegistry::init($class);
+ } else {
+ $instance = new $class();
+ }
+ return $instance;
+ }
+
+/**
+ * Gets the real class name from the cake short form. If the class name is already
+ * suffixed with the type, the type will not be duplicated.
+ *
+ * @param string $type The Type of object you are generating tests for eg. controller
+ * @param string $class the Classname of the class the test is being generated for.
+ * @return string Real classname
+ */
+ public function getRealClassName($type, $class) {
+ if (strtolower($type) == 'model' || empty($this->classTypes[$type])) {
+ return $class;
+ }
+
+ $position = strpos($class, $type);
+
+ if ($position !== false && strlen($class) - $position == strlen($type)) {
+ return $class;
+ }
+ return $class . $type;
+ }
+
+/**
+ * Map the types that TestTask uses to concrete types that App::uses can use.
+ *
+ * @param string $type The type of thing having a test generated.
+ * @param string $plugin The plugin name.
+ * @return string
+ * @throws CakeException When invalid object types are requested.
+ */
+ public function mapType($type, $plugin) {
+ $type = ucfirst($type);
+ if (empty($this->classTypes[$type])) {
+ throw new CakeException(__d('cake_dev', 'Invalid object type.'));
+ }
+ $real = $this->classTypes[$type];
+ if ($plugin) {
+ $real = trim($plugin, '.') . '.' . $real;
+ }
+ return $real;
+ }
+
+/**
+ * Get methods declared in the class given.
+ * No parent methods will be returned
+ *
+ * @param string $className Name of class to look at.
+ * @return array Array of method names.
+ */
+ public function getTestableMethods($className) {
+ $classMethods = get_class_methods($className);
+ $parentMethods = get_class_methods(get_parent_class($className));
+ $thisMethods = array_diff($classMethods, $parentMethods);
+ $out = array();
+ foreach ($thisMethods as $method) {
+ if (substr($method, 0, 1) != '_' && $method != strtolower($className)) {
+ $out[] = $method;
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Generate the list of fixtures that will be required to run this test based on
+ * loaded models.
+ *
+ * @param object $subject The object you want to generate fixtures for.
+ * @return array Array of fixtures to be included in the test.
+ */
+ public function generateFixtureList($subject) {
+ $this->_fixtures = array();
+ if (is_a($subject, 'Model')) {
+ $this->_processModel($subject);
+ } elseif (is_a($subject, 'Controller')) {
+ $this->_processController($subject);
+ }
+ return array_values($this->_fixtures);
+ }
+
+/**
+ * Process a model recursively and pull out all the
+ * model names converting them to fixture names.
+ *
+ * @param Model $subject A Model class to scan for associations and pull fixtures off of.
+ * @return void
+ */
+ protected function _processModel($subject) {
+ $this->_addFixture($subject->name);
+ $associated = $subject->getAssociated();
+ foreach ($associated as $alias => $type) {
+ $className = $subject->{$alias}->name;
+ if (!isset($this->_fixtures[$className])) {
+ $this->_processModel($subject->{$alias});
+ }
+ if ($type == 'hasAndBelongsToMany') {
+ if (!empty($subject->hasAndBelongsToMany[$alias]['with'])) {
+ list($plugin, $joinModel) = pluginSplit($subject->hasAndBelongsToMany[$alias]['with']);
+ } else {
+ $joinModel = Inflector::classify($subject->hasAndBelongsToMany[$alias]['joinTable']);
+ }
+ if (!isset($this->_fixtures[$joinModel])) {
+ $this->_processModel($subject->{$joinModel});
+ }
+ }
+ }
+ }
+
+/**
+ * Process all the models attached to a controller
+ * and generate a fixture list.
+ *
+ * @param Controller $subject A controller to pull model names off of.
+ * @return void
+ */
+ protected function _processController($subject) {
+ $subject->constructClasses();
+ $models = array(Inflector::classify($subject->name));
+ if (!empty($subject->uses)) {
+ $models = $subject->uses;
+ }
+ foreach ($models as $model) {
+ list($plugin, $model) = pluginSplit($model);
+ $this->_processModel($subject->{$model});
+ }
+ }
+
+/**
+ * Add classname to the fixture list.
+ * Sets the app. or plugin.plugin_name. prefix.
+ *
+ * @param string $name Name of the Model class that a fixture might be required for.
+ * @return void
+ */
+ protected function _addFixture($name) {
+ if ($this->plugin) {
+ $prefix = 'plugin.' . Inflector::underscore($this->plugin) . '.';
+ } else {
+ $prefix = 'app.';
+ }
+ $fixture = $prefix . Inflector::underscore($name);
+ $this->_fixtures[$name] = $fixture;
+ }
+
+/**
+ * Interact with the user to get additional fixtures they want to use.
+ *
+ * @return array Array of fixtures the user wants to add.
+ */
+ public function getUserFixtures() {
+ $proceed = $this->in(__d('cake_console', 'Bake could not detect fixtures, would you like to add some?'), array('y', 'n'), 'n');
+ $fixtures = array();
+ if (strtolower($proceed) == 'y') {
+ $fixtureList = $this->in(__d('cake_console', "Please provide a comma separated list of the fixtures names you'd like to use.\nExample: 'app.comment, app.post, plugin.forums.post'"));
+ $fixtureListTrimmed = str_replace(' ', '', $fixtureList);
+ $fixtures = explode(',', $fixtureListTrimmed);
+ }
+ $this->_fixtures = array_merge($this->_fixtures, $fixtures);
+ return $fixtures;
+ }
+
+/**
+ * Is a mock class required for this type of test?
+ * Controllers require a mock class.
+ *
+ * @param string $type The type of object tests are being generated for eg. controller.
+ * @return boolean
+ */
+ public function hasMockClass($type) {
+ $type = strtolower($type);
+ return $type == 'controller';
+ }
+
+/**
+ * Generate a constructor code snippet for the type and classname
+ *
+ * @param string $type The Type of object you are generating tests for eg. controller
+ * @param string $fullClassName The Classname of the class the test is being generated for.
+ * @param string $plugin The plugin name.
+ * @return array Constructor snippets for the thing you are building.
+ */
+ public function generateConstructor($type, $fullClassName, $plugin) {
+ $type = strtolower($type);
+ $pre = $construct = $post = '';
+ if ($type == 'model') {
+ $construct = "ClassRegistry::init('{$plugin}$fullClassName');\n";
+ }
+ if ($type == 'behavior') {
+ $construct = "new $fullClassName();\n";
+ }
+ if ($type == 'helper') {
+ $pre = "\$View = new View();\n";
+ $construct = "new {$fullClassName}(\$View);\n";
+ }
+ if ($type == 'component') {
+ $pre = "\$Collection = new ComponentCollection();\n";
+ $construct = "new {$fullClassName}(\$Collection);\n";
+ }
+ return array($pre, $construct, $post);
+ }
+
+/**
+ * Generate the uses() calls for a type & classname
+ *
+ * @param string $type The Type of object you are generating tests for eg. controller
+ * @param string $realType The package name for the class.
+ * @param string $className The Classname of the class the test is being generated for.
+ * @return array An array containing used classes
+ */
+ public function generateUses($type, $realType, $className) {
+ $uses = array();
+ if ($type == 'component') {
+ $uses[] = array('ComponentCollection', 'Controller');
+ $uses[] = array('Component', 'Controller');
+ }
+ if ($type == 'helper') {
+ $uses[] = array('View', 'View');
+ $uses[] = array('Helper', 'View');
+ }
+ $uses[] = array($className, $realType);
+ return $uses;
+ }
+
+/**
+ * Make the filename for the test case. resolve the suffixes for controllers
+ * and get the plugin path if needed.
+ *
+ * @param string $type The Type of object you are generating tests for eg. controller
+ * @param string $className the Classname of the class the test is being generated for.
+ * @return string filename the test should be created on.
+ */
+ public function testCaseFileName($type, $className) {
+ $path = $this->getPath() . 'Case' . DS;
+ $type = Inflector::camelize($type);
+ if (isset($this->classTypes[$type])) {
+ $path .= $this->classTypes[$type] . DS;
+ }
+ $className = $this->getRealClassName($type, $className);
+ return str_replace('/', DS, $path) . Inflector::camelize($className) . 'Test.php';
+ }
+
+/**
+ * get the option parser.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(__d('cake_console', 'Bake test case skeletons for classes.'))
+ ->addArgument('type', array(
+ 'help' => __d('cake_console', 'Type of class to bake, can be any of the following: controller, model, helper, component or behavior.'),
+ 'choices' => array(
+ 'Controller', 'controller',
+ 'Model', 'model',
+ 'Helper', 'helper',
+ 'Component', 'component',
+ 'Behavior', 'behavior'
+ )
+ ))->addArgument('name', array(
+ 'help' => __d('cake_console', 'An existing class to bake tests for.')
+ ))->addOption('plugin', array(
+ 'short' => 'p',
+ 'help' => __d('cake_console', 'CamelCased name of the plugin to bake tests for.')
+ ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ViewTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ViewTask.php
new file mode 100644
index 0000000..8baf426
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/Task/ViewTask.php
@@ -0,0 +1,468 @@
+<?php
+/**
+ * The View Tasks handles creating and updating view files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('Controller', 'Controller');
+App::uses('BakeTask', 'Console/Command/Task');
+
+/**
+ * Task class for creating and updating view files.
+ *
+ * @package Cake.Console.Command.Task
+ */
+class ViewTask extends BakeTask {
+
+/**
+ * Tasks to be loaded by this Task
+ *
+ * @var array
+ */
+ public $tasks = array('Project', 'Controller', 'DbConfig', 'Template');
+
+/**
+ * path to View directory
+ *
+ * @var array
+ */
+ public $path = null;
+
+/**
+ * Name of the controller being used
+ *
+ * @var string
+ */
+ public $controllerName = null;
+
+/**
+ * The template file to use
+ *
+ * @var string
+ */
+ public $template = null;
+
+/**
+ * Actions to use for scaffolding
+ *
+ * @var array
+ */
+ public $scaffoldActions = array('index', 'view', 'add', 'edit');
+
+/**
+ * An array of action names that don't require templates. These
+ * actions will not emit errors when doing bakeActions()
+ *
+ * @var array
+ */
+ public $noTemplateActions = array('delete');
+
+/**
+ * Override initialize
+ *
+ * @return void
+ */
+ public function initialize() {
+ $this->path = current(App::path('View'));
+ }
+
+/**
+ * Execution method always used for tasks
+ *
+ * @return mixed
+ */
+ public function execute() {
+ parent::execute();
+ if (empty($this->args)) {
+ $this->_interactive();
+ }
+ if (empty($this->args[0])) {
+ return;
+ }
+ if (!isset($this->connection)) {
+ $this->connection = 'default';
+ }
+ $action = null;
+ $this->controllerName = $this->_controllerName($this->args[0]);
+
+ $this->Project->interactive = false;
+ if (strtolower($this->args[0]) == 'all') {
+ return $this->all();
+ }
+
+ if (isset($this->args[1])) {
+ $this->template = $this->args[1];
+ }
+ if (isset($this->args[2])) {
+ $action = $this->args[2];
+ }
+ if (!$action) {
+ $action = $this->template;
+ }
+ if ($action) {
+ return $this->bake($action, true);
+ }
+
+ $vars = $this->_loadController();
+ $methods = $this->_methodsToBake();
+
+ foreach ($methods as $method) {
+ $content = $this->getContent($method, $vars);
+ if ($content) {
+ $this->bake($method, $content);
+ }
+ }
+ }
+
+/**
+ * Get a list of actions that can / should have views baked for them.
+ *
+ * @return array Array of action names that should be baked
+ */
+ protected function _methodsToBake() {
+ $methods = array_diff(
+ array_map('strtolower', get_class_methods($this->controllerName . 'Controller')),
+ array_map('strtolower', get_class_methods('AppController'))
+ );
+ $scaffoldActions = false;
+ if (empty($methods)) {
+ $scaffoldActions = true;
+ $methods = $this->scaffoldActions;
+ }
+ $adminRoute = $this->Project->getPrefix();
+ foreach ($methods as $i => $method) {
+ if ($adminRoute && !empty($this->params['admin'])) {
+ if ($scaffoldActions) {
+ $methods[$i] = $adminRoute . $method;
+ continue;
+ } elseif (strpos($method, $adminRoute) === false) {
+ unset($methods[$i]);
+ }
+ }
+ if ($method[0] === '_' || $method == strtolower($this->controllerName . 'Controller')) {
+ unset($methods[$i]);
+ }
+ }
+ return $methods;
+ }
+
+/**
+ * Bake All views for All controllers.
+ *
+ * @return void
+ */
+ public function all() {
+ $this->Controller->interactive = false;
+ $tables = $this->Controller->listAll($this->connection, false);
+
+ $actions = null;
+ if (isset($this->args[1])) {
+ $actions = array($this->args[1]);
+ }
+ $this->interactive = false;
+ foreach ($tables as $table) {
+ $model = $this->_modelName($table);
+ $this->controllerName = $this->_controllerName($model);
+ App::uses($model, 'Model');
+ if (class_exists($model)) {
+ $vars = $this->_loadController();
+ if (!$actions) {
+ $actions = $this->_methodsToBake();
+ }
+ $this->bakeActions($actions, $vars);
+ $actions = null;
+ }
+ }
+ }
+
+/**
+ * Handles interactive baking
+ *
+ * @return void
+ */
+ protected function _interactive() {
+ $this->hr();
+ $this->out(sprintf("Bake View\nPath: %s", $this->getPath()));
+ $this->hr();
+
+ $this->DbConfig->interactive = $this->Controller->interactive = $this->interactive = true;
+
+ if (empty($this->connection)) {
+ $this->connection = $this->DbConfig->getConfig();
+ }
+
+ $this->Controller->connection = $this->connection;
+ $this->controllerName = $this->Controller->getName();
+
+ $prompt = __d('cake_console', "Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite %s views if it exist.", $this->controllerName);
+ $interactive = $this->in($prompt, array('y', 'n'), 'n');
+
+ if (strtolower($interactive) == 'n') {
+ $this->interactive = false;
+ }
+
+ $prompt = __d('cake_console', "Would you like to create some CRUD views\n(index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller\nand model classes (including associated models).");
+ $wannaDoScaffold = $this->in($prompt, array('y', 'n'), 'y');
+
+ $wannaDoAdmin = $this->in(__d('cake_console', "Would you like to create the views for admin routing?"), array('y', 'n'), 'n');
+
+ if (strtolower($wannaDoScaffold) == 'y' || strtolower($wannaDoAdmin) == 'y') {
+ $vars = $this->_loadController();
+ if (strtolower($wannaDoScaffold) == 'y') {
+ $actions = $this->scaffoldActions;
+ $this->bakeActions($actions, $vars);
+ }
+ if (strtolower($wannaDoAdmin) == 'y') {
+ $admin = $this->Project->getPrefix();
+ $regularActions = $this->scaffoldActions;
+ $adminActions = array();
+ foreach ($regularActions as $action) {
+ $adminActions[] = $admin . $action;
+ }
+ $this->bakeActions($adminActions, $vars);
+ }
+ $this->hr();
+ $this->out();
+ $this->out(__d('cake_console', "View Scaffolding Complete.\n"));
+ } else {
+ $this->customAction();
+ }
+ }
+
+/**
+ * Loads Controller and sets variables for the template
+ * Available template variables
+ * 'modelClass', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
+ * 'singularHumanName', 'pluralHumanName', 'fields', 'foreignKeys',
+ * 'belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'
+ *
+ * @return array Returns an variables to be made available to a view template
+ */
+ protected function _loadController() {
+ if (!$this->controllerName) {
+ $this->err(__d('cake_console', 'Controller not found'));
+ }
+
+ $plugin = null;
+ if ($this->plugin) {
+ $plugin = $this->plugin . '.';
+ }
+
+ $controllerClassName = $this->controllerName . 'Controller';
+ App::uses($controllerClassName, $plugin . 'Controller');
+ if (!class_exists($controllerClassName)) {
+ $file = $controllerClassName . '.php';
+ $this->err(__d('cake_console', "The file '%s' could not be found.\nIn order to bake a view, you'll need to first create the controller.", $file));
+ $this->_stop();
+ }
+ $controllerObj = new $controllerClassName();
+ $controllerObj->plugin = $this->plugin;
+ $controllerObj->constructClasses();
+ $modelClass = $controllerObj->modelClass;
+ $modelObj = $controllerObj->{$controllerObj->modelClass};
+
+ if ($modelObj) {
+ $primaryKey = $modelObj->primaryKey;
+ $displayField = $modelObj->displayField;
+ $singularVar = Inflector::variable($modelClass);
+ $singularHumanName = $this->_singularHumanName($this->controllerName);
+ $schema = $modelObj->schema(true);
+ $fields = array_keys($schema);
+ $associations = $this->_associations($modelObj);
+ } else {
+ $primaryKey = $displayField = null;
+ $singularVar = Inflector::variable(Inflector::singularize($this->controllerName));
+ $singularHumanName = $this->_singularHumanName($this->controllerName);
+ $fields = $schema = $associations = array();
+ }
+ $pluralVar = Inflector::variable($this->controllerName);
+ $pluralHumanName = $this->_pluralHumanName($this->controllerName);
+
+ return compact('modelClass', 'schema', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
+ 'singularHumanName', 'pluralHumanName', 'fields', 'associations');
+ }
+
+/**
+ * Bake a view file for each of the supplied actions
+ *
+ * @param array $actions Array of actions to make files for.
+ * @param array $vars
+ * @return void
+ */
+ public function bakeActions($actions, $vars) {
+ foreach ($actions as $action) {
+ $content = $this->getContent($action, $vars);
+ $this->bake($action, $content);
+ }
+ }
+
+/**
+ * handle creation of baking a custom action view file
+ *
+ * @return void
+ */
+ public function customAction() {
+ $action = '';
+ while ($action == '') {
+ $action = $this->in(__d('cake_console', 'Action Name? (use lowercase_underscored function name)'));
+ if ($action == '') {
+ $this->out(__d('cake_console', 'The action name you supplied was empty. Please try again.'));
+ }
+ }
+ $this->out();
+ $this->hr();
+ $this->out(__d('cake_console', 'The following view will be created:'));
+ $this->hr();
+ $this->out(__d('cake_console', 'Controller Name: %s', $this->controllerName));
+ $this->out(__d('cake_console', 'Action Name: %s', $action));
+ $this->out(__d('cake_console', 'Path: %s', $this->getPath() . $this->controllerName . DS . Inflector::underscore($action) . ".ctp"));
+ $this->hr();
+ $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y');
+ if (strtolower($looksGood) == 'y') {
+ $this->bake($action, ' ');
+ $this->_stop();
+ } else {
+ $this->out(__d('cake_console', 'Bake Aborted.'));
+ }
+ }
+
+/**
+ * Assembles and writes bakes the view file.
+ *
+ * @param string $action Action to bake
+ * @param string $content Content to write
+ * @return boolean Success
+ */
+ public function bake($action, $content = '') {
+ if ($content === true) {
+ $content = $this->getContent($action);
+ }
+ if (empty($content)) {
+ return false;
+ }
+ $this->out("\n" . __d('cake_console', 'Baking `%s` view file...', $action), 1, Shell::QUIET);
+ $path = $this->getPath();
+ $filename = $path . $this->controllerName . DS . Inflector::underscore($action) . '.ctp';
+ return $this->createFile($filename, $content);
+ }
+
+/**
+ * Builds content from template and variables
+ *
+ * @param string $action name to generate content to
+ * @param array $vars passed for use in templates
+ * @return string content from template
+ */
+ public function getContent($action, $vars = null) {
+ if (!$vars) {
+ $vars = $this->_loadController();
+ }
+
+ $this->Template->set('action', $action);
+ $this->Template->set('plugin', $this->plugin);
+ $this->Template->set($vars);
+ $template = $this->getTemplate($action);
+ if ($template) {
+ return $this->Template->generate('views', $template);
+ }
+ return false;
+ }
+
+/**
+ * Gets the template name based on the action name
+ *
+ * @param string $action name
+ * @return string template name
+ */
+ public function getTemplate($action) {
+ if ($action != $this->template && in_array($action, $this->noTemplateActions)) {
+ return false;
+ }
+ if (!empty($this->template) && $action != $this->template) {
+ return $this->template;
+ }
+ $themePath = $this->Template->getThemePath();
+ if (file_exists($themePath . 'views' . DS . $action . '.ctp')) {
+ return $action;
+ }
+ $template = $action;
+ $prefixes = Configure::read('Routing.prefixes');
+ foreach ((array)$prefixes as $prefix) {
+ if (strpos($template, $prefix) !== false) {
+ $template = str_replace($prefix . '_', '', $template);
+ }
+ }
+ if (in_array($template, array('add', 'edit'))) {
+ $template = 'form';
+ } elseif (preg_match('@(_add|_edit)$@', $template)) {
+ $template = str_replace(array('_add', '_edit'), '_form', $template);
+ }
+ return $template;
+ }
+
+/**
+ * get the option parser for this task
+ *
+ * @return ConsoleOptionParser
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ return $parser->description(
+ __d('cake_console', 'Bake views for a controller, using built-in or custom templates.')
+ )->addArgument('controller', array(
+ 'help' => __d('cake_console', 'Name of the controller views to bake. Can be Plugin.name as a shortcut for plugin baking.')
+ ))->addArgument('action', array(
+ 'help' => __d('cake_console', "Will bake a single action's file. core templates are (index, add, edit, view)")
+ ))->addArgument('alias', array(
+ 'help' => __d('cake_console', 'Will bake the template in <action> but create the filename after <alias>.')
+ ))->addOption('plugin', array(
+ 'short' => 'p',
+ 'help' => __d('cake_console', 'Plugin to bake the view into.')
+ ))->addOption('admin', array(
+ 'help' => __d('cake_console', 'Set to only bake views for a prefix in Routing.prefixes'),
+ 'boolean' => true
+ ))->addOption('connection', array(
+ 'short' => 'c',
+ 'help' => __d('cake_console', 'The connection the connected model is on.')
+ ))->addSubcommand('all', array(
+ 'help' => __d('cake_console', 'Bake all CRUD action views for all controllers. Requires models and controllers to exist.')
+ ))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
+ }
+
+/**
+ * Returns associations for controllers models.
+ *
+ * @param Model $model
+ * @return array $associations
+ */
+ protected function _associations(Model $model) {
+ $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+ $associations = array();
+
+ foreach ($keys as $key => $type) {
+ foreach ($model->{$type} as $assocKey => $assocData) {
+ list($plugin, $modelClass) = pluginSplit($assocData['className']);
+ $associations[$type][$assocKey]['primaryKey'] = $model->{$assocKey}->primaryKey;
+ $associations[$type][$assocKey]['displayField'] = $model->{$assocKey}->displayField;
+ $associations[$type][$assocKey]['foreignKey'] = $assocData['foreignKey'];
+ $associations[$type][$assocKey]['controller'] = Inflector::pluralize(Inflector::underscore($modelClass));
+ $associations[$type][$assocKey]['fields'] = array_keys($model->{$assocKey}->schema(true));
+ }
+ }
+ return $associations;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestShell.php
new file mode 100644
index 0000000..0d0127a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestShell.php
@@ -0,0 +1,434 @@
+<?php
+/**
+ * Test Shell
+ *
+ * This Shell allows the running of test suites via the cake command line
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Shell', 'Console');
+App::uses('CakeTestSuiteDispatcher', 'TestSuite');
+App::uses('CakeTestSuiteCommand', 'TestSuite');
+App::uses('CakeTestLoader', 'TestSuite');
+
+/**
+ * Provides a CakePHP wrapper around PHPUnit.
+ * Adds in CakePHP's fixtures and gives access to plugin, app and core test cases
+ *
+ * @package Cake.Console.Command
+ */
+class TestShell extends Shell {
+
+/**
+ * Dispatcher object for the run.
+ *
+ * @var CakeTestDispatcher
+ */
+ protected $_dispatcher = null;
+
+/**
+ * get the option parser for the test suite.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = new ConsoleOptionParser($this->name);
+ $parser->description(array(
+ __d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line'),
+ ))->addArgument('category', array(
+ 'help' => __d('cake_console', 'The category for the test, or test file, to test.'),
+ 'required' => false,
+ ))->addArgument('file', array(
+ 'help' => __d('cake_console', 'The path to the file, or test file, to test.'),
+ 'required' => false,
+ ))->addOption('log-junit', array(
+ 'help' => __d('cake_console', '<file> Log test execution in JUnit XML format to file.'),
+ 'default' => false
+ ))->addOption('log-json', array(
+ 'help' => __d('cake_console', '<file> Log test execution in TAP format to file.'),
+ 'default' => false
+ ))->addOption('log-tap', array(
+ 'help' => __d('cake_console', '<file> Log test execution in TAP format to file.'),
+ 'default' => false
+ ))->addOption('log-dbus', array(
+ 'help' => __d('cake_console', 'Log test execution to DBUS.'),
+ 'default' => false
+ ))->addOption('coverage-html', array(
+ 'help' => __d('cake_console', '<dir> Generate code coverage report in HTML format.'),
+ 'default' => false
+ ))->addOption('coverage-clover', array(
+ 'help' => __d('cake_console', '<file> Write code coverage data in Clover XML format.'),
+ 'default' => false
+ ))->addOption('testdox-html', array(
+ 'help' => __d('cake_console', '<file> Write agile documentation in HTML format to file.'),
+ 'default' => false
+ ))->addOption('testdox-text', array(
+ 'help' => __d('cake_console', '<file> Write agile documentation in Text format to file.'),
+ 'default' => false
+ ))->addOption('filter', array(
+ 'help' => __d('cake_console', '<pattern> Filter which tests to run.'),
+ 'default' => false
+ ))->addOption('group', array(
+ 'help' => __d('cake_console', '<name> Only runs tests from the specified group(s).'),
+ 'default' => false
+ ))->addOption('exclude-group', array(
+ 'help' => __d('cake_console', '<name> Exclude tests from the specified group(s).'),
+ 'default' => false
+ ))->addOption('list-groups', array(
+ 'help' => __d('cake_console', 'List available test groups.'),
+ 'boolean' => true
+ ))->addOption('loader', array(
+ 'help' => __d('cake_console', 'TestSuiteLoader implementation to use.'),
+ 'default' => false
+ ))->addOption('repeat', array(
+ 'help' => __d('cake_console', '<times> Runs the test(s) repeatedly.'),
+ 'default' => false
+ ))->addOption('tap', array(
+ 'help' => __d('cake_console', 'Report test execution progress in TAP format.'),
+ 'boolean' => true
+ ))->addOption('testdox', array(
+ 'help' => __d('cake_console', 'Report test execution progress in TestDox format.'),
+ 'default' => false,
+ 'boolean' => true
+ ))->addOption('no-colors', array(
+ 'help' => __d('cake_console', 'Do not use colors in output.'),
+ 'boolean' => true
+ ))->addOption('stderr', array(
+ 'help' => __d('cake_console', 'Write to STDERR instead of STDOUT.'),
+ 'boolean' => true
+ ))->addOption('stop-on-error', array(
+ 'help' => __d('cake_console', 'Stop execution upon first error or failure.'),
+ 'boolean' => true
+ ))->addOption('stop-on-failure', array(
+ 'help' => __d('cake_console', 'Stop execution upon first failure.'),
+ 'boolean' => true
+ ))->addOption('stop-on-skipped ', array(
+ 'help' => __d('cake_console', 'Stop execution upon first skipped test.'),
+ 'boolean' => true
+ ))->addOption('stop-on-incomplete', array(
+ 'help' => __d('cake_console', 'Stop execution upon first incomplete test.'),
+ 'boolean' => true
+ ))->addOption('strict', array(
+ 'help' => __d('cake_console', 'Mark a test as incomplete if no assertions are made.'),
+ 'boolean' => true
+ ))->addOption('wait', array(
+ 'help' => __d('cake_console', 'Waits for a keystroke after each test.'),
+ 'boolean' => true
+ ))->addOption('process-isolation', array(
+ 'help' => __d('cake_console', 'Run each test in a separate PHP process.'),
+ 'boolean' => true
+ ))->addOption('no-globals-backup', array(
+ 'help' => __d('cake_console', 'Do not backup and restore $GLOBALS for each test.'),
+ 'boolean' => true
+ ))->addOption('static-backup ', array(
+ 'help' => __d('cake_console', 'Backup and restore static attributes for each test.'),
+ 'boolean' => true
+ ))->addOption('syntax-check', array(
+ 'help' => __d('cake_console', 'Try to check source files for syntax errors.'),
+ 'boolean' => true
+ ))->addOption('bootstrap', array(
+ 'help' => __d('cake_console', '<file> A "bootstrap" PHP file that is run before the tests.'),
+ 'default' => false
+ ))->addOption('configuration', array(
+ 'help' => __d('cake_console', '<file> Read configuration from XML file.'),
+ 'default' => false
+ ))->addOption('no-configuration', array(
+ 'help' => __d('cake_console', 'Ignore default configuration file (phpunit.xml).'),
+ 'boolean' => true
+ ))->addOption('include-path', array(
+ 'help' => __d('cake_console', '<path(s)> Prepend PHP include_path with given path(s).'),
+ 'default' => false
+ ))->addOption('directive', array(
+ 'help' => __d('cake_console', 'key[=value] Sets a php.ini value.'),
+ 'default' => false
+ ))->addOption('fixture', array(
+ 'help' => __d('cake_console', 'Choose a custom fixture manager.'),
+ ))->addOption('debug', array(
+ 'help' => __d('cake_console', 'More verbose output.'),
+ ));
+
+ return $parser;
+ }
+
+/**
+ * Initialization method installs PHPUnit and loads all plugins
+ *
+ * @return void
+ * @throws Exception
+ */
+ public function initialize() {
+ $this->_dispatcher = new CakeTestSuiteDispatcher();
+ $sucess = $this->_dispatcher->loadTestFramework();
+ if (!$sucess) {
+ throw new Exception(__d('cake_dev', 'Please install PHPUnit framework <info>(http://www.phpunit.de)</info>'));
+ }
+ }
+
+/**
+ * Parse the CLI options into an array CakeTestDispatcher can use.
+ *
+ * @return array Array of params for CakeTestDispatcher
+ */
+ protected function _parseArgs() {
+ if (empty($this->args)) {
+ return;
+ }
+ $params = array(
+ 'core' => false,
+ 'app' => false,
+ 'plugin' => null,
+ 'output' => 'text',
+ );
+
+ if (strpos($this->args[0], '.php')) {
+ $category = $this->_mapFileToCategory($this->args[0]);
+ $params['case'] = $this->_mapFileToCase($this->args[0], $category);
+ } else {
+ $category = $this->args[0];
+ if (isset($this->args[1])) {
+ $params['case'] = $this->args[1];
+ }
+ }
+
+ if ($category === 'core') {
+ $params['core'] = true;
+ } elseif ($category === 'app') {
+ $params['app'] = true;
+ } else {
+ $params['plugin'] = $category;
+ }
+
+ return $params;
+ }
+
+/**
+ * Converts the options passed to the shell as options for the PHPUnit cli runner
+ *
+ * @return array Array of params for CakeTestDispatcher
+ */
+ protected function _runnerOptions() {
+ $options = array();
+ $params = $this->params;
+ unset($params['help']);
+
+ if (!empty($params['no-colors'])) {
+ unset($params['no-colors'], $params['colors']);
+ } else {
+ $params['colors'] = true;
+ }
+
+ foreach ($params as $param => $value) {
+ if ($value === false) {
+ continue;
+ }
+ $options[] = '--' . $param;
+ if (is_string($value)) {
+ $options[] = $value;
+ }
+ }
+ return $options;
+ }
+
+/**
+ * Main entry point to this shell
+ *
+ * @return void
+ */
+ public function main() {
+ $this->out(__d('cake_console', 'CakePHP Test Shell'));
+ $this->hr();
+
+ $args = $this->_parseArgs();
+
+ if (empty($args['case'])) {
+ return $this->available();
+ }
+
+ $this->_run($args, $this->_runnerOptions());
+ }
+
+/**
+ * Runs the test case from $runnerArgs
+ *
+ * @param array $runnerArgs list of arguments as obtained from _parseArgs()
+ * @param array $options list of options as constructed by _runnerOptions()
+ * @return void
+ */
+ protected function _run($runnerArgs, $options = array()) {
+ restore_error_handler();
+ restore_error_handler();
+
+ $testCli = new CakeTestSuiteCommand('CakeTestLoader', $runnerArgs);
+ $testCli->run($options);
+ }
+
+/**
+ * Shows a list of available test cases and gives the option to run one of them
+ *
+ * @return void
+ */
+ public function available() {
+ $params = $this->_parseArgs();
+ $testCases = CakeTestLoader::generateTestList($params);
+ $app = $params['app'];
+ $plugin = $params['plugin'];
+
+ $title = "Core Test Cases:";
+ $category = 'core';
+ if ($app) {
+ $title = "App Test Cases:";
+ $category = 'app';
+ } elseif ($plugin) {
+ $title = Inflector::humanize($plugin) . " Test Cases:";
+ $category = $plugin;
+ }
+
+ if (empty($testCases)) {
+ $this->out(__d('cake_console', "No test cases available \n\n"));
+ return $this->out($this->OptionParser->help());
+ }
+
+ $this->out($title);
+ $i = 1;
+ $cases = array();
+ foreach ($testCases as $testCaseFile => $testCase) {
+ $case = str_replace('Test.php', '', $testCase);
+ $this->out("[$i] $case");
+ $cases[$i] = $case;
+ $i++;
+ }
+
+ while ($choice = $this->in(__d('cake_console', 'What test case would you like to run?'), null, 'q')) {
+ if (is_numeric($choice) && isset($cases[$choice])) {
+ $this->args[0] = $category;
+ $this->args[1] = $cases[$choice];
+ $this->_run($this->_parseArgs(), $this->_runnerOptions());
+ break;
+ }
+
+ if (is_string($choice) && in_array($choice, $cases)) {
+ $this->args[0] = $category;
+ $this->args[1] = $choice;
+ $this->_run($this->_parseArgs(), $this->_runnerOptions());
+ break;
+ }
+
+ if ($choice == 'q') {
+ break;
+ }
+ }
+ }
+
+/**
+ * Find the test case for the passed file. The file could itself be a test.
+ *
+ * @param string $file
+ * @param string $category
+ * @param boolean $throwOnMissingFile
+ * @access protected
+ * @return array(type, case)
+ * @throws Exception
+ */
+ protected function _mapFileToCase($file, $category, $throwOnMissingFile = true) {
+ if (!$category || (substr($file, -4) !== '.php')) {
+ return false;
+ }
+
+ $_file = realpath($file);
+ if ($_file) {
+ $file = $_file;
+ }
+
+ $testFile = $testCase = null;
+
+ if (preg_match('@Test[\\\/]@', $file)) {
+
+ if (substr($file, -8) === 'Test.php') {
+
+ $testCase = substr($file, 0, -8);
+ $testCase = str_replace(DS, '/', $testCase);
+
+ if ($testCase = preg_replace('@.*Test\/Case\/@', '', $testCase)) {
+
+ if ($category === 'core') {
+ $testCase = str_replace('lib/Cake', '', $testCase);
+ }
+
+ return $testCase;
+ }
+
+ throw new Exception(__d('cake_dev', 'Test case %s cannot be run via this shell', $testFile));
+ }
+ }
+
+ $file = substr($file, 0, -4);
+ if ($category === 'core') {
+
+ $testCase = str_replace(DS, '/', $file);
+ $testCase = preg_replace('@.*lib/Cake/@', '', $file);
+ $testCase[0] = strtoupper($testCase[0]);
+ $testFile = CAKE . 'Test/Case/' . $testCase . 'Test.php';
+
+ if (!file_exists($testFile) && $throwOnMissingFile) {
+ throw new Exception(__d('cake_dev', 'Test case %s not found', $testFile));
+ }
+
+ return $testCase;
+ }
+
+ if ($category === 'app') {
+ $testFile = str_replace(APP, APP . 'Test/Case/', $file) . 'Test.php';
+ } else {
+ $testFile = preg_replace(
+ "@((?:plugins|Plugin)[\\/]{$category}[\\/])(.*)$@",
+ '\1Test/Case/\2Test.php',
+ $file
+ );
+ }
+
+ if (!file_exists($testFile) && $throwOnMissingFile) {
+ throw new Exception(__d('cake_dev', 'Test case %s not found', $testFile));
+ }
+
+ $testCase = substr($testFile, 0, -8);
+ $testCase = str_replace(DS, '/', $testCase);
+ $testCase = preg_replace('@.*Test/Case/@', '', $testCase);
+
+ return $testCase;
+ }
+
+/**
+ * For the given file, what category of test is it? returns app, core or the name of the plugin
+ *
+ * @param string $file
+ * @access protected
+ * @return string
+ */
+ protected function _mapFileToCategory($file) {
+ $_file = realpath($file);
+ if ($_file) {
+ $file = $_file;
+ }
+
+ $file = str_replace(DS, '/', $file);
+ if (strpos($file, 'lib/Cake/') !== false) {
+ return 'core';
+ } elseif (preg_match('@(?:plugins|Plugin)/([^/]*)@', $file, $match)) {
+ return $match[1];
+ }
+ return 'app';
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestsuiteShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestsuiteShell.php
new file mode 100644
index 0000000..2f858c2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/TestsuiteShell.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Test Suite Shell
+ *
+ * This is a bc wrapper for the newer Test shell
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('TestShell', 'Console/Command');
+App::uses('AppShell', 'Console/Command');
+App::uses('CakeTestSuiteDispatcher', 'TestSuite');
+App::uses('CakeTestSuiteCommand', 'TestSuite');
+App::uses('CakeTestLoader', 'TestSuite');
+
+/**
+ * Provides a CakePHP wrapper around PHPUnit.
+ * Adds in CakePHP's fixtures and gives access to plugin, app and core test cases
+ *
+ * @package Cake.Console.Command
+ */
+class TestsuiteShell extends TestShell {
+
+/**
+ * get the option parser for the test suite.
+ *
+ * @return void
+ */
+ public function getOptionParser() {
+ $parser = parent::getOptionParser();
+ $parser->description(array(
+ __d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line'),
+ __d('cake_console', '<warning>This shell is for backwards-compatibility only</warning>'),
+ __d('cake_console', 'use the test shell instead')
+ ));
+
+ return $parser;
+ }
+
+/**
+ * Parse the CLI options into an array CakeTestDispatcher can use.
+ *
+ * @return array Array of params for CakeTestDispatcher
+ */
+ protected function _parseArgs() {
+ if (empty($this->args)) {
+ return;
+ }
+ $params = array(
+ 'core' => false,
+ 'app' => false,
+ 'plugin' => null,
+ 'output' => 'text',
+ );
+
+ $category = $this->args[0];
+
+ if ($category == 'core') {
+ $params['core'] = true;
+ } elseif ($category == 'app') {
+ $params['app'] = true;
+ } elseif ($category != 'core') {
+ $params['plugin'] = $category;
+ }
+
+ if (isset($this->args[1])) {
+ $params['case'] = $this->args[1];
+ }
+ return $params;
+ }
+
+/**
+ * Main entry point to this shell
+ *
+ * @return void
+ */
+ public function main() {
+ $this->out(__d('cake_console', 'CakePHP Test Shell'));
+ $this->hr();
+
+ $args = $this->_parseArgs();
+
+ if (empty($args['case'])) {
+ return $this->available();
+ }
+
+ $this->_run($args, $this->_runnerOptions());
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/UpgradeShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/UpgradeShell.php
new file mode 100644
index 0000000..c9d3a21
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Command/UpgradeShell.php
@@ -0,0 +1,861 @@
+<?php
+/**
+ * Upgrade Shell
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Command
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppShell', 'Console/Command');
+App::uses('Folder', 'Utility');
+
+/**
+ * A shell class to help developers upgrade applications to CakePHP 2.0
+ *
+ * @package Cake.Console.Command
+ */
+class UpgradeShell extends AppShell {
+
+/**
+ * Files
+ *
+ * @var array
+ */
+ protected $_files = array();
+
+/**
+ * Paths
+ *
+ * @var array
+ */
+ protected $_paths = array();
+
+/**
+ * Map
+ *
+ * @var array
+ */
+ protected $_map = array(
+ 'Controller' => 'Controller',
+ 'Component' => 'Controller/Component',
+ 'Model' => 'Model',
+ 'Behavior' => 'Model/Behavior',
+ 'Datasource' => 'Model/Datasource',
+ 'Dbo' => 'Model/Datasource/Database',
+ 'View' => 'View',
+ 'Helper' => 'View/Helper',
+ 'Shell' => 'Console/Command',
+ 'Task' => 'Console/Command/Task',
+ 'Case' => 'Test/Case',
+ 'Fixture' => 'Test/Fixture',
+ 'Error' => 'Lib/Error',
+ );
+
+/**
+ * Shell startup, prints info message about dry run.
+ *
+ * @return void
+ */
+ public function startup() {
+ parent::startup();
+ if ($this->params['dry-run']) {
+ $this->out(__d('cake_console', '<warning>Dry-run mode enabled!</warning>'), 1, Shell::QUIET);
+ }
+ if ($this->params['git'] && !is_dir('.git')) {
+ $this->out(__d('cake_console', '<warning>No git repository detected!</warning>'), 1, Shell::QUIET);
+ }
+ }
+
+/**
+ * Run all upgrade steps one at a time
+ *
+ * @return void
+ */
+ public function all() {
+ foreach ($this->OptionParser->subcommands() as $command) {
+ $name = $command->name();
+ if ($name === 'all') {
+ continue;
+ }
+ $this->out(__d('cake_console', 'Running %s', $name));
+ $this->$name();
+ }
+ }
+
+/**
+ * Update tests.
+ *
+ * - Update tests class names to FooTest rather than FooTestCase.
+ *
+ * @return void
+ */
+ public function tests() {
+ $this->_paths = array(APP . 'tests' . DS);
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']) . 'tests' . DS);
+ }
+ $patterns = array(
+ array(
+ '*TestCase extends CakeTestCase to *Test extends CakeTestCase',
+ '/([a-zA-Z]*Test)Case extends CakeTestCase/',
+ '\1 extends CakeTestCase'
+ ),
+ );
+
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Move files and folders to their new homes
+ *
+ * Moves folders containing files which cannot necessarily be auto-detected (libs and templates)
+ * and then looks for all php files except vendors, and moves them to where Cake 2.0 expects
+ * to find them.
+ *
+ * @return void
+ */
+ public function locations() {
+ $cwd = getcwd();
+
+ if (!empty($this->params['plugin'])) {
+ chdir(App::pluginPath($this->params['plugin']));
+ }
+
+ if (is_dir('plugins')) {
+ $Folder = new Folder('plugins');
+ list($plugins) = $Folder->read();
+ foreach ($plugins as $plugin) {
+ chdir($cwd . DS . 'plugins' . DS . $plugin);
+ $this->out(__d('cake_console', 'Upgrading locations for plugin %s', $plugin));
+ $this->locations();
+ }
+ $this->_files = array();
+ chdir($cwd);
+ $this->out(__d('cake_console', 'Upgrading locations for app directory'));
+ }
+ $moves = array(
+ 'config' => 'Config',
+ 'Config' . DS . 'schema' => 'Config' . DS . 'Schema',
+ 'libs' => 'Lib',
+ 'tests' => 'Test',
+ 'views' => 'View',
+ 'models' => 'Model',
+ 'Model' . DS . 'behaviors' => 'Model' . DS . 'Behavior',
+ 'Model' . DS . 'datasources' => 'Model' . DS . 'Datasource',
+ 'Test' . DS . 'cases' => 'Test' . DS . 'Case',
+ 'Test' . DS . 'fixtures' => 'Test' . DS . 'Fixture',
+ 'vendors' . DS . 'shells' . DS . 'templates' => 'Console' . DS . 'Templates',
+ );
+ foreach ($moves as $old => $new) {
+ if (is_dir($old)) {
+ $this->out(__d('cake_console', 'Moving %s to %s', $old, $new));
+ if (!$this->params['dry-run']) {
+ if ($this->params['git']) {
+ exec('git mv -f ' . escapeshellarg($old) . ' ' . escapeshellarg($old . '__'));
+ exec('git mv -f ' . escapeshellarg($old . '__') . ' ' . escapeshellarg($new));
+ } else {
+ $Folder = new Folder($old);
+ $Folder->move($new);
+ }
+ }
+ }
+ }
+
+ $this->_moveViewFiles();
+ $this->_moveAppClasses();
+
+ $sourceDirs = array(
+ '.' => array('recursive' => false),
+ 'Console',
+ 'controllers',
+ 'Controller',
+ 'Lib' => array('checkFolder' => false),
+ 'models',
+ 'Model',
+ 'tests',
+ 'Test' => array('regex' => '@class (\S*Test) extends CakeTestCase@'),
+ 'views',
+ 'View',
+ 'vendors/shells',
+ );
+
+ $defaultOptions = array(
+ 'recursive' => true,
+ 'checkFolder' => true,
+ 'regex' => '@class (\S*) .*(\s|\v)*{@i'
+ );
+ foreach ($sourceDirs as $dir => $options) {
+ if (is_numeric($dir)) {
+ $dir = $options;
+ $options = array();
+ }
+ $options = array_merge($defaultOptions, $options);
+ $this->_movePhpFiles($dir, $options);
+ }
+ }
+
+/**
+ * Update helpers.
+ *
+ * - Converts helpers usage to new format.
+ *
+ * @return void
+ */
+ public function helpers() {
+ $this->_paths = array_diff(App::path('views'), App::core('views'));
+
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']) . 'views' . DS);
+ }
+
+ $patterns = array();
+ App::build(array(
+ 'View/Helper' => App::core('View/Helper'),
+ ), App::APPEND);
+ $helpers = App::objects('helper');
+ $plugins = App::objects('plugin');
+ $pluginHelpers = array();
+ foreach ($plugins as $plugin) {
+ CakePlugin::load($plugin);
+ $pluginHelpers = array_merge(
+ $pluginHelpers,
+ App::objects('helper', App::pluginPath($plugin) . DS . 'views' . DS . 'helpers' . DS, false)
+ );
+ }
+ $helpers = array_merge($pluginHelpers, $helpers);
+ foreach ($helpers as $helper) {
+ $helper = preg_replace('/Helper$/', '', $helper);
+ $oldHelper = $helper;
+ $oldHelper{0} = strtolower($oldHelper{0});
+ $patterns[] = array(
+ "\${$oldHelper} to \$this->{$helper}",
+ "/\\\${$oldHelper}->/",
+ "\\\$this->{$helper}->"
+ );
+ }
+
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Update i18n.
+ *
+ * - Removes extra true param.
+ * - Add the echo to __*() calls that didn't need them before.
+ *
+ * @return void
+ */
+ public function i18n() {
+ $this->_paths = array(
+ APP
+ );
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']));
+ }
+
+ $patterns = array(
+ array(
+ '<?php __*(*) to <?php echo __*(*)',
+ '/<\?php\s*(__[a-z]*\(.*?\))/',
+ '<?php echo \1'
+ ),
+ array(
+ '<?php __*(*, true) to <?php echo __*()',
+ '/<\?php\s*(__[a-z]*\(.*?)(,\s*true)(\))/',
+ '<?php echo \1\3'
+ ),
+ array('__*(*, true) to __*(*)', '/(__[a-z]*\(.*?)(,\s*true)(\))/', '\1\3')
+ );
+
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Upgrade the removed basics functions.
+ *
+ * - a(*) -> array(*)
+ * - e(*) -> echo *
+ * - ife(*, *, *) -> !empty(*) ? * : *
+ * - a(*) -> array(*)
+ * - r(*, *, *) -> str_replace(*, *, *)
+ * - up(*) -> strtoupper(*)
+ * - low(*, *, *) -> strtolower(*)
+ * - getMicrotime() -> microtime(true)
+ *
+ * @return void
+ */
+ public function basics() {
+ $this->_paths = array(
+ APP
+ );
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']));
+ }
+ $patterns = array(
+ array(
+ 'a(*) -> array(*)',
+ '/\ba\((.*)\)/',
+ 'array(\1)'
+ ),
+ array(
+ 'e(*) -> echo *',
+ '/\be\((.*)\)/',
+ 'echo \1'
+ ),
+ array(
+ 'ife(*, *, *) -> !empty(*) ? * : *',
+ '/ife\((.*), (.*), (.*)\)/',
+ '!empty(\1) ? \2 : \3'
+ ),
+ array(
+ 'r(*, *, *) -> str_replace(*, *, *)',
+ '/\br\(/',
+ 'str_replace('
+ ),
+ array(
+ 'up(*) -> strtoupper(*)',
+ '/\bup\(/',
+ 'strtoupper('
+ ),
+ array(
+ 'low(*) -> strtolower(*)',
+ '/\blow\(/',
+ 'strtolower('
+ ),
+ array(
+ 'getMicrotime() -> microtime(true)',
+ '/getMicrotime\(\)/',
+ 'microtime(true)'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Update the properties moved to CakeRequest.
+ *
+ * @return void
+ */
+ public function request() {
+ $views = array_diff(App::path('views'), App::core('views'));
+ $controllers = array_diff(App::path('controllers'), App::core('controllers'), array(APP));
+ $components = array_diff(App::path('components'), App::core('components'));
+
+ $this->_paths = array_merge($views, $controllers, $components);
+
+ if (!empty($this->params['plugin'])) {
+ $pluginPath = App::pluginPath($this->params['plugin']);
+ $this->_paths = array(
+ $pluginPath . 'controllers' . DS,
+ $pluginPath . 'controllers' . DS . 'components' . DS,
+ $pluginPath . 'views' . DS,
+ );
+ }
+ $patterns = array(
+ array(
+ '$this->data -> $this->request->data',
+ '/(\$this->data\b(?!\())/',
+ '$this->request->data'
+ ),
+ array(
+ '$this->params -> $this->request->params',
+ '/(\$this->params\b(?!\())/',
+ '$this->request->params'
+ ),
+ array(
+ '$this->webroot -> $this->request->webroot',
+ '/(\$this->webroot\b(?!\())/',
+ '$this->request->webroot'
+ ),
+ array(
+ '$this->base -> $this->request->base',
+ '/(\$this->base\b(?!\())/',
+ '$this->request->base'
+ ),
+ array(
+ '$this->here -> $this->request->here',
+ '/(\$this->here\b(?!\())/',
+ '$this->request->here'
+ ),
+ array(
+ '$this->action -> $this->request->action',
+ '/(\$this->action\b(?!\())/',
+ '$this->request->action'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Update Configure::read() calls with no params.
+ *
+ * @return void
+ */
+ public function configure() {
+ $this->_paths = array(
+ APP
+ );
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']));
+ }
+ $patterns = array(
+ array(
+ "Configure::read() -> Configure::read('debug')",
+ '/Configure::read\(\)/',
+ 'Configure::read(\'debug\')'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * constants
+ *
+ * @return void
+ */
+ public function constants() {
+ $this->_paths = array(
+ APP
+ );
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']));
+ }
+ $patterns = array(
+ array(
+ "LIBS -> CAKE",
+ '/\bLIBS\b/',
+ 'CAKE'
+ ),
+ array(
+ "CONFIGS -> APP . 'Config' . DS",
+ '/\bCONFIGS\b/',
+ 'APP . \'Config\' . DS'
+ ),
+ array(
+ "CONTROLLERS -> APP . 'Controller' . DS",
+ '/\bCONTROLLERS\b/',
+ 'APP . \'Controller\' . DS'
+ ),
+ array(
+ "COMPONENTS -> APP . 'Controller' . DS . 'Component' . DS",
+ '/\bCOMPONENTS\b/',
+ 'APP . \'Controller\' . DS . \'Component\''
+ ),
+ array(
+ "MODELS -> APP . 'Model' . DS",
+ '/\bMODELS\b/',
+ 'APP . \'Model\' . DS'
+ ),
+ array(
+ "BEHAVIORS -> APP . 'Model' . DS . 'Behavior' . DS",
+ '/\bBEHAVIORS\b/',
+ 'APP . \'Model\' . DS . \'Behavior\' . DS'
+ ),
+ array(
+ "VIEWS -> APP . 'View' . DS",
+ '/\bVIEWS\b/',
+ 'APP . \'View\' . DS'
+ ),
+ array(
+ "HELPERS -> APP . 'View' . DS . 'Helper' . DS",
+ '/\bHELPERS\b/',
+ 'APP . \'View\' . DS . \'Helper\' . DS'
+ ),
+ array(
+ "LAYOUTS -> APP . 'View' . DS . 'Layouts' . DS",
+ '/\bLAYOUTS\b/',
+ 'APP . \'View\' . DS . \'Layouts\' . DS'
+ ),
+ array(
+ "ELEMENTS -> APP . 'View' . DS . 'Elements' . DS",
+ '/\bELEMENTS\b/',
+ 'APP . \'View\' . DS . \'Elements\' . DS'
+ ),
+ array(
+ "CONSOLE_LIBS -> CAKE . 'Console' . DS",
+ '/\bCONSOLE_LIBS\b/',
+ 'CAKE . \'Console\' . DS'
+ ),
+ array(
+ "CAKE_TESTS_LIB -> CAKE . 'TestSuite' . DS",
+ '/\bCAKE_TESTS_LIB\b/',
+ 'CAKE . \'TestSuite\' . DS'
+ ),
+ array(
+ "CAKE_TESTS -> CAKE . 'Test' . DS",
+ '/\bCAKE_TESTS\b/',
+ 'CAKE . \'Test\' . DS'
+ )
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Update components.
+ *
+ * - Make components that extend Object to extend Component.
+ *
+ * @return void
+ */
+ public function components() {
+ $this->_paths = App::Path('Controller/Component');
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = App::Path('Controller/Component', $this->params['plugin']);
+ }
+ $patterns = array(
+ array(
+ '*Component extends Object to *Component extends Component',
+ '/([a-zA-Z]*Component extends) Object/',
+ '\1 Component'
+ ),
+ );
+
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Replace cakeError with built-in exceptions.
+ * NOTE: this ignores calls where you've passed your own secondary parameters to cakeError().
+ * @return void
+ */
+ public function exceptions() {
+ $controllers = array_diff(App::path('controllers'), App::core('controllers'), array(APP));
+ $components = array_diff(App::path('components'), App::core('components'));
+
+ $this->_paths = array_merge($controllers, $components);
+
+ if (!empty($this->params['plugin'])) {
+ $pluginPath = App::pluginPath($this->params['plugin']);
+ $this->_paths = array(
+ $pluginPath . 'controllers' . DS,
+ $pluginPath . 'controllers' . DS . 'components' . DS,
+ );
+ }
+ $patterns = array(
+ array(
+ '$this->cakeError("error400") -> throw new BadRequestException()',
+ '/(\$this->cakeError\(["\']error400["\']\));/',
+ 'throw new BadRequestException();'
+ ),
+ array(
+ '$this->cakeError("error404") -> throw new NotFoundException()',
+ '/(\$this->cakeError\(["\']error404["\']\));/',
+ 'throw new NotFoundException();'
+ ),
+ array(
+ '$this->cakeError("error500") -> throw new InternalErrorException()',
+ '/(\$this->cakeError\(["\']error500["\']\));/',
+ 'throw new InternalErrorException();'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Move application views files to where they now should be
+ *
+ * Find all view files in the folder and determine where cake expects the file to be
+ *
+ * @return void
+ */
+ protected function _moveViewFiles() {
+ if (!is_dir('View')) {
+ return;
+ }
+
+ $dirs = scandir('View');
+ foreach ($dirs as $old) {
+ if (!is_dir('View' . DS . $old) || $old === '.' || $old === '..') {
+ continue;
+ }
+
+ $new = 'View' . DS . Inflector::camelize($old);
+ $old = 'View' . DS . $old;
+ if ($new == $old) {
+ continue;
+ }
+
+ $this->out(__d('cake_console', 'Moving %s to %s', $old, $new));
+ if (!$this->params['dry-run']) {
+ if ($this->params['git']) {
+ exec('git mv -f ' . escapeshellarg($old) . ' ' . escapeshellarg($old . '__'));
+ exec('git mv -f ' . escapeshellarg($old . '__') . ' ' . escapeshellarg($new));
+ } else {
+ $Folder = new Folder($old);
+ $Folder->move($new);
+ }
+ }
+ }
+ }
+
+/**
+ * Move the AppController, and AppModel classes.
+ *
+ * @return void
+ */
+ protected function _moveAppClasses() {
+ $files = array(
+ APP . 'app_controller.php' => APP . 'Controller' . DS . 'AppController.php',
+ APP . 'controllers' . DS . 'app_controller.php' => APP . 'Controller' . DS . 'AppController.php',
+ APP . 'app_model.php' => APP . 'Model' . DS . 'AppModel.php',
+ APP . 'models' . DS . 'app_model.php' => APP . 'Model' . DS . 'AppModel.php',
+ );
+ foreach ($files as $old => $new) {
+ if (file_exists($old)) {
+ $this->out(__d('cake_console', 'Moving %s to %s', $old, $new));
+
+ if ($this->params['dry-run']) {
+ continue;
+ }
+ if ($this->params['git']) {
+ exec('git mv -f ' . escapeshellarg($old) . ' ' . escapeshellarg($old . '__'));
+ exec('git mv -f ' . escapeshellarg($old . '__') . ' ' . escapeshellarg($new));
+ } else {
+ rename($old, $new);
+ }
+ }
+ }
+ }
+
+/**
+ * Move application php files to where they now should be
+ *
+ * Find all php files in the folder (honoring recursive) and determine where cake expects the file to be
+ * If the file is not exactly where cake expects it - move it.
+ *
+ * @param string $path
+ * @param array $options array(recursive, checkFolder)
+ * @return void
+ */
+ protected function _movePhpFiles($path, $options) {
+ if (!is_dir($path)) {
+ return;
+ }
+
+ $paths = $this->_paths;
+
+ $this->_paths = array($path);
+ $this->_files = array();
+ if ($options['recursive']) {
+ $this->_findFiles('php');
+ } else {
+ $this->_files = scandir($path);
+ foreach ($this->_files as $i => $file) {
+ if (strlen($file) < 5 || substr($file, -4) !== '.php') {
+ unset($this->_files[$i]);
+ }
+ }
+ }
+
+ $cwd = getcwd();
+ foreach ($this->_files as &$file) {
+ $file = $cwd . DS . $file;
+
+ $contents = file_get_contents($file);
+ preg_match($options['regex'], $contents, $match);
+ if (!$match) {
+ continue;
+ }
+
+ $class = $match[1];
+
+ if (substr($class, 0, 3) === 'Dbo') {
+ $type = 'Dbo';
+ } else {
+ preg_match('@([A-Z][^A-Z]*)$@', $class, $match);
+ if ($match) {
+ $type = $match[1];
+ } else {
+ $type = 'unknown';
+ }
+ }
+
+ preg_match('@^.*[\\\/]plugins[\\\/](.*?)[\\\/]@', $file, $match);
+ $base = $cwd . DS;
+ $plugin = false;
+ if ($match) {
+ $base = $match[0];
+ $plugin = $match[1];
+ }
+
+ if ($options['checkFolder'] && !empty($this->_map[$type])) {
+ $folder = str_replace('/', DS, $this->_map[$type]);
+ $new = $base . $folder . DS . $class . '.php';
+ } else {
+ $new = dirname($file) . DS . $class . '.php';
+ }
+
+ if ($file === $new) {
+ continue;
+ }
+
+ $dir = dirname($new);
+ if (!is_dir($dir)) {
+ new Folder($dir, true);
+ }
+
+ $this->out(__d('cake_console', 'Moving %s to %s', $file, $new), 1, Shell::VERBOSE);
+ if (!$this->params['dry-run']) {
+ if ($this->params['git']) {
+ exec('git mv -f ' . escapeshellarg($file) . ' ' . escapeshellarg($file . '__'));
+ exec('git mv -f ' . escapeshellarg($file . '__') . ' ' . escapeshellarg($new));
+ } else {
+ rename($file, $new);
+ }
+ }
+ }
+
+ $this->_paths = $paths;
+ }
+
+/**
+ * Updates files based on regular expressions.
+ *
+ * @param array $patterns Array of search and replacement patterns.
+ * @return void
+ */
+ protected function _filesRegexpUpdate($patterns) {
+ $this->_findFiles($this->params['ext']);
+ foreach ($this->_files as $file) {
+ $this->out(__d('cake_console', 'Updating %s...', $file), 1, Shell::VERBOSE);
+ $this->_updateFile($file, $patterns);
+ }
+ }
+
+/**
+ * Searches the paths and finds files based on extension.
+ *
+ * @param string $extensions
+ * @return void
+ */
+ protected function _findFiles($extensions = '') {
+ $this->_files = array();
+ foreach ($this->_paths as $path) {
+ if (!is_dir($path)) {
+ continue;
+ }
+ $Iterator = new RegexIterator(
+ new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)),
+ '/^.+\.(' . $extensions . ')$/i',
+ RegexIterator::MATCH
+ );
+ foreach ($Iterator as $file) {
+ if ($file->isFile()) {
+ $this->_files[] = $file->getPathname();
+ }
+ }
+ }
+ }
+
+/**
+ * Update a single file.
+ *
+ * @param string $file The file to update
+ * @param array $patterns The replacement patterns to run.
+ * @return void
+ */
+ protected function _updateFile($file, $patterns) {
+ $contents = file_get_contents($file);
+
+ foreach ($patterns as $pattern) {
+ $this->out(__d('cake_console', ' * Updating %s', $pattern[0]), 1, Shell::VERBOSE);
+ $contents = preg_replace($pattern[1], $pattern[2], $contents);
+ }
+
+ $this->out(__d('cake_console', 'Done updating %s', $file), 1);
+ if (!$this->params['dry-run']) {
+ file_put_contents($file, $contents);
+ }
+ }
+
+/**
+ * get the option parser
+ *
+ * @return ConsoleOptionParser
+ */
+ public function getOptionParser() {
+ $subcommandParser = array(
+ 'options' => array(
+ 'plugin' => array(
+ 'short' => 'p',
+ 'help' => __d('cake_console', 'The plugin to update. Only the specified plugin will be updated.')
+ ),
+ 'ext' => array(
+ 'short' => 'e',
+ 'help' => __d('cake_console', 'The extension(s) to search. A pipe delimited list, or a preg_match compatible subpattern'),
+ 'default' => 'php|ctp|thtml|inc|tpl'
+ ),
+ 'git' => array(
+ 'short' => 'g',
+ 'help' => __d('cake_console', 'Use git command for moving files around.'),
+ 'boolean' => true
+ ),
+ 'dry-run' => array(
+ 'short' => 'd',
+ 'help' => __d('cake_console', 'Dry run the update, no files will actually be modified.'),
+ 'boolean' => true
+ )
+ )
+ );
+
+ return parent::getOptionParser()
+ ->description(__d('cake_console', "A shell to help automate upgrading from CakePHP 1.3 to 2.0. \n" .
+ "Be sure to have a backup of your application before running these commands."))
+ ->addSubcommand('all', array(
+ 'help' => __d('cake_console', 'Run all upgrade commands.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('tests', array(
+ 'help' => __d('cake_console', 'Update tests class names to FooTest rather than FooTestCase.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('locations', array(
+ 'help' => __d('cake_console', 'Move files and folders to their new homes.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('i18n', array(
+ 'help' => __d('cake_console', 'Update the i18n translation method calls.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('helpers', array(
+ 'help' => __d('cake_console', 'Update calls to helpers.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('basics', array(
+ 'help' => __d('cake_console', 'Update removed basics functions to PHP native functions.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('request', array(
+ 'help' => __d('cake_console', 'Update removed request access, and replace with $this->request.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('configure', array(
+ 'help' => __d('cake_console', "Update Configure::read() to Configure::read('debug')"),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('constants', array(
+ 'help' => __d('cake_console', "Replace Obsolete constants"),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('components', array(
+ 'help' => __d('cake_console', 'Update components to extend Component class.'),
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('exceptions', array(
+ 'help' => __d('cake_console', 'Replace use of cakeError with exceptions.'),
+ 'parser' => $subcommandParser
+ ));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleErrorHandler.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleErrorHandler.php
new file mode 100644
index 0000000..043c621
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleErrorHandler.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * ErrorHandler for Console Shells
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ErrorHandler', 'Error');
+App::uses('ConsoleOutput', 'Console');
+App::uses('CakeLog', 'Log');
+
+/**
+ * Error Handler for Cake console. Does simple printing of the
+ * exception that occurred and the stack trace of the error.
+ *
+ * @package Cake.Console
+ */
+class ConsoleErrorHandler {
+
+/**
+ * Standard error stream.
+ *
+ * @var ConsoleOutput
+ */
+ public static $stderr;
+
+/**
+ * Get the stderr object for the console error handling.
+ *
+ * @return ConsoleOutput
+ */
+ public static function getStderr() {
+ if (empty(self::$stderr)) {
+ self::$stderr = new ConsoleOutput('php://stderr');
+ }
+ return self::$stderr;
+ }
+
+/**
+ * Handle a exception in the console environment. Prints a message to stderr.
+ *
+ * @param Exception $exception The exception to handle
+ * @return void
+ */
+ public function handleException(Exception $exception) {
+ $stderr = self::getStderr();
+ $stderr->write(__d('cake_console', "<error>Error:</error> %s\n%s",
+ $exception->getMessage(),
+ $exception->getTraceAsString()
+ ));
+ $this->_stop($exception->getCode() ? $exception->getCode() : 1);
+ }
+
+/**
+ * Handle errors in the console environment. Writes errors to stderr,
+ * and logs messages if Configure::read('debug') is 0.
+ *
+ * @param integer $code Error code
+ * @param string $description Description of the error.
+ * @param string $file The file the error occurred in.
+ * @param integer $line The line the error occurred on.
+ * @param array $context The backtrace of the error.
+ * @return void
+ */
+ public function handleError($code, $description, $file = null, $line = null, $context = null) {
+ if (error_reporting() === 0) {
+ return;
+ }
+ $stderr = self::getStderr();
+ list($name, $log) = ErrorHandler::mapErrorCode($code);
+ $message = __d('cake_console', '%s in [%s, line %s]', $description, $file, $line);
+ $stderr->write(__d('cake_console', "<error>%s Error:</error> %s\n", $name, $message));
+
+ if (Configure::read('debug') == 0) {
+ CakeLog::write($log, $message);
+ }
+ }
+
+/**
+ * Wrapper for exit(), used for testing.
+ *
+ * @param $code int The exit code.
+ */
+ protected function _stop($code = 0) {
+ exit($code);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInput.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInput.php
new file mode 100644
index 0000000..eb4928b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInput.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * ConsoleInput file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * Object wrapper for interacting with stdin
+ *
+ * @package Cake.Console
+ */
+class ConsoleInput {
+
+/**
+ * Input value.
+ *
+ * @var resource
+ */
+ protected $_input;
+
+/**
+ * Constructor
+ *
+ * @param string $handle The location of the stream to use as input.
+ */
+ public function __construct($handle = 'php://stdin') {
+ $this->_input = fopen($handle, 'r');
+ }
+
+/**
+ * Read a value from the stream
+ *
+ * @return mixed The value of the stream
+ */
+ public function read() {
+ return fgets($this->_input);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputArgument.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputArgument.php
new file mode 100644
index 0000000..ae7911b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputArgument.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * ConsoleArgumentOption file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * An object to represent a single argument used in the command line.
+ * ConsoleOptionParser creates these when you use addArgument()
+ *
+ * @see ConsoleOptionParser::addArgument()
+ * @package Cake.Console
+ */
+class ConsoleInputArgument {
+
+/**
+ * Name of the argument.
+ *
+ * @var string
+ */
+ protected $_name;
+
+/**
+ * Help string
+ *
+ * @var string
+ */
+ protected $_help;
+
+/**
+ * Is this option required?
+ *
+ * @var boolean
+ */
+ protected $_required;
+
+/**
+ * An array of valid choices for this argument.
+ *
+ * @var array
+ */
+ protected $_choices;
+
+/**
+ * Make a new Input Argument
+ *
+ * @param string|array $name The long name of the option, or an array with all the properties.
+ * @param string $help The help text for this option
+ * @param boolean $required Whether this argument is required. Missing required args will trigger exceptions
+ * @param array $choices Valid choices for this option.
+ */
+ public function __construct($name, $help = '', $required = false, $choices = array()) {
+ if (is_array($name) && isset($name['name'])) {
+ foreach ($name as $key => $value) {
+ $this->{'_' . $key} = $value;
+ }
+ } else {
+ $this->_name = $name;
+ $this->_help = $help;
+ $this->_required = $required;
+ $this->_choices = $choices;
+ }
+ }
+
+/**
+ * Get the value of the name attribute.
+ *
+ * @return string Value of this->_name.
+ */
+ public function name() {
+ return $this->_name;
+ }
+
+/**
+ * Generate the help for this argument.
+ *
+ * @param integer $width The width to make the name of the option.
+ * @return string
+ */
+ public function help($width = 0) {
+ $name = $this->_name;
+ if (strlen($name) < $width) {
+ $name = str_pad($name, $width, ' ');
+ }
+ $optional = '';
+ if (!$this->isRequired()) {
+ $optional = __d('cake_console', ' <comment>(optional)</comment>');
+ }
+ if (!empty($this->_choices)) {
+ $optional .= __d('cake_console', ' <comment>(choices: %s)</comment>', implode('|', $this->_choices));
+ }
+ return sprintf('%s%s%s', $name, $this->_help, $optional);
+ }
+
+/**
+ * Get the usage value for this argument
+ *
+ * @return string
+ */
+ public function usage() {
+ $name = $this->_name;
+ if (!empty($this->_choices)) {
+ $name = implode('|', $this->_choices);
+ }
+ $name = '<' . $name . '>';
+ if (!$this->isRequired()) {
+ $name = '[' . $name . ']';
+ }
+ return $name;
+ }
+
+/**
+ * Check if this argument is a required argument
+ *
+ * @return boolean
+ */
+ public function isRequired() {
+ return (bool)$this->_required;
+ }
+
+/**
+ * Check that $value is a valid choice for this argument.
+ *
+ * @param string $value
+ * @return boolean
+ * @throws ConsoleException
+ */
+ public function validChoice($value) {
+ if (empty($this->_choices)) {
+ return true;
+ }
+ if (!in_array($value, $this->_choices)) {
+ throw new ConsoleException(
+ __d('cake_console', '"%s" is not a valid value for %s. Please use one of "%s"',
+ $value, $this->_name, implode(', ', $this->_choices)
+ ));
+ }
+ return true;
+ }
+
+/**
+ * Append this arguments XML representation to the passed in SimpleXml object.
+ *
+ * @param SimpleXmlElement $parent The parent element.
+ * @return SimpleXmlElement The parent with this argument appended.
+ */
+ public function xml(SimpleXmlElement $parent) {
+ $option = $parent->addChild('argument');
+ $option->addAttribute('name', $this->_name);
+ $option->addAttribute('help', $this->_help);
+ $option->addAttribute('required', $this->isRequired());
+ $choices = $option->addChild('choices');
+ foreach ($this->_choices as $valid) {
+ $choices->addChild('choice', $valid);
+ }
+ return $parent;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputOption.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputOption.php
new file mode 100644
index 0000000..9323c64
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputOption.php
@@ -0,0 +1,221 @@
+<?php
+/**
+ * ConsoleInputOption file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * An object to represent a single option used in the command line.
+ * ConsoleOptionParser creates these when you use addOption()
+ *
+ * @see ConsoleOptionParser::addOption()
+ * @package Cake.Console
+ */
+class ConsoleInputOption {
+
+/**
+ * Name of the option
+ *
+ * @var string
+ */
+ protected $_name;
+
+/**
+ * Short (1 character) alias for the option.
+ *
+ * @var string
+ */
+ protected $_short;
+
+/**
+ * Help text for the option.
+ *
+ * @var string
+ */
+ protected $_help;
+
+/**
+ * Is the option a boolean option. Boolean options do not consume a parameter.
+ *
+ * @var boolean
+ */
+ protected $_boolean;
+
+/**
+ * Default value for the option
+ *
+ * @var mixed
+ */
+ protected $_default;
+
+/**
+ * An array of choices for the option.
+ *
+ * @var array
+ */
+ protected $_choices;
+
+/**
+ * Make a new Input Option
+ *
+ * @param string|array $name The long name of the option, or an array with all the properties.
+ * @param string $short The short alias for this option
+ * @param string $help The help text for this option
+ * @param boolean $boolean Whether this option is a boolean option. Boolean options don't consume extra tokens
+ * @param string $default The default value for this option.
+ * @param array $choices Valid choices for this option.
+ * @throws ConsoleException
+ */
+ public function __construct($name, $short = null, $help = '', $boolean = false, $default = '', $choices = array()) {
+ if (is_array($name) && isset($name['name'])) {
+ foreach ($name as $key => $value) {
+ $this->{'_' . $key} = $value;
+ }
+ } else {
+ $this->_name = $name;
+ $this->_short = $short;
+ $this->_help = $help;
+ $this->_boolean = $boolean;
+ $this->_default = $default;
+ $this->_choices = $choices;
+ }
+ if (strlen($this->_short) > 1) {
+ throw new ConsoleException(
+ __d('cake_console', 'Short options must be one letter.')
+ );
+ }
+ }
+
+/**
+ * Get the value of the name attribute.
+ *
+ * @return string Value of this->_name.
+ */
+ public function name() {
+ return $this->_name;
+ }
+
+/**
+ * Get the value of the short attribute.
+ *
+ * @return string Value of this->_short.
+ */
+ public function short() {
+ return $this->_short;
+ }
+
+/**
+ * Generate the help for this this option.
+ *
+ * @param integer $width The width to make the name of the option.
+ * @return string
+ */
+ public function help($width = 0) {
+ $default = $short = '';
+ if (!empty($this->_default) && $this->_default !== true) {
+ $default = __d('cake_console', ' <comment>(default: %s)</comment>', $this->_default);
+ }
+ if (!empty($this->_choices)) {
+ $default .= __d('cake_console', ' <comment>(choices: %s)</comment>', implode('|', $this->_choices));
+ }
+ if (!empty($this->_short)) {
+ $short = ', -' . $this->_short;
+ }
+ $name = sprintf('--%s%s', $this->_name, $short);
+ if (strlen($name) < $width) {
+ $name = str_pad($name, $width, ' ');
+ }
+ return sprintf('%s%s%s', $name, $this->_help, $default);
+ }
+
+/**
+ * Get the usage value for this option
+ *
+ * @return string
+ */
+ public function usage() {
+ $name = empty($this->_short) ? '--' . $this->_name : '-' . $this->_short;
+ $default = '';
+ if (!empty($this->_default) && $this->_default !== true) {
+ $default = ' ' . $this->_default;
+ }
+ if (!empty($this->_choices)) {
+ $default = ' ' . implode('|', $this->_choices);
+ }
+ return sprintf('[%s%s]', $name, $default);
+ }
+
+/**
+ * Get the default value for this option
+ *
+ * @return mixed
+ */
+ public function defaultValue() {
+ return $this->_default;
+ }
+
+/**
+ * Check if this option is a boolean option
+ *
+ * @return boolean
+ */
+ public function isBoolean() {
+ return (bool)$this->_boolean;
+ }
+
+/**
+ * Check that a value is a valid choice for this option.
+ *
+ * @param string $value
+ * @return boolean
+ * @throws ConsoleException
+ */
+ public function validChoice($value) {
+ if (empty($this->_choices)) {
+ return true;
+ }
+ if (!in_array($value, $this->_choices)) {
+ throw new ConsoleException(
+ __d('cake_console', '"%s" is not a valid value for --%s. Please use one of "%s"',
+ $value, $this->_name, implode(', ', $this->_choices)
+ ));
+ }
+ return true;
+ }
+
+/**
+ * Append the option's xml into the parent.
+ *
+ * @param SimpleXmlElement $parent The parent element.
+ * @return SimpleXmlElement The parent with this option appended.
+ */
+ public function xml(SimpleXmlElement $parent) {
+ $option = $parent->addChild('option');
+ $option->addAttribute('name', '--' . $this->_name);
+ $short = '';
+ if (strlen($this->_short)) {
+ $short = $this->_short;
+ }
+ $option->addAttribute('short', '-' . $short);
+ $option->addAttribute('boolean', $this->_boolean);
+ $option->addChild('default', $this->_default);
+ $choices = $option->addChild('choices');
+ foreach ($this->_choices as $valid) {
+ $choices->addChild('choice', $valid);
+ }
+ return $parent;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputSubcommand.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputSubcommand.php
new file mode 100644
index 0000000..04e4ea3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleInputSubcommand.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * ConsoleInputSubcommand file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * An object to represent a single subcommand used in the command line.
+ * Created when you call ConsoleOptionParser::addSubcommand()
+ *
+ * @see ConsoleOptionParser::addSubcommand()
+ * @package Cake.Console
+ */
+class ConsoleInputSubcommand {
+
+/**
+ * Name of the subcommand
+ *
+ * @var string
+ */
+ protected $_name;
+
+/**
+ * Help string for the subcommand
+ *
+ * @var string
+ */
+ protected $_help;
+
+/**
+ * The ConsoleOptionParser for this subcommand.
+ *
+ * @var ConsoleOptionParser
+ */
+ protected $_parser;
+
+/**
+ * Make a new Subcommand
+ *
+ * @param string|array $name The long name of the subcommand, or an array with all the properties.
+ * @param string $help The help text for this option
+ * @param ConsoleOptionParser|array $parser A parser for this subcommand. Either a ConsoleOptionParser, or an array that can be
+ * used with ConsoleOptionParser::buildFromArray()
+ */
+ public function __construct($name, $help = '', $parser = null) {
+ if (is_array($name) && isset($name['name'])) {
+ foreach ($name as $key => $value) {
+ $this->{'_' . $key} = $value;
+ }
+ } else {
+ $this->_name = $name;
+ $this->_help = $help;
+ $this->_parser = $parser;
+ }
+ if (is_array($this->_parser)) {
+ $this->_parser['command'] = $this->_name;
+ $this->_parser = ConsoleOptionParser::buildFromArray($this->_parser);
+ }
+ }
+
+/**
+ * Get the value of the name attribute.
+ *
+ * @return string Value of this->_name.
+ */
+ public function name() {
+ return $this->_name;
+ }
+
+/**
+ * Generate the help for this this subcommand.
+ *
+ * @param integer $width The width to make the name of the subcommand.
+ * @return string
+ */
+ public function help($width = 0) {
+ $name = $this->_name;
+ if (strlen($name) < $width) {
+ $name = str_pad($name, $width, ' ');
+ }
+ return $name . $this->_help;
+ }
+
+/**
+ * Get the usage value for this option
+ *
+ * @return mixed Either false or a ConsoleOptionParser
+ */
+ public function parser() {
+ if ($this->_parser instanceof ConsoleOptionParser) {
+ return $this->_parser;
+ }
+ return false;
+ }
+
+/**
+ * Append this subcommand to the Parent element
+ *
+ * @param SimpleXmlElement $parent The parent element.
+ * @return SimpleXmlElement The parent with this subcommand appended.
+ */
+ public function xml(SimpleXmlElement $parent) {
+ $command = $parent->addChild('command');
+ $command->addAttribute('name', $this->_name);
+ $command->addAttribute('help', $this->_help);
+ return $parent;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOptionParser.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOptionParser.php
new file mode 100644
index 0000000..1983e22
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOptionParser.php
@@ -0,0 +1,651 @@
+<?php
+/**
+ * ConsoleOptionParser file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('TaskCollection', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ConsoleInputSubcommand', 'Console');
+App::uses('ConsoleInputOption', 'Console');
+App::uses('ConsoleInputArgument', 'Console');
+App::uses('ConsoleOptionParser', 'Console');
+App::uses('HelpFormatter', 'Console');
+
+/**
+ * Handles parsing the ARGV in the command line and provides support
+ * for GetOpt compatible option definition. Provides a builder pattern implementation
+ * for creating shell option parsers.
+ *
+ * ### Options
+ *
+ * Named arguments come in two forms, long and short. Long arguments are preceded
+ * by two - and give a more verbose option name. i.e. `--version`. Short arguments are
+ * preceded by one - and are only one character long. They usually match with a long option,
+ * and provide a more terse alternative.
+ *
+ * ### Using Options
+ *
+ * Options can be defined with both long and short forms. By using `$parser->addOption()`
+ * you can define new options. The name of the option is used as its long form, and you
+ * can supply an additional short form, with the `short` option. Short options should
+ * only be one letter long. Using more than one letter for a short option will raise an exception.
+ *
+ * Calling options can be done using syntax similar to most *nix command line tools. Long options
+ * cane either include an `=` or leave it out.
+ *
+ * `cake myshell command --connection default --name=something`
+ *
+ * Short options can be defined signally or in groups.
+ *
+ * `cake myshell command -cn`
+ *
+ * Short options can be combined into groups as seen above. Each letter in a group
+ * will be treated as a separate option. The previous example is equivalent to:
+ *
+ * `cake myshell command -c -n`
+ *
+ * Short options can also accept values:
+ *
+ * `cake myshell command -c default`
+ *
+ * ### Positional arguments
+ *
+ * If no positional arguments are defined, all of them will be parsed. If you define positional
+ * arguments any arguments greater than those defined will cause exceptions. Additionally you can
+ * declare arguments as optional, by setting the required param to false.
+ *
+ * `$parser->addArgument('model', array('required' => false));`
+ *
+ * ### Providing Help text
+ *
+ * By providing help text for your positional arguments and named arguments, the ConsoleOptionParser
+ * can generate a help display for you. You can view the help for shells by using the `--help` or `-h` switch.
+ *
+ * @package Cake.Console
+ */
+class ConsoleOptionParser {
+
+/**
+ * Description text - displays before options when help is generated
+ *
+ * @see ConsoleOptionParser::description()
+ * @var string
+ */
+ protected $_description = null;
+
+/**
+ * Epilog text - displays after options when help is generated
+ *
+ * @see ConsoleOptionParser::epilog()
+ * @var string
+ */
+ protected $_epilog = null;
+
+/**
+ * Option definitions.
+ *
+ * @see ConsoleOptionParser::addOption()
+ * @var array
+ */
+ protected $_options = array();
+
+/**
+ * Map of short -> long options, generated when using addOption()
+ *
+ * @var string
+ */
+ protected $_shortOptions = array();
+
+/**
+ * Positional argument definitions.
+ *
+ * @see ConsoleOptionParser::addArgument()
+ * @var array
+ */
+ protected $_args = array();
+
+/**
+ * Subcommands for this Shell.
+ *
+ * @see ConsoleOptionParser::addSubcommand()
+ * @var array
+ */
+ protected $_subcommands = array();
+
+/**
+ * Command name.
+ *
+ * @var string
+ */
+ protected $_command = '';
+
+/**
+ * Construct an OptionParser so you can define its behavior
+ *
+ * @param string $command The command name this parser is for. The command name is used for generating help.
+ * @param boolean $defaultOptions Whether you want the verbose and quiet options set. Setting
+ * this to false will prevent the addition of `--verbose` & `--quiet` options.
+ */
+ public function __construct($command = null, $defaultOptions = true) {
+ $this->command($command);
+
+ $this->addOption('help', array(
+ 'short' => 'h',
+ 'help' => __d('cake_console', 'Display this help.'),
+ 'boolean' => true
+ ));
+
+ if ($defaultOptions) {
+ $this->addOption('verbose', array(
+ 'short' => 'v',
+ 'help' => __d('cake_console', 'Enable verbose output.'),
+ 'boolean' => true
+ ))->addOption('quiet', array(
+ 'short' => 'q',
+ 'help' => __d('cake_console', 'Enable quiet output.'),
+ 'boolean' => true
+ ));
+ }
+ }
+
+/**
+ * Static factory method for creating new OptionParsers so you can chain methods off of them.
+ *
+ * @param string $command The command name this parser is for. The command name is used for generating help.
+ * @param boolean $defaultOptions Whether you want the verbose and quiet options set.
+ * @return ConsoleOptionParser
+ */
+ public static function create($command, $defaultOptions = true) {
+ return new ConsoleOptionParser($command, $defaultOptions);
+ }
+
+/**
+ * Build a parser from an array. Uses an array like
+ *
+ * {{{
+ * $spec = array(
+ * 'description' => 'text',
+ * 'epilog' => 'text',
+ * 'arguments' => array(
+ * // list of arguments compatible with addArguments.
+ * ),
+ * 'options' => array(
+ * // list of options compatible with addOptions
+ * ),
+ * 'subcommands' => array(
+ * // list of subcommands to add.
+ * )
+ * );
+ * }}}
+ *
+ * @param array $spec The spec to build the OptionParser with.
+ * @return ConsoleOptionParser
+ */
+ public static function buildFromArray($spec) {
+ $parser = new ConsoleOptionParser($spec['command']);
+ if (!empty($spec['arguments'])) {
+ $parser->addArguments($spec['arguments']);
+ }
+ if (!empty($spec['options'])) {
+ $parser->addOptions($spec['options']);
+ }
+ if (!empty($spec['subcommands'])) {
+ $parser->addSubcommands($spec['subcommands']);
+ }
+ if (!empty($spec['description'])) {
+ $parser->description($spec['description']);
+ }
+ if (!empty($spec['epilog'])) {
+ $parser->epilog($spec['epilog']);
+ }
+ return $parser;
+ }
+
+/**
+ * Get or set the command name for shell/task.
+ *
+ * @param string $text The text to set, or null if you want to read
+ * @return mixed If reading, the value of the command. If setting $this will be returned
+ */
+ public function command($text = null) {
+ if ($text !== null) {
+ $this->_command = Inflector::underscore($text);
+ return $this;
+ }
+ return $this->_command;
+ }
+
+/**
+ * Get or set the description text for shell/task.
+ *
+ * @param string|array $text The text to set, or null if you want to read. If an array the
+ * text will be imploded with "\n"
+ * @return mixed If reading, the value of the description. If setting $this will be returned
+ */
+ public function description($text = null) {
+ if ($text !== null) {
+ if (is_array($text)) {
+ $text = implode("\n", $text);
+ }
+ $this->_description = $text;
+ return $this;
+ }
+ return $this->_description;
+ }
+
+/**
+ * Get or set an epilog to the parser. The epilog is added to the end of
+ * the options and arguments listing when help is generated.
+ *
+ * @param string|array $text Text when setting or null when reading. If an array the text will be imploded with "\n"
+ * @return mixed If reading, the value of the epilog. If setting $this will be returned.
+ */
+ public function epilog($text = null) {
+ if ($text !== null) {
+ if (is_array($text)) {
+ $text = implode("\n", $text);
+ }
+ $this->_epilog = $text;
+ return $this;
+ }
+ return $this->_epilog;
+ }
+
+/**
+ * Add an option to the option parser. Options allow you to define optional or required
+ * parameters for your console application. Options are defined by the parameters they use.
+ *
+ * ### Options
+ *
+ * - `short` - The single letter variant for this option, leave undefined for none.
+ * - `help` - Help text for this option. Used when generating help for the option.
+ * - `default` - The default value for this option. Defaults are added into the parsed params when the
+ * attached option is not provided or has no value. Using default and boolean together will not work.
+ * are added into the parsed parameters when the option is undefined. Defaults to null.
+ * - `boolean` - The option uses no value, its just a boolean switch. Defaults to false.
+ * If an option is defined as boolean, it will always be added to the parsed params. If no present
+ * it will be false, if present it will be true.
+ * - `choices` A list of valid choices for this option. If left empty all values are valid..
+ * An exception will be raised when parse() encounters an invalid value.
+ *
+ * @param ConsoleInputOption|string $name The long name you want to the value to be parsed out as when options are parsed.
+ * Will also accept an instance of ConsoleInputOption
+ * @param array $options An array of parameters that define the behavior of the option
+ * @return ConsoleOptionParser $this.
+ */
+ public function addOption($name, $options = array()) {
+ if (is_object($name) && $name instanceof ConsoleInputOption) {
+ $option = $name;
+ $name = $option->name();
+ } else {
+ $defaults = array(
+ 'name' => $name,
+ 'short' => null,
+ 'help' => '',
+ 'default' => null,
+ 'boolean' => false,
+ 'choices' => array()
+ );
+ $options = array_merge($defaults, $options);
+ $option = new ConsoleInputOption($options);
+ }
+ $this->_options[$name] = $option;
+ if ($option->short() !== null) {
+ $this->_shortOptions[$option->short()] = $name;
+ }
+ return $this;
+ }
+
+/**
+ * Add a positional argument to the option parser.
+ *
+ * ### Params
+ *
+ * - `help` The help text to display for this argument.
+ * - `required` Whether this parameter is required.
+ * - `index` The index for the arg, if left undefined the argument will be put
+ * onto the end of the arguments. If you define the same index twice the first
+ * option will be overwritten.
+ * - `choices` A list of valid choices for this argument. If left empty all values are valid..
+ * An exception will be raised when parse() encounters an invalid value.
+ *
+ * @param ConsoleInputArgument|string $name The name of the argument. Will also accept an instance of ConsoleInputArgument
+ * @param array $params Parameters for the argument, see above.
+ * @return ConsoleOptionParser $this.
+ */
+ public function addArgument($name, $params = array()) {
+ if (is_object($name) && $name instanceof ConsoleInputArgument) {
+ $arg = $name;
+ $index = count($this->_args);
+ } else {
+ $defaults = array(
+ 'name' => $name,
+ 'help' => '',
+ 'index' => count($this->_args),
+ 'required' => false,
+ 'choices' => array()
+ );
+ $options = array_merge($defaults, $params);
+ $index = $options['index'];
+ unset($options['index']);
+ $arg = new ConsoleInputArgument($options);
+ }
+ $this->_args[$index] = $arg;
+ return $this;
+ }
+
+/**
+ * Add multiple arguments at once. Take an array of argument definitions.
+ * The keys are used as the argument names, and the values as params for the argument.
+ *
+ * @param array $args Array of arguments to add.
+ * @see ConsoleOptionParser::addArgument()
+ * @return ConsoleOptionParser $this
+ */
+ public function addArguments(array $args) {
+ foreach ($args as $name => $params) {
+ $this->addArgument($name, $params);
+ }
+ return $this;
+ }
+
+/**
+ * Add multiple options at once. Takes an array of option definitions.
+ * The keys are used as option names, and the values as params for the option.
+ *
+ * @param array $options Array of options to add.
+ * @see ConsoleOptionParser::addOption()
+ * @return ConsoleOptionParser $this
+ */
+ public function addOptions(array $options) {
+ foreach ($options as $name => $params) {
+ $this->addOption($name, $params);
+ }
+ return $this;
+ }
+
+/**
+ * Append a subcommand to the subcommand list.
+ * Subcommands are usually methods on your Shell, but can also be used to document Tasks.
+ *
+ * ### Options
+ *
+ * - `help` - Help text for the subcommand.
+ * - `parser` - A ConsoleOptionParser for the subcommand. This allows you to create method
+ * specific option parsers. When help is generated for a subcommand, if a parser is present
+ * it will be used.
+ *
+ * @param ConsoleInputSubcommand|string $name Name of the subcommand. Will also accept an instance of ConsoleInputSubcommand
+ * @param array $options Array of params, see above.
+ * @return ConsoleOptionParser $this.
+ */
+ public function addSubcommand($name, $options = array()) {
+ if (is_object($name) && $name instanceof ConsoleInputSubcommand) {
+ $command = $name;
+ $name = $command->name();
+ } else {
+ $defaults = array(
+ 'name' => $name,
+ 'help' => '',
+ 'parser' => null
+ );
+ $options = array_merge($defaults, $options);
+ $command = new ConsoleInputSubcommand($options);
+ }
+ $this->_subcommands[$name] = $command;
+ return $this;
+ }
+
+/**
+ * Add multiple subcommands at once.
+ *
+ * @param array $commands Array of subcommands.
+ * @return ConsoleOptionParser $this
+ */
+ public function addSubcommands(array $commands) {
+ foreach ($commands as $name => $params) {
+ $this->addSubcommand($name, $params);
+ }
+ return $this;
+ }
+
+/**
+ * Gets the arguments defined in the parser.
+ *
+ * @return array Array of argument descriptions
+ */
+ public function arguments() {
+ return $this->_args;
+ }
+
+/**
+ * Get the defined options in the parser.
+ *
+ * @return array
+ */
+ public function options() {
+ return $this->_options;
+ }
+
+/**
+ * Get the array of defined subcommands
+ *
+ * @return array
+ */
+ public function subcommands() {
+ return $this->_subcommands;
+ }
+
+/**
+ * Parse the argv array into a set of params and args. If $command is not null
+ * and $command is equal to a subcommand that has a parser, that parser will be used
+ * to parse the $argv
+ *
+ * @param array $argv Array of args (argv) to parse.
+ * @param string $command The subcommand to use. If this parameter is a subcommand, that has a parser,
+ * That parser will be used to parse $argv instead.
+ * @return Array array($params, $args)
+ * @throws ConsoleException When an invalid parameter is encountered.
+ */
+ public function parse($argv, $command = null) {
+ if (isset($this->_subcommands[$command]) && $this->_subcommands[$command]->parser()) {
+ return $this->_subcommands[$command]->parser()->parse($argv);
+ }
+ $params = $args = array();
+ $this->_tokens = $argv;
+ while (($token = array_shift($this->_tokens)) !== null) {
+ if (substr($token, 0, 2) == '--') {
+ $params = $this->_parseLongOption($token, $params);
+ } elseif (substr($token, 0, 1) == '-') {
+ $params = $this->_parseShortOption($token, $params);
+ } else {
+ $args = $this->_parseArg($token, $args);
+ }
+ }
+ foreach ($this->_args as $i => $arg) {
+ if ($arg->isRequired() && !isset($args[$i]) && empty($params['help'])) {
+ throw new ConsoleException(
+ __d('cake_console', 'Missing required arguments. %s is required.', $arg->name())
+ );
+ }
+ }
+ foreach ($this->_options as $option) {
+ $name = $option->name();
+ $isBoolean = $option->isBoolean();
+ $default = $option->defaultValue();
+
+ if ($default !== null && !isset($params[$name]) && !$isBoolean) {
+ $params[$name] = $default;
+ }
+ if ($isBoolean && !isset($params[$name])) {
+ $params[$name] = false;
+ }
+ }
+ return array($params, $args);
+ }
+
+/**
+ * Gets formatted help for this parser object.
+ * Generates help text based on the description, options, arguments, subcommands and epilog
+ * in the parser.
+ *
+ * @param string $subcommand If present and a valid subcommand that has a linked parser.
+ * That subcommands help will be shown instead.
+ * @param string $format Define the output format, can be text or xml
+ * @param integer $width The width to format user content to. Defaults to 72
+ * @return string Generated help.
+ */
+ public function help($subcommand = null, $format = 'text', $width = 72) {
+ if (
+ isset($this->_subcommands[$subcommand]) &&
+ $this->_subcommands[$subcommand]->parser() instanceof self
+ ) {
+ $subparser = $this->_subcommands[$subcommand]->parser();
+ $subparser->command($this->command() . ' ' . $subparser->command());
+ return $subparser->help(null, $format, $width);
+ }
+ $formatter = new HelpFormatter($this);
+ if ($format == 'text' || $format === true) {
+ return $formatter->text($width);
+ } elseif ($format == 'xml') {
+ return $formatter->xml();
+ }
+ }
+
+/**
+ * Parse the value for a long option out of $this->_tokens. Will handle
+ * options with an `=` in them.
+ *
+ * @param string $option The option to parse.
+ * @param array $params The params to append the parsed value into
+ * @return array Params with $option added in.
+ */
+ protected function _parseLongOption($option, $params) {
+ $name = substr($option, 2);
+ if (strpos($name, '=') !== false) {
+ list($name, $value) = explode('=', $name, 2);
+ array_unshift($this->_tokens, $value);
+ }
+ return $this->_parseOption($name, $params);
+ }
+
+/**
+ * Parse the value for a short option out of $this->_tokens
+ * If the $option is a combination of multiple shortcuts like -otf
+ * they will be shifted onto the token stack and parsed individually.
+ *
+ * @param string $option The option to parse.
+ * @param array $params The params to append the parsed value into
+ * @return array Params with $option added in.
+ * @throws ConsoleException When unknown short options are encountered.
+ */
+ protected function _parseShortOption($option, $params) {
+ $key = substr($option, 1);
+ if (strlen($key) > 1) {
+ $flags = str_split($key);
+ $key = $flags[0];
+ for ($i = 1, $len = count($flags); $i < $len; $i++) {
+ array_unshift($this->_tokens, '-' . $flags[$i]);
+ }
+ }
+ if (!isset($this->_shortOptions[$key])) {
+ throw new ConsoleException(__d('cake_console', 'Unknown short option `%s`', $key));
+ }
+ $name = $this->_shortOptions[$key];
+ return $this->_parseOption($name, $params);
+ }
+
+/**
+ * Parse an option by its name index.
+ *
+ * @param string $name The name to parse.
+ * @param array $params The params to append the parsed value into
+ * @return array Params with $option added in.
+ * @throws ConsoleException
+ */
+ protected function _parseOption($name, $params) {
+ if (!isset($this->_options[$name])) {
+ throw new ConsoleException(__d('cake_console', 'Unknown option `%s`', $name));
+ }
+ $option = $this->_options[$name];
+ $isBoolean = $option->isBoolean();
+ $nextValue = $this->_nextToken();
+ if (!$isBoolean && !empty($nextValue) && !$this->_optionExists($nextValue)) {
+ array_shift($this->_tokens);
+ $value = $nextValue;
+ } elseif ($isBoolean) {
+ $value = true;
+ } else {
+ $value = $option->defaultValue();
+ }
+ if ($option->validChoice($value)) {
+ $params[$name] = $value;
+ return $params;
+ }
+ }
+
+/**
+ * Check to see if $name has an option (short/long) defined for it.
+ *
+ * @param string $name The name of the option.
+ * @return boolean
+ */
+ protected function _optionExists($name) {
+ if (substr($name, 0, 2) === '--') {
+ return isset($this->_options[substr($name, 2)]);
+ }
+ if ($name{0} === '-' && $name{1} !== '-') {
+ return isset($this->_shortOptions[$name{1}]);
+ }
+ return false;
+ }
+
+/**
+ * Parse an argument, and ensure that the argument doesn't exceed the number of arguments
+ * and that the argument is a valid choice.
+ *
+ * @param string $argument The argument to append
+ * @param array $args The array of parsed args to append to.
+ * @return array Args
+ * @throws ConsoleException
+ */
+ protected function _parseArg($argument, $args) {
+ if (empty($this->_args)) {
+ array_push($args, $argument);
+ return $args;
+ }
+ $next = count($args);
+ if (!isset($this->_args[$next])) {
+ throw new ConsoleException(__d('cake_console', 'Too many arguments.'));
+ }
+
+ if ($this->_args[$next]->validChoice($argument)) {
+ array_push($args, $argument);
+ return $args;
+ }
+ }
+
+/**
+ * Find the next token in the argv set.
+ *
+ * @return string next token or ''
+ */
+ protected function _nextToken() {
+ return isset($this->_tokens[0]) ? $this->_tokens[0] : '';
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOutput.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOutput.php
new file mode 100644
index 0000000..04ceb9a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ConsoleOutput.php
@@ -0,0 +1,292 @@
+<?php
+/**
+ * ConsoleOutput file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * Object wrapper for outputting information from a shell application.
+ * Can be connected to any stream resource that can be used with fopen()
+ *
+ * Can generate colorized output on consoles that support it. There are a few
+ * built in styles
+ *
+ * - `error` Error messages.
+ * - `warning` Warning messages.
+ * - `info` Informational messages.
+ * - `comment` Additional text.
+ * - `question` Magenta text used for user prompts
+ *
+ * By defining styles with addStyle() you can create custom console styles.
+ *
+ * ### Using styles in output
+ *
+ * You can format console output using tags with the name of the style to apply. From inside a shell object
+ *
+ * `$this->out('<warning>Overwrite:</warning> foo.php was overwritten.');`
+ *
+ * This would create orange 'Overwrite:' text, while the rest of the text would remain the normal color.
+ * See ConsoleOutput::styles() to learn more about defining your own styles. Nested styles are not supported
+ * at this time.
+ *
+ * @package Cake.Console
+ */
+class ConsoleOutput {
+/**
+ * Raw output constant - no modification of output text.
+ */
+ const RAW = 0;
+
+/**
+ * Plain output - tags will be stripped.
+ */
+ const PLAIN = 1;
+
+/**
+ * Color output - Convert known tags in to ANSI color escape codes.
+ */
+ const COLOR = 2;
+
+/**
+ * Constant for a newline.
+ */
+ const LF = PHP_EOL;
+
+/**
+ * File handle for output.
+ *
+ * @var resource
+ */
+ protected $_output;
+
+/**
+ * The current output type. Manipulated with ConsoleOutput::outputAs();
+ *
+ * @var integer.
+ */
+ protected $_outputAs = self::COLOR;
+
+/**
+ * text colors used in colored output.
+ *
+ * @var array
+ */
+ protected static $_foregroundColors = array(
+ 'black' => 30,
+ 'red' => 31,
+ 'green' => 32,
+ 'yellow' => 33,
+ 'blue' => 34,
+ 'magenta' => 35,
+ 'cyan' => 36,
+ 'white' => 37
+ );
+
+/**
+ * background colors used in colored output.
+ *
+ * @var array
+ */
+ protected static $_backgroundColors = array(
+ 'black' => 40,
+ 'red' => 41,
+ 'green' => 42,
+ 'yellow' => 43,
+ 'blue' => 44,
+ 'magenta' => 45,
+ 'cyan' => 46,
+ 'white' => 47
+ );
+
+/**
+ * formatting options for colored output
+ *
+ * @var string
+ */
+ protected static $_options = array(
+ 'bold' => 1,
+ 'underline' => 4,
+ 'blink' => 5,
+ 'reverse' => 7,
+ );
+
+/**
+ * Styles that are available as tags in console output.
+ * You can modify these styles with ConsoleOutput::styles()
+ *
+ * @var array
+ */
+ protected static $_styles = array(
+ 'emergency' => array('text' => 'red', 'underline' => true),
+ 'alert' => array('text' => 'red', 'underline' => true),
+ 'critical' => array('text' => 'red', 'underline' => true),
+ 'error' => array('text' => 'red', 'underline' => true),
+ 'warning' => array('text' => 'yellow'),
+ 'info' => array('text' => 'cyan'),
+ 'debug' => array('text' => 'yellow'),
+ 'success' => array('text' => 'green'),
+ 'comment' => array('text' => 'blue'),
+ 'question' => array('text' => 'magenta'),
+ );
+
+/**
+ * Construct the output object.
+ *
+ * Checks for a pretty console environment. Ansicon allows pretty consoles
+ * on windows, and is supported.
+ *
+ * @param string $stream The identifier of the stream to write output to.
+ */
+ public function __construct($stream = 'php://stdout') {
+ $this->_output = fopen($stream, 'w');
+
+ if (DS == '\\' && !(bool)env('ANSICON')) {
+ $this->_outputAs = self::PLAIN;
+ }
+ }
+
+/**
+ * Outputs a single or multiple messages to stdout. If no parameters
+ * are passed, outputs just a newline.
+ *
+ * @param string|array $message A string or a an array of strings to output
+ * @param integer $newlines Number of newlines to append
+ * @return integer Returns the number of bytes returned from writing to stdout.
+ */
+ public function write($message, $newlines = 1) {
+ if (is_array($message)) {
+ $message = implode(self::LF, $message);
+ }
+ return $this->_write($this->styleText($message . str_repeat(self::LF, $newlines)));
+ }
+
+/**
+ * Apply styling to text.
+ *
+ * @param string $text Text with styling tags.
+ * @return string String with color codes added.
+ */
+ public function styleText($text) {
+ if ($this->_outputAs == self::RAW) {
+ return $text;
+ }
+ if ($this->_outputAs == self::PLAIN) {
+ $tags = implode('|', array_keys(self::$_styles));
+ return preg_replace('#</?(?:' . $tags . ')>#', '', $text);
+ }
+ return preg_replace_callback(
+ '/<(?P<tag>[a-z0-9-_]+)>(?P<text>.*?)<\/(\1)>/ims', array($this, '_replaceTags'), $text
+ );
+ }
+
+/**
+ * Replace tags with color codes.
+ *
+ * @param array $matches.
+ * @return string
+ */
+ protected function _replaceTags($matches) {
+ $style = $this->styles($matches['tag']);
+ if (empty($style)) {
+ return '<' . $matches['tag'] . '>' . $matches['text'] . '</' . $matches['tag'] . '>';
+ }
+
+ $styleInfo = array();
+ if (!empty($style['text']) && isset(self::$_foregroundColors[$style['text']])) {
+ $styleInfo[] = self::$_foregroundColors[$style['text']];
+ }
+ if (!empty($style['background']) && isset(self::$_backgroundColors[$style['background']])) {
+ $styleInfo[] = self::$_backgroundColors[$style['background']];
+ }
+ unset($style['text'], $style['background']);
+ foreach ($style as $option => $value) {
+ if ($value) {
+ $styleInfo[] = self::$_options[$option];
+ }
+ }
+ return "\033[" . implode($styleInfo, ';') . 'm' . $matches['text'] . "\033[0m";
+ }
+
+/**
+ * Writes a message to the output stream.
+ *
+ * @param string $message Message to write.
+ * @return boolean success
+ */
+ protected function _write($message) {
+ return fwrite($this->_output, $message);
+ }
+
+/**
+ * Get the current styles offered, or append new ones in.
+ *
+ * ### Get a style definition
+ *
+ * `$this->output->styles('error');`
+ *
+ * ### Get all the style definitions
+ *
+ * `$this->output->styles();`
+ *
+ * ### Create or modify an existing style
+ *
+ * `$this->output->styles('annoy', array('text' => 'purple', 'background' => 'yellow', 'blink' => true));`
+ *
+ * ### Remove a style
+ *
+ * `$this->output->styles('annoy', false);`
+ *
+ * @param string $style The style to get or create.
+ * @param array $definition The array definition of the style to change or create a style
+ * or false to remove a style.
+ * @return mixed If you are getting styles, the style or null will be returned. If you are creating/modifying
+ * styles true will be returned.
+ */
+ public function styles($style = null, $definition = null) {
+ if ($style === null && $definition === null) {
+ return self::$_styles;
+ }
+ if (is_string($style) && $definition === null) {
+ return isset(self::$_styles[$style]) ? self::$_styles[$style] : null;
+ }
+ if ($definition === false) {
+ unset(self::$_styles[$style]);
+ return true;
+ }
+ self::$_styles[$style] = $definition;
+ return true;
+ }
+
+/**
+ * Get/Set the output type to use. The output type how formatting tags are treated.
+ *
+ * @param integer $type The output type to use. Should be one of the class constants.
+ * @return mixed Either null or the value if getting.
+ */
+ public function outputAs($type = null) {
+ if ($type === null) {
+ return $this->_outputAs;
+ }
+ $this->_outputAs = $type;
+ }
+
+/**
+ * clean up and close handles
+ *
+ */
+ public function __destruct() {
+ fclose($this->_output);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/HelpFormatter.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/HelpFormatter.php
new file mode 100644
index 0000000..2b495b9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/HelpFormatter.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * HelpFormatter
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('String', 'Utility');
+
+/**
+ * HelpFormatter formats help for console shells. Can format to either
+ * text or XML formats. Uses ConsoleOptionParser methods to generate help.
+ *
+ * Generally not directly used. Using $parser->help($command, 'xml'); is usually
+ * how you would access help. Or via the `--help=xml` option on the command line.
+ *
+ * Xml output is useful for integration with other tools like IDE's or other build tools.
+ *
+ * @package Cake.Console
+ * @since CakePHP(tm) v 2.0
+ */
+class HelpFormatter {
+
+/**
+ * The maximum number of arguments shown when generating usage.
+ *
+ * @var integer
+ */
+ protected $_maxArgs = 6;
+
+/**
+ * The maximum number of options shown when generating usage.
+ *
+ * @var integer
+ */
+ protected $_maxOptions = 6;
+
+/**
+ * Build the help formatter for a an OptionParser
+ *
+ * @param ConsoleOptionParser $parser The option parser help is being generated for.
+ */
+ public function __construct(ConsoleOptionParser $parser) {
+ $this->_parser = $parser;
+ }
+
+/**
+ * Get the help as formatted text suitable for output on the command line.
+ *
+ * @param integer $width The width of the help output.
+ * @return string
+ */
+ public function text($width = 72) {
+ $parser = $this->_parser;
+ $out = array();
+ $description = $parser->description();
+ if (!empty($description)) {
+ $out[] = String::wrap($description, $width);
+ $out[] = '';
+ }
+ $out[] = __d('cake_console', '<info>Usage:</info>');
+ $out[] = $this->_generateUsage();
+ $out[] = '';
+ $subcommands = $parser->subcommands();
+ if (!empty($subcommands)) {
+ $out[] = __d('cake_console', '<info>Subcommands:</info>');
+ $out[] = '';
+ $max = $this->_getMaxLength($subcommands) + 2;
+ foreach ($subcommands as $command) {
+ $out[] = String::wrap($command->help($max), array(
+ 'width' => $width,
+ 'indent' => str_repeat(' ', $max),
+ 'indentAt' => 1
+ ));
+ }
+ $out[] = '';
+ $out[] = __d('cake_console', 'To see help on a subcommand use <info>`cake %s [subcommand] --help`</info>', $parser->command());
+ $out[] = '';
+ }
+
+ $options = $parser->options();
+ if (!empty($options)) {
+ $max = $this->_getMaxLength($options) + 8;
+ $out[] = __d('cake_console', '<info>Options:</info>');
+ $out[] = '';
+ foreach ($options as $option) {
+ $out[] = String::wrap($option->help($max), array(
+ 'width' => $width,
+ 'indent' => str_repeat(' ', $max),
+ 'indentAt' => 1
+ ));
+ }
+ $out[] = '';
+ }
+
+ $arguments = $parser->arguments();
+ if (!empty($arguments)) {
+ $max = $this->_getMaxLength($arguments) + 2;
+ $out[] = __d('cake_console', '<info>Arguments:</info>');
+ $out[] = '';
+ foreach ($arguments as $argument) {
+ $out[] = String::wrap($argument->help($max), array(
+ 'width' => $width,
+ 'indent' => str_repeat(' ', $max),
+ 'indentAt' => 1
+ ));
+ }
+ $out[] = '';
+ }
+ $epilog = $parser->epilog();
+ if (!empty($epilog)) {
+ $out[] = String::wrap($epilog, $width);
+ $out[] = '';
+ }
+ return implode("\n", $out);
+ }
+
+/**
+ * Generate the usage for a shell based on its arguments and options.
+ * Usage strings favor short options over the long ones. and optional args will
+ * be indicated with []
+ *
+ * @return string
+ */
+ protected function _generateUsage() {
+ $usage = array('cake ' . $this->_parser->command());
+ $subcommands = $this->_parser->subcommands();
+ if (!empty($subcommands)) {
+ $usage[] = '[subcommand]';
+ }
+ $options = array();
+ foreach ($this->_parser->options() as $option) {
+ $options[] = $option->usage();
+ }
+ if (count($options) > $this->_maxOptions) {
+ $options = array('[options]');
+ }
+ $usage = array_merge($usage, $options);
+ $args = array();
+ foreach ($this->_parser->arguments() as $argument) {
+ $args[] = $argument->usage();
+ }
+ if (count($args) > $this->_maxArgs) {
+ $args = array('[arguments]');
+ }
+ $usage = array_merge($usage, $args);
+ return implode(' ', $usage);
+ }
+
+/**
+ * Iterate over a collection and find the longest named thing.
+ *
+ * @param array $collection
+ * @return integer
+ */
+ protected function _getMaxLength($collection) {
+ $max = 0;
+ foreach ($collection as $item) {
+ $max = (strlen($item->name()) > $max) ? strlen($item->name()) : $max;
+ }
+ return $max;
+ }
+
+/**
+ * Get the help as an xml string.
+ *
+ * @param boolean $string Return the SimpleXml object or a string. Defaults to true.
+ * @return mixed. See $string
+ */
+ public function xml($string = true) {
+ $parser = $this->_parser;
+ $xml = new SimpleXmlElement('<shell></shell>');
+ $xml->addChild('command', $parser->command());
+ $xml->addChild('description', $parser->description());
+
+ $xml->addChild('epilog', $parser->epilog());
+ $subcommands = $xml->addChild('subcommands');
+ foreach ($parser->subcommands() as $command) {
+ $command->xml($subcommands);
+ }
+ $options = $xml->addChild('options');
+ foreach ($parser->options() as $option) {
+ $option->xml($options);
+ }
+ $arguments = $xml->addChild('arguments');
+ foreach ($parser->arguments() as $argument) {
+ $argument->xml($arguments);
+ }
+ return $string ? $xml->asXml() : $xml;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Shell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Shell.php
new file mode 100644
index 0000000..801410b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Shell.php
@@ -0,0 +1,847 @@
+<?php
+/**
+ * Base class for Shells
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.5012
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('TaskCollection', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ConsoleInputSubcommand', 'Console');
+App::uses('ConsoleOptionParser', 'Console');
+App::uses('File', 'Utility');
+
+/**
+ * Base class for command-line utilities for automating programmer chores.
+ *
+ * @package Cake.Console
+ */
+class Shell extends Object {
+
+/**
+ * Output constants for making verbose and quiet shells.
+ */
+ const VERBOSE = 2;
+ const NORMAL = 1;
+ const QUIET = 0;
+
+/**
+ * An instance of ConsoleOptionParser that has been configured for this class.
+ *
+ * @var ConsoleOptionParser
+ */
+ public $OptionParser;
+
+/**
+ * If true, the script will ask for permission to perform actions.
+ *
+ * @var boolean
+ */
+ public $interactive = true;
+
+/**
+ * Contains command switches parsed from the command line.
+ *
+ * @var array
+ */
+ public $params = array();
+
+/**
+ * The command (method/task) that is being run.
+ *
+ * @var string
+ */
+ public $command;
+
+/**
+ * Contains arguments parsed from the command line.
+ *
+ * @var array
+ */
+ public $args = array();
+
+/**
+ * The name of the shell in camelized.
+ *
+ * @var string
+ */
+ public $name = null;
+
+/**
+ * The name of the plugin the shell belongs to.
+ * Is automatically set by ShellDispatcher when a shell is constructed.
+ *
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Contains tasks to load and instantiate
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::$tasks
+ */
+ public $tasks = array();
+
+/**
+ * Contains the loaded tasks
+ *
+ * @var array
+ */
+ public $taskNames = array();
+
+/**
+ * Contains models to load and instantiate
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::$uses
+ */
+ public $uses = array();
+
+/**
+ * Task Collection for the command, used to create Tasks.
+ *
+ * @var TaskCollection
+ */
+ public $Tasks;
+
+/**
+ * Normalized map of tasks.
+ *
+ * @var string
+ */
+ protected $_taskMap = array();
+
+/**
+ * stdout object.
+ *
+ * @var ConsoleOutput
+ */
+ public $stdout;
+
+/**
+ * stderr object.
+ *
+ * @var ConsoleOutput
+ */
+ public $stderr;
+
+/**
+ * stdin object
+ *
+ * @var ConsoleInput
+ */
+ public $stdin;
+
+/**
+ * Constructs this Shell instance.
+ *
+ * @param ConsoleOutput $stdout A ConsoleOutput object for stdout.
+ * @param ConsoleOutput $stderr A ConsoleOutput object for stderr.
+ * @param ConsoleInput $stdin A ConsoleInput object for stdin.
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell
+ */
+ public function __construct($stdout = null, $stderr = null, $stdin = null) {
+ if ($this->name == null) {
+ $this->name = Inflector::camelize(str_replace(array('Shell', 'Task'), '', get_class($this)));
+ }
+ $this->Tasks = new TaskCollection($this);
+
+ $this->stdout = $stdout;
+ $this->stderr = $stderr;
+ $this->stdin = $stdin;
+ if ($this->stdout == null) {
+ $this->stdout = new ConsoleOutput('php://stdout');
+ }
+ if ($this->stderr == null) {
+ $this->stderr = new ConsoleOutput('php://stderr');
+ }
+ if ($this->stdin == null) {
+ $this->stdin = new ConsoleInput('php://stdin');
+ }
+ $this->_useLogger();
+ $parent = get_parent_class($this);
+ if ($this->tasks !== null && $this->tasks !== false) {
+ $this->_mergeVars(array('tasks'), $parent, true);
+ }
+ if ($this->uses !== null && $this->uses !== false) {
+ $this->_mergeVars(array('uses'), $parent, false);
+ }
+ }
+
+/**
+ * Initializes the Shell
+ * acts as constructor for subclasses
+ * allows configuration of tasks prior to shell execution
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::initialize
+ */
+ public function initialize() {
+ $this->_loadModels();
+ }
+
+/**
+ * Starts up the Shell and displays the welcome message.
+ * Allows for checking and configuring prior to command or main execution
+ *
+ * Override this method if you want to remove the welcome information,
+ * or otherwise modify the pre-command flow.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::startup
+ */
+ public function startup() {
+ $this->_welcome();
+ }
+
+/**
+ * Displays a header for the shell
+ *
+ * @return void
+ */
+ protected function _welcome() {
+ $this->out();
+ $this->out(__d('cake_console', '<info>Welcome to CakePHP %s Console</info>', 'v' . Configure::version()));
+ $this->hr();
+ $this->out(__d('cake_console', 'App : %s', APP_DIR));
+ $this->out(__d('cake_console', 'Path: %s', APP));
+ $this->hr();
+ }
+
+/**
+ * If $uses = true
+ * Loads AppModel file and constructs AppModel class
+ * makes $this->AppModel available to subclasses
+ * If public $uses is an array of models will load those models
+ *
+ * @return boolean
+ */
+ protected function _loadModels() {
+ if ($this->uses === null || $this->uses === false) {
+ return;
+ }
+ App::uses('ClassRegistry', 'Utility');
+
+ if ($this->uses !== true && !empty($this->uses)) {
+ $uses = is_array($this->uses) ? $this->uses : array($this->uses);
+
+ $modelClassName = $uses[0];
+ if (strpos($uses[0], '.') !== false) {
+ list($plugin, $modelClassName) = explode('.', $uses[0]);
+ }
+ $this->modelClass = $modelClassName;
+
+ foreach ($uses as $modelClass) {
+ list($plugin, $modelClass) = pluginSplit($modelClass, true);
+ $this->{$modelClass} = ClassRegistry::init($plugin . $modelClass);
+ }
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Loads tasks defined in public $tasks
+ *
+ * @return boolean
+ */
+ public function loadTasks() {
+ if ($this->tasks === true || empty($this->tasks) || empty($this->Tasks)) {
+ return true;
+ }
+ $this->_taskMap = TaskCollection::normalizeObjectArray((array)$this->tasks);
+ foreach ($this->_taskMap as $task => $properties) {
+ $this->taskNames[] = $task;
+ }
+ return true;
+ }
+
+/**
+ * Check to see if this shell has a task with the provided name.
+ *
+ * @param string $task The task name to check.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::hasTask
+ */
+ public function hasTask($task) {
+ return isset($this->_taskMap[Inflector::camelize($task)]);
+ }
+
+/**
+ * Check to see if this shell has a callable method by the given name.
+ *
+ * @param string $name The method name to check.
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::hasMethod
+ */
+ public function hasMethod($name) {
+ try {
+ $method = new ReflectionMethod($this, $name);
+ if (!$method->isPublic() || substr($name, 0, 1) === '_') {
+ return false;
+ }
+ if ($method->getDeclaringClass()->name == 'Shell') {
+ return false;
+ }
+ return true;
+ } catch (ReflectionException $e) {
+ return false;
+ }
+ }
+
+/**
+ * Dispatch a command to another Shell. Similar to Object::requestAction()
+ * but intended for running shells from other shells.
+ *
+ * ### Usage:
+ *
+ * With a string command:
+ *
+ * `return $this->dispatchShell('schema create DbAcl');`
+ *
+ * Avoid using this form if you have string arguments, with spaces in them.
+ * The dispatched will be invoked incorrectly. Only use this form for simple
+ * command dispatching.
+ *
+ * With an array command:
+ *
+ * `return $this->dispatchShell('schema', 'create', 'i18n', '--dry');`
+ *
+ * @return mixed The return of the other shell.
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::dispatchShell
+ */
+ public function dispatchShell() {
+ $args = func_get_args();
+ if (is_string($args[0]) && count($args) == 1) {
+ $args = explode(' ', $args[0]);
+ }
+
+ $Dispatcher = new ShellDispatcher($args, false);
+ return $Dispatcher->dispatch();
+ }
+
+/**
+ * Runs the Shell with the provided argv.
+ *
+ * Delegates calls to Tasks and resolves methods inside the class. Commands are looked
+ * up with the following order:
+ *
+ * - Method on the shell.
+ * - Matching task name.
+ * - `main()` method.
+ *
+ * If a shell implements a `main()` method, all missing method calls will be sent to
+ * `main()` with the original method name in the argv.
+ *
+ * @param string $command The command name to run on this shell. If this argument is empty,
+ * and the shell has a `main()` method, that will be called instead.
+ * @param array $argv Array of arguments to run the shell with. This array should be missing the shell name.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::runCommand
+ */
+ public function runCommand($command, $argv) {
+ $isTask = $this->hasTask($command);
+ $isMethod = $this->hasMethod($command);
+ $isMain = $this->hasMethod('main');
+
+ if ($isTask || $isMethod && $command !== 'execute') {
+ array_shift($argv);
+ }
+
+ try {
+ $this->OptionParser = $this->getOptionParser();
+ list($this->params, $this->args) = $this->OptionParser->parse($argv, $command);
+ } catch (ConsoleException $e) {
+ $this->out($this->OptionParser->help($command));
+ return false;
+ }
+
+ if (!empty($this->params['quiet'])) {
+ $this->_useLogger(false);
+ }
+
+ $this->command = $command;
+ if (!empty($this->params['help'])) {
+ return $this->_displayHelp($command);
+ }
+
+ if (($isTask || $isMethod || $isMain) && $command !== 'execute') {
+ $this->startup();
+ }
+
+ if ($isTask) {
+ $command = Inflector::camelize($command);
+ return $this->{$command}->runCommand('execute', $argv);
+ }
+ if ($isMethod) {
+ return $this->{$command}();
+ }
+ if ($isMain) {
+ return $this->main();
+ }
+ $this->out($this->OptionParser->help($command));
+ return false;
+ }
+
+/**
+ * Display the help in the correct format
+ *
+ * @param string $command
+ * @return void
+ */
+ protected function _displayHelp($command) {
+ $format = 'text';
+ if (!empty($this->args[0]) && $this->args[0] == 'xml') {
+ $format = 'xml';
+ $this->stdout->outputAs(ConsoleOutput::RAW);
+ } else {
+ $this->_welcome();
+ }
+ return $this->out($this->OptionParser->help($command, $format));
+ }
+
+/**
+ * Gets the option parser instance and configures it.
+ * By overriding this method you can configure the ConsoleOptionParser before returning it.
+ *
+ * @return ConsoleOptionParser
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::getOptionParser
+ */
+ public function getOptionParser() {
+ $name = ($this->plugin ? $this->plugin . '.' : '') . $this->name;
+ $parser = new ConsoleOptionParser($name);
+ return $parser;
+ }
+
+/**
+ * Overload get for lazy building of tasks
+ *
+ * @param string $name
+ * @return Shell Object of Task
+ */
+ public function __get($name) {
+ if (empty($this->{$name}) && in_array($name, $this->taskNames)) {
+ $properties = $this->_taskMap[$name];
+ $this->{$name} = $this->Tasks->load($properties['class'], $properties['settings']);
+ $this->{$name}->args =& $this->args;
+ $this->{$name}->params =& $this->params;
+ $this->{$name}->initialize();
+ $this->{$name}->loadTasks();
+ }
+ return $this->{$name};
+ }
+
+/**
+ * Prompts the user for input, and returns it.
+ *
+ * @param string $prompt Prompt text.
+ * @param string|array $options Array or string of options.
+ * @param string $default Default input value.
+ * @return mixed Either the default value, or the user-provided input.
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::in
+ */
+ public function in($prompt, $options = null, $default = null) {
+ if (!$this->interactive) {
+ return $default;
+ }
+ $originalOptions = $options;
+ $in = $this->_getInput($prompt, $originalOptions, $default);
+
+ if ($options && is_string($options)) {
+ if (strpos($options, ',')) {
+ $options = explode(',', $options);
+ } elseif (strpos($options, '/')) {
+ $options = explode('/', $options);
+ } else {
+ $options = array($options);
+ }
+ }
+ if (is_array($options)) {
+ $options = array_merge(
+ array_map('strtolower', $options),
+ array_map('strtoupper', $options),
+ $options
+ );
+ while ($in === '' || !in_array($in, $options)) {
+ $in = $this->_getInput($prompt, $originalOptions, $default);
+ }
+ }
+ return $in;
+ }
+
+/**
+ * Prompts the user for input, and returns it.
+ *
+ * @param string $prompt Prompt text.
+ * @param string|array $options Array or string of options.
+ * @param string $default Default input value.
+ * @return Either the default value, or the user-provided input.
+ */
+ protected function _getInput($prompt, $options, $default) {
+ if (!is_array($options)) {
+ $printOptions = '';
+ } else {
+ $printOptions = '(' . implode('/', $options) . ')';
+ }
+
+ if ($default === null) {
+ $this->stdout->write('<question>' . $prompt . '</question>' . " $printOptions \n" . '> ', 0);
+ } else {
+ $this->stdout->write('<question>' . $prompt . '</question>' . " $printOptions \n" . "[$default] > ", 0);
+ }
+ $result = $this->stdin->read();
+
+ if ($result === false) {
+ $this->_stop(1);
+ }
+ $result = trim($result);
+
+ if ($default !== null && ($result === '' || $result === null)) {
+ return $default;
+ }
+ return $result;
+ }
+
+/**
+ * Wrap a block of text.
+ * Allows you to set the width, and indenting on a block of text.
+ *
+ * ### Options
+ *
+ * - `width` The width to wrap to. Defaults to 72
+ * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true.
+ * - `indent` Indent the text with the string provided. Defaults to null.
+ *
+ * @param string $text Text the text to format.
+ * @param string|integer|array $options Array of options to use, or an integer to wrap the text to.
+ * @return string Wrapped / indented text
+ * @see String::wrap()
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::wrapText
+ */
+ public function wrapText($text, $options = array()) {
+ return String::wrap($text, $options);
+ }
+
+/**
+ * Outputs a single or multiple messages to stdout. If no parameters
+ * are passed outputs just a newline.
+ *
+ * ### Output levels
+ *
+ * There are 3 built-in output level. Shell::QUIET, Shell::NORMAL, Shell::VERBOSE.
+ * The verbose and quiet output levels, map to the `verbose` and `quiet` output switches
+ * present in most shells. Using Shell::QUIET for a message means it will always display.
+ * While using Shell::VERBOSE means it will only display when verbose output is toggled.
+ *
+ * @param string|array $message A string or a an array of strings to output
+ * @param integer $newlines Number of newlines to append
+ * @param integer $level The message's output level, see above.
+ * @return integer|boolean Returns the number of bytes returned from writing to stdout.
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::out
+ */
+ public function out($message = null, $newlines = 1, $level = Shell::NORMAL) {
+ $currentLevel = Shell::NORMAL;
+ if (!empty($this->params['verbose'])) {
+ $currentLevel = Shell::VERBOSE;
+ }
+ if (!empty($this->params['quiet'])) {
+ $currentLevel = Shell::QUIET;
+ }
+ if ($level <= $currentLevel) {
+ return $this->stdout->write($message, $newlines);
+ }
+ return true;
+ }
+
+/**
+ * Outputs a single or multiple error messages to stderr. If no parameters
+ * are passed outputs just a newline.
+ *
+ * @param string|array $message A string or a an array of strings to output
+ * @param integer $newlines Number of newlines to append
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::err
+ */
+ public function err($message = null, $newlines = 1) {
+ $this->stderr->write($message, $newlines);
+ }
+
+/**
+ * Returns a single or multiple linefeeds sequences.
+ *
+ * @param integer $multiplier Number of times the linefeed sequence should be repeated
+ * @return string
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::nl
+ */
+ public function nl($multiplier = 1) {
+ return str_repeat(ConsoleOutput::LF, $multiplier);
+ }
+
+/**
+ * Outputs a series of minus characters to the standard output, acts as a visual separator.
+ *
+ * @param integer $newlines Number of newlines to pre- and append
+ * @param integer $width Width of the line, defaults to 63
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::hr
+ */
+ public function hr($newlines = 0, $width = 63) {
+ $this->out(null, $newlines);
+ $this->out(str_repeat('-', $width));
+ $this->out(null, $newlines);
+ }
+
+/**
+ * Displays a formatted error message
+ * and exits the application with status code 1
+ *
+ * @param string $title Title of the error
+ * @param string $message An optional error message
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::error
+ */
+ public function error($title, $message = null) {
+ $this->err(__d('cake_console', '<error>Error:</error> %s', $title));
+
+ if (!empty($message)) {
+ $this->err($message);
+ }
+ $this->_stop(1);
+ }
+
+/**
+ * Clear the console
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::clear
+ */
+ public function clear() {
+ if (empty($this->params['noclear'])) {
+ if (DS === '/') {
+ passthru('clear');
+ } else {
+ passthru('cls');
+ }
+ }
+ }
+
+/**
+ * Creates a file at given path
+ *
+ * @param string $path Where to put the file.
+ * @param string $contents Content to put in the file.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::createFile
+ */
+ public function createFile($path, $contents) {
+ $path = str_replace(DS . DS, DS, $path);
+
+ $this->out();
+
+ if (is_file($path) && $this->interactive === true) {
+ $this->out(__d('cake_console', '<warning>File `%s` exists</warning>', $path));
+ $key = $this->in(__d('cake_console', 'Do you want to overwrite?'), array('y', 'n', 'q'), 'n');
+
+ if (strtolower($key) == 'q') {
+ $this->out(__d('cake_console', '<error>Quitting</error>.'), 2);
+ $this->_stop();
+ } elseif (strtolower($key) != 'y') {
+ $this->out(__d('cake_console', 'Skip `%s`', $path), 2);
+ return false;
+ }
+ } else {
+ $this->out(__d('cake_console', 'Creating file %s', $path));
+ }
+
+ $File = new File($path, true);
+ if ($File->exists() && $File->writable()) {
+ $data = $File->prepare($contents);
+ $File->write($data);
+ $this->out(__d('cake_console', '<success>Wrote</success> `%s`', $path));
+ return true;
+ } else {
+ $this->err(__d('cake_console', '<error>Could not write to `%s`</error>.', $path), 2);
+ return false;
+ }
+ }
+
+/**
+ * Action to create a Unit Test
+ *
+ * @return boolean Success
+ */
+ protected function _checkUnitTest() {
+ if (class_exists('PHPUnit_Framework_TestCase')) {
+ return true;
+ } elseif (@include 'PHPUnit' . DS . 'Autoload.php') {
+ return true;
+ } elseif (App::import('Vendor', 'phpunit', array('file' => 'PHPUnit' . DS . 'Autoload.php'))) {
+ return true;
+ }
+
+ $prompt = __d('cake_console', 'PHPUnit is not installed. Do you want to bake unit test files anyway?');
+ $unitTest = $this->in($prompt, array('y', 'n'), 'y');
+ $result = strtolower($unitTest) == 'y' || strtolower($unitTest) == 'yes';
+
+ if ($result) {
+ $this->out();
+ $this->out(__d('cake_console', 'You can download PHPUnit from %s', 'http://phpunit.de'));
+ }
+ return $result;
+ }
+
+/**
+ * Makes absolute file path easier to read
+ *
+ * @param string $file Absolute file path
+ * @return string short path
+ * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::shortPath
+ */
+ public function shortPath($file) {
+ $shortPath = str_replace(ROOT, null, $file);
+ $shortPath = str_replace('..' . DS, '', $shortPath);
+ return str_replace(DS . DS, DS, $shortPath);
+ }
+
+/**
+ * Creates the proper controller path for the specified controller class name
+ *
+ * @param string $name Controller class name
+ * @return string Path to controller
+ */
+ protected function _controllerPath($name) {
+ return Inflector::underscore($name);
+ }
+
+/**
+ * Creates the proper controller plural name for the specified controller class name
+ *
+ * @param string $name Controller class name
+ * @return string Controller plural name
+ */
+ protected function _controllerName($name) {
+ return Inflector::pluralize(Inflector::camelize($name));
+ }
+
+/**
+ * Creates the proper model camelized name (singularized) for the specified name
+ *
+ * @param string $name Name
+ * @return string Camelized and singularized model name
+ */
+ protected function _modelName($name) {
+ return Inflector::camelize(Inflector::singularize($name));
+ }
+
+/**
+ * Creates the proper underscored model key for associations
+ *
+ * @param string $name Model class name
+ * @return string Singular model key
+ */
+ protected function _modelKey($name) {
+ return Inflector::underscore($name) . '_id';
+ }
+
+/**
+ * Creates the proper model name from a foreign key
+ *
+ * @param string $key Foreign key
+ * @return string Model name
+ */
+ protected function _modelNameFromKey($key) {
+ return Inflector::camelize(str_replace('_id', '', $key));
+ }
+
+/**
+ * creates the singular name for use in views.
+ *
+ * @param string $name
+ * @return string $name
+ */
+ protected function _singularName($name) {
+ return Inflector::variable(Inflector::singularize($name));
+ }
+
+/**
+ * Creates the plural name for views
+ *
+ * @param string $name Name to use
+ * @return string Plural name for views
+ */
+ protected function _pluralName($name) {
+ return Inflector::variable(Inflector::pluralize($name));
+ }
+
+/**
+ * Creates the singular human name used in views
+ *
+ * @param string $name Controller name
+ * @return string Singular human name
+ */
+ protected function _singularHumanName($name) {
+ return Inflector::humanize(Inflector::underscore(Inflector::singularize($name)));
+ }
+
+/**
+ * Creates the plural human name used in views
+ *
+ * @param string $name Controller name
+ * @return string Plural human name
+ */
+ protected function _pluralHumanName($name) {
+ return Inflector::humanize(Inflector::underscore($name));
+ }
+
+/**
+ * Find the correct path for a plugin. Scans $pluginPaths for the plugin you want.
+ *
+ * @param string $pluginName Name of the plugin you want ie. DebugKit
+ * @return string $path path to the correct plugin.
+ */
+ protected function _pluginPath($pluginName) {
+ if (CakePlugin::loaded($pluginName)) {
+ return CakePlugin::path($pluginName);
+ }
+ return current(App::path('plugins')) . $pluginName . DS;
+ }
+
+/**
+ * Used to enable or disable logging stream output to stdout and stderr
+ * If you don't wish to see in your stdout or stderr everything that is logged
+ * through CakeLog, call this function with first param as false
+ *
+ * @param boolean $enable wheter to enable CakeLog output or not
+ * @return void
+ **/
+ protected function _useLogger($enable = true) {
+ if (!$enable) {
+ CakeLog::drop('stdout');
+ CakeLog::drop('stderr');
+ return;
+ }
+ CakeLog::config('stdout', array(
+ 'engine' => 'ConsoleLog',
+ 'types' => array('notice', 'info'),
+ 'stream' => $this->stdout,
+ ));
+ CakeLog::config('stderr', array(
+ 'engine' => 'ConsoleLog',
+ 'types' => array('emergency', 'alert', 'critical', 'error', 'warning', 'debug'),
+ 'stream' => $this->stderr,
+ ));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ShellDispatcher.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ShellDispatcher.php
new file mode 100644
index 0000000..40c27cc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/ShellDispatcher.php
@@ -0,0 +1,356 @@
+<?php
+/**
+ * ShellDispatcher file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Shell dispatcher handles dispatching cli commands.
+ *
+ * @package Cake.Console
+ */
+class ShellDispatcher {
+
+/**
+ * Contains command switches parsed from the command line.
+ *
+ * @var array
+ */
+ public $params = array();
+
+/**
+ * Contains arguments parsed from the command line.
+ *
+ * @var array
+ */
+ public $args = array();
+
+/**
+ * Constructor
+ *
+ * The execution of the script is stopped after dispatching the request with
+ * a status code of either 0 or 1 according to the result of the dispatch.
+ *
+ * @param array $args the argv from PHP
+ * @param boolean $bootstrap Should the environment be bootstrapped.
+ */
+ public function __construct($args = array(), $bootstrap = true) {
+ set_time_limit(0);
+
+ if ($bootstrap) {
+ $this->_initConstants();
+ }
+ $this->parseParams($args);
+ if ($bootstrap) {
+ $this->_initEnvironment();
+ }
+ }
+
+/**
+ * Run the dispatcher
+ *
+ * @param array $argv The argv from PHP
+ * @return void
+ */
+ public static function run($argv) {
+ $dispatcher = new ShellDispatcher($argv);
+ $dispatcher->_stop($dispatcher->dispatch() === false ? 1 : 0);
+ }
+
+/**
+ * Defines core configuration.
+ *
+ * @return void
+ */
+ protected function _initConstants() {
+ if (function_exists('ini_set')) {
+ ini_set('html_errors', false);
+ ini_set('implicit_flush', true);
+ ini_set('max_execution_time', 0);
+ }
+
+ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ define('DS', DIRECTORY_SEPARATOR);
+ define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(dirname(__FILE__))));
+ define('CAKEPHP_SHELL', true);
+ if (!defined('CORE_PATH')) {
+ define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+ }
+ }
+ }
+
+/**
+ * Defines current working environment.
+ *
+ * @return void
+ * @throws CakeException
+ */
+ protected function _initEnvironment() {
+ if (!$this->_bootstrap()) {
+ $message = "Unable to load CakePHP core.\nMake sure " . DS . 'lib' . DS . 'Cake exists in ' . CAKE_CORE_INCLUDE_PATH;
+ throw new CakeException($message);
+ }
+
+ if (!isset($this->args[0]) || !isset($this->params['working'])) {
+ $message = "This file has been loaded incorrectly and cannot continue.\n" .
+ "Please make sure that " . DS . 'lib' . DS . 'Cake' . DS . "Console is in your system path,\n" .
+ "and check the cookbook for the correct usage of this command.\n" .
+ "(http://book.cakephp.org/)";
+ throw new CakeException($message);
+ }
+
+ $this->shiftArgs();
+ }
+
+/**
+ * Initializes the environment and loads the Cake core.
+ *
+ * @return boolean Success.
+ */
+ protected function _bootstrap() {
+ define('ROOT', $this->params['root']);
+ define('APP_DIR', $this->params['app']);
+ define('APP', $this->params['working'] . DS);
+ define('WWW_ROOT', APP . $this->params['webroot'] . DS);
+ if (!is_dir(ROOT . DS . APP_DIR . DS . 'tmp')) {
+ define('TMP', CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'tmp' . DS);
+ }
+ $boot = file_exists(ROOT . DS . APP_DIR . DS . 'Config' . DS . 'bootstrap.php');
+ require CORE_PATH . 'Cake' . DS . 'bootstrap.php';
+
+ if (!file_exists(APP . 'Config' . DS . 'core.php')) {
+ include_once CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'Config' . DS . 'core.php';
+ App::build();
+ }
+
+ $this->setErrorHandlers();
+
+ if (!defined('FULL_BASE_URL')) {
+ define('FULL_BASE_URL', 'http://localhost');
+ }
+
+ return true;
+ }
+
+/**
+ * Set the error/exception handlers for the console
+ * based on the `Error.consoleHandler`, and `Exception.consoleHandler` values
+ * if they are set. If they are not set, the default ConsoleErrorHandler will be
+ * used.
+ *
+ * @return void
+ */
+ public function setErrorHandlers() {
+ App::uses('ConsoleErrorHandler', 'Console');
+ $error = Configure::read('Error');
+ $exception = Configure::read('Exception');
+
+ $errorHandler = new ConsoleErrorHandler();
+ if (empty($error['consoleHandler'])) {
+ $error['consoleHandler'] = array($errorHandler, 'handleError');
+ Configure::write('error', $error);
+ }
+ if (empty($exception['consoleHandler'])) {
+ $exception['consoleHandler'] = array($errorHandler, 'handleException');
+ Configure::write('exception', $exception);
+ }
+ set_exception_handler($exception['consoleHandler']);
+ set_error_handler($error['consoleHandler'], Configure::read('Error.level'));
+ }
+
+/**
+ * Dispatches a CLI request
+ *
+ * @return boolean
+ * @throws MissingShellMethodException
+ */
+ public function dispatch() {
+ $shell = $this->shiftArgs();
+
+ if (!$shell) {
+ $this->help();
+ return false;
+ }
+ if (in_array($shell, array('help', '--help', '-h'))) {
+ $this->help();
+ return true;
+ }
+
+ $Shell = $this->_getShell($shell);
+
+ $command = null;
+ if (isset($this->args[0])) {
+ $command = $this->args[0];
+ }
+
+ if ($Shell instanceof Shell) {
+ $Shell->initialize();
+ $Shell->loadTasks();
+ return $Shell->runCommand($command, $this->args);
+ }
+ $methods = array_diff(get_class_methods($Shell), get_class_methods('Shell'));
+ $added = in_array($command, $methods);
+ $private = $command[0] == '_' && method_exists($Shell, $command);
+
+ if (!$private) {
+ if ($added) {
+ $this->shiftArgs();
+ $Shell->startup();
+ return $Shell->{$command}();
+ }
+ if (method_exists($Shell, 'main')) {
+ $Shell->startup();
+ return $Shell->main();
+ }
+ }
+ throw new MissingShellMethodException(array('shell' => $shell, 'method' => $arg));
+ }
+
+/**
+ * Get shell to use, either plugin shell or application shell
+ *
+ * All paths in the loaded shell paths are searched.
+ *
+ * @param string $shell Optionally the name of a plugin
+ * @return mixed An object
+ * @throws MissingShellException when errors are encountered.
+ */
+ protected function _getShell($shell) {
+ list($plugin, $shell) = pluginSplit($shell, true);
+
+ $plugin = Inflector::camelize($plugin);
+ $class = Inflector::camelize($shell) . 'Shell';
+
+ App::uses('Shell', 'Console');
+ App::uses('AppShell', 'Console/Command');
+ App::uses($class, $plugin . 'Console/Command');
+
+ if (!class_exists($class)) {
+ throw new MissingShellException(array(
+ 'class' => $class
+ ));
+ }
+ $Shell = new $class();
+ $Shell->plugin = trim($plugin, '.');
+ return $Shell;
+ }
+
+/**
+ * Parses command line options and extracts the directory paths from $params
+ *
+ * @param array $args Parameters to parse
+ * @return void
+ */
+ public function parseParams($args) {
+ $this->_parsePaths($args);
+
+ $defaults = array(
+ 'app' => 'app',
+ 'root' => dirname(dirname(dirname(dirname(__FILE__)))),
+ 'working' => null,
+ 'webroot' => 'webroot'
+ );
+ $params = array_merge($defaults, array_intersect_key($this->params, $defaults));
+ $isWin = false;
+ foreach ($defaults as $default => $value) {
+ if (strpos($params[$default], '\\') !== false) {
+ $isWin = true;
+ break;
+ }
+ }
+ $params = str_replace('\\', '/', $params);
+
+ if (isset($params['working'])) {
+ $params['working'] = trim($params['working']);
+ }
+ if (!empty($params['working']) && (!isset($this->args[0]) || isset($this->args[0]) && $this->args[0]{0} !== '.')) {
+ if (empty($this->params['app']) && $params['working'] != $params['root']) {
+ $params['root'] = dirname($params['working']);
+ $params['app'] = basename($params['working']);
+ } else {
+ $params['root'] = $params['working'];
+ }
+ }
+
+ if ($params['app'][0] == '/' || preg_match('/([a-z])(:)/i', $params['app'], $matches)) {
+ $params['root'] = dirname($params['app']);
+ } elseif (strpos($params['app'], '/')) {
+ $params['root'] .= '/' . dirname($params['app']);
+ }
+
+ $params['app'] = basename($params['app']);
+ $params['working'] = rtrim($params['root'], '/');
+ if (!$isWin || !preg_match('/^[A-Z]:$/i', $params['app'])) {
+ $params['working'] .= '/' . $params['app'];
+ }
+
+ if (!empty($matches[0]) || !empty($isWin)) {
+ $params = str_replace('/', '\\', $params);
+ }
+
+ $this->params = array_merge($this->params, $params);
+ }
+
+/**
+ * Parses out the paths from from the argv
+ *
+ * @param array $args
+ * @return void
+ */
+ protected function _parsePaths($args) {
+ $parsed = array();
+ $keys = array('-working', '--working', '-app', '--app', '-root', '--root');
+ foreach ($keys as $key) {
+ while (($index = array_search($key, $args)) !== false) {
+ $keyname = str_replace('-', '', $key);
+ $valueIndex = $index + 1;
+ $parsed[$keyname] = $args[$valueIndex];
+ array_splice($args, $index, 2);
+ }
+ }
+ $this->args = $args;
+ $this->params = $parsed;
+ }
+
+/**
+ * Removes first argument and shifts other arguments up
+ *
+ * @return mixed Null if there are no arguments otherwise the shifted argument
+ */
+ public function shiftArgs() {
+ return array_shift($this->args);
+ }
+
+/**
+ * Shows console help. Performs an internal dispatch to the CommandList Shell
+ *
+ * @return void
+ */
+ public function help() {
+ $this->args = array_merge(array('command_list'), $this->args);
+ $this->dispatch();
+ }
+
+/**
+ * Stop execution of the current script
+ *
+ * @param integer|string $status see http://php.net/exit for values
+ * @return void
+ */
+ protected function _stop($status = 0) {
+ exit($status);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/TaskCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/TaskCollection.php
new file mode 100644
index 0000000..35f21ee
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/TaskCollection.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Task collection is used as a registry for loaded tasks and handles loading
+ * and constructing task class objects.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+
+/**
+ * Collection object for Tasks. Provides features
+ * for lazily loading tasks, and firing callbacks on loaded tasks.
+ *
+ * @package Cake.Console
+ */
+class TaskCollection extends ObjectCollection {
+
+/**
+ * Shell to use to set params to tasks.
+ *
+ * @var Shell
+ */
+ protected $_Shell;
+
+/**
+ * The directory inside each shell path that contains tasks.
+ *
+ * @var string
+ */
+ public $taskPathPrefix = 'tasks/';
+
+/**
+ * Constructor
+ *
+ * @param Shell $Shell
+ */
+ public function __construct(Shell $Shell) {
+ $this->_Shell = $Shell;
+ }
+
+/**
+ * Loads/constructs a task. Will return the instance in the collection
+ * if it already exists.
+ *
+ * @param string $task Task name to load
+ * @param array $settings Settings for the task.
+ * @return Task A task object, Either the existing loaded task or a new one.
+ * @throws MissingTaskException when the task could not be found
+ */
+ public function load($task, $settings = array()) {
+ list($plugin, $name) = pluginSplit($task, true);
+
+ if (isset($this->_loaded[$name])) {
+ return $this->_loaded[$name];
+ }
+ $taskClass = $name . 'Task';
+ App::uses($taskClass, $plugin . 'Console/Command/Task');
+ if (!class_exists($taskClass)) {
+ if (!class_exists($taskClass)) {
+ throw new MissingTaskException(array(
+ 'class' => $taskClass
+ ));
+ }
+ }
+
+ $this->_loaded[$name] = new $taskClass(
+ $this->_Shell->stdout, $this->_Shell->stderr, $this->_Shell->stdin
+ );
+ return $this->_loaded[$name];
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/actions/controller_actions.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/actions/controller_actions.ctp
new file mode 100644
index 0000000..e34c382
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/actions/controller_actions.ctp
@@ -0,0 +1,161 @@
+<?php
+/**
+ * Bake Template for Controller action generation.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.actions
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+
+/**
+ * <?php echo $admin ?>index method
+ *
+ * @return void
+ */
+ public function <?php echo $admin ?>index() {
+ $this-><?php echo $currentModelName ?>->recursive = 0;
+ $this->set('<?php echo $pluralName ?>', $this->paginate());
+ }
+
+/**
+ * <?php echo $admin ?>view method
+ *
+ * @throws NotFoundException
+ * @param string $id
+ * @return void
+ */
+ public function <?php echo $admin ?>view($id = null) {
+ $this-><?php echo $currentModelName; ?>->id = $id;
+ if (!$this-><?php echo $currentModelName; ?>->exists()) {
+ throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
+ }
+ $this->set('<?php echo $singularName; ?>', $this-><?php echo $currentModelName; ?>->read(null, $id));
+ }
+
+<?php $compact = array(); ?>
+/**
+ * <?php echo $admin ?>add method
+ *
+ * @return void
+ */
+ public function <?php echo $admin ?>add() {
+ if ($this->request->is('post')) {
+ $this-><?php echo $currentModelName; ?>->create();
+ if ($this-><?php echo $currentModelName; ?>->save($this->request->data)) {
+<?php if ($wannaUseSession): ?>
+ $this->Session->setFlash(__('The <?php echo strtolower($singularHumanName); ?> has been saved'));
+ $this->redirect(array('action' => 'index'));
+<?php else: ?>
+ $this->flash(__('<?php echo ucfirst(strtolower($currentModelName)); ?> saved.'), array('action' => 'index'));
+<?php endif; ?>
+ } else {
+<?php if ($wannaUseSession): ?>
+ $this->Session->setFlash(__('The <?php echo strtolower($singularHumanName); ?> could not be saved. Please, try again.'));
+<?php endif; ?>
+ }
+ }
+<?php
+ foreach (array('belongsTo', 'hasAndBelongsToMany') as $assoc):
+ foreach ($modelObj->{$assoc} as $associationName => $relation):
+ if (!empty($associationName)):
+ $otherModelName = $this->_modelName($associationName);
+ $otherPluralName = $this->_pluralName($associationName);
+ echo "\t\t\${$otherPluralName} = \$this->{$currentModelName}->{$otherModelName}->find('list');\n";
+ $compact[] = "'{$otherPluralName}'";
+ endif;
+ endforeach;
+ endforeach;
+ if (!empty($compact)):
+ echo "\t\t\$this->set(compact(".join(', ', $compact)."));\n";
+ endif;
+?>
+ }
+
+<?php $compact = array(); ?>
+/**
+ * <?php echo $admin ?>edit method
+ *
+ * @throws NotFoundException
+ * @param string $id
+ * @return void
+ */
+ public function <?php echo $admin; ?>edit($id = null) {
+ $this-><?php echo $currentModelName; ?>->id = $id;
+ if (!$this-><?php echo $currentModelName; ?>->exists()) {
+ throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
+ }
+ if ($this->request->is('post') || $this->request->is('put')) {
+ if ($this-><?php echo $currentModelName; ?>->save($this->request->data)) {
+<?php if ($wannaUseSession): ?>
+ $this->Session->setFlash(__('The <?php echo strtolower($singularHumanName); ?> has been saved'));
+ $this->redirect(array('action' => 'index'));
+<?php else: ?>
+ $this->flash(__('The <?php echo strtolower($singularHumanName); ?> has been saved.'), array('action' => 'index'));
+<?php endif; ?>
+ } else {
+<?php if ($wannaUseSession): ?>
+ $this->Session->setFlash(__('The <?php echo strtolower($singularHumanName); ?> could not be saved. Please, try again.'));
+<?php endif; ?>
+ }
+ } else {
+ $this->request->data = $this-><?php echo $currentModelName; ?>->read(null, $id);
+ }
+<?php
+ foreach (array('belongsTo', 'hasAndBelongsToMany') as $assoc):
+ foreach ($modelObj->{$assoc} as $associationName => $relation):
+ if (!empty($associationName)):
+ $otherModelName = $this->_modelName($associationName);
+ $otherPluralName = $this->_pluralName($associationName);
+ echo "\t\t\${$otherPluralName} = \$this->{$currentModelName}->{$otherModelName}->find('list');\n";
+ $compact[] = "'{$otherPluralName}'";
+ endif;
+ endforeach;
+ endforeach;
+ if (!empty($compact)):
+ echo "\t\t\$this->set(compact(".join(', ', $compact)."));\n";
+ endif;
+ ?>
+ }
+
+/**
+ * <?php echo $admin ?>delete method
+ *
+ * @throws MethodNotAllowedException
+ * @throws NotFoundException
+ * @param string $id
+ * @return void
+ */
+ public function <?php echo $admin; ?>delete($id = null) {
+ if (!$this->request->is('post')) {
+ throw new MethodNotAllowedException();
+ }
+ $this-><?php echo $currentModelName; ?>->id = $id;
+ if (!$this-><?php echo $currentModelName; ?>->exists()) {
+ throw new NotFoundException(__('Invalid <?php echo strtolower($singularHumanName); ?>'));
+ }
+ if ($this-><?php echo $currentModelName; ?>->delete()) {
+<?php if ($wannaUseSession): ?>
+ $this->Session->setFlash(__('<?php echo ucfirst(strtolower($singularHumanName)); ?> deleted'));
+ $this->redirect(array('action' => 'index'));
+<?php else: ?>
+ $this->flash(__('<?php echo ucfirst(strtolower($singularHumanName)); ?> deleted'), array('action' => 'index'));
+<?php endif; ?>
+ }
+<?php if ($wannaUseSession): ?>
+ $this->Session->setFlash(__('<?php echo ucfirst(strtolower($singularHumanName)); ?> was not deleted'));
+<?php else: ?>
+ $this->flash(__('<?php echo ucfirst(strtolower($singularHumanName)); ?> was not deleted'), array('action' => 'index'));
+<?php endif; ?>
+ $this->redirect(array('action' => 'index'));
+ }
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/controller.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/controller.ctp
new file mode 100644
index 0000000..6e27d0d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/controller.ctp
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Controller bake template file
+ *
+ * Allows templating of Controllers generated from bake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.classes
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+echo "<?php\n";
+echo "App::uses('{$plugin}AppController', '{$pluginPath}Controller');\n";
+?>
+/**
+ * <?php echo $controllerName; ?> Controller
+ *
+<?php
+if (!$isScaffold) {
+ $defaultModel = Inflector::singularize($controllerName);
+ echo " * @property {$defaultModel} \${$defaultModel}\n";
+ if (!empty($components)) {
+ foreach ($components as $component) {
+ echo " * @property {$component}Component \${$component}\n";
+ }
+ }
+}
+?>
+ */
+class <?php echo $controllerName; ?>Controller extends <?php echo $plugin; ?>AppController {
+
+<?php if ($isScaffold): ?>
+/**
+ * Scaffold
+ *
+ * @var mixed
+ */
+ public $scaffold;
+
+<?php else:
+
+ if (count($helpers)):
+ echo "/**\n * Helpers\n *\n * @var array\n */\n";
+ echo "\tpublic \$helpers = array(";
+ for ($i = 0, $len = count($helpers); $i < $len; $i++):
+ if ($i != $len - 1):
+ echo "'" . Inflector::camelize($helpers[$i]) . "', ";
+ else:
+ echo "'" . Inflector::camelize($helpers[$i]) . "'";
+ endif;
+ endfor;
+ echo ");\n\n";
+ endif;
+
+ if (count($components)):
+ echo "/**\n * Components\n *\n * @var array\n */\n";
+ echo "\tpublic \$components = array(";
+ for ($i = 0, $len = count($components); $i < $len; $i++):
+ if ($i != $len - 1):
+ echo "'" . Inflector::camelize($components[$i]) . "', ";
+ else:
+ echo "'" . Inflector::camelize($components[$i]) . "'";
+ endif;
+ endfor;
+ echo ");\n\n";
+ endif;
+
+ echo trim($actions) . "\n";
+
+endif; ?>
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/fixture.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/fixture.ctp
new file mode 100644
index 0000000..dda2baf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/fixture.ctp
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Fixture Template file
+ *
+ * Fixture Template used when baking fixtures with bake
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.classes
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo '<?php' . "\n"; ?>
+/**
+ * <?php echo $model; ?>Fixture
+ *
+ */
+class <?php echo $model; ?>Fixture extends CakeTestFixture {
+
+<?php if ($table): ?>
+/**
+ * Table name
+ *
+ * @var string
+ */
+ public $table = '<?php echo $table; ?>';
+
+<?php endif; ?>
+<?php if ($import): ?>
+/**
+ * Import
+ *
+ * @var array
+ */
+ public $import = <?php echo $import; ?>;
+
+<?php endif; ?>
+<?php if ($schema): ?>
+/**
+ * Fields
+ *
+ * @var array
+ */
+ public $fields = <?php echo $schema; ?>;
+
+<?php endif; ?>
+<?php if ($records): ?>
+/**
+ * Records
+ *
+ * @var array
+ */
+ public $records = <?php echo $records; ?>;
+
+<?php endif; ?>
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/model.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/model.ctp
new file mode 100644
index 0000000..f7895da
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/model.ctp
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Model template file.
+ *
+ * Used by bake to create new Model files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.classes
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+echo "<?php\n";
+echo "App::uses('{$plugin}AppModel', '{$pluginPath}Model');\n";
+?>
+/**
+ * <?php echo $name ?> Model
+ *
+<?php
+foreach (array('hasOne', 'belongsTo', 'hasMany', 'hasAndBelongsToMany') as $assocType) {
+ if (!empty($associations[$assocType])) {
+ foreach ($associations[$assocType] as $relation) {
+ echo " * @property {$relation['className']} \${$relation['alias']}\n";
+ }
+ }
+}
+?>
+ */
+class <?php echo $name ?> extends <?php echo $plugin; ?>AppModel {
+
+<?php if ($useDbConfig != 'default'): ?>
+/**
+ * Use database config
+ *
+ * @var string
+ */
+ public $useDbConfig = '<?php echo $useDbConfig; ?>';
+
+<?php endif;
+
+if ($useTable && $useTable !== Inflector::tableize($name)):
+ $table = "'$useTable'";
+ echo "/**\n * Use table\n *\n * @var mixed False or table name\n */\n";
+ echo "\tpublic \$useTable = $table;\n\n";
+endif;
+
+if ($primaryKey !== 'id'): ?>
+/**
+ * Primary key field
+ *
+ * @var string
+ */
+ public $primaryKey = '<?php echo $primaryKey; ?>';
+
+<?php endif;
+
+if ($displayField): ?>
+/**
+ * Display field
+ *
+ * @var string
+ */
+ public $displayField = '<?php echo $displayField; ?>';
+
+<?php endif;
+
+if (!empty($validate)):
+ echo "/**\n * Validation rules\n *\n * @var array\n */\n";
+ echo "\tpublic \$validate = array(\n";
+ foreach ($validate as $field => $validations):
+ echo "\t\t'$field' => array(\n";
+ foreach ($validations as $key => $validator):
+ echo "\t\t\t'$key' => array(\n";
+ echo "\t\t\t\t'rule' => array('$validator'),\n";
+ echo "\t\t\t\t//'message' => 'Your custom message here',\n";
+ echo "\t\t\t\t//'allowEmpty' => false,\n";
+ echo "\t\t\t\t//'required' => false,\n";
+ echo "\t\t\t\t//'last' => false, // Stop validation after this rule\n";
+ echo "\t\t\t\t//'on' => 'create', // Limit validation to 'create' or 'update' operations\n";
+ echo "\t\t\t),\n";
+ endforeach;
+ echo "\t\t),\n";
+ endforeach;
+ echo "\t);\n";
+endif;
+
+foreach ($associations as $assoc):
+ if (!empty($assoc)):
+?>
+
+ //The Associations below have been created with all possible keys, those that are not needed can be removed
+<?php
+ break;
+ endif;
+endforeach;
+
+foreach (array('hasOne', 'belongsTo') as $assocType):
+ if (!empty($associations[$assocType])):
+ $typeCount = count($associations[$assocType]);
+ echo "\n/**\n * $assocType associations\n *\n * @var array\n */";
+ echo "\n\tpublic \$$assocType = array(";
+ foreach ($associations[$assocType] as $i => $relation):
+ $out = "\n\t\t'{$relation['alias']}' => array(\n";
+ $out .= "\t\t\t'className' => '{$relation['className']}',\n";
+ $out .= "\t\t\t'foreignKey' => '{$relation['foreignKey']}',\n";
+ $out .= "\t\t\t'conditions' => '',\n";
+ $out .= "\t\t\t'fields' => '',\n";
+ $out .= "\t\t\t'order' => ''\n";
+ $out .= "\t\t)";
+ if ($i + 1 < $typeCount) {
+ $out .= ",";
+ }
+ echo $out;
+ endforeach;
+ echo "\n\t);\n";
+ endif;
+endforeach;
+
+if (!empty($associations['hasMany'])):
+ $belongsToCount = count($associations['hasMany']);
+ echo "\n/**\n * hasMany associations\n *\n * @var array\n */";
+ echo "\n\tpublic \$hasMany = array(";
+ foreach ($associations['hasMany'] as $i => $relation):
+ $out = "\n\t\t'{$relation['alias']}' => array(\n";
+ $out .= "\t\t\t'className' => '{$relation['className']}',\n";
+ $out .= "\t\t\t'foreignKey' => '{$relation['foreignKey']}',\n";
+ $out .= "\t\t\t'dependent' => false,\n";
+ $out .= "\t\t\t'conditions' => '',\n";
+ $out .= "\t\t\t'fields' => '',\n";
+ $out .= "\t\t\t'order' => '',\n";
+ $out .= "\t\t\t'limit' => '',\n";
+ $out .= "\t\t\t'offset' => '',\n";
+ $out .= "\t\t\t'exclusive' => '',\n";
+ $out .= "\t\t\t'finderQuery' => '',\n";
+ $out .= "\t\t\t'counterQuery' => ''\n";
+ $out .= "\t\t)";
+ if ($i + 1 < $belongsToCount) {
+ $out .= ",";
+ }
+ echo $out;
+ endforeach;
+ echo "\n\t);\n\n";
+endif;
+
+if (!empty($associations['hasAndBelongsToMany'])):
+ $habtmCount = count($associations['hasAndBelongsToMany']);
+ echo "\n/**\n * hasAndBelongsToMany associations\n *\n * @var array\n */";
+ echo "\n\tpublic \$hasAndBelongsToMany = array(";
+ foreach ($associations['hasAndBelongsToMany'] as $i => $relation):
+ $out = "\n\t\t'{$relation['alias']}' => array(\n";
+ $out .= "\t\t\t'className' => '{$relation['className']}',\n";
+ $out .= "\t\t\t'joinTable' => '{$relation['joinTable']}',\n";
+ $out .= "\t\t\t'foreignKey' => '{$relation['foreignKey']}',\n";
+ $out .= "\t\t\t'associationForeignKey' => '{$relation['associationForeignKey']}',\n";
+ $out .= "\t\t\t'unique' => 'keepExisting',\n";
+ $out .= "\t\t\t'conditions' => '',\n";
+ $out .= "\t\t\t'fields' => '',\n";
+ $out .= "\t\t\t'order' => '',\n";
+ $out .= "\t\t\t'limit' => '',\n";
+ $out .= "\t\t\t'offset' => '',\n";
+ $out .= "\t\t\t'finderQuery' => '',\n";
+ $out .= "\t\t\t'deleteQuery' => '',\n";
+ $out .= "\t\t\t'insertQuery' => ''\n";
+ $out .= "\t\t)";
+ if ($i + 1 < $habtmCount) {
+ $out .= ",";
+ }
+ echo $out;
+ endforeach;
+ echo "\n\t);\n\n";
+endif;
+?>
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/test.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/test.ctp
new file mode 100644
index 0000000..2eb2b6c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/classes/test.ctp
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Test Case bake template
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.classes
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+echo "<?php\n";
+?>
+<?php foreach ($uses as $dependency): ?>
+App::uses('<?php echo $dependency[0]; ?>', '<?php echo $dependency[1]; ?>');
+<?php endforeach; ?>
+
+/**
+ * <?php echo $fullClassName; ?> Test Case
+ *
+ */
+<?php if ($type === 'Controller'): ?>
+class <?php echo $fullClassName; ?>Test extends ControllerTestCase {
+<?php else: ?>
+class <?php echo $fullClassName; ?>Test extends CakeTestCase {
+<?php endif; ?>
+
+<?php if (!empty($fixtures)): ?>
+/**
+ * Fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ '<?php echo join("',\n\t\t'", $fixtures); ?>'
+ );
+
+<?php endif; ?>
+<?php if (!empty($construction)): ?>
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+<?php echo $preConstruct ? "\t\t" . $preConstruct : ''; ?>
+ $this-><?php echo $className . ' = ' . $construction; ?>
+<?php echo $postConstruct ? "\t\t" . $postConstruct : ''; ?>
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this-><?php echo $className; ?>);
+
+ parent::tearDown();
+ }
+
+<?php endif; ?>
+<?php foreach ($methods as $method): ?>
+/**
+ * test<?php echo Inflector::camelize($method); ?> method
+ *
+ * @return void
+ */
+ public function test<?php echo Inflector::camelize($method); ?>() {
+ }
+
+<?php endforeach; ?>
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/form.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/form.ctp
new file mode 100644
index 0000000..b6fa788
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/form.ctp
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.views
+ * @since CakePHP(tm) v 1.2.0.5234
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> form">
+<?php echo "<?php echo \$this->Form->create('{$modelClass}'); ?>\n"; ?>
+ <fieldset>
+ <legend><?php printf("<?php echo __('%s %s'); ?>", Inflector::humanize($action), $singularHumanName); ?></legend>
+<?php
+ echo "\t<?php\n";
+ foreach ($fields as $field) {
+ if (strpos($action, 'add') !== false && $field == $primaryKey) {
+ continue;
+ } elseif (!in_array($field, array('created', 'modified', 'updated'))) {
+ echo "\t\techo \$this->Form->input('{$field}');\n";
+ }
+ }
+ if (!empty($associations['hasAndBelongsToMany'])) {
+ foreach ($associations['hasAndBelongsToMany'] as $assocName => $assocData) {
+ echo "\t\techo \$this->Form->input('{$assocName}');\n";
+ }
+ }
+ echo "\t?>\n";
+?>
+ </fieldset>
+<?php
+ echo "<?php echo \$this->Form->end(__('Submit')); ?>\n";
+?>
+</div>
+<div class="actions">
+ <h3><?php echo "<?php echo __('Actions'); ?>"; ?></h3>
+ <ul>
+
+<?php if (strpos($action, 'add') === false): ?>
+ <li><?php echo "<?php echo \$this->Form->postLink(__('Delete'), array('action' => 'delete', \$this->Form->value('{$modelClass}.{$primaryKey}')), null, __('Are you sure you want to delete # %s?', \$this->Form->value('{$modelClass}.{$primaryKey}'))); ?>"; ?></li>
+<?php endif; ?>
+ <li><?php echo "<?php echo \$this->Html->link(__('List " . $pluralHumanName . "'), array('action' => 'index')); ?>"; ?></li>
+<?php
+ $done = array();
+ foreach ($associations as $type => $data) {
+ foreach ($data as $alias => $details) {
+ if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) {
+ echo "\t\t<li><?php echo \$this->Html->link(__('List " . Inflector::humanize($details['controller']) . "'), array('controller' => '{$details['controller']}', 'action' => 'index')); ?> </li>\n";
+ echo "\t\t<li><?php echo \$this->Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'add')); ?> </li>\n";
+ $done[] = $details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/index.ctp
new file mode 100644
index 0000000..451ddfd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/index.ctp
@@ -0,0 +1,93 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.views
+ * @since CakePHP(tm) v 1.2.0.5234
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> index">
+ <h2><?php echo "<?php echo __('{$pluralHumanName}'); ?>"; ?></h2>
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <?php foreach ($fields as $field): ?>
+ <th><?php echo "<?php echo \$this->Paginator->sort('{$field}'); ?>"; ?></th>
+ <?php endforeach; ?>
+ <th class="actions"><?php echo "<?php echo __('Actions'); ?>"; ?></th>
+ </tr>
+ <?php
+ echo "<?php
+ foreach (\${$pluralVar} as \${$singularVar}): ?>\n";
+ echo "\t<tr>\n";
+ foreach ($fields as $field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $alias => $details) {
+ if ($field === $details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t<td>\n\t\t\t<?php echo \$this->Html->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller' => '{$details['controller']}', 'action' => 'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>\n\t\t</td>\n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t<td><?php echo h(\${$singularVar}['{$modelClass}']['{$field}']); ?>&nbsp;</td>\n";
+ }
+ }
+
+ echo "\t\t<td class=\"actions\">\n";
+ echo "\t\t\t<?php echo \$this->Html->link(__('View'), array('action' => 'view', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n";
+ echo "\t\t\t<?php echo \$this->Html->link(__('Edit'), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n";
+ echo "\t\t\t<?php echo \$this->Form->postLink(__('Delete'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>\n";
+ echo "\t\t</td>\n";
+ echo "\t</tr>\n";
+
+ echo "<?php endforeach; ?>\n";
+ ?>
+ </table>
+ <p>
+ <?php echo "<?php
+ echo \$this->Paginator->counter(array(
+ 'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
+ ));
+ ?>"; ?>
+ </p>
+
+ <div class="paging">
+ <?php
+ echo "<?php\n";
+ echo "\t\techo \$this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));\n";
+ echo "\t\techo \$this->Paginator->numbers(array('separator' => ''));\n";
+ echo "\t\techo \$this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));\n";
+ echo "\t?>\n";
+ ?>
+ </div>
+</div>
+<div class="actions">
+ <h3><?php echo "<?php echo __('Actions'); ?>"; ?></h3>
+ <ul>
+ <li><?php echo "<?php echo \$this->Html->link(__('New " . $singularHumanName . "'), array('action' => 'add')); ?>"; ?></li>
+<?php
+ $done = array();
+ foreach ($associations as $type => $data) {
+ foreach ($data as $alias => $details) {
+ if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) {
+ echo "\t\t<li><?php echo \$this->Html->link(__('List " . Inflector::humanize($details['controller']) . "'), array('controller' => '{$details['controller']}', 'action' => 'index')); ?> </li>\n";
+ echo "\t\t<li><?php echo \$this->Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'add')); ?> </li>\n";
+ $done[] = $details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/view.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/view.ctp
new file mode 100644
index 0000000..c3a7087
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/default/views/view.ctp
@@ -0,0 +1,139 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console.Templates.default.views
+ * @since CakePHP(tm) v 1.2.0.5234
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> view">
+<h2><?php echo "<?php echo __('{$singularHumanName}'); ?>"; ?></h2>
+ <dl>
+<?php
+foreach ($fields as $field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $alias => $details) {
+ if ($field === $details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t<dt><?php echo __('" . Inflector::humanize(Inflector::underscore($alias)) . "'); ?></dt>\n";
+ echo "\t\t<dd>\n\t\t\t<?php echo \$this->Html->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller' => '{$details['controller']}', 'action' => 'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t<dt><?php echo __('" . Inflector::humanize($field) . "'); ?></dt>\n";
+ echo "\t\t<dd>\n\t\t\t<?php echo h(\${$singularVar}['{$modelClass}']['{$field}']); ?>\n\t\t\t&nbsp;\n\t\t</dd>\n";
+ }
+}
+?>
+ </dl>
+</div>
+<div class="actions">
+ <h3><?php echo "<?php echo __('Actions'); ?>"; ?></h3>
+ <ul>
+<?php
+ echo "\t\t<li><?php echo \$this->Html->link(__('Edit " . $singularHumanName ."'), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?> </li>\n";
+ echo "\t\t<li><?php echo \$this->Form->postLink(__('Delete " . $singularHumanName . "'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?> </li>\n";
+ echo "\t\t<li><?php echo \$this->Html->link(__('List " . $pluralHumanName . "'), array('action' => 'index')); ?> </li>\n";
+ echo "\t\t<li><?php echo \$this->Html->link(__('New " . $singularHumanName . "'), array('action' => 'add')); ?> </li>\n";
+
+ $done = array();
+ foreach ($associations as $type => $data) {
+ foreach ($data as $alias => $details) {
+ if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) {
+ echo "\t\t<li><?php echo \$this->Html->link(__('List " . Inflector::humanize($details['controller']) . "'), array('controller' => '{$details['controller']}', 'action' => 'index')); ?> </li>\n";
+ echo "\t\t<li><?php echo \$this->Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'add')); ?> </li>\n";
+ $done[] = $details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div>
+<?php
+if (!empty($associations['hasOne'])) :
+ foreach ($associations['hasOne'] as $alias => $details): ?>
+ <div class="related">
+ <h3><?php echo "<?php echo __('Related " . Inflector::humanize($details['controller']) . "'); ?>"; ?></h3>
+ <?php echo "<?php if (!empty(\${$singularVar}['{$alias}'])): ?>\n"; ?>
+ <dl>
+ <?php
+ foreach ($details['fields'] as $field) {
+ echo "\t\t<dt><?php echo __('" . Inflector::humanize($field) . "'); ?></dt>\n";
+ echo "\t\t<dd>\n\t<?php echo \${$singularVar}['{$alias}']['{$field}']; ?>\n&nbsp;</dd>\n";
+ }
+ ?>
+ </dl>
+ <?php echo "<?php endif; ?>\n"; ?>
+ <div class="actions">
+ <ul>
+ <li><?php echo "<?php echo \$this->Html->link(__('Edit " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'edit', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?></li>\n"; ?>
+ </ul>
+ </div>
+ </div>
+ <?php
+ endforeach;
+endif;
+if (empty($associations['hasMany'])) {
+ $associations['hasMany'] = array();
+}
+if (empty($associations['hasAndBelongsToMany'])) {
+ $associations['hasAndBelongsToMany'] = array();
+}
+$relations = array_merge($associations['hasMany'], $associations['hasAndBelongsToMany']);
+$i = 0;
+foreach ($relations as $alias => $details):
+ $otherSingularVar = Inflector::variable($alias);
+ $otherPluralHumanName = Inflector::humanize($details['controller']);
+ ?>
+<div class="related">
+ <h3><?php echo "<?php echo __('Related " . $otherPluralHumanName . "'); ?>"; ?></h3>
+ <?php echo "<?php if (!empty(\${$singularVar}['{$alias}'])): ?>\n"; ?>
+ <table cellpadding = "0" cellspacing = "0">
+ <tr>
+<?php
+ foreach ($details['fields'] as $field) {
+ echo "\t\t<th><?php echo __('" . Inflector::humanize($field) . "'); ?></th>\n";
+ }
+?>
+ <th class="actions"><?php echo "<?php echo __('Actions'); ?>"; ?></th>
+ </tr>
+<?php
+echo "\t<?php
+ \$i = 0;
+ foreach (\${$singularVar}['{$alias}'] as \${$otherSingularVar}): ?>\n";
+ echo "\t\t<tr>\n";
+ foreach ($details['fields'] as $field) {
+ echo "\t\t\t<td><?php echo \${$otherSingularVar}['{$field}']; ?></td>\n";
+ }
+
+ echo "\t\t\t<td class=\"actions\">\n";
+ echo "\t\t\t\t<?php echo \$this->Html->link(__('View'), array('controller' => '{$details['controller']}', 'action' => 'view', \${$otherSingularVar}['{$details['primaryKey']}'])); ?>\n";
+ echo "\t\t\t\t<?php echo \$this->Html->link(__('Edit'), array('controller' => '{$details['controller']}', 'action' => 'edit', \${$otherSingularVar}['{$details['primaryKey']}'])); ?>\n";
+ echo "\t\t\t\t<?php echo \$this->Form->postLink(__('Delete'), array('controller' => '{$details['controller']}', 'action' => 'delete', \${$otherSingularVar}['{$details['primaryKey']}']), null, __('Are you sure you want to delete # %s?', \${$otherSingularVar}['{$details['primaryKey']}'])); ?>\n";
+ echo "\t\t\t</td>\n";
+ echo "\t\t</tr>\n";
+
+echo "\t<?php endforeach; ?>\n";
+?>
+ </table>
+<?php echo "<?php endif; ?>\n\n"; ?>
+ <div class="actions">
+ <ul>
+ <li><?php echo "<?php echo \$this->Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>"; ?> </li>
+ </ul>
+ </div>
+</div>
+<?php endforeach; ?>
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/.htaccess b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/.htaccess
index 0ed8662..fc3aac4 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/.htaccess
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/.htaccess
@@ -2,4 +2,4 @@
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
- </IfModule> \ No newline at end of file
+</IfModule> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php
new file mode 100644
index 0000000..de35962
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.php
@@ -0,0 +1,74 @@
+<?php
+/*DbAcl schema generated on: 2007-11-24 15:11:13 : 1195945453*/
+
+/**
+ * This is Acl Schema file
+ *
+ * Use it to configure database for ACL
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config.Schema
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create DbAcl
+ *
+ */
+class DbAclSchema extends CakeSchema {
+
+ public $name = 'DbAcl';
+
+ public function before($event = array()) {
+ return true;
+ }
+
+ public function after($event = array()) {
+ }
+
+ public $acos = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'alias' => array('type' => 'string', 'null' => true),
+ 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+ public $aros = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'alias' => array('type' => 'string', 'null' => true),
+ 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+ public $aros_acos = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'aro_id' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
+ 'aco_id' => array('type' => 'integer', 'null' => false, 'length' => 10),
+ '_create' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ '_read' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ '_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ '_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1))
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql
new file mode 100644
index 0000000..f50f392
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/db_acl.sql
@@ -0,0 +1,40 @@
+# $Id$
+#
+# Copyright 2005-2012, Cake Software Foundation, Inc.
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+CREATE TABLE acos (
+ id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ parent_id INTEGER(10) DEFAULT NULL,
+ model VARCHAR(255) DEFAULT '',
+ foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
+ alias VARCHAR(255) DEFAULT '',
+ lft INTEGER(10) DEFAULT NULL,
+ rght INTEGER(10) DEFAULT NULL,
+ PRIMARY KEY (id)
+);
+
+CREATE TABLE aros_acos (
+ id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ aro_id INTEGER(10) UNSIGNED NOT NULL,
+ aco_id INTEGER(10) UNSIGNED NOT NULL,
+ _create CHAR(2) NOT NULL DEFAULT 0,
+ _read CHAR(2) NOT NULL DEFAULT 0,
+ _update CHAR(2) NOT NULL DEFAULT 0,
+ _delete CHAR(2) NOT NULL DEFAULT 0,
+ PRIMARY KEY(id)
+);
+
+CREATE TABLE aros (
+ id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ parent_id INTEGER(10) DEFAULT NULL,
+ model VARCHAR(255) DEFAULT '',
+ foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
+ alias VARCHAR(255) DEFAULT '',
+ lft INTEGER(10) DEFAULT NULL,
+ rght INTEGER(10) DEFAULT NULL,
+ PRIMARY KEY (id)
+); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php
new file mode 100644
index 0000000..1a29ffd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.php
@@ -0,0 +1,51 @@
+<?php
+/*i18n schema generated on: 2007-11-25 07:11:25 : 1196004805*/
+
+/**
+ * This is i18n Schema file
+ *
+ * Use it to configure database for i18n
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config.Schema
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create i18n
+ *
+ */
+class i18nSchema extends CakeSchema {
+
+ public $name = 'i18n';
+
+ public function before($event = array()) {
+ return true;
+ }
+
+ public function after($event = array()) {
+ }
+
+ public $i18n = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'locale' => array('type' => 'string', 'null' => false, 'length' => 6, 'key' => 'index'),
+ 'model' => array('type' => 'string', 'null' => false, 'key' => 'index'),
+ 'foreign_key' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
+ 'field' => array('type' => 'string', 'null' => false, 'key' => 'index'),
+ 'content' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'locale' => array('column' => 'locale', 'unique' => 0), 'model' => array('column' => 'model', 'unique' => 0), 'row_id' => array('column' => 'foreign_key', 'unique' => 0), 'field' => array('column' => 'field', 'unique' => 0))
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql
new file mode 100644
index 0000000..239e146
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/i18n.sql
@@ -0,0 +1,26 @@
+# $Id$
+#
+# Copyright 2005-2012, Cake Software Foundation, Inc.
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+CREATE TABLE i18n (
+ id int(10) NOT NULL auto_increment,
+ locale varchar(6) NOT NULL,
+ model varchar(255) NOT NULL,
+ foreign_key int(10) NOT NULL,
+ field varchar(255) NOT NULL,
+ content mediumtext,
+ PRIMARY KEY (id),
+# UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
+# INDEX I18N_LOCALE_ROW(locale, model, foreign_key),
+# INDEX I18N_LOCALE_MODEL(locale, model),
+# INDEX I18N_FIELD(model, foreign_key, field),
+# INDEX I18N_ROW(model, foreign_key),
+ INDEX locale (locale),
+ INDEX model (model),
+ INDEX row_id (foreign_key),
+ INDEX field (field)
+); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php
new file mode 100644
index 0000000..d83e096
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/sessions.php
@@ -0,0 +1,48 @@
+<?php
+/*Sessions schema generated on: 2007-11-25 07:11:54 : 1196004714*/
+
+/**
+ * This is Sessions Schema file
+ *
+ * Use it to configure database for Sessions
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config.Schema
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create Sessions
+ *
+ */
+class SessionsSchema extends CakeSchema {
+
+ public $name = 'Sessions';
+
+ public function before($event = array()) {
+ return true;
+ }
+
+ public function after($event = array()) {
+ }
+
+ public $cake_sessions = array(
+ 'id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
+ 'data' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'expires' => array('type' => 'integer', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/sql/sessions.sql b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/sessions.sql
index 14c0036..b8951b6 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/sql/sessions.sql
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/Schema/sessions.sql
@@ -1,12 +1,12 @@
-# $Id: sessions.sql 6305 2008-01-02 02:33:56Z phpnut $
+# $Id$
#
-# Copyright 2005-2008, Cake Software Foundation, Inc.
+# Copyright 2005-2012, Cake Software Foundation, Inc.
# 1785 E. Sahara Avenue, Suite 490-204
# Las Vegas, Nevada 89104
#
# Licensed under The MIT License
# Redistributions of files must retain the above copyright notice.
-# http://www.opensource.org/licenses/mit-license.php The MIT License
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE cake_sessions (
id varchar(255) NOT NULL default '',
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/acl.ini.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/acl.ini.php
index 486e790..11ce65b 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/config/acl.ini.php
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/acl.ini.php
@@ -1,29 +1,21 @@
-;<?php die() ?>
-; SVN FILE: $Id: acl.ini.php 6305 2008-01-02 02:33:56Z phpnut $
+;<?php exit() ?>
;/**
-; * Short description for file.
+; * ACL Configuration
; *
; *
-; * PHP versions 4 and 5
+; * PHP 5
; *
-; * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
-; * Copyright 2005-2008, Cake Software Foundation, Inc.
-; * 1785 E. Sahara Avenue, Suite 490-204
-; * Las Vegas, Nevada 89104
+; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
; *
; * Licensed under The MIT License
; * Redistributions of files must retain the above copyright notice.
; *
-; * @filesource
-; * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
-; * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
-; * @package cake
-; * @subpackage cake.app.config
-; * @since CakePHP(tm) v 0.10.0.1076
-; * @version $Revision: 6305 $
-; * @modifiedby $LastChangedBy: phpnut $
-; * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
-; * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+; * @link http://cakephp.org CakePHP(tm) Project
+; * @package app.Config
+; * @since CakePHP(tm) v 0.10.0.1076
+; * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
; */
; acl.ini.php - Cake ACL Configuration
@@ -73,4 +65,4 @@ allow = aco3, aco4
[groupname-goes-here]
deny = aco5, aco6
-allow = aco7, aco8 \ No newline at end of file
+allow = aco7, aco8
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/bootstrap.php
new file mode 100644
index 0000000..786011e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/bootstrap.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * This file is loaded automatically by the app/webroot/index.php file after core.php
+ *
+ * This file should load/create any application wide configuration settings, such as
+ * Caching, Logging, loading additional configuration files.
+ *
+ * You should also use this file to include any files that provide global functions/constants
+ * that your application uses.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.10.8.2117
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+// Setup a 'default' cache configuration for use in the application.
+Cache::config('default', array('engine' => 'File'));
+
+/**
+ * The settings below can be used to set additional paths to models, views and controllers.
+ *
+ * App::build(array(
+ * 'Model' => array('/path/to/models', '/next/path/to/models'),
+ * 'Model/Behavior' => array('/path/to/behaviors', '/next/path/to/behaviors'),
+ * 'Model/Datasource' => array('/path/to/datasources', '/next/path/to/datasources'),
+ * 'Model/Datasource/Database' => array('/path/to/databases', '/next/path/to/database'),
+ * 'Model/Datasource/Session' => array('/path/to/sessions', '/next/path/to/sessions'),
+ * 'Controller' => array('/path/to/controllers', '/next/path/to/controllers'),
+ * 'Controller/Component' => array('/path/to/components', '/next/path/to/components'),
+ * 'Controller/Component/Auth' => array('/path/to/auths', '/next/path/to/auths'),
+ * 'Controller/Component/Acl' => array('/path/to/acls', '/next/path/to/acls'),
+ * 'View' => array('/path/to/views', '/next/path/to/views'),
+ * 'View/Helper' => array('/path/to/helpers', '/next/path/to/helpers'),
+ * 'Console' => array('/path/to/consoles', '/next/path/to/consoles'),
+ * 'Console/Command' => array('/path/to/commands', '/next/path/to/commands'),
+ * 'Console/Command/Task' => array('/path/to/tasks', '/next/path/to/tasks'),
+ * 'Lib' => array('/path/to/libs', '/next/path/to/libs'),
+ * 'Locale' => array('/path/to/locales', '/next/path/to/locales'),
+ * 'Vendor' => array('/path/to/vendors', '/next/path/to/vendors'),
+ * 'Plugin' => array('/path/to/plugins', '/next/path/to/plugins'),
+ * ));
+ *
+ */
+
+/**
+ * Custom Inflector rules, can be set to correctly pluralize or singularize table, model, controller names or whatever other
+ * string is passed to the inflection functions
+ *
+ * Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
+ * Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
+ *
+ */
+
+/**
+ * Plugins need to be loaded manually, you can either load them one by one or all of them in a single call
+ * Uncomment one of the lines below, as you need. make sure you read the documentation on CakePlugin to use more
+ * advanced ways of loading plugins
+ *
+ * CakePlugin::loadAll(); // Loads all plugins at once
+ * CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit
+ *
+ */
+
+/**
+ * You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters:
+ *
+ * - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins
+ * - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers
+ *
+ * Feel free to remove or add filters as you see fit for your application. A few examples:
+ *
+ * Configure::write('Dispatcher.filters', array(
+ * 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app.
+ * 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin.
+ * array('callbale' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch
+ * array('callbale' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch
+ *
+ * ));
+ */
+Configure::write('Dispatcher.filters', array(
+ 'AssetDispatcher',
+ 'CacheDispatcher'
+));
+
+/**
+ * Configures default file logging options
+ */
+App::uses('CakeLog', 'Log');
+CakeLog::config('debug', array(
+ 'engine' => 'FileLog',
+ 'scopes' => array('notice', 'info', 'debug'),
+ 'file' => 'debug',
+));
+CakeLog::config('error', array(
+ 'engine' => 'FileLog',
+ 'scopes' => array('warning', 'error', 'critical', 'alert', 'emergency'),
+ 'file' => 'error',
+));
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/core.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/core.php
new file mode 100644
index 0000000..c53e2fd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/core.php
@@ -0,0 +1,336 @@
+<?php
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behavior of Cake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * CakePHP Debug Level:
+ *
+ * Production Mode:
+ * 0: No error messages, errors, or warnings shown. Flash messages redirect.
+ *
+ * Development Mode:
+ * 1: Errors and warnings shown, model caches refreshed, flash messages halted.
+ * 2: As in 1, but also with full debug messages and SQL output.
+ *
+ * In production mode, flash messages redirect after a time interval.
+ * In development mode, you need to click the flash message to continue.
+ */
+ Configure::write('debug', 2);
+
+/**
+ * Configure the Error handler used to handle errors for your application. By default
+ * ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0
+ * and log errors with CakeLog when debug = 0.
+ *
+ * Options:
+ *
+ * - `handler` - callback - The callback to handle errors. You can set this to any callable type,
+ * including anonymous functions.
+ * - `level` - int - The level of errors you are interested in capturing.
+ * - `trace` - boolean - Include stack traces for errors in log files.
+ *
+ * @see ErrorHandler for more information on error handling and configuration.
+ */
+ Configure::write('Error', array(
+ 'handler' => 'ErrorHandler::handleError',
+ 'level' => E_ALL & ~E_DEPRECATED,
+ 'trace' => true
+ ));
+
+/**
+ * Configure the Exception handler used for uncaught exceptions. By default,
+ * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and
+ * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0,
+ * framework errors will be coerced into generic HTTP errors.
+ *
+ * Options:
+ *
+ * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type,
+ * including anonymous functions.
+ * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you
+ * should place the file for that class in app/Lib/Error. This class needs to implement a render method.
+ * - `log` - boolean - Should Exceptions be logged?
+ *
+ * @see ErrorHandler for more information on exception handling and configuration.
+ */
+ Configure::write('Exception', array(
+ 'handler' => 'ErrorHandler::handleException',
+ 'renderer' => 'ExceptionRenderer',
+ 'log' => true
+ ));
+
+/**
+ * Application wide charset encoding
+ */
+ Configure::write('App.encoding', 'UTF-8');
+
+/**
+ * To configure CakePHP *not* to use mod_rewrite and to
+ * use CakePHP pretty URLs, remove these .htaccess
+ * files:
+ *
+ * /.htaccess
+ * /app/.htaccess
+ * /app/webroot/.htaccess
+ *
+ * And uncomment the App.baseUrl below:
+ */
+ //Configure::write('App.baseUrl', env('SCRIPT_NAME'));
+
+/**
+ * Uncomment the define below to use CakePHP prefix routes.
+ *
+ * The value of the define determines the names of the routes
+ * and their associated controller actions:
+ *
+ * Set to an array of prefixes you want to use in your application. Use for
+ * admin or other prefixed routes.
+ *
+ * Routing.prefixes = array('admin', 'manager');
+ *
+ * Enables:
+ * `admin_index()` and `/admin/controller/index`
+ * `manager_index()` and `/manager/controller/index`
+ *
+ */
+ //Configure::write('Routing.prefixes', array('admin'));
+
+/**
+ * Turn off all caching application-wide.
+ *
+ */
+ //Configure::write('Cache.disable', true);
+
+/**
+ * Enable cache checking.
+ *
+ * If set to true, for view caching you must still use the controller
+ * public $cacheAction inside your controllers to define caching settings.
+ * You can either set it controller-wide by setting public $cacheAction = true,
+ * or in each action using $this->cacheAction = true.
+ *
+ */
+ //Configure::write('Cache.check', true);
+
+/**
+ * Defines the default error type when using the log() function. Used for
+ * differentiating error logging and debugging. Currently PHP supports LOG_DEBUG.
+ */
+ define('LOG_ERROR', LOG_ERR);
+
+/**
+ * Session configuration.
+ *
+ * Contains an array of settings to use for session configuration. The defaults key is
+ * used to define a default preset to use for sessions, any settings declared here will override
+ * the settings of the default config.
+ *
+ * ## Options
+ *
+ * - `Session.cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'
+ * - `Session.timeout` - The number of minutes you want sessions to live for. This timeout is handled by CakePHP
+ * - `Session.cookieTimeout` - The number of minutes you want session cookies to live for.
+ * - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the
+ * value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX
+ * - `Session.defaults` - The default configuration set to use as a basis for your session.
+ * There are four builtins: php, cake, cache, database.
+ * - `Session.handler` - Can be used to enable a custom session handler. Expects an array of of callables,
+ * that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler`
+ * to the ini array.
+ * - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and
+ * sessionids that change frequently. See CakeSession::$requestCountdown.
+ * - `Session.ini` - An associative array of additional ini values to set.
+ *
+ * The built in defaults are:
+ *
+ * - 'php' - Uses settings defined in your php.ini.
+ * - 'cake' - Saves session files in CakePHP's /tmp directory.
+ * - 'database' - Uses CakePHP's database sessions.
+ * - 'cache' - Use the Cache class to save sessions.
+ *
+ * To define a custom session handler, save it at /app/Model/Datasource/Session/<name>.php.
+ * Make sure the class implements `CakeSessionHandlerInterface` and set Session.handler to <name>
+ *
+ * To use database sessions, run the app/Config/Schema/sessions.php schema using
+ * the cake shell command: cake schema create Sessions
+ *
+ */
+ Configure::write('Session', array(
+ 'defaults' => 'php'
+ ));
+
+/**
+ * The level of CakePHP security.
+ */
+ Configure::write('Security.level', 'medium');
+
+/**
+ * A random string used in security hashing methods.
+ */
+ Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
+
+/**
+ * A random numeric string (digits only) used to encrypt/decrypt strings.
+ */
+ Configure::write('Security.cipherSeed', '76859309657453542496749683645');
+
+/**
+ * Apply timestamps with the last modified time to static assets (js, css, images).
+ * Will append a querystring parameter containing the time the file was modified. This is
+ * useful for invalidating browser caches.
+ *
+ * Set to `true` to apply timestamps when debug > 0. Set to 'force' to always enable
+ * timestamping regardless of debug value.
+ */
+ //Configure::write('Asset.timestamp', true);
+
+/**
+ * Compress CSS output by removing comments, whitespace, repeating tags, etc.
+ * This requires a/var/cache directory to be writable by the web server for caching.
+ * and /vendors/csspp/csspp.php
+ *
+ * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use HtmlHelper::css().
+ */
+ //Configure::write('Asset.filter.css', 'css.php');
+
+/**
+ * Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the
+ * output, and setting the config below to the name of the script.
+ *
+ * To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JavaScriptHelper::link().
+ */
+ //Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');
+
+/**
+ * The classname and database used in CakePHP's
+ * access control lists.
+ */
+ Configure::write('Acl.classname', 'DbAcl');
+ Configure::write('Acl.database', 'default');
+
+/**
+ * Uncomment this line and correct your server timezone to fix
+ * any date & time related errors.
+ */
+ //date_default_timezone_set('UTC');
+
+/**
+ *
+ * Cache Engine Configuration
+ * Default settings provided below
+ *
+ * File storage engine.
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'File', //[required]
+ * 'duration' => 3600, //[optional]
+ * 'probability' => 100, //[optional]
+ * 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
+ * 'prefix' => 'cake_', //[optional] prefix every cache file with this string
+ * 'lock' => false, //[optional] use file locking
+ * 'serialize' => true, [optional]
+ * ));
+ *
+ * APC (http://pecl.php.net/package/APC)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Apc', //[required]
+ * 'duration' => 3600, //[optional]
+ * 'probability' => 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * ));
+ *
+ * Xcache (http://xcache.lighttpd.net/)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Xcache', //[required]
+ * 'duration' => 3600, //[optional]
+ * 'probability' => 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * 'user' => 'user', //user from xcache.admin.user settings
+ * 'password' => 'password', //plaintext password (xcache.admin.pass)
+ * ));
+ *
+ * Memcache (http://www.danga.com/memcached/)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Memcache', //[required]
+ * 'duration' => 3600, //[optional]
+ * 'probability' => 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * 'servers' => array(
+ * '127.0.0.1:11211' // localhost, default port 11211
+ * ), //[optional]
+ * 'persistent' => true, // [optional] set this to false for non-persistent connections
+ * 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
+ * ));
+ *
+ * Wincache (http://php.net/wincache)
+ *
+ * Cache::config('default', array(
+ * 'engine' => 'Wincache', //[required]
+ * 'duration' => 3600, //[optional]
+ * 'probability' => 100, //[optional]
+ * 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ * ));
+ */
+
+/**
+ * Pick the caching engine to use. If APC is enabled use it.
+ * If running via cli - apc is disabled by default. ensure it's available and enabled in this case
+ *
+ */
+$engine = 'File';
+if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
+ $engine = 'Apc';
+}
+
+// In development mode, caches should expire quickly.
+$duration = '+999 days';
+if (Configure::read('debug') >= 1) {
+ $duration = '+10 seconds';
+}
+
+// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
+$prefix = 'myapp_';
+
+/**
+ * Configure the cache used for general framework caching. Path information,
+ * object listings, and translation cache files are stored with this configuration.
+ */
+Cache::config('_cake_core_', array(
+ 'engine' => $engine,
+ 'prefix' => $prefix . 'cake_core_',
+ 'path' => CACHE . 'persistent' . DS,
+ 'serialize' => ($engine === 'File'),
+ 'duration' => $duration
+));
+
+/**
+ * Configure the cache for model and datasource caches. This cache configuration
+ * is used to store schema descriptions, and table listings in connections.
+ */
+Cache::config('_cake_model_', array(
+ 'engine' => $engine,
+ 'prefix' => $prefix . 'cake_model_',
+ 'path' => CACHE . 'models' . DS,
+ 'serialize' => ($engine === 'File'),
+ 'duration' => $duration
+));
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/database.php.default b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/database.php.default
new file mode 100644
index 0000000..245c282
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/database.php.default
@@ -0,0 +1,84 @@
+<?php
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour of Cake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * In this file you set up your database connection details.
+ *
+ * @package cake.config
+ */
+/**
+ * Database configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * datasource => The name of a supported datasource; valid options are as follows:
+ * Database/Mysql - MySQL 4 & 5,
+ * Database/Sqlite - SQLite (PHP5 only),
+ * Database/Postgres - PostgreSQL 7 and higher,
+ * Database/Sqlserver - Microsoft SQL Server 2005 and higher
+ *
+ * You can add custom database datasources (or override existing datasources) by adding the
+ * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php',
+ *
+ *
+ * persistent => true / false
+ * Determines whether or not the database should use a persistent connection
+ *
+ * host =>
+ * the host you connect to the database. To add a socket or port number, use 'port' => #
+ *
+ * prefix =>
+ * Uses the given prefix for all the tables in this database. This setting can be overridden
+ * on a per-table basis with the Model::$tablePrefix property.
+ *
+ * schema =>
+ * For Postgres/Sqlserver specifies which schema you would like to use the tables in. Postgres defaults to 'public'. For Sqlserver, it defaults to empty and use
+ * the connected user's default schema (typically 'dbo').
+ *
+ * encoding =>
+ * For MySQL, Postgres specifies the character encoding to use when connecting to the
+ * database. Uses database default not specified.
+ *
+ * unix_socket =>
+ * For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port`
+ */
+class DATABASE_CONFIG {
+
+ public $default = array(
+ 'datasource' => 'Database/Mysql',
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'login' => 'user',
+ 'password' => 'password',
+ 'database' => 'database_name',
+ 'prefix' => '',
+ //'encoding' => 'utf8',
+ );
+
+ public $test = array(
+ 'datasource' => 'Database/Mysql',
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'login' => 'user',
+ 'password' => 'password',
+ 'database' => 'test_database_name',
+ 'prefix' => '',
+ //'encoding' => 'utf8',
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/email.php.default b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/email.php.default
new file mode 100644
index 0000000..c423f78
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/email.php.default
@@ -0,0 +1,97 @@
+<?php
+/**
+ * This is email configuration file.
+ *
+ * Use it to configure email transports of Cake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * In this file you set up your send email details.
+ *
+ * @package cake.config
+ */
+/**
+ * Email configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * transport => The name of a supported transport; valid options are as follows:
+ * Mail - Send using PHP mail function
+ * Smtp - Send using SMTP
+ * Debug - Do not send the email, just return the result
+ *
+ * You can add custom transports (or override existing transports) by adding the
+ * appropriate file to app/Network/Email. Transports should be named 'YourTransport.php',
+ * where 'Your' is the name of the transport.
+ *
+ * from =>
+ * The origin email. See CakeEmail::from() about the valid values
+ *
+ */
+class EmailConfig {
+
+ public $default = array(
+ 'transport' => 'Mail',
+ 'from' => 'you@localhost',
+ //'charset' => 'utf-8',
+ //'headerCharset' => 'utf-8',
+ );
+
+ public $smtp = array(
+ 'transport' => 'Smtp',
+ 'from' => array('site@localhost' => 'My Site'),
+ 'host' => 'localhost',
+ 'port' => 25,
+ 'timeout' => 30,
+ 'username' => 'user',
+ 'password' => 'secret',
+ 'client' => null,
+ 'log' => false
+ //'charset' => 'utf-8',
+ //'headerCharset' => 'utf-8',
+ );
+
+ public $fast = array(
+ 'from' => 'you@localhost',
+ 'sender' => null,
+ 'to' => null,
+ 'cc' => null,
+ 'bcc' => null,
+ 'replyTo' => null,
+ 'readReceipt' => null,
+ 'returnPath' => null,
+ 'messageId' => true,
+ 'subject' => null,
+ 'message' => null,
+ 'headers' => null,
+ 'viewRender' => null,
+ 'template' => false,
+ 'layout' => false,
+ 'viewVars' => null,
+ 'attachments' => null,
+ 'emailFormat' => null,
+ 'transport' => 'Smtp',
+ 'host' => 'localhost',
+ 'port' => 25,
+ 'timeout' => 30,
+ 'username' => 'user',
+ 'password' => 'secret',
+ 'client' => null,
+ 'log' => true,
+ //'charset' => 'utf-8',
+ //'headerCharset' => 'utf-8',
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/routes.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/routes.php
new file mode 100644
index 0000000..82cd2db
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Config/routes.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Routes configuration
+ *
+ * In this file, you set up routes to your controllers and their actions.
+ * Routes are very important mechanism that allows you to freely connect
+ * different urls to chosen controllers and their actions (functions).
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Config
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * Here, we are connecting '/' (base path) to controller called 'Pages',
+ * its action called 'display', and we pass a param to select the view file
+ * to use (in this case, /app/View/Pages/home.ctp)...
+ */
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+/**
+ * ...and connect the rest of 'Pages' controller's urls.
+ */
+ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+
+/**
+ * Load all plugin routes. See the CakePlugin documentation on
+ * how to customize the loading of plugin routes.
+ */
+ CakePlugin::routes();
+
+/**
+ * Load the CakePHP default routes. Remove this if you do not want to use
+ * the built-in default routes.
+ */
+ require CAKE . 'Config' . DS . 'routes.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php
new file mode 100644
index 0000000..5cc915f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Command/AppShell.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * AppShell file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Shell', 'Console');
+
+/**
+ * Application Shell
+ *
+ * Add your application-wide methods in the class below, your shells
+ * will inherit them.
+ *
+ * @package app.Console.Command
+ */
+class AppShell extends Shell {
+
+}
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/views/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Command/Task/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/cache/views/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Command/Task/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Templates/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/Templates/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake
new file mode 100644
index 0000000..447743d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+################################################################################
+#
+# Bake is a shell script for running CakePHP bake script
+# PHP 5
+#
+# CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+# Copyright 2005-2012, Cake Software Foundation, Inc.
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+#
+# @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+# @link http://cakephp.org CakePHP(tm) Project
+# @package app.Console
+# @since CakePHP(tm) v 2.0
+# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+#
+################################################################################
+LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0")
+
+while [ -h "$LIB" ]; do
+ DIR=$(dirname -- "$LIB")
+ SYM=$(readlink "$LIB")
+ LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
+done
+
+LIB=$(dirname -- "$LIB")/
+APP=`pwd`
+
+exec php -q "$LIB"cake.php -working "$APP" "$@"
+
+exit;
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.bat b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.bat
new file mode 100644
index 0000000..b28ec8d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.bat
@@ -0,0 +1,32 @@
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: Bake is a shell script for running CakePHP bake script
+:: PHP 5
+::
+:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+:: Copyright 2005-2012, Cake Software Foundation, Inc.
+::
+:: Licensed under The MIT License
+:: Redistributions of files must retain the above copyright notice.
+::
+:: @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+:: @link http://cakephp.org CakePHP(tm) Project
+:: @package app.Console
+:: @since CakePHP(tm) v 2.0
+:: @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:: In order for this script to work as intended, the cake\console\ folder must be in your PATH
+
+@echo.
+@echo off
+
+SET app=%0
+SET lib=%~dp0
+
+php -q "%lib%cake.php" -working "%CD% " %*
+
+echo.
+
+exit /B %ERRORLEVEL%
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.php
new file mode 100644
index 0000000..d3c91b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Console/cake.php
@@ -0,0 +1,33 @@
+#!/usr/bin/php -q
+<?php
+/**
+ * Command-line code generation utility to automate programmer chores.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$ds = DIRECTORY_SEPARATOR;
+$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
+
+if (function_exists('ini_set')) {
+ $root = dirname(dirname(dirname(__FILE__)));
+ ini_set('include_path', $root . PATH_SEPARATOR . __CAKE_PATH__ . PATH_SEPARATOR . ini_get('include_path'));
+}
+
+if (!include $dispatcher) {
+ trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
+}
+unset($paths, $path, $dispatcher, $root, $ds);
+
+return ShellDispatcher::run($argv);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/AppController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/AppController.php
new file mode 100644
index 0000000..7aab7e9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/AppController.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Application level Controller
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+
+/**
+ * Application Controller
+ *
+ * Add your application-wide methods in the class below, your controllers
+ * will inherit them.
+ *
+ * @package app.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
+ */
+class AppController extends Controller {
+}
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/logs/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/Component/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/logs/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/Component/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/PagesController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/PagesController.php
new file mode 100644
index 0000000..28edfb6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Controller/PagesController.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Static content controller.
+ *
+ * This file will render views from views/pages/
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Static content controller
+ *
+ * Override this controller by placing a copy in controllers directory of an application
+ *
+ * @package app.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers/pages-controller.html
+ */
+class PagesController extends AppController {
+
+/**
+ * This controller does not use a model
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * Displays a view
+ *
+ * @param string What page to display
+ */
+ public function display() {
+ $path = func_get_args();
+
+ $count = count($path);
+ if (!$count) {
+ $this->redirect('/');
+ }
+ $page = $subpage = $title = null;
+
+ if (!empty($path[0])) {
+ $page = $path[0];
+ }
+ if (!empty($path[1])) {
+ $subpage = $path[1];
+ }
+ if (!empty($path[$count - 1])) {
+ $title = Inflector::humanize($path[$count - 1]);
+ }
+ $this->set(compact('page', 'subpage'));
+ $this->set('title_for_layout', $title);
+ $this->render(implode('/', $path));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/sessions/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Lib/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/sessions/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Lib/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/tests/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Locale/eng/LC_MESSAGES/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/tmp/tests/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Locale/eng/LC_MESSAGES/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/AppModel.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/AppModel.php
new file mode 100644
index 0000000..94e5e5f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/AppModel.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Application model for Cake.
+ *
+ * This file is application-wide model file. You can put all
+ * application-wide model-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+
+/**
+ * Application model for Cake.
+ *
+ * Add your application-wide methods in the class below, your models
+ * will inherit them.
+ *
+ * @package app.Model
+ */
+class AppModel extends Model {
+}
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/vendors/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/Behavior/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/vendors/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/Behavior/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/views/elements/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/Datasource/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/views/elements/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Model/Datasource/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/views/errors/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Plugin/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/views/errors/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Plugin/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/views/helpers/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/Controller/Component/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/views/helpers/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/Controller/Component/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/views/layouts/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/Model/Behavior/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/views/layouts/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/Model/Behavior/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/views/pages/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/View/Helper/empty
index e69de29..e69de29 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/views/pages/empty
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Case/View/Helper/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Fixture/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Fixture/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Test/Fixture/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Vendor/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Vendor/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/Vendor/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Elements/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Elements/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Elements/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp
new file mode 100644
index 0000000..2d00c3d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/html/default.ctp
@@ -0,0 +1,25 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Emails.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php
+$content = explode("\n", $content);
+
+foreach ($content as $line):
+ echo '<p> ' . $line . '</p>';
+endforeach;
+?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp
new file mode 100644
index 0000000..8b5e8c8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Emails/text/default.ctp
@@ -0,0 +1,19 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Emails.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo $content; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp
new file mode 100644
index 0000000..6d50860
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error400.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo $name; ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake', 'Error'); ?>: </strong>
+ <?php printf(
+ __d('cake', 'The requested address %s was not found on this server.'),
+ "<strong>'{$url}'</strong>"
+ ); ?>
+</p>
+<?php
+if (Configure::read('debug') > 0 ):
+ echo $this->element('exception_stack_trace');
+endif;
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp
new file mode 100644
index 0000000..4e1f36e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Errors/error500.ctp
@@ -0,0 +1,28 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo $name; ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake', 'Error'); ?>: </strong>
+ <?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
+</p>
+<?php
+if (Configure::read('debug') > 0 ):
+ echo $this->element('exception_stack_trace');
+endif;
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php
new file mode 100644
index 0000000..caceda8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Helper/AppHelper.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Application level View Helper
+ *
+ * This file is application-wide helper file. You can put all
+ * application-wide helper-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Helper
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Helper', 'View');
+
+/**
+ * Application helper
+ *
+ * Add your application-wide methods in the class below, your helpers
+ * will inherit them.
+ *
+ * @package app.View.Helper
+ */
+class AppHelper extends Helper {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp
new file mode 100644
index 0000000..12a9171
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/html/default.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Layouts.Email.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+
+<html>
+<head>
+ <title><?php echo $title_for_layout; ?></title>
+</head>
+
+<body>
+ <?php echo $this->fetch('content'); ?>
+
+ <p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>
+</body>
+</html>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp
new file mode 100644
index 0000000..f914b3d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/Emails/text/default.ctp
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Layouts.Email.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+
+<?php echo $this->fetch('content'); ?>
+
+This email was sent using the CakePHP Framework, http://cakephp.org.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp
new file mode 100644
index 0000000..9dc5ee5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/ajax.ctp
@@ -0,0 +1,19 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo $this->fetch('content'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp
new file mode 100644
index 0000000..4aab010
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/default.ctp
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <?php echo $this->Html->charset(); ?>
+ <title>
+ <?php echo __('CakePHP: the rapid development php framework:'); ?>
+ <?php echo $title_for_layout; ?>
+ </title>
+ <?php
+ echo $this->Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $this->fetch('meta');
+ echo $this->fetch('css');
+ echo $this->fetch('script');
+ ?>
+</head>
+<body>
+ <div id="container">
+ <div id="header">
+ <h1><?php echo $this->Html->link(__('CakePHP: the rapid development php framework'), 'http://cakephp.org'); ?></h1>
+ </div>
+ <div id="content">
+
+ <?php echo $this->Session->flash(); ?>
+
+ <?php echo $this->fetch('content'); ?>
+ </div>
+ <div id="footer">
+ <?php echo $this->Html->link(
+ $this->Html->image('cake.power.gif', array('alt' => __('CakePHP: the rapid development php framework'), 'border' => '0')),
+ 'http://www.cakephp.org/',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+ </div>
+ </div>
+ <?php echo $this->element('sql_dump'); ?>
+</body>
+</html>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/error.ctp
new file mode 100644
index 0000000..c7d6787
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/error.ctp
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <?php echo $this->Html->charset(); ?>
+ <title>
+ <?php echo __('CakePHP: the rapid development php framework:'); ?>
+ <?php echo $title_for_layout; ?>
+ </title>
+ <?php
+ echo $this->Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $this->fetch('meta');
+ echo $this->fetch('css');
+ echo $this->fetch('script');
+ ?>
+</head>
+<body>
+ <div id="container">
+ <div id="header">
+ <h1><?php echo $this->Html->link(__('CakePHP: the rapid development php framework'), 'http://cakephp.org'); ?></h1>
+ </div>
+ <div id="content">
+
+ <?php echo $this->Session->flash(); ?>
+
+ <?php echo $this->fetch('content'); ?>
+ </div>
+ <div id="footer">
+ <?php echo $this->Html->link(
+ $this->Html->image('cake.power.gif', array('alt' => __('CakePHP: the rapid development php framework'), 'border' => '0')),
+ 'http://www.cakephp.org/',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+ </div>
+ </div>
+ <?php echo $this->element('sql_dump'); ?>
+</body>
+</html>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/flash.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/flash.ctp
new file mode 100644
index 0000000..35f5a94
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/flash.ctp
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.View.Layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<?php echo $this->Html->charset(); ?>
+<title><?php echo $page_title; ?></title>
+
+<?php if (Configure::read('debug') == 0) { ?>
+<meta http-equiv="Refresh" content="<?php echo $pause?>;url=<?php echo $url?>"/>
+<?php } ?>
+<style><!--
+P { text-align:center; font:bold 1.1em sans-serif }
+A { color:#444; text-decoration:none }
+A:HOVER { text-decoration: underline; color:#44E }
+--></style>
+</head>
+<body>
+<p><a href="<?php echo $url?>"><?php echo $message?></a></p>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/js/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/js/default.ctp
new file mode 100644
index 0000000..7239b5d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/js/default.ctp
@@ -0,0 +1,2 @@
+<?php echo $scripts_for_layout; ?>
+<script type="text/javascript"><?php echo $this->fetch('content'); ?></script>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/rss/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/rss/default.ctp
new file mode 100644
index 0000000..077de61
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/rss/default.ctp
@@ -0,0 +1,14 @@
+<?php
+if (!isset($channel)) {
+ $channel = array();
+}
+if (!isset($channel['title'])) {
+ $channel['title'] = $title_for_layout;
+}
+
+echo $this->Rss->document(
+ $this->Rss->channel(
+ array(), $channel, $this->fetch('content')
+ )
+);
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/xml/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/xml/default.ctp
new file mode 100644
index 0000000..fbd5ee0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Layouts/xml/default.ctp
@@ -0,0 +1 @@
+<?php echo $this->fetch('content'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Pages/home.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Pages/home.ctp
new file mode 100644
index 0000000..82f76fe
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Pages/home.ctp
@@ -0,0 +1,188 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Pages
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+if (Configure::read('debug') == 0):
+ throw new NotFoundException();
+endif;
+App::uses('Debugger', 'Utility');
+?>
+<iframe src="http://cakephp.org/bake-banner" width="830" height="160" style="overflow:hidden; border:none;">
+ <p>For updates and important announcements, visit http://cakefest.org</p>
+</iframe>
+<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
+<a href="http://cakephp.org/changelogs/<?php echo Configure::version(); ?>"><?php echo __d('cake_dev', 'Read the changelog'); ?> </a>
+<?php
+if (Configure::read('debug') > 0):
+ Debugger::checkSecurityKeys();
+endif;
+?>
+<p id="url-rewriting-warning" style="background-color:#e32; color:#fff;">
+ <?php echo __d('cake_dev', 'URL rewriting is not properly configured on your server.'); ?>
+ 1) <a target="_blank" href="http://book.cakephp.org/2.0/en/installation/advanced-installation.html#apache-and-mod-rewrite-and-htaccess" style="color:#fff;">Help me configure it</a>
+ 2) <a target="_blank" href="http://book.cakephp.org/2.0/en/development/configuration.html#cakephp-core-configuration" style="color:#fff;">I don't / can't use URL rewriting</a>
+</p>
+<p>
+<?php
+ if (version_compare(PHP_VERSION, '5.2.8', '>=')):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your version of PHP is 5.2.8 or higher.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your version of PHP is too low. You need PHP 5.2.8 or higher to use CakePHP.');
+ echo '</span>';
+ endif;
+?>
+</p>
+<p>
+ <?php
+ if (is_writable(TMP)):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your tmp directory is writable.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your tmp directory is NOT writable.');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<p>
+ <?php
+ $settings = Cache::settings();
+ if (!empty($settings)):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit APP/Config/core.php ', '<em>'. $settings['engine'] . 'Engine</em>');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in APP/Config/core.php');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<p>
+ <?php
+ $filePresent = null;
+ if (file_exists(APP . 'Config' . DS . 'database.php')):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your database configuration file is present.');
+ $filePresent = true;
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your database configuration file is NOT present.');
+ echo '<br/>';
+ echo __d('cake_dev', 'Rename APP/Config/database.php.default to APP/Config/database.php');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<?php
+if (isset($filePresent)):
+ App::uses('ConnectionManager', 'Model');
+ try {
+ $connected = ConnectionManager::getDataSource('default');
+ } catch (Exception $connectionError) {
+ $connected = false;
+ }
+?>
+<p>
+ <?php
+ if ($connected && $connected->isConnected()):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Cake is able to connect to the database.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Cake is NOT able to connect to the database.');
+ echo '<br /><br />';
+ echo $connectionError->getMessage();
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<?php endif; ?>
+<?php
+ App::uses('Validation', 'Utility');
+ if (!Validation::alphaNumeric('cakephp')) {
+ echo '<p><span class="notice">';
+ echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.');
+ echo '<br/>';
+ echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
+ echo '</span></p>';
+ }
+?>
+<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
+<p>
+<?php
+echo __d('cake_dev', 'To change the content of this page, create: APP/View/Pages/home.ctp.<br />
+To change its layout, create: APP/View/Layouts/default.ctp.<br />
+You can also add some CSS styles for your pages at: APP/webroot/css.');
+?>
+</p>
+
+<h3><?php echo __d('cake_dev', 'Getting Started'); ?></h3>
+<p>
+ <?php
+ echo $this->Html->link(
+ sprintf('<strong>%s</strong> %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 2.0 Docs')),
+ 'http://book.cakephp.org/2.0/en/',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+</p>
+<p>
+ <?php
+ echo $this->Html->link(
+ __d('cake_dev', 'The 15 min Blog Tutorial'),
+ 'http://book.cakephp.org/2.0/en/tutorials-and-examples/blog/blog.html',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+</p>
+
+<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3>
+<p>
+<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
+</p>
+<p>
+<?php echo __d('cake_dev', 'Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.'); ?>
+</p>
+
+<ul>
+ <li><a href="http://cakefoundation.org/"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
+ <li><a href="http://www.cakephp.org"><?php echo __d('cake_dev', 'CakePHP'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li>
+ <li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li>
+ <li><a href="http://api20.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li>
+ <li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
+ <li><a href="http://live.cakephp.org"><?php echo __d('cake_dev', 'The Show'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'The Show is a live and archived internet radio broadcast CakePHP-related topics and answer questions live via IRC, Skype, and telephone.'); ?></li></ul></li>
+ <li><a href="http://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
+ <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
+ <ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li>
+ <li><a href="http://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'For the Development of CakePHP Git repository, Downloads'); ?></li></ul></li>
+ <li><a href="http://cakephp.lighthouseapp.com/"><?php echo __d('cake_dev', 'CakePHP Lighthouse'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'CakePHP Tickets, Wiki pages, Roadmap'); ?></li></ul></li>
+</ul>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Scaffolds/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Scaffolds/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/View/Scaffolds/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/index.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/index.php
new file mode 100644
index 0000000..29f2c57
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/index.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/models/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/models/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/models/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/persistent/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/persistent/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/persistent/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/views/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/views/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/cache/views/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/logs/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/logs/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/logs/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/sessions/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/sessions/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/sessions/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/tests/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/tests/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/tmp/tests/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/.htaccess b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/.htaccess
index f9d8b93..48a63f0 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/app/webroot/.htaccess
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/.htaccess
@@ -2,5 +2,5 @@
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
- RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
-</IfModule> \ No newline at end of file
+ RewriteRule ^(.*)$ index.php [QSA,L]
+</IfModule>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/css/cake.generic.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/css/cake.generic.css
new file mode 100644
index 0000000..2244ad2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/css/cake.generic.css
@@ -0,0 +1,739 @@
+@charset "utf-8";
+/**
+ *
+ * Generic CSS for CakePHP
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.webroot.css
+ * @since CakePHP(tm)
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+* {
+ margin:0;
+ padding:0;
+}
+
+/** General Style Info **/
+body {
+ background: #003d4c;
+ color: #fff;
+ font-family:'lucida grande',verdana,helvetica,arial,sans-serif;
+ font-size:90%;
+ margin: 0;
+}
+a {
+ color: #003d4c;
+ text-decoration: underline;
+ font-weight: bold;
+}
+a:hover {
+ color: #367889;
+ text-decoration:none;
+}
+a img {
+ border:none;
+}
+h1, h2, h3, h4 {
+ font-weight: normal;
+ margin-bottom:0.5em;
+}
+h1 {
+ background:#fff;
+ color: #003d4c;
+ font-size: 100%;
+}
+h2 {
+ background:#fff;
+ color: #e32;
+ font-family:'Gill Sans','lucida grande', helvetica, arial, sans-serif;
+ font-size: 190%;
+}
+h3 {
+ color: #2c6877;
+ font-family:'Gill Sans','lucida grande', helvetica, arial, sans-serif;
+ font-size: 165%;
+}
+h4 {
+ color: #993;
+ font-weight: normal;
+}
+ul, li {
+ margin: 0 12px;
+}
+p {
+ margin: 0 0 1em 0;
+}
+
+/** Layout **/
+#container {
+ text-align: left;
+}
+
+#header{
+ padding: 10px 20px;
+}
+#header h1 {
+ line-height:20px;
+ background: #003d4c url('../img/cake.icon.png') no-repeat left;
+ color: #fff;
+ padding: 0px 30px;
+}
+#header h1 a {
+ color: #fff;
+ background: #003d4c;
+ font-weight: normal;
+ text-decoration: none;
+}
+#header h1 a:hover {
+ color: #fff;
+ background: #003d4c;
+ text-decoration: underline;
+}
+#content{
+ background: #fff;
+ clear: both;
+ color: #333;
+ padding: 10px 20px 40px 20px;
+ overflow: auto;
+}
+#footer {
+ clear: both;
+ padding: 6px 10px;
+ text-align: right;
+}
+
+/** containers **/
+div.form,
+div.index,
+div.view {
+ float:right;
+ width:76%;
+ border-left:1px solid #666;
+ padding:10px 2%;
+}
+div.actions {
+ float:left;
+ width:16%;
+ padding:10px 1.5%;
+}
+div.actions h3 {
+ padding-top:0;
+ color:#777;
+}
+
+
+/** Tables **/
+table {
+ border-right:0;
+ clear: both;
+ color: #333;
+ margin-bottom: 10px;
+ width: 100%;
+}
+th {
+ border:0;
+ border-bottom:2px solid #555;
+ text-align: left;
+ padding:4px;
+}
+th a {
+ display: block;
+ padding: 2px 4px;
+ text-decoration: none;
+}
+th a.asc:after {
+ content: ' ⇣';
+}
+th a.desc:after {
+ content: ' ⇡';
+}
+table tr td {
+ padding: 6px;
+ text-align: left;
+ vertical-align: top;
+ border-bottom:1px solid #ddd;
+}
+table tr:nth-child(even) {
+ background: #f9f9f9;
+}
+td.actions {
+ text-align: center;
+ white-space: nowrap;
+}
+table td.actions a {
+ margin: 0px 6px;
+ padding:2px 5px;
+}
+
+/* SQL log */
+.cake-sql-log {
+ background: #fff;
+}
+.cake-sql-log td {
+ padding: 4px 8px;
+ text-align: left;
+ font-family: Monaco, Consolas, "Courier New", monospaced;
+}
+.cake-sql-log caption {
+ color:#fff;
+}
+
+/** Paging **/
+.paging {
+ background:#fff;
+ color: #ccc;
+ margin-top: 1em;
+ clear:both;
+}
+.paging .current,
+.paging .disabled,
+.paging a {
+ text-decoration: none;
+ padding: 5px 8px;
+ display: inline-block
+}
+.paging > span {
+ display: inline-block;
+ border: 1px solid #ccc;
+ border-left: 0;
+}
+.paging > span:hover {
+ background: #efefef;
+}
+.paging .prev {
+ border-left: 1px solid #ccc;
+ -moz-border-radius: 4px 0 0 4px;
+ -webkit-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+.paging .next {
+ -moz-border-radius: 0 4px 4px 0;
+ -webkit-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+.paging .disabled {
+ color: #ddd;
+}
+.paging .disabled:hover {
+ background: transparent;
+}
+.paging .current {
+ background: #efefef;
+ color: #c73e14;
+}
+
+/** Scaffold View **/
+dl {
+ line-height: 2em;
+ margin: 0em 0em;
+ width: 60%;
+}
+dl dd:nth-child(4n+2),
+dl dt:nth-child(4n+1) {
+ background: #f4f4f4;
+}
+
+dt {
+ font-weight: bold;
+ padding-left: 4px;
+ vertical-align: top;
+ width: 10em;
+}
+dd {
+ margin-left: 10em;
+ margin-top: -2em;
+ vertical-align: top;
+}
+
+/** Forms **/
+form {
+ clear: both;
+ margin-right: 20px;
+ padding: 0;
+ width: 95%;
+}
+fieldset {
+ border: none;
+ margin-bottom: 1em;
+ padding: 16px 10px;
+}
+fieldset legend {
+ color: #e32;
+ font-size: 160%;
+ font-weight: bold;
+}
+fieldset fieldset {
+ margin-top: 0;
+ padding: 10px 0 0;
+}
+fieldset fieldset legend {
+ font-size: 120%;
+ font-weight: normal;
+}
+fieldset fieldset div {
+ clear: left;
+ margin: 0 20px;
+}
+form div {
+ clear: both;
+ margin-bottom: 1em;
+ padding: .5em;
+ vertical-align: text-top;
+}
+form .input {
+ color: #444;
+}
+form .required {
+ font-weight: bold;
+}
+form .required label:after {
+ color: #e32;
+ content: '*';
+ display:inline;
+}
+form div.submit {
+ border: 0;
+ clear: both;
+ margin-top: 10px;
+}
+label {
+ display: block;
+ font-size: 110%;
+ margin-bottom:3px;
+}
+input, textarea {
+ clear: both;
+ font-size: 140%;
+ font-family: "frutiger linotype", "lucida grande", "verdana", sans-serif;
+ padding: 1%;
+ width:98%;
+}
+select {
+ clear: both;
+ font-size: 120%;
+ vertical-align: text-bottom;
+}
+select[multiple=multiple] {
+ width: 100%;
+}
+option {
+ font-size: 120%;
+ padding: 0 3px;
+}
+input[type=checkbox] {
+ clear: left;
+ float: left;
+ margin: 0px 6px 7px 2px;
+ width: auto;
+}
+div.checkbox label {
+ display: inline;
+}
+input[type=radio] {
+ float:left;
+ width:auto;
+ margin: 6px 0;
+ padding: 0;
+ line-height: 26px;
+}
+.radio label {
+ margin: 0 0 6px 20px;
+ line-height: 26px;
+}
+input[type=submit] {
+ display: inline;
+ font-size: 110%;
+ width: auto;
+}
+form .submit input[type=submit] {
+ background:#62af56;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#76BF6B), to(#3B8230));
+ background-image: -webkit-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -moz-linear-gradient(top, #76BF6B, #3B8230);
+ border-color: #2d6324;
+ color: #fff;
+ text-shadow: rgba(0, 0, 0, 0.5) 0px -1px 0px;
+ padding: 8px 10px;
+}
+form .submit input[type=submit]:hover {
+ background: #5BA150;
+}
+/* Form errors */
+form .error {
+ background: #FFDACC;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ font-weight: normal;
+}
+form .error-message {
+ -moz-border-radius: none;
+ -webkit-border-radius: none;
+ border-radius: none;
+ border: none;
+ background: none;
+ margin: 0;
+ padding-left: 4px;
+ padding-right: 0;
+}
+form .error,
+form .error-message {
+ color: #9E2424;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ -ms-box-shadow: none;
+ -o-box-shadow: none;
+ box-shadow: none;
+ text-shadow: none;
+}
+
+/** Notices and Errors **/
+.message {
+ clear: both;
+ color: #fff;
+ font-size: 140%;
+ font-weight: bold;
+ margin: 0 0 1em 0;
+ padding: 5px;
+}
+
+.success,
+.message,
+.cake-error,
+.cake-debug,
+.notice,
+p.error,
+.error-message {
+ background: #ffcc00;
+ background-repeat: repeat-x;
+ background-image: -moz-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: -ms-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ffcc00), to(#E6B800));
+ background-image: -webkit-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: -o-linear-gradient(top, #ffcc00, #E6B800);
+ background-image: linear-gradient(top, #ffcc00, #E6B800);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ margin-bottom: 18px;
+ padding: 7px 14px;
+ color: #404040;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+}
+.success,
+.message,
+.cake-error,
+p.error,
+.error-message {
+ clear: both;
+ color: #fff;
+ background: #c43c35;
+ border: 1px solid rgba(0, 0, 0, 0.5);
+ background-repeat: repeat-x;
+ background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
+ background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: linear-gradient(top, #ee5f5b, #c43c35);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+}
+.success {
+ clear: both;
+ color: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.5);
+ background: #3B8230;
+ background-repeat: repeat-x;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#76BF6B), to(#3B8230));
+ background-image: -webkit-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -moz-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -ms-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: -o-linear-gradient(top, #76BF6B, #3B8230);
+ background-image: linear-gradient(top, #76BF6B, #3B8230);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+}
+p.error {
+ font-family: Monaco, Consolas, Courier, monospace;
+ font-size: 120%;
+ padding: 0.8em;
+ margin: 1em 0;
+}
+p.error em {
+ font-weight: normal;
+ line-height: 140%;
+}
+.notice {
+ color: #000;
+ display: block;
+ font-size: 120%;
+ padding: 0.8em;
+ margin: 1em 0;
+}
+.success {
+ color: #fff;
+}
+
+/** Actions **/
+.actions ul {
+ margin: 0;
+ padding: 0;
+}
+.actions li {
+ margin:0 0 0.5em 0;
+ list-style-type: none;
+ white-space: nowrap;
+ padding: 0;
+}
+.actions ul li a {
+ font-weight: normal;
+ display: block;
+ clear: both;
+}
+
+/* Buttons and button links */
+input[type=submit],
+.actions ul li a,
+.actions a {
+ font-weight:normal;
+ padding: 4px 8px;
+ background: #dcdcdc;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fefefe), to(#dcdcdc));
+ background-image: -webkit-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -moz-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -ms-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -o-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: linear-gradient(top, #fefefe, #dcdcdc);
+ color:#333;
+ border:1px solid #bbb;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ text-decoration: none;
+ text-shadow: #fff 0px 1px 0px;
+ min-width: 0;
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0px 1px 1px rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0px 1px 1px rgba(0, 0, 0, 0.2);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0px 1px 1px rgba(0, 0, 0, 0.2);
+ -webkit-user-select: none;
+ user-select: none;
+}
+.actions ul li a:hover,
+.actions a:hover {
+ background: #ededed;
+ border-color: #acacac;
+ text-decoration: none;
+}
+input[type=submit]:active,
+.actions ul li a:active,
+.actions a:active {
+ background: #eee;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#dfdfdf), to(#eee));
+ background-image: -webkit-linear-gradient(top, #dfdfdf, #eee);
+ background-image: -moz-linear-gradient(top, #dfdfdf, #eee);
+ background-image: -ms-linear-gradient(top, #dfdfdf, #eee);
+ background-image: -o-linear-gradient(top, #dfdfdf, #eee);
+ background-image: linear-gradient(top, #dfdfdf, #eee);
+ text-shadow: #eee 0px 1px 0px;
+ -moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
+ box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
+ border-color: #aaa;
+ text-decoration: none;
+}
+
+/** Related **/
+.related {
+ clear: both;
+ display: block;
+}
+
+/** Debugging **/
+pre {
+ color: #000;
+ background: #f0f0f0;
+ padding: 15px;
+ -moz-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
+}
+.cake-debug-output {
+ padding: 0;
+ position: relative;
+}
+.cake-debug-output > span {
+ position: absolute;
+ top: 5px;
+ right: 5px;
+ background: rgba(255, 255, 255, 0.3);
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ padding: 5px 6px;
+ color: #000;
+ display: block;
+ float: left;
+ -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(255, 255, 255, 0.5);
+ -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(255, 255, 255, 0.5);
+ box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.25), 0 1px 0 rgba(255, 255, 255, 0.5);
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
+}
+.cake-debug,
+.cake-error {
+ font-size: 16px;
+ line-height: 20px;
+ clear: both;
+}
+.cake-error > a {
+ text-shadow: none;
+}
+.cake-error {
+ white-space: normal;
+}
+.cake-stack-trace {
+ background: rgba(255, 255, 255, 0.7);
+ color: #333;
+ margin: 10px 0 5px 0;
+ padding: 10px 10px 0 10px;
+ font-size: 120%;
+ line-height: 140%;
+ overflow: auto;
+ position: relative;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+}
+.cake-stack-trace a {
+ text-shadow: none;
+ background: rgba(255, 255, 255, 0.7);
+ padding: 5px;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+ margin: 0px 4px 10px 2px;
+ font-family: sans-serif;
+ font-size: 14px;
+ line-height: 14px;
+ display: inline-block;
+ text-decoration: none;
+ -moz-box-shadow: inset 0px 1px 0 rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: inset 0px 1px 0 rgba(0, 0, 0, 0.3);
+ box-shadow: inset 0px 1px 0 rgba(0, 0, 0, 0.3);
+}
+.cake-code-dump pre {
+ position: relative;
+ overflow: auto;
+}
+.cake-context {
+ margin-bottom: 10px;
+}
+.cake-stack-trace pre {
+ color: #000;
+ background-color: #F0F0F0;
+ margin: 0px 0 10px 0;
+ padding: 1em;
+ overflow: auto;
+ text-shadow: none;
+}
+.cake-stack-trace li {
+ padding: 10px 5px 0px;
+ margin: 0 0 4px 0;
+ font-family: monospace;
+ border: 1px solid #bbb;
+ -moz-border-radius: 4px;
+ -wekbkit-border-radius: 4px;
+ border-radius: 4px;
+ background: #dcdcdc;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fefefe), to(#dcdcdc));
+ background-image: -webkit-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -moz-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -ms-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: -o-linear-gradient(top, #fefefe, #dcdcdc);
+ background-image: linear-gradient(top, #fefefe, #dcdcdc);
+}
+/* excerpt */
+.cake-code-dump pre,
+.cake-code-dump pre code {
+ clear: both;
+ font-size: 12px;
+ line-height: 15px;
+ margin: 4px 2px;
+ padding: 4px;
+ overflow: auto;
+}
+.cake-code-dump .code-highlight {
+ display: block;
+ background-color: rgba(255, 255, 0, 0.5);
+}
+.code-coverage-results div.code-line {
+ padding-left:5px;
+ display:block;
+ margin-left:10px;
+}
+.code-coverage-results div.uncovered span.content {
+ background:#ecc;
+}
+.code-coverage-results div.covered span.content {
+ background:#cec;
+}
+.code-coverage-results div.ignored span.content {
+ color:#aaa;
+}
+.code-coverage-results span.line-num {
+ color:#666;
+ display:block;
+ float:left;
+ width:20px;
+ text-align:right;
+ margin-right:5px;
+}
+.code-coverage-results span.line-num strong {
+ color:#666;
+}
+.code-coverage-results div.start {
+ border:1px solid #aaa;
+ border-width:1px 1px 0px 1px;
+ margin-top:30px;
+ padding-top:5px;
+}
+.code-coverage-results div.end {
+ border:1px solid #aaa;
+ border-width:0px 1px 1px 1px;
+ margin-bottom:30px;
+ padding-bottom:5px;
+}
+.code-coverage-results div.realstart {
+ margin-top:0px;
+}
+.code-coverage-results p.note {
+ color:#bbb;
+ padding:5px;
+ margin:5px 0 10px;
+ font-size:10px;
+}
+.code-coverage-results span.result-bad {
+ color: #a00;
+}
+.code-coverage-results span.result-ok {
+ color: #fa0;
+}
+.code-coverage-results span.result-good {
+ color: #0a0;
+}
+
+/** Elements **/
+#url-rewriting-warning {
+ display:none;
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/favicon.ico b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/favicon.ico
new file mode 100644
index 0000000..b36e81f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/favicon.ico
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/files/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/files/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/files/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.icon.png
new file mode 100644
index 0000000..394fa42
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif
new file mode 100644
index 0000000..8f8d570
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/favicon.ico b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-error-icon.png
index 1bc32bd..07bb124 100644
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/favicon.ico
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-error-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-fail-icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-fail-icon.png
new file mode 100644
index 0000000..f9d2f14
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-fail-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-pass-icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-pass-icon.png
new file mode 100644
index 0000000..99c5eb0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-pass-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-skip-icon.png b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-skip-icon.png
new file mode 100644
index 0000000..749771c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/img/test-skip-icon.png
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/index.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/index.php
new file mode 100644
index 0000000..fd482f8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/index.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Index
+ *
+ * The Front Controller for handling every request
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package app.webroot
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * Use the DS to separate the directories in other defines
+ */
+if (!defined('DS')) {
+ define('DS', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * When using custom settings be sure to use the DS and do not add a trailing DS.
+ */
+
+/**
+ * The full path to the directory which holds "app", WITHOUT a trailing DS.
+ *
+ */
+if (!defined('ROOT')) {
+ define('ROOT', dirname(dirname(dirname(__FILE__))));
+}
+
+/**
+ * The actual directory name for the "app".
+ *
+ */
+if (!defined('APP_DIR')) {
+ define('APP_DIR', basename(dirname(dirname(__FILE__))));
+}
+
+/**
+ * The absolute path to the "cake" directory, WITHOUT a trailing DS.
+ *
+ * Un-comment this line to specify a fixed path to CakePHP.
+ * This should point at the directory containing `Cake`.
+ *
+ * For ease of development CakePHP uses PHP's include_path. If you
+ * cannot modify your include_path set this value.
+ *
+ * Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
+ */
+//define('CAKE_CORE_INCLUDE_PATH', __CAKE_PATH__);
+
+/**
+ * Editing below this line should NOT be necessary.
+ * Change at your own risk.
+ *
+ */
+if (!defined('WEBROOT_DIR')) {
+ define('WEBROOT_DIR', basename(dirname(__FILE__)));
+}
+if (!defined('WWW_ROOT')) {
+ define('WWW_ROOT', dirname(__FILE__) . DS);
+}
+
+if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ if (function_exists('ini_set')) {
+ ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
+ }
+ if (!include 'Cake' . DS . 'bootstrap.php') {
+ $failed = true;
+ }
+} else {
+ if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') {
+ $failed = true;
+ }
+}
+if (!empty($failed)) {
+ trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
+}
+
+App::uses('Dispatcher', 'Routing');
+
+$Dispatcher = new Dispatcher();
+$Dispatcher->dispatch(
+ new CakeRequest(),
+ new CakeResponse(array('charset' => Configure::read('App.encoding')))
+);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/js/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/js/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/js/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/test.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/test.php
new file mode 100644
index 0000000..37b7f25
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/Templates/skel/webroot/test.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Web Access Frontend for TestSuite
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html
+ * @package app.webroot
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+set_time_limit(0);
+ini_set('display_errors', 1);
+/**
+ * Use the DS to separate the directories in other defines
+ */
+if (!defined('DS')) {
+ define('DS', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * When using custom settings be sure to use the DS and do not add a trailing DS.
+ */
+
+/**
+ * The full path to the directory which holds "app", WITHOUT a trailing DS.
+ *
+ */
+if (!defined('ROOT')) {
+ define('ROOT', dirname(dirname(dirname(__FILE__))));
+}
+
+/**
+ * The actual directory name for the "app".
+ *
+ */
+if (!defined('APP_DIR')) {
+ define('APP_DIR', basename(dirname(dirname(__FILE__))));
+}
+
+/**
+ * The absolute path to the "Cake" directory, WITHOUT a trailing DS.
+ *
+ * For ease of development CakePHP uses PHP's include_path. If you
+ * need to cannot modify your include_path, you can set this path.
+ *
+ * Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
+ */
+//define('CAKE_CORE_INCLUDE_PATH', __CAKE_PATH__);
+
+/**
+ * Editing below this line should not be necessary.
+ * Change at your own risk.
+ *
+ */
+if (!defined('WEBROOT_DIR')) {
+ define('WEBROOT_DIR', basename(dirname(__FILE__)));
+}
+if (!defined('WWW_ROOT')) {
+ define('WWW_ROOT', dirname(__FILE__) . DS);
+}
+
+if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ if (function_exists('ini_set')) {
+ ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
+ }
+ if (!include 'Cake' . DS . 'bootstrap.php') {
+ $failed = true;
+ }
+} else {
+ if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') {
+ $failed = true;
+ }
+}
+if (!empty($failed)) {
+ trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
+}
+
+if (Configure::read('debug') < 1) {
+ die(__d('cake_dev', 'Debug setting does not allow access to this url.'));
+}
+
+require_once CAKE . 'TestSuite' . DS . 'CakeTestSuiteDispatcher.php';
+
+CakeTestSuiteDispatcher::run();
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake
new file mode 100755
index 0000000..fbef004
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+################################################################################
+#
+# Bake is a shell script for running CakePHP bake script
+# PHP 5
+#
+# CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+# Copyright 2005-2012, Cake Software Foundation, Inc.
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+#
+# @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+# @link http://cakephp.org CakePHP(tm) Project
+# @package cake.Console
+# @since CakePHP(tm) v 1.2.0.5012
+# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+#
+################################################################################
+LIB=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && LIB=$LIB/$(basename -- "$0")
+
+while [ -h "$LIB" ]; do
+ DIR=$(dirname -- "$LIB")
+ SYM=$(readlink "$LIB")
+ LIB=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
+done
+
+LIB=$(dirname -- "$LIB")/
+APP=`pwd`
+
+exec php -q "$LIB"cake.php -working "$APP" "$@"
+
+exit;
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.bat b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.bat
new file mode 100644
index 0000000..4444f38
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.bat
@@ -0,0 +1,32 @@
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: Bake is a shell script for running CakePHP bake script
+:: PHP 5
+::
+:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+:: Copyright 2005-2012, Cake Software Foundation, Inc.
+::
+:: Licensed under The MIT License
+:: Redistributions of files must retain the above copyright notice.
+::
+:: @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+:: @link http://cakephp.org CakePHP(tm) Project
+:: @package cake.console
+:: @since CakePHP(tm) v 1.2.0.5012
+:: @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:: In order for this script to work as intended, the cake\console\ folder must be in your PATH
+
+@echo.
+@echo off
+
+SET app=%0
+SET lib=%~dp0
+
+php -q "%lib%cake.php" -working "%CD% " %*
+
+echo.
+
+exit /B %ERRORLEVEL%
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.php
new file mode 100644
index 0000000..bae9cf3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Console/cake.php
@@ -0,0 +1,41 @@
+#!/usr/bin/php -q
+<?php
+/**
+ * Command-line code generation utility to automate programmer chores.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Console
+ * @since CakePHP(tm) v 1.2.0.5012
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$ds = DIRECTORY_SEPARATOR;
+$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
+$found = false;
+$paths = explode(PATH_SEPARATOR, ini_get('include_path'));
+
+foreach ($paths as $path) {
+ if (file_exists($path . $ds . $dispatcher)) {
+ $found = $path;
+ }
+}
+
+if (!$found && function_exists('ini_set')) {
+ $root = dirname(dirname(dirname(__FILE__)));
+ ini_set('include_path', $root . $ds . PATH_SEPARATOR . ini_get('include_path'));
+}
+
+if (!include $dispatcher) {
+ trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
+}
+unset($paths, $path, $found, $dispatcher, $root, $ds);
+
+return ShellDispatcher::run($argv);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php
new file mode 100644
index 0000000..5778648
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/CakeErrorController.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Error Handling Controller
+ *
+ * Controller used by ErrorHandler to render error views.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Error Handling Controller
+ *
+ * Controller used by ErrorHandler to render error views.
+ *
+ * @package Cake.Controller
+ */
+class CakeErrorController extends AppController {
+
+/**
+ * Controller name
+ *
+ * @var string
+ */
+ public $name = 'CakeError';
+
+/**
+ * Uses Property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * __construct
+ *
+ * @param CakeRequest $request
+ * @param CakeResponse $response
+ */
+ public function __construct($request = null, $response = null) {
+ parent::__construct($request, $response);
+ if (count(Router::extensions())) {
+ $this->components[] = 'RequestHandler';
+ }
+ $this->constructClasses();
+ if ($this->Components->enabled('Auth')) {
+ $this->Components->disable('Auth');
+ }
+ if ($this->Components->enabled('Security')) {
+ $this->Components->disable('Security');
+ }
+ $this->startupProcess();
+
+ $this->_set(array('cacheAction' => false, 'viewPath' => 'Errors'));
+ }
+
+/**
+ * Escapes the viewVars.
+ *
+ * @return void
+ */
+ public function beforeRender() {
+ parent::beforeRender();
+ foreach ($this->viewVars as $key => $value) {
+ if (!is_object($value)) {
+ $this->viewVars[$key] = h($value);
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php
new file mode 100644
index 0000000..876174e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component.php
@@ -0,0 +1,165 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ComponentCollection', 'Controller');
+
+/**
+ * Base class for an individual Component. Components provide reusable bits of
+ * controller logic that can be composed into a controller. Components also
+ * provide request life-cycle callbacks for injecting logic at specific points.
+ *
+ * ## Life cycle callbacks
+ *
+ * Components can provide several callbacks that are fired at various stages of the request
+ * cycle. The available callbacks are:
+ *
+ * - `initialize()` - Fired before the controller's beforeFilter method.
+ * - `startup()` - Fired after the controller's beforeFilter method.
+ * - `beforeRender()` - Fired before the view + layout are rendered.
+ * - `shutdown()` - Fired after the action is complete and the view has been rendered
+ * but before Controller::afterFilter().
+ * - `beforeRedirect()` - Fired before a redirect() is done.
+ *
+ * @package Cake.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html
+ * @see Controller::$components
+ */
+class Component extends Object {
+
+/**
+ * Component collection class used to lazy load components.
+ *
+ * @var ComponentCollection
+ */
+ protected $_Collection;
+
+/**
+ * Settings for this Component
+ *
+ * @var array
+ */
+ public $settings = array();
+
+/**
+ * Other Components this component uses.
+ *
+ * @var array
+ */
+ public $components = array();
+
+/**
+ * A component lookup table used to lazy load component objects.
+ *
+ * @var array
+ */
+ protected $_componentMap = array();
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
+ * @param array $settings Array of configuration settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->_Collection = $collection;
+ $this->settings = $settings;
+ $this->_set($settings);
+ if (!empty($this->components)) {
+ $this->_componentMap = ComponentCollection::normalizeObjectArray($this->components);
+ }
+ }
+
+/**
+ * Magic method for lazy loading $components.
+ *
+ * @param string $name Name of component to get.
+ * @return mixed A Component object or null.
+ */
+ public function __get($name) {
+ if (isset($this->_componentMap[$name]) && !isset($this->{$name})) {
+ $settings = array_merge((array)$this->_componentMap[$name]['settings'], array('enabled' => false));
+ $this->{$name} = $this->_Collection->load($this->_componentMap[$name]['class'], $settings);
+ }
+ if (isset($this->{$name})) {
+ return $this->{$name};
+ }
+ }
+
+/**
+ * Called before the Controller::beforeFilter().
+ *
+ * @param Controller $controller Controller with components to initialize
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::initialize
+ */
+ public function initialize(Controller $controller) {
+ }
+
+/**
+ * Called after the Controller::beforeFilter() and before the controller action
+ *
+ * @param Controller $controller Controller with components to startup
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::startup
+ */
+ public function startup(Controller $controller) {
+ }
+
+/**
+ * Called before the Controller::beforeRender(), and before
+ * the view class is loaded, and before Controller::render()
+ *
+ * @param Controller $controller Controller with components to beforeRender
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRender
+ */
+ public function beforeRender(Controller $controller) {
+ }
+
+/**
+ * Called after Controller::render() and before the output is printed to the browser.
+ *
+ * @param Controller $controller Controller with components to shutdown
+ * @return void
+ * @link @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::shutdown
+ */
+ public function shutdown(Controller $controller) {
+ }
+
+/**
+ * Called before Controller::redirect(). Allows you to replace the url that will
+ * be redirected to with a new url. The return of this method can either be an array or a string.
+ *
+ * If the return is an array and contains a 'url' key. You may also supply the following:
+ *
+ * - `status` The status code for the redirect
+ * - `exit` Whether or not the redirect should exit.
+ *
+ * If your response is a string or an array that does not contain a 'url' key it will
+ * be used as the new url to redirect to.
+ *
+ * @param Controller $controller Controller with components to beforeRedirect
+ * @param string|array $url Either the string or url array that is being redirected to.
+ * @param integer $status The status code of the redirect
+ * @param boolean $exit Will the script exit.
+ * @return array|null Either an array or null.
+ * @link @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRedirect
+ */
+ public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php
new file mode 100644
index 0000000..7cd9813
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/AclInterface.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Access Control List interface.
+ * Implementing classes are used by AclComponent to perform ACL checks in Cake.
+ *
+ * @package Cake.Controller.Component
+ */
+interface AclInterface {
+
+/**
+ * Empty method to be overridden in subclasses
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ */
+ public function check($aro, $aco, $action = "*");
+
+/**
+ * Allow methods are used to grant an ARO access to an ACO.
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*");
+
+/**
+ * Deny methods are used to remove permission from an ARO to access an ACO.
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*");
+
+/**
+ * Inherit methods modify the permission for an ARO to be that of its parent object.
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*");
+
+/**
+ * Initialization method for the Acl implementation
+ *
+ * @param AclComponent $component
+ */
+ public function initialize(Component $component);
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php
new file mode 100644
index 0000000..37c756b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/DbAcl.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('AclInterface', 'Controller/Component/Acl');
+App::uses('Hash', 'Utility');
+
+/**
+ * DbAcl implements an ACL control system in the database. ARO's and ACO's are
+ * structured into trees and a linking table is used to define permissions. You
+ * can install the schema for DbAcl with the Schema Shell.
+ *
+ * `$aco` and `$aro` parameters can be slash delimited paths to tree nodes.
+ *
+ * eg. `controllers/Users/edit`
+ *
+ * Would point to a tree structure like
+ *
+ * {{{
+ * controllers
+ * Users
+ * edit
+ * }}}
+ *
+ * @package Cake.Controller.Component
+ */
+class DbAcl extends Object implements AclInterface {
+
+/**
+ * Constructor
+ *
+ */
+ public function __construct() {
+ parent::__construct();
+ $this->Permission = ClassRegistry::init(array('class' => 'Permission', 'alias' => 'Permission'));
+ $this->Aro = $this->Permission->Aro;
+ $this->Aco = $this->Permission->Aco;
+ }
+
+/**
+ * Initializes the containing component and sets the Aro/Aco objects to it.
+ *
+ * @param AclComponent $component
+ * @return void
+ */
+ public function initialize(Component $component) {
+ $component->Aro = $this->Aro;
+ $component->Aco = $this->Aco;
+ }
+
+/**
+ * Checks if the given $aro has access to action $action in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success (true if ARO has access to action in ACO, false otherwise)
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#checking-permissions-the-acl-component
+ */
+ public function check($aro, $aco, $action = "*") {
+ return $this->Permission->check($aro, $aco, $action);
+ }
+
+/**
+ * Allow $aro to have access to action $actions in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $actions Action (defaults to *)
+ * @param integer $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit)
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#assigning-permissions
+ */
+ public function allow($aro, $aco, $actions = "*", $value = 1) {
+ return $this->Permission->allow($aro, $aco, $actions, $value);
+ }
+
+/**
+ * Deny access for $aro to action $action in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html#assigning-permissions
+ */
+ public function deny($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action, -1);
+ }
+
+/**
+ * Let access for $aro to action $action in $aco be inherited
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action, 0);
+ }
+
+/**
+ * Allow $aro to have access to action $actions in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @see allow()
+ */
+ public function grant($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action);
+ }
+
+/**
+ * Deny access for $aro to action $action in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @see deny()
+ */
+ public function revoke($aro, $aco, $action = "*") {
+ return $this->deny($aro, $aco, $action);
+ }
+
+/**
+ * Get an array of access-control links between the given Aro and Aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @return array Indexed array with: 'aro', 'aco' and 'link'
+ */
+ public function getAclLink($aro, $aco) {
+ return $this->Permission->getAclLink($aro, $aco);
+ }
+
+/**
+ * Get the keys used in an ACO
+ *
+ * @param array $keys Permission model info
+ * @return array ACO keys
+ */
+ protected function _getAcoKeys($keys) {
+ return $this->Permission->getAcoKeys($keys);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php
new file mode 100644
index 0000000..8810668
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/IniAcl.php
@@ -0,0 +1,172 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('AclInterface', 'Controller/Component/Acl');
+
+/**
+ * IniAcl implements an access control system using an INI file. An example
+ * of the ini file used can be found in /config/acl.ini.php.
+ *
+ * @package Cake.Controller.Component
+ */
+class IniAcl extends Object implements AclInterface {
+
+/**
+ * Array with configuration, parsed from ini file
+ *
+ * @var array
+ */
+ public $config = null;
+
+/**
+ * The Hash::extract() path to the user/aro identifier in the
+ * acl.ini file. This path will be used to extract the string
+ * representation of a user used in the ini file.
+ *
+ * @var string
+ */
+ public $userPath = 'User.username';
+
+/**
+ * Initialize method
+ *
+ * @param AclBase $component
+ * @return void
+ */
+ public function initialize(Component $component) {
+ }
+
+/**
+ * No op method, allow cannot be done with IniAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*") {
+ }
+
+/**
+ * No op method, deny cannot be done with IniAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*") {
+ }
+
+/**
+ * No op method, inherit cannot be done with IniAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ }
+
+/**
+ * Main ACL check function. Checks to see if the ARO (access request object) has access to the
+ * ACO (access control object).Looks at the acl.ini.php file for permissions
+ * (see instructions in /config/acl.ini.php).
+ *
+ * @param string $aro ARO
+ * @param string $aco ACO
+ * @param string $action Action
+ * @return boolean Success
+ */
+ public function check($aro, $aco, $action = null) {
+ if ($this->config == null) {
+ $this->config = $this->readConfigFile(APP . 'Config' . DS . 'acl.ini.php');
+ }
+ $aclConfig = $this->config;
+
+ if (is_array($aro)) {
+ $aro = Hash::get($aro, $this->userPath);
+ }
+
+ if (isset($aclConfig[$aro]['deny'])) {
+ $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny']));
+
+ if (array_search($aco, $userDenies)) {
+ return false;
+ }
+ }
+
+ if (isset($aclConfig[$aro]['allow'])) {
+ $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow']));
+
+ if (array_search($aco, $userAllows)) {
+ return true;
+ }
+ }
+
+ if (isset($aclConfig[$aro]['groups'])) {
+ $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
+
+ foreach ($userGroups as $group) {
+ if (array_key_exists($group, $aclConfig)) {
+ if (isset($aclConfig[$group]['deny'])) {
+ $groupDenies = $this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
+
+ if (array_search($aco, $groupDenies)) {
+ return false;
+ }
+ }
+
+ if (isset($aclConfig[$group]['allow'])) {
+ $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
+
+ if (array_search($aco, $groupAllows)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Parses an INI file and returns an array that reflects the
+ * INI file's section structure. Double-quote friendly.
+ *
+ * @param string $filename File
+ * @return array INI section structure
+ */
+ public function readConfigFile($filename) {
+ App::uses('IniReader', 'Configure');
+ $iniFile = new IniReader(dirname($filename) . DS);
+ return $iniFile->read(basename($filename));
+ }
+
+/**
+ * Removes trailing spaces on all array elements (to prepare for searching)
+ *
+ * @param array $array Array to trim
+ * @return array Trimmed array
+ */
+ public function arrayTrim($array) {
+ foreach ($array as $key => $value) {
+ $array[$key] = trim($value);
+ }
+ array_unshift($array, "");
+ return $array;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php
new file mode 100644
index 0000000..28b3b94
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Acl/PhpAcl.php
@@ -0,0 +1,539 @@
+<?php
+/**
+ * PHP configuration based AclInterface implementation
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component.Acl
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * PhpAcl implements an access control system using a plain PHP configuration file.
+ * An example file can be found in app/Config/acl.php
+ *
+ * @package Cake.Controller.Component.Acl
+ */
+class PhpAcl extends Object implements AclInterface {
+
+ const DENY = false;
+ const ALLOW = true;
+
+/**
+ * Options:
+ * - policy: determines behavior of the check method. Deny policy needs explicit allow rules, allow policy needs explicit deny rules
+ * - config: absolute path to config file that contains the acl rules (@see app/Config/acl.php)
+ *
+ * @var array
+ */
+ public $options = array();
+
+/**
+ * Aro Object
+ *
+ * @var PhpAro
+ */
+ public $Aro = null;
+
+/**
+ * Aco Object
+ *
+ * @var PhpAco
+ */
+ public $Aco = null;
+
+/**
+ * Constructor
+ *
+ * Sets a few default settings up.
+ */
+ public function __construct() {
+ $this->options = array(
+ 'policy' => self::DENY,
+ 'config' => APP . 'Config' . DS . 'acl.php',
+ );
+ }
+
+/**
+ * Initialize method
+ *
+ * @param AclComponent $Component Component instance
+ * @return void
+ */
+ public function initialize(Component $Component) {
+ if (!empty($Component->settings['adapter'])) {
+ $this->options = array_merge($this->options, $Component->settings['adapter']);
+ }
+
+ App::uses('PhpReader', 'Configure');
+ $Reader = new PhpReader(dirname($this->options['config']) . DS);
+ $config = $Reader->read(basename($this->options['config']));
+ $this->build($config);
+ $Component->Aco = $this->Aco;
+ $Component->Aro = $this->Aro;
+ }
+
+/**
+ * build and setup internal ACL representation
+ *
+ * @param array $config configuration array, see docs
+ * @return void
+ * @throws AclException When required keys are missing.
+ */
+ public function build(array $config) {
+ if (empty($config['roles'])) {
+ throw new AclException(__d('cake_dev','"roles" section not found in configuration.'));
+ }
+
+ if (empty($config['rules']['allow']) && empty($config['rules']['deny'])) {
+ throw new AclException(__d('cake_dev','Neither "allow" nor "deny" rules were provided in configuration.'));
+ }
+
+ $rules['allow'] = !empty($config['rules']['allow']) ? $config['rules']['allow'] : array();
+ $rules['deny'] = !empty($config['rules']['deny']) ? $config['rules']['deny'] : array();
+ $roles = !empty($config['roles']) ? $config['roles'] : array();
+ $map = !empty($config['map']) ? $config['map'] : array();
+ $alias = !empty($config['alias']) ? $config['alias'] : array();
+
+ $this->Aro = new PhpAro($roles, $map, $alias);
+ $this->Aco = new PhpAco($rules);
+ }
+
+/**
+ * No op method, allow cannot be done with PhpAcl
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*") {
+ return $this->Aco->access($this->Aro->resolve($aro), $aco, $action, 'allow');
+ }
+
+/**
+ * deny ARO access to ACO
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*") {
+ return $this->Aco->access($this->Aro->resolve($aro), $aco, $action, 'deny');
+ }
+
+/**
+ * No op method
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ return false;
+ }
+
+/**
+ * Main ACL check function. Checks to see if the ARO (access request object) has access to the
+ * ACO (access control object).
+ *
+ * @param string $aro ARO
+ * @param string $aco ACO
+ * @param string $action Action
+ * @return boolean true if access is granted, false otherwise
+ */
+ public function check($aro, $aco, $action = "*") {
+ $allow = $this->options['policy'];
+ $prioritizedAros = $this->Aro->roles($aro);
+
+ if ($action && $action != "*") {
+ $aco .= '/' . $action;
+ }
+
+ $path = $this->Aco->path($aco);
+
+ if (empty($path)) {
+ return $allow;
+ }
+
+ foreach ($path as $depth => $node) {
+ foreach ($prioritizedAros as $aros) {
+ if (!empty($node['allow'])) {
+ $allow = $allow || count(array_intersect($node['allow'], $aros)) > 0;
+ }
+
+ if (!empty($node['deny'])) {
+ $allow = $allow && count(array_intersect($node['deny'], $aros)) == 0;
+ }
+ }
+ }
+
+ return $allow;
+ }
+
+}
+
+/**
+ * Access Control Object
+ *
+ */
+class PhpAco {
+
+/**
+ * holds internal ACO representation
+ *
+ * @var array
+ */
+ protected $_tree = array();
+
+/**
+ * map modifiers for ACO paths to their respective PCRE pattern
+ *
+ * @var array
+ */
+ public static $modifiers = array(
+ '*' => '.*',
+ );
+
+ public function __construct(array $rules = array()) {
+ foreach (array('allow', 'deny') as $type) {
+ if (empty($rules[$type])) {
+ $rules[$type] = array();
+ }
+ }
+
+ $this->build($rules['allow'], $rules['deny']);
+ }
+
+/**
+ * return path to the requested ACO with allow and deny rules attached on each level
+ *
+ * @return array
+ */
+ public function path($aco) {
+ $aco = $this->resolve($aco);
+ $path = array();
+ $level = 0;
+ $root = $this->_tree;
+ $stack = array(array($root, 0));
+
+ while (!empty($stack)) {
+ list($root, $level) = array_pop($stack);
+
+ if (empty($path[$level])) {
+ $path[$level] = array();
+ }
+
+ foreach ($root as $node => $elements) {
+ $pattern = '/^' . str_replace(array_keys(self::$modifiers), array_values(self::$modifiers), $node) . '$/';
+
+ if ($node == $aco[$level] || preg_match($pattern, $aco[$level])) {
+ // merge allow/denies with $path of current level
+ foreach (array('allow', 'deny') as $policy) {
+ if (!empty($elements[$policy])) {
+ if (empty($path[$level][$policy])) {
+ $path[$level][$policy] = array();
+ }
+ $path[$level][$policy] = array_merge($path[$level][$policy], $elements[$policy]);
+ }
+ }
+
+ // traverse
+ if (!empty($elements['children']) && isset($aco[$level + 1])) {
+ array_push($stack, array($elements['children'], $level + 1));
+ }
+ }
+ }
+ }
+
+ return $path;
+ }
+
+/**
+ * allow/deny ARO access to ARO
+ *
+ * @return void
+ */
+ public function access($aro, $aco, $action, $type = 'deny') {
+ $aco = $this->resolve($aco);
+ $depth = count($aco);
+ $root = $this->_tree;
+ $tree = &$root;
+
+ foreach ($aco as $i => $node) {
+ if (!isset($tree[$node])) {
+ $tree[$node] = array(
+ 'children' => array(),
+ );
+ }
+
+ if ($i < $depth - 1) {
+ $tree = &$tree[$node]['children'];
+ } else {
+ if (empty($tree[$node][$type])) {
+ $tree[$node][$type] = array();
+ }
+
+ $tree[$node][$type] = array_merge(is_array($aro) ? $aro : array($aro), $tree[$node][$type]);
+ }
+ }
+
+ $this->_tree = &$root;
+ }
+
+/**
+ * resolve given ACO string to a path
+ *
+ * @param string $aco ACO string
+ * @return array path
+ */
+ public function resolve($aco) {
+ if (is_array($aco)) {
+ return array_map('strtolower', $aco);
+ }
+
+ // strip multiple occurences of '/'
+ $aco = preg_replace('#/+#', '/', $aco);
+ // make case insensitive
+ $aco = ltrim(strtolower($aco), '/');
+ return array_filter(array_map('trim', explode('/', $aco)));
+ }
+
+/**
+ * build a tree representation from the given allow/deny informations for ACO paths
+ *
+ * @param array $allow ACO allow rules
+ * @param array $deny ACO deny rules
+ * @return void
+ */
+ public function build(array $allow, array $deny = array()) {
+ $stack = array();
+ $this->_tree = array();
+ $tree = array();
+ $root = &$tree;
+
+ foreach ($allow as $dotPath => $aros) {
+ if (is_string($aros)) {
+ $aros = array_map('trim', explode(',', $aros));
+ }
+
+ $this->access($aros, $dotPath, null, 'allow');
+ }
+
+ foreach ($deny as $dotPath => $aros) {
+ if (is_string($aros)) {
+ $aros = array_map('trim', explode(',', $aros));
+ }
+
+ $this->access($aros, $dotPath, null, 'deny');
+ }
+ }
+
+}
+
+/**
+ * Access Request Object
+ *
+ */
+class PhpAro {
+
+/**
+ * role to resolve to when a provided ARO is not listed in
+ * the internal tree
+ *
+ * @var string
+ */
+ const DEFAULT_ROLE = 'Role/default';
+
+/**
+ * map external identifiers. E.g. if
+ *
+ * array('User' => array('username' => 'jeff', 'role' => 'editor'))
+ *
+ * is passed as an ARO to one of the methods of AclComponent, PhpAcl
+ * will check if it can be resolved to an User or a Role defined in the
+ * configuration file.
+ *
+ * @var array
+ * @see app/Config/acl.php
+ */
+ public $map = array(
+ 'User' => 'User/username',
+ 'Role' => 'User/role',
+ );
+
+/**
+ * aliases to map
+ *
+ * @var array
+ */
+ public $aliases = array();
+
+/**
+ * internal ARO representation
+ *
+ * @var array
+ */
+ protected $_tree = array();
+
+ public function __construct(array $aro = array(), array $map = array(), array $aliases = array()) {
+ if (!empty($map)) {
+ $this->map = $map;
+ }
+
+ $this->aliases = $aliases;
+ $this->build($aro);
+ }
+
+/**
+ * From the perspective of the given ARO, walk down the tree and
+ * collect all inherited AROs levelwise such that AROs from different
+ * branches with equal distance to the requested ARO will be collected at the same
+ * index. The resulting array will contain a prioritized list of (list of) roles ordered from
+ * the most distant AROs to the requested one itself.
+ *
+ * @param string|array $aro An ARO identifier
+ * @return array prioritized AROs
+ */
+ public function roles($aro) {
+ $aros = array();
+ $aro = $this->resolve($aro);
+ $stack = array(array($aro, 0));
+
+ while (!empty($stack)) {
+ list($element, $depth) = array_pop($stack);
+ $aros[$depth][] = $element;
+
+ foreach ($this->_tree as $node => $children) {
+ if (in_array($element, $children)) {
+ array_push($stack, array($node, $depth + 1));
+ }
+ }
+ }
+
+ return array_reverse($aros);
+ }
+
+/**
+ * resolve an ARO identifier to an internal ARO string using
+ * the internal mapping information.
+ *
+ * @param string|array $aro ARO identifier (User.jeff, array('User' => ...), etc)
+ * @return string internal aro string (e.g. User/jeff, Role/default)
+ */
+ public function resolve($aro) {
+ foreach ($this->map as $aroGroup => $map) {
+ list ($model, $field) = explode('/', $map, 2);
+ $mapped = '';
+
+ if (is_array($aro)) {
+ if (isset($aro['model']) && isset($aro['foreign_key']) && $aro['model'] == $aroGroup) {
+ $mapped = $aroGroup . '/' . $aro['foreign_key'];
+ } elseif (isset($aro[$model][$field])) {
+ $mapped = $aroGroup . '/' . $aro[$model][$field];
+ } elseif (isset($aro[$field])) {
+ $mapped = $aroGroup . '/' . $aro[$field];
+ }
+ } elseif (is_string($aro)) {
+ $aro = ltrim($aro, '/');
+
+ if (strpos($aro, '/') === false) {
+ $mapped = $aroGroup . '/' . $aro;
+ } else {
+ list($aroModel, $aroValue) = explode('/', $aro, 2);
+
+ $aroModel = Inflector::camelize($aroModel);
+
+ if ($aroModel == $model || $aroModel == $aroGroup) {
+ $mapped = $aroGroup . '/' . $aroValue;
+ }
+ }
+ }
+
+ if (isset($this->_tree[$mapped])) {
+ return $mapped;
+ }
+
+ // is there a matching alias defined (e.g. Role/1 => Role/admin)?
+ if (!empty($this->aliases[$mapped])) {
+ return $this->aliases[$mapped];
+ }
+ }
+ return self::DEFAULT_ROLE;
+ }
+
+/**
+ * adds a new ARO to the tree
+ *
+ * @param array $aro one or more ARO records
+ * @return void
+ */
+ public function addRole(array $aro) {
+ foreach ($aro as $role => $inheritedRoles) {
+ if (!isset($this->_tree[$role])) {
+ $this->_tree[$role] = array();
+ }
+
+ if (!empty($inheritedRoles)) {
+ if (is_string($inheritedRoles)) {
+ $inheritedRoles = array_map('trim', explode(',', $inheritedRoles));
+ }
+
+ foreach ($inheritedRoles as $dependency) {
+ // detect cycles
+ $roles = $this->roles($dependency);
+
+ if (in_array($role, Hash::flatten($roles))) {
+ $path = '';
+
+ foreach ($roles as $roleDependencies) {
+ $path .= implode('|', (array)$roleDependencies) . ' -> ';
+ }
+
+ trigger_error(__d('cake_dev', 'cycle detected when inheriting %s from %s. Path: %s', $role, $dependency, $path . $role));
+ continue;
+ }
+
+ if (!isset($this->_tree[$dependency])) {
+ $this->_tree[$dependency] = array();
+ }
+
+ $this->_tree[$dependency][] = $role;
+ }
+ }
+ }
+ }
+
+/**
+ * adds one or more aliases to the internal map. Overwrites existing entries.
+ *
+ * @param array $alias alias from => to (e.g. Role/13 -> Role/editor)
+ * @return void
+ */
+ public function addAlias(array $alias) {
+ $this->aliases = array_merge($this->aliases, $alias);
+ }
+
+/**
+ * build an ARO tree structure for internal processing
+ *
+ * @param array $aros array of AROs as key and their inherited AROs as values
+ * @return void
+ */
+ public function build(array $aros) {
+ $this->_tree = array();
+ $this->addRole($aros);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php
new file mode 100644
index 0000000..66ee9a3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AclComponent.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Component', 'Controller');
+App::uses('AclInterface', 'Controller/Component/Acl');
+
+/**
+ * Access Control List factory class.
+ *
+ * Uses a strategy pattern to allow custom ACL implementations to be used with the same component interface.
+ * You can define by changing `Configure::write('Acl.classname', 'DbAcl');` in your core.php. Concrete ACL
+ * implementations should extend `AclBase` and implement the methods it defines.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html
+ */
+class AclComponent extends Component {
+
+/**
+ * Instance of an ACL class
+ *
+ * @var AclInterface
+ */
+ protected $_Instance = null;
+
+/**
+ * Aro object.
+ *
+ * @var string
+ */
+ public $Aro;
+
+/**
+ * Aco object
+ *
+ * @var string
+ */
+ public $Aco;
+
+/**
+ * Constructor. Will return an instance of the correct ACL class as defined in `Configure::read('Acl.classname')`
+ *
+ * @param ComponentCollection $collection
+ * @param array $settings
+ * @throws CakeException when Acl.classname could not be loaded.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ parent::__construct($collection, $settings);
+ $name = Configure::read('Acl.classname');
+ if (!class_exists($name)) {
+ list($plugin, $name) = pluginSplit($name, true);
+ App::uses($name, $plugin . 'Controller/Component/Acl');
+ if (!class_exists($name)) {
+ throw new CakeException(__d('cake_dev', 'Could not find %s.', $name));
+ }
+ }
+ $this->adapter($name);
+ }
+
+/**
+ * Sets or gets the Adapter object currently in the AclComponent.
+ *
+ * `$this->Acl->adapter();` will get the current adapter class while
+ * `$this->Acl->adapter($obj);` will set the adapter class
+ *
+ * Will call the initialize method on the adapter if setting a new one.
+ *
+ * @param AclInterface|string $adapter Instance of AclInterface or a string name of the class to use. (optional)
+ * @return AclInterface|void either null, or the adapter implementation.
+ * @throws CakeException when the given class is not an instance of AclInterface
+ */
+ public function adapter($adapter = null) {
+ if ($adapter) {
+ if (is_string($adapter)) {
+ $adapter = new $adapter();
+ }
+ if (!$adapter instanceof AclInterface) {
+ throw new CakeException(__d('cake_dev', 'AclComponent adapters must implement AclInterface'));
+ }
+ $this->_Instance = $adapter;
+ $this->_Instance->initialize($this);
+ return;
+ }
+ return $this->_Instance;
+ }
+
+/**
+ * Pass-thru function for ACL check instance. Check methods
+ * are used to check whether or not an ARO can access an ACO
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function check($aro, $aco, $action = "*") {
+ return $this->_Instance->check($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL allow instance. Allow methods
+ * are used to grant an ARO access to an ACO.
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $action = "*") {
+ return $this->_Instance->allow($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL deny instance. Deny methods
+ * are used to remove permission from an ARO to access an ACO.
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function deny($aro, $aco, $action = "*") {
+ return $this->_Instance->deny($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL inherit instance. Inherit methods
+ * modify the permission for an ARO to be that of its parent object.
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ */
+ public function inherit($aro, $aco, $action = "*") {
+ return $this->_Instance->inherit($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL grant instance. An alias for AclComponent::allow()
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @deprecated
+ */
+ public function grant($aro, $aco, $action = "*") {
+ trigger_error(__d('cake_dev', 'AclComponent::grant() is deprecated, use allow() instead'), E_USER_WARNING);
+ return $this->_Instance->allow($aro, $aco, $action);
+ }
+
+/**
+ * Pass-thru function for ACL grant instance. An alias for AclComponent::deny()
+ *
+ * @param array|string|Model $aro ARO The requesting object identifier. See `AclNode::node()` for possible formats
+ * @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
+ * @param string $action Action (defaults to *)
+ * @return boolean Success
+ * @deprecated
+ */
+ public function revoke($aro, $aco, $action = "*") {
+ trigger_error(__d('cake_dev', 'AclComponent::revoke() is deprecated, use deny() instead'), E_USER_WARNING);
+ return $this->_Instance->deny($aro, $aco, $action);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php
new file mode 100644
index 0000000..3f279b0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ActionsAuthorize.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+
+/**
+ * An authorization adapter for AuthComponent. Provides the ability to authorize using the AclComponent,
+ * If AclComponent is not already loaded it will be loaded using the Controller's ComponentCollection.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ * @see AclComponent::check()
+ */
+class ActionsAuthorize extends BaseAuthorize {
+
+/**
+ * Authorize a user using the AclComponent.
+ *
+ * @param array $user The user to authorize
+ * @param CakeRequest $request The request needing authorization.
+ * @return boolean
+ */
+ public function authorize($user, CakeRequest $request) {
+ $Acl = $this->_Collection->load('Acl');
+ $user = array($this->settings['userModel'] => $user);
+ return $Acl->check($user, $this->action($request));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php
new file mode 100644
index 0000000..d9dc724
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Security', 'Utility');
+App::uses('Hash', 'Utility');
+
+/**
+ * Base Authentication class with common methods and properties.
+ *
+ * @package Cake.Controller.Component.Auth
+ */
+abstract class BaseAuthenticate {
+
+/**
+ * Settings for this object.
+ *
+ * - `fields` The fields to use to identify a user by.
+ * - `userModel` The model name of the User, defaults to User.
+ * - `scope` Additional conditions to use when looking up and authenticating users,
+ * i.e. `array('User.is_active' => 1).`
+ * - `recursive` The value of the recursive key passed to find(). Defaults to 0.
+ * - `contain` Extra models to contain and store in session.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'fields' => array(
+ 'username' => 'username',
+ 'password' => 'password'
+ ),
+ 'userModel' => 'User',
+ 'scope' => array(),
+ 'recursive' => 0,
+ 'contain' => null,
+ );
+
+/**
+ * A Component collection, used to get more components.
+ *
+ * @var ComponentCollection
+ */
+ protected $_Collection;
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection The Component collection used on this request.
+ * @param array $settings Array of settings to use.
+ */
+ public function __construct(ComponentCollection $collection, $settings) {
+ $this->_Collection = $collection;
+ $this->settings = Hash::merge($this->settings, $settings);
+ }
+
+/**
+ * Find a user record using the standard options.
+ *
+ * @param string $username The username/identifier.
+ * @param string $password The unhashed password.
+ * @return Mixed Either false on failure, or an array of user data.
+ */
+ protected function _findUser($username, $password) {
+ $userModel = $this->settings['userModel'];
+ list($plugin, $model) = pluginSplit($userModel);
+ $fields = $this->settings['fields'];
+
+ $conditions = array(
+ $model . '.' . $fields['username'] => $username,
+ $model . '.' . $fields['password'] => $this->_password($password),
+ );
+ if (!empty($this->settings['scope'])) {
+ $conditions = array_merge($conditions, $this->settings['scope']);
+ }
+ $result = ClassRegistry::init($userModel)->find('first', array(
+ 'conditions' => $conditions,
+ 'recursive' => (int)$this->settings['recursive'],
+ 'contain' => $this->settings['contain'],
+ ));
+ if (empty($result) || empty($result[$model])) {
+ return false;
+ }
+ $user = $result[$model];
+ unset($user[$fields['password']]);
+ unset($result[$model]);
+ return array_merge($user, $result);
+ }
+
+/**
+ * Hash the plain text password so that it matches the hashed/encrypted password
+ * in the datasource.
+ *
+ * @param string $password The plain text password.
+ * @return string The hashed form of the password.
+ */
+ protected function _password($password) {
+ return Security::hash($password, null, true);
+ }
+
+/**
+ * Authenticate a user based on the request information.
+ *
+ * @param CakeRequest $request Request to get authentication information from.
+ * @param CakeResponse $response A response object that can have headers added.
+ * @return mixed Either false on failure, or an array of user data on success.
+ */
+ abstract public function authenticate(CakeRequest $request, CakeResponse $response);
+
+/**
+ * Allows you to hook into AuthComponent::logout(),
+ * and implement specialized logout behavior.
+ *
+ * All attached authentication objects will have this method
+ * called when a user logs out.
+ *
+ * @param array $user The user about to be logged out.
+ * @return void
+ */
+ public function logout($user) {
+ }
+
+/**
+ * Get a user based on information in the request. Primarily used by stateless authentication
+ * systems like basic and digest auth.
+ *
+ * @param CakeRequest $request Request object.
+ * @return mixed Either false or an array of user information
+ */
+ public function getUser($request) {
+ return false;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php
new file mode 100644
index 0000000..9bf2d1b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BaseAuthorize.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Hash', 'Utility');
+
+/**
+ * Abstract base authorization adapter for AuthComponent.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ */
+abstract class BaseAuthorize {
+
+/**
+ * Controller for the request.
+ *
+ * @var Controller
+ */
+ protected $_Controller = null;
+
+/**
+ * Component collection instance for getting more components.
+ *
+ * @var ComponentCollection
+ */
+ protected $_Collection;
+
+/**
+ * Settings for authorize objects.
+ *
+ * - `actionPath` - The path to ACO nodes that contains the nodes for controllers. Used as a prefix
+ * when calling $this->action();
+ * - `actionMap` - Action -> crud mappings. Used by authorization objects that want to map actions to CRUD roles.
+ * - `userModel` - Model name that ARO records can be found under. Defaults to 'User'.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'actionPath' => null,
+ 'actionMap' => array(
+ 'index' => 'read',
+ 'add' => 'create',
+ 'edit' => 'update',
+ 'view' => 'read',
+ 'delete' => 'delete',
+ 'remove' => 'delete'
+ ),
+ 'userModel' => 'User'
+ );
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection The controller for this request.
+ * @param string $settings An array of settings. This class does not use any settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->_Collection = $collection;
+ $controller = $collection->getController();
+ $this->controller($controller);
+ $this->settings = Hash::merge($this->settings, $settings);
+ }
+
+/**
+ * Checks user authorization.
+ *
+ * @param array $user Active user data
+ * @param CakeRequest $request
+ * @return boolean
+ */
+ abstract public function authorize($user, CakeRequest $request);
+
+/**
+ * Accessor to the controller object.
+ *
+ * @param Controller $controller null to get, a controller to set.
+ * @return mixed
+ * @throws CakeException
+ */
+ public function controller(Controller $controller = null) {
+ if ($controller) {
+ if (!$controller instanceof Controller) {
+ throw new CakeException(__d('cake_dev', '$controller needs to be an instance of Controller'));
+ }
+ $this->_Controller = $controller;
+ return true;
+ }
+ return $this->_Controller;
+ }
+
+/**
+ * Get the action path for a given request. Primarily used by authorize objects
+ * that need to get information about the plugin, controller, and action being invoked.
+ *
+ * @param CakeRequest $request The request a path is needed for.
+ * @param string $path
+ * @return string the action path for the given request.
+ */
+ public function action($request, $path = '/:plugin/:controller/:action') {
+ $plugin = empty($request['plugin']) ? null : Inflector::camelize($request['plugin']) . '/';
+ $path = str_replace(
+ array(':controller', ':action', ':plugin/'),
+ array(Inflector::camelize($request['controller']), $request['action'], $plugin),
+ $this->settings['actionPath'] . $path
+ );
+ $path = str_replace('//', '/', $path);
+ return trim($path, '/');
+ }
+
+/**
+ * Maps crud actions to actual action names. Used to modify or get the current mapped actions.
+ *
+ * Create additional mappings for a standard CRUD operation:
+ *
+ * {{{
+ * $this->Auth->mapActions(array('create' => array('add', 'register'));
+ * }}}
+ *
+ * Create mappings for custom CRUD operations:
+ *
+ * {{{
+ * $this->Auth->mapActions(array('my_action' => 'admin'));
+ * }}}
+ *
+ * You can use the custom CRUD operations to create additional generic permissions
+ * that behave like CRUD operations. Doing this will require additional columns on the
+ * permissions lookup. When using with DbAcl, you'll have to add additional _admin type columns
+ * to the `aros_acos` table.
+ *
+ * @param array $map Either an array of mappings, or undefined to get current values.
+ * @return mixed Either the current mappings or null when setting.
+ * @see AuthComponent::mapActions()
+ */
+ public function mapActions($map = array()) {
+ if (empty($map)) {
+ return $this->settings['actionMap'];
+ }
+ $crud = array('create', 'read', 'update', 'delete');
+ foreach ($map as $action => $type) {
+ if (in_array($action, $crud) && is_array($type)) {
+ foreach ($type as $typedAction) {
+ $this->settings['actionMap'][$typedAction] = $action;
+ }
+ } else {
+ $this->settings['actionMap'][$action] = $type;
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php
new file mode 100644
index 0000000..df65e9c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/BasicAuthenticate.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * Basic Authentication adapter for AuthComponent.
+ *
+ * Provides Basic HTTP authentication support for AuthComponent. Basic Auth will authenticate users
+ * against the configured userModel and verify the username and passwords match. Clients using Basic Authentication
+ * must support cookies. Since AuthComponent identifies users based on Session contents, clients using Basic
+ * Auth must support cookies.
+ *
+ * ### Using Basic auth
+ *
+ * In your controller's components array, add auth + the required settings.
+ * {{{
+ * public $components = array(
+ * 'Auth' => array(
+ * 'authenticate' => array('Basic')
+ * )
+ * );
+ * }}}
+ *
+ * In your login function just call `$this->Auth->login()` without any checks for POST data. This
+ * will send the authentication headers, and trigger the login dialog in the browser/client.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ */
+class BasicAuthenticate extends BaseAuthenticate {
+
+/**
+ * Settings for this object.
+ *
+ * - `fields` The fields to use to identify a user by.
+ * - `userModel` The model name of the User, defaults to User.
+ * - `scope` Additional conditions to use when looking up and authenticating users,
+ * i.e. `array('User.is_active' => 1).`
+ * - `recursive` The value of the recursive key passed to find(). Defaults to 0.
+ * - `contain` Extra models to contain and store in session.
+ * - `realm` The realm authentication is for. Defaults the server name.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'fields' => array(
+ 'username' => 'username',
+ 'password' => 'password'
+ ),
+ 'userModel' => 'User',
+ 'scope' => array(),
+ 'recursive' => 0,
+ 'contain' => null,
+ 'realm' => '',
+ );
+
+/**
+ * Constructor, completes configuration for basic authentication.
+ *
+ * @param ComponentCollection $collection The Component collection used on this request.
+ * @param array $settings An array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings) {
+ parent::__construct($collection, $settings);
+ if (empty($this->settings['realm'])) {
+ $this->settings['realm'] = env('SERVER_NAME');
+ }
+ }
+
+/**
+ * Authenticate a user using basic HTTP auth. Will use the configured User model and attempt a
+ * login using basic HTTP auth.
+ *
+ * @param CakeRequest $request The request to authenticate with.
+ * @param CakeResponse $response The response to add headers to.
+ * @return mixed Either false on failure, or an array of user data on success.
+ */
+ public function authenticate(CakeRequest $request, CakeResponse $response) {
+ $result = $this->getUser($request);
+
+ if (empty($result)) {
+ $response->header($this->loginHeaders());
+ $response->statusCode(401);
+ $response->send();
+ return false;
+ }
+ return $result;
+ }
+
+/**
+ * Get a user based on information in the request. Used by cookie-less auth for stateless clients.
+ *
+ * @param CakeRequest $request Request object.
+ * @return mixed Either false or an array of user information
+ */
+ public function getUser($request) {
+ $username = env('PHP_AUTH_USER');
+ $pass = env('PHP_AUTH_PW');
+
+ if (empty($username) || empty($pass)) {
+ return false;
+ }
+ return $this->_findUser($username, $pass);
+ }
+
+/**
+ * Generate the login headers
+ *
+ * @return string Headers for logging in.
+ */
+ public function loginHeaders() {
+ return sprintf('WWW-Authenticate: Basic realm="%s"', $this->settings['realm']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php
new file mode 100644
index 0000000..7fa486d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/ControllerAuthorize.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+
+/**
+ * An authorization adapter for AuthComponent. Provides the ability to authorize using a controller callback.
+ * Your controller's isAuthorized() method should return a boolean to indicate whether or not the user is authorized.
+ *
+ * {{{
+ * public function isAuthorized($user) {
+ * if (!empty($this->request->params['admin'])) {
+ * return $user['role'] == 'admin';
+ * }
+ * return !empty($user);
+ * }
+ * }}}
+ *
+ * the above is simple implementation that would only authorize users of the 'admin' role to access
+ * admin routing.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ */
+class ControllerAuthorize extends BaseAuthorize {
+
+/**
+ * Get/set the controller this authorize object will be working with. Also checks that isAuthorized is implemented.
+ *
+ * @param Controller $controller null to get, a controller to set.
+ * @return mixed
+ * @throws CakeException
+ */
+ public function controller(Controller $controller = null) {
+ if ($controller) {
+ if (!method_exists($controller, 'isAuthorized')) {
+ throw new CakeException(__d('cake_dev', '$controller does not implement an isAuthorized() method.'));
+ }
+ }
+ return parent::controller($controller);
+ }
+
+/**
+ * Checks user authorization using a controller callback.
+ *
+ * @param array $user Active user data
+ * @param CakeRequest $request
+ * @return boolean
+ */
+ public function authorize($user, CakeRequest $request) {
+ return (bool)$this->_Controller->isAuthorized($user);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php
new file mode 100644
index 0000000..83761b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/CrudAuthorize.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+App::uses('Router', 'Routing');
+
+/**
+ * An authorization adapter for AuthComponent. Provides the ability to authorize using CRUD mappings.
+ * CRUD mappings allow you to translate controller actions into *C*reate *R*ead *U*pdate *D*elete actions.
+ * This is then checked in the AclComponent as specific permissions.
+ *
+ * For example, taking `/posts/index` as the current request. The default mapping for `index`, is a `read` permission
+ * check. The Acl check would then be for the `posts` controller with the `read` permission. This allows you
+ * to create permission systems that focus more on what is being done to resources, rather than the specific actions
+ * being visited.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ * @see AclComponent::check()
+ */
+class CrudAuthorize extends BaseAuthorize {
+
+/**
+ * Sets up additional actionMap values that match the configured `Routing.prefixes`.
+ *
+ * @param ComponentCollection $collection The component collection from the controller.
+ * @param string $settings An array of settings. This class does not use any settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ parent::__construct($collection, $settings);
+ $this->_setPrefixMappings();
+ }
+
+/**
+ * sets the crud mappings for prefix routes.
+ *
+ * @return void
+ */
+ protected function _setPrefixMappings() {
+ $crud = array('create', 'read', 'update', 'delete');
+ $map = array_combine($crud, $crud);
+
+ $prefixes = Router::prefixes();
+ if (!empty($prefixes)) {
+ foreach ($prefixes as $prefix) {
+ $map = array_merge($map, array(
+ $prefix . '_index' => 'read',
+ $prefix . '_add' => 'create',
+ $prefix . '_edit' => 'update',
+ $prefix . '_view' => 'read',
+ $prefix . '_remove' => 'delete',
+ $prefix . '_create' => 'create',
+ $prefix . '_read' => 'read',
+ $prefix . '_update' => 'update',
+ $prefix . '_delete' => 'delete'
+ ));
+ }
+ }
+ $this->mapActions($map);
+ }
+
+/**
+ * Authorize a user using the mapped actions and the AclComponent.
+ *
+ * @param array $user The user to authorize
+ * @param CakeRequest $request The request needing authorization.
+ * @return boolean
+ */
+ public function authorize($user, CakeRequest $request) {
+ if (!isset($this->settings['actionMap'][$request->params['action']])) {
+ trigger_error(__d('cake_dev',
+ 'CrudAuthorize::authorize() - Attempted access of un-mapped action "%1$s" in controller "%2$s"',
+ $request->action,
+ $request->controller
+ ),
+ E_USER_WARNING
+ );
+ return false;
+ }
+ $user = array($this->settings['userModel'] => $user);
+ $Acl = $this->_Collection->load('Acl');
+ return $Acl->check(
+ $user,
+ $this->action($request, ':controller'),
+ $this->settings['actionMap'][$request->params['action']]
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php
new file mode 100644
index 0000000..bdea7d8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * Digest Authentication adapter for AuthComponent.
+ *
+ * Provides Digest HTTP authentication support for AuthComponent. Unlike most AuthComponent adapters,
+ * DigestAuthenticate requires a special password hash that conforms to RFC2617. You can create this
+ * password using `DigestAuthenticate::password()`. If you wish to use digest authentication alongside other
+ * authentication methods, its recommended that you store the digest authentication separately.
+ *
+ * Clients using Digest Authentication must support cookies. Since AuthComponent identifies users based
+ * on Session contents, clients without support for cookies will not function properly.
+ *
+ * ### Using Digest auth
+ *
+ * In your controller's components array, add auth + the required settings.
+ * {{{
+ * public $components = array(
+ * 'Auth' => array(
+ * 'authenticate' => array('Digest')
+ * )
+ * );
+ * }}}
+ *
+ * In your login function just call `$this->Auth->login()` without any checks for POST data. This
+ * will send the authentication headers, and trigger the login dialog in the browser/client.
+ *
+ * ### Generating passwords compatible with Digest authentication.
+ *
+ * Due to the Digest authentication specification, digest auth requires a special password value. You
+ * can generate this password using `DigestAuthenticate::password()`
+ *
+ * `$digestPass = DigestAuthenticate::password($username, env('SERVER_NAME'), $password);`
+ *
+ * Its recommended that you store this digest auth only password separate from password hashes used for other
+ * login methods. For example `User.digest_pass` could be used for a digest password, while `User.password` would
+ * store the password hash for use with other methods like Basic or Form.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ */
+class DigestAuthenticate extends BaseAuthenticate {
+
+/**
+ * Settings for this object.
+ *
+ * - `fields` The fields to use to identify a user by.
+ * - `userModel` The model name of the User, defaults to User.
+ * - `scope` Additional conditions to use when looking up and authenticating users,
+ * i.e. `array('User.is_active' => 1).`
+ * - `recursive` The value of the recursive key passed to find(). Defaults to 0.
+ * - `contain` Extra models to contain and store in session.
+ * - `realm` The realm authentication is for, Defaults to the servername.
+ * - `nonce` A nonce used for authentication. Defaults to `uniqid()`.
+ * - `qop` Defaults to auth, no other values are supported at this time.
+ * - `opaque` A string that must be returned unchanged by clients.
+ * Defaults to `md5($settings['realm'])`
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'fields' => array(
+ 'username' => 'username',
+ 'password' => 'password'
+ ),
+ 'userModel' => 'User',
+ 'scope' => array(),
+ 'recursive' => 0,
+ 'contain' => null,
+ 'realm' => '',
+ 'qop' => 'auth',
+ 'nonce' => '',
+ 'opaque' => ''
+ );
+
+/**
+ * Constructor, completes configuration for digest authentication.
+ *
+ * @param ComponentCollection $collection The Component collection used on this request.
+ * @param array $settings An array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings) {
+ parent::__construct($collection, $settings);
+ if (empty($this->settings['realm'])) {
+ $this->settings['realm'] = env('SERVER_NAME');
+ }
+ if (empty($this->settings['nonce'])) {
+ $this->settings['nonce'] = uniqid('');
+ }
+ if (empty($this->settings['opaque'])) {
+ $this->settings['opaque'] = md5($this->settings['realm']);
+ }
+ }
+
+/**
+ * Authenticate a user using Digest HTTP auth. Will use the configured User model and attempt a
+ * login using Digest HTTP auth.
+ *
+ * @param CakeRequest $request The request to authenticate with.
+ * @param CakeResponse $response The response to add headers to.
+ * @return mixed Either false on failure, or an array of user data on success.
+ */
+ public function authenticate(CakeRequest $request, CakeResponse $response) {
+ $user = $this->getUser($request);
+
+ if (empty($user)) {
+ $response->header($this->loginHeaders());
+ $response->statusCode(401);
+ $response->send();
+ return false;
+ }
+ return $user;
+ }
+
+/**
+ * Get a user based on information in the request. Used by cookie-less auth for stateless clients.
+ *
+ * @param CakeRequest $request Request object.
+ * @return mixed Either false or an array of user information
+ */
+ public function getUser($request) {
+ $digest = $this->_getDigest();
+ if (empty($digest)) {
+ return false;
+ }
+ $user = $this->_findUser($digest['username'], null);
+ if (empty($user)) {
+ return false;
+ }
+ $password = $user[$this->settings['fields']['password']];
+ unset($user[$this->settings['fields']['password']]);
+ if ($digest['response'] === $this->generateResponseHash($digest, $password)) {
+ return $user;
+ }
+ return false;
+ }
+
+/**
+ * Find a user record using the standard options.
+ *
+ * @param string $username The username/identifier.
+ * @param string $password Unused password, digest doesn't require passwords.
+ * @return Mixed Either false on failure, or an array of user data.
+ */
+ protected function _findUser($username, $password) {
+ $userModel = $this->settings['userModel'];
+ list($plugin, $model) = pluginSplit($userModel);
+ $fields = $this->settings['fields'];
+
+ $conditions = array(
+ $model . '.' . $fields['username'] => $username,
+ );
+ if (!empty($this->settings['scope'])) {
+ $conditions = array_merge($conditions, $this->settings['scope']);
+ }
+ $result = ClassRegistry::init($userModel)->find('first', array(
+ 'conditions' => $conditions,
+ 'recursive' => (int)$this->settings['recursive']
+ ));
+ if (empty($result) || empty($result[$model])) {
+ return false;
+ }
+ return $result[$model];
+ }
+
+/**
+ * Gets the digest headers from the request/environment.
+ *
+ * @return array Array of digest information.
+ */
+ protected function _getDigest() {
+ $digest = env('PHP_AUTH_DIGEST');
+ if (empty($digest) && function_exists('apache_request_headers')) {
+ $headers = apache_request_headers();
+ if (!empty($headers['Authorization']) && substr($headers['Authorization'], 0, 7) == 'Digest ') {
+ $digest = substr($headers['Authorization'], 7);
+ }
+ }
+ if (empty($digest)) {
+ return false;
+ }
+ return $this->parseAuthData($digest);
+ }
+
+/**
+ * Parse the digest authentication headers and split them up.
+ *
+ * @param string $digest The raw digest authentication headers.
+ * @return array An array of digest authentication headers
+ */
+ public function parseAuthData($digest) {
+ if (substr($digest, 0, 7) == 'Digest ') {
+ $digest = substr($digest, 7);
+ }
+ $keys = $match = array();
+ $req = array('nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1);
+ preg_match_all('/(\w+)=([\'"]?)([a-zA-Z0-9@=.\/_-]+)\2/', $digest, $match, PREG_SET_ORDER);
+
+ foreach ($match as $i) {
+ $keys[$i[1]] = $i[3];
+ unset($req[$i[1]]);
+ }
+
+ if (empty($req)) {
+ return $keys;
+ }
+ return null;
+ }
+
+/**
+ * Generate the response hash for a given digest array.
+ *
+ * @param array $digest Digest information containing data from DigestAuthenticate::parseAuthData().
+ * @param string $password The digest hash password generated with DigestAuthenticate::password()
+ * @return string Response hash
+ */
+ public function generateResponseHash($digest, $password) {
+ return md5(
+ $password .
+ ':' . $digest['nonce'] . ':' . $digest['nc'] . ':' . $digest['cnonce'] . ':' . $digest['qop'] . ':' .
+ md5(env('REQUEST_METHOD') . ':' . $digest['uri'])
+ );
+ }
+
+/**
+ * Creates an auth digest password hash to store
+ *
+ * @param string $username The username to use in the digest hash.
+ * @param string $password The unhashed password to make a digest hash for.
+ * @param string $realm The realm the password is for.
+ * @return string the hashed password that can later be used with Digest authentication.
+ */
+ public static function password($username, $password, $realm) {
+ return md5($username . ':' . $realm . ':' . $password);
+ }
+
+/**
+ * Generate the login headers
+ *
+ * @return string Headers for logging in.
+ */
+ public function loginHeaders() {
+ $options = array(
+ 'realm' => $this->settings['realm'],
+ 'qop' => $this->settings['qop'],
+ 'nonce' => $this->settings['nonce'],
+ 'opaque' => $this->settings['opaque']
+ );
+ $opts = array();
+ foreach ($options as $k => $v) {
+ $opts[] = sprintf('%s="%s"', $k, $v);
+ }
+ return 'WWW-Authenticate: Digest ' . implode(',', $opts);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php
new file mode 100644
index 0000000..0a51f52
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/Auth/FormAuthenticate.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * An authentication adapter for AuthComponent. Provides the ability to authenticate using POST
+ * data. Can be used by configuring AuthComponent to use it via the AuthComponent::$authenticate setting.
+ *
+ * {{{
+ * $this->Auth->authenticate = array(
+ * 'Form' => array(
+ * 'scope' => array('User.active' => 1)
+ * )
+ * )
+ * }}}
+ *
+ * When configuring FormAuthenticate you can pass in settings to which fields, model and additional conditions
+ * are used. See FormAuthenticate::$settings for more information.
+ *
+ * @package Cake.Controller.Component.Auth
+ * @since 2.0
+ * @see AuthComponent::$authenticate
+ */
+class FormAuthenticate extends BaseAuthenticate {
+
+/**
+ * Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields`
+ * to find POST data that is used to find a matching record in the `settings.userModel`. Will return false if
+ * there is no post data, either username or password is missing, of if the scope conditions have not been met.
+ *
+ * @param CakeRequest $request The request that contains login information.
+ * @param CakeResponse $response Unused response object.
+ * @return mixed. False on login failure. An array of User data on success.
+ */
+ public function authenticate(CakeRequest $request, CakeResponse $response) {
+ $userModel = $this->settings['userModel'];
+ list($plugin, $model) = pluginSplit($userModel);
+
+ $fields = $this->settings['fields'];
+ if (empty($request->data[$model])) {
+ return false;
+ }
+ if (
+ empty($request->data[$model][$fields['username']]) ||
+ empty($request->data[$model][$fields['password']])
+ ) {
+ return false;
+ }
+ return $this->_findUser(
+ $request->data[$model][$fields['username']],
+ $request->data[$model][$fields['password']]
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php
new file mode 100644
index 0000000..311b95a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/AuthComponent.php
@@ -0,0 +1,722 @@
+<?php
+/**
+ * Authentication component
+ *
+ * Manages user logins and permissions.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('Router', 'Routing');
+App::uses('Security', 'Utility');
+App::uses('Debugger', 'Utility');
+App::uses('Hash', 'Utility');
+App::uses('CakeSession', 'Model/Datasource');
+App::uses('BaseAuthorize', 'Controller/Component/Auth');
+App::uses('BaseAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * Authentication control component class
+ *
+ * Binds access control with user authentication and session management.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
+ */
+class AuthComponent extends Component {
+
+ const ALL = 'all';
+
+/**
+ * Other components utilized by AuthComponent
+ *
+ * @var array
+ */
+ public $components = array('Session', 'RequestHandler');
+
+/**
+ * An array of authentication objects to use for authenticating users. You can configure
+ * multiple adapters and they will be checked sequentially when users are identified.
+ *
+ * {{{
+ * $this->Auth->authenticate = array(
+ * 'Form' => array(
+ * 'userModel' => 'Users.User'
+ * )
+ * );
+ * }}}
+ *
+ * Using the class name without 'Authenticate' as the key, you can pass in an array of settings for each
+ * authentication object. Additionally you can define settings that should be set to all authentications objects
+ * using the 'all' key:
+ *
+ * {{{
+ * $this->Auth->authenticate = array(
+ * 'all' => array(
+ * 'userModel' => 'Users.User',
+ * 'scope' => array('User.active' => 1)
+ * ),
+ * 'Form',
+ * 'Basic'
+ * );
+ * }}}
+ *
+ * You can also use AuthComponent::ALL instead of the string 'all'.
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
+ */
+ public $authenticate = array('Form');
+
+/**
+ * Objects that will be used for authentication checks.
+ *
+ * @var array
+ */
+ protected $_authenticateObjects = array();
+
+/**
+ * An array of authorization objects to use for authorizing users. You can configure
+ * multiple adapters and they will be checked sequentially when authorization checks are done.
+ *
+ * {{{
+ * $this->Auth->authorize = array(
+ * 'Crud' => array(
+ * 'actionPath' => 'controllers/'
+ * )
+ * );
+ * }}}
+ *
+ * Using the class name without 'Authorize' as the key, you can pass in an array of settings for each
+ * authorization object. Additionally you can define settings that should be set to all authorization objects
+ * using the 'all' key:
+ *
+ * {{{
+ * $this->Auth->authorize = array(
+ * 'all' => array(
+ * 'actionPath' => 'controllers/'
+ * ),
+ * 'Crud',
+ * 'CustomAuth'
+ * );
+ * }}}
+ *
+ * You can also use AuthComponent::ALL instead of the string 'all'
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#authorization
+ */
+ public $authorize = false;
+
+/**
+ * Objects that will be used for authorization checks.
+ *
+ * @var array
+ */
+ protected $_authorizeObjects = array();
+
+/**
+ * The name of an optional view element to render when an Ajax request is made
+ * with an invalid or expired session
+ *
+ * @var string
+ */
+ public $ajaxLogin = null;
+
+/**
+ * Settings to use when Auth needs to do a flash message with SessionComponent::setFlash().
+ * Available keys are:
+ *
+ * - `element` - The element to use, defaults to 'default'.
+ * - `key` - The key to use, defaults to 'auth'
+ * - `params` - The array of additional params to use, defaults to array()
+ *
+ * @var array
+ */
+ public $flash = array(
+ 'element' => 'default',
+ 'key' => 'auth',
+ 'params' => array()
+ );
+
+/**
+ * The session key name where the record of the current user is stored. If
+ * unspecified, it will be "Auth.User".
+ *
+ * @var string
+ */
+ public static $sessionKey = 'Auth.User';
+
+/**
+ * The current user, used for stateless authentication when
+ * sessions are not available.
+ *
+ * @var array
+ */
+ protected static $_user = array();
+
+/**
+ * A URL (defined as a string or array) to the controller action that handles
+ * logins. Defaults to `/users/login`
+ *
+ * @var mixed
+ */
+ public $loginAction = array(
+ 'controller' => 'users',
+ 'action' => 'login',
+ 'plugin' => null
+ );
+
+/**
+ * Normally, if a user is redirected to the $loginAction page, the location they
+ * were redirected from will be stored in the session so that they can be
+ * redirected back after a successful login. If this session value is not
+ * set, the user will be redirected to the page specified in $loginRedirect.
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$loginRedirect
+ */
+ public $loginRedirect = null;
+
+/**
+ * The default action to redirect to after the user is logged out. While AuthComponent does
+ * not handle post-logout redirection, a redirect URL will be returned from AuthComponent::logout().
+ * Defaults to AuthComponent::$loginAction.
+ *
+ * @var mixed
+ * @see AuthComponent::$loginAction
+ * @see AuthComponent::logout()
+ */
+ public $logoutRedirect = null;
+
+/**
+ * Error to display when user attempts to access an object or action to which they do not have
+ * access.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$authError
+ */
+ public $authError = null;
+
+/**
+ * Controller actions for which user validation is not required.
+ *
+ * @var array
+ * @see AuthComponent::allow()
+ */
+ public $allowedActions = array();
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Response object
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * Method list for bound controller
+ *
+ * @var array
+ */
+ protected $_methods = array();
+
+/**
+ * Initializes AuthComponent for use in the controller
+ *
+ * @param Controller $controller A reference to the instantiating controller object
+ * @return void
+ */
+ public function initialize(Controller $controller) {
+ $this->request = $controller->request;
+ $this->response = $controller->response;
+ $this->_methods = $controller->methods;
+
+ if (Configure::read('debug') > 0) {
+ Debugger::checkSecurityKeys();
+ }
+ }
+
+/**
+ * Main execution method. Handles redirecting of invalid users, and processing
+ * of login form data.
+ *
+ * @param Controller $controller A reference to the instantiating controller object
+ * @return boolean
+ */
+ public function startup(Controller $controller) {
+ $methods = array_flip(array_map('strtolower', $controller->methods));
+ $action = strtolower($controller->request->params['action']);
+
+ $isMissingAction = (
+ $controller->scaffold === false &&
+ !isset($methods[$action])
+ );
+
+ if ($isMissingAction) {
+ return true;
+ }
+
+ if (!$this->_setDefaults()) {
+ return false;
+ }
+ $request = $controller->request;
+
+ $url = '';
+
+ if (isset($request->url)) {
+ $url = $request->url;
+ }
+ $url = Router::normalize($url);
+ $loginAction = Router::normalize($this->loginAction);
+
+ $allowedActions = $this->allowedActions;
+ $isAllowed = (
+ $this->allowedActions == array('*') ||
+ in_array($action, array_map('strtolower', $allowedActions))
+ );
+
+ if ($loginAction != $url && $isAllowed) {
+ return true;
+ }
+
+ if ($loginAction == $url) {
+ if (empty($request->data)) {
+ if (!$this->Session->check('Auth.redirect') && !$this->loginRedirect && env('HTTP_REFERER')) {
+ $this->Session->write('Auth.redirect', $controller->referer(null, true));
+ }
+ }
+ return true;
+ } else {
+ if (!$this->_getUser()) {
+ if (!$request->is('ajax')) {
+ $this->flash($this->authError);
+ $this->Session->write('Auth.redirect', $request->here());
+ $controller->redirect($loginAction);
+ return false;
+ } elseif (!empty($this->ajaxLogin)) {
+ $controller->viewPath = 'Elements';
+ echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
+ $this->_stop();
+ return false;
+ } else {
+ $controller->redirect(null, 403);
+ }
+ }
+ }
+ if (empty($this->authorize) || $this->isAuthorized($this->user())) {
+ return true;
+ }
+
+ $this->flash($this->authError);
+ $default = '/';
+ if (!empty($this->loginRedirect)) {
+ $default = $this->loginRedirect;
+ }
+ $controller->redirect($controller->referer($default), null, true);
+ return false;
+ }
+
+/**
+ * Attempts to introspect the correct values for object properties.
+ *
+ * @return boolean
+ */
+ protected function _setDefaults() {
+ $defaults = array(
+ 'logoutRedirect' => $this->loginAction,
+ 'authError' => __d('cake', 'You are not authorized to access that location.')
+ );
+ foreach ($defaults as $key => $value) {
+ if (empty($this->{$key})) {
+ $this->{$key} = $value;
+ }
+ }
+ return true;
+ }
+
+/**
+ * Uses the configured Authorization adapters to check whether or not a user is authorized.
+ * Each adapter will be checked in sequence, if any of them return true, then the user will
+ * be authorized for the request.
+ *
+ * @param array $user The user to check the authorization of. If empty the user in the session will be used.
+ * @param CakeRequest $request The request to authenticate for. If empty, the current request will be used.
+ * @return boolean True if $user is authorized, otherwise false
+ */
+ public function isAuthorized($user = null, $request = null) {
+ if (empty($user) && !$this->user()) {
+ return false;
+ } elseif (empty($user)) {
+ $user = $this->user();
+ }
+ if (empty($request)) {
+ $request = $this->request;
+ }
+ if (empty($this->_authorizeObjects)) {
+ $this->constructAuthorize();
+ }
+ foreach ($this->_authorizeObjects as $authorizer) {
+ if ($authorizer->authorize($user, $request) === true) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Loads the authorization objects configured.
+ *
+ * @return mixed Either null when authorize is empty, or the loaded authorization objects.
+ * @throws CakeException
+ */
+ public function constructAuthorize() {
+ if (empty($this->authorize)) {
+ return;
+ }
+ $this->_authorizeObjects = array();
+ $config = Hash::normalize((array)$this->authorize);
+ $global = array();
+ if (isset($config[AuthComponent::ALL])) {
+ $global = $config[AuthComponent::ALL];
+ unset($config[AuthComponent::ALL]);
+ }
+ foreach ($config as $class => $settings) {
+ list($plugin, $class) = pluginSplit($class, true);
+ $className = $class . 'Authorize';
+ App::uses($className, $plugin . 'Controller/Component/Auth');
+ if (!class_exists($className)) {
+ throw new CakeException(__d('cake_dev', 'Authorization adapter "%s" was not found.', $class));
+ }
+ if (!method_exists($className, 'authorize')) {
+ throw new CakeException(__d('cake_dev', 'Authorization objects must implement an authorize method.'));
+ }
+ $settings = array_merge($global, (array)$settings);
+ $this->_authorizeObjects[] = new $className($this->_Collection, $settings);
+ }
+ return $this->_authorizeObjects;
+ }
+
+/**
+ * Takes a list of actions in the current controller for which authentication is not required, or
+ * no parameters to allow all actions.
+ *
+ * You can use allow with either an array, or var args.
+ *
+ * `$this->Auth->allow(array('edit', 'add'));` or
+ * `$this->Auth->allow('edit', 'add');` or
+ * `$this->Auth->allow();` to allow all actions
+ *
+ * @param string|array $action,... Controller action name or array of actions
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-public
+ */
+ public function allow($action = null) {
+ $args = func_get_args();
+ if (empty($args) || $action === null) {
+ $this->allowedActions = $this->_methods;
+ } else {
+ if (isset($args[0]) && is_array($args[0])) {
+ $args = $args[0];
+ }
+ $this->allowedActions = array_merge($this->allowedActions, $args);
+ }
+ }
+
+/**
+ * Removes items from the list of allowed/no authentication required actions.
+ *
+ * You can use deny with either an array, or var args.
+ *
+ * `$this->Auth->deny(array('edit', 'add'));` or
+ * `$this->Auth->deny('edit', 'add');` or
+ * `$this->Auth->deny();` to remove all items from the allowed list
+ *
+ * @param string|array $action,... Controller action name or array of actions
+ * @return void
+ * @see AuthComponent::allow()
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#making-actions-require-authorization
+ */
+ public function deny($action = null) {
+ $args = func_get_args();
+ if (empty($args) || $action === null) {
+ $this->allowedActions = array();
+ } else {
+ if (isset($args[0]) && is_array($args[0])) {
+ $args = $args[0];
+ }
+ foreach ($args as $arg) {
+ $i = array_search($arg, $this->allowedActions);
+ if (is_int($i)) {
+ unset($this->allowedActions[$i]);
+ }
+ }
+ $this->allowedActions = array_values($this->allowedActions);
+ }
+ }
+
+/**
+ * Maps action names to CRUD operations. Used for controller-based authentication. Make sure
+ * to configure the authorize property before calling this method. As it delegates $map to all the
+ * attached authorize objects.
+ *
+ * @param array $map Actions to map
+ * @return void
+ * @see BaseAuthorize::mapActions()
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#mapping-actions-when-using-crudauthorize
+ */
+ public function mapActions($map = array()) {
+ if (empty($this->_authorizeObjects)) {
+ $this->constructAuthorize();
+ }
+ foreach ($this->_authorizeObjects as $auth) {
+ $auth->mapActions($map);
+ }
+ }
+
+/**
+ * Log a user in. If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not
+ * specified, the request will be used to identify a user. If the identification was successful,
+ * the user record is written to the session key specified in AuthComponent::$sessionKey. Logging in
+ * will also change the session id in order to help mitigate session replays.
+ *
+ * @param array $user Either an array of user data, or null to identify a user using the current request.
+ * @return boolean True on login success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#identifying-users-and-logging-them-in
+ */
+ public function login($user = null) {
+ $this->_setDefaults();
+
+ if (empty($user)) {
+ $user = $this->identify($this->request, $this->response);
+ }
+ if ($user) {
+ $this->Session->renew();
+ $this->Session->write(self::$sessionKey, $user);
+ }
+ return $this->loggedIn();
+ }
+
+/**
+ * Logs a user out, and returns the login action to redirect to.
+ * Triggers the logout() method of all the authenticate objects, so they can perform
+ * custom logout logic. AuthComponent will remove the session data, so
+ * there is no need to do that in an authentication object. Logging out
+ * will also renew the session id. This helps mitigate issues with session replays.
+ *
+ * @return string AuthComponent::$logoutRedirect
+ * @see AuthComponent::$logoutRedirect
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#logging-users-out
+ */
+ public function logout() {
+ $this->_setDefaults();
+ if (empty($this->_authenticateObjects)) {
+ $this->constructAuthenticate();
+ }
+ $user = $this->user();
+ foreach ($this->_authenticateObjects as $auth) {
+ $auth->logout($user);
+ }
+ $this->Session->delete(self::$sessionKey);
+ $this->Session->delete('Auth.redirect');
+ $this->Session->renew();
+ return Router::normalize($this->logoutRedirect);
+ }
+
+/**
+ * Get the current user.
+ *
+ * Will prefer the static user cache over sessions. The static user
+ * cache is primarily used for stateless authentication. For stateful authentication,
+ * cookies + sessions will be used.
+ *
+ * @param string $key field to retrieve. Leave null to get entire User record
+ * @return mixed User record. or null if no user is logged in.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user
+ */
+ public static function user($key = null) {
+ if (empty(self::$_user) && !CakeSession::check(self::$sessionKey)) {
+ return null;
+ }
+ if (!empty(self::$_user)) {
+ $user = self::$_user;
+ } else {
+ $user = CakeSession::read(self::$sessionKey);
+ }
+ if ($key === null) {
+ return $user;
+ }
+ if ($value = Hash::get($user, $key)) {
+ return $value;
+ }
+ return null;
+ }
+
+/**
+ * Similar to AuthComponent::user() except if the session user cannot be found, connected authentication
+ * objects will have their getUser() methods called. This lets stateless authentication methods function correctly.
+ *
+ * @return boolean true if a user can be found, false if one cannot.
+ */
+ protected function _getUser() {
+ $user = $this->user();
+ if ($user) {
+ return true;
+ }
+ if (empty($this->_authenticateObjects)) {
+ $this->constructAuthenticate();
+ }
+ foreach ($this->_authenticateObjects as $auth) {
+ $result = $auth->getUser($this->request);
+ if (!empty($result) && is_array($result)) {
+ self::$_user = $result;
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * If no parameter is passed, gets the authentication redirect URL. Pass a url in to
+ * set the destination a user should be redirected to upon logging in. Will fallback to
+ * AuthComponent::$loginRedirect if there is no stored redirect value.
+ *
+ * @param string|array $url Optional URL to write as the login redirect URL.
+ * @return string Redirect URL
+ */
+ public function redirect($url = null) {
+ if (!is_null($url)) {
+ $redir = $url;
+ $this->Session->write('Auth.redirect', $redir);
+ } elseif ($this->Session->check('Auth.redirect')) {
+ $redir = $this->Session->read('Auth.redirect');
+ $this->Session->delete('Auth.redirect');
+
+ if (Router::normalize($redir) == Router::normalize($this->loginAction)) {
+ $redir = $this->loginRedirect;
+ }
+ } else {
+ $redir = $this->loginRedirect;
+ }
+ return Router::normalize($redir);
+ }
+
+/**
+ * Use the configured authentication adapters, and attempt to identify the user
+ * by credentials contained in $request.
+ *
+ * @param CakeRequest $request The request that contains authentication data.
+ * @param CakeResponse $response The response
+ * @return array User record data, or false, if the user could not be identified.
+ */
+ public function identify(CakeRequest $request, CakeResponse $response) {
+ if (empty($this->_authenticateObjects)) {
+ $this->constructAuthenticate();
+ }
+ foreach ($this->_authenticateObjects as $auth) {
+ $result = $auth->authenticate($request, $response);
+ if (!empty($result) && is_array($result)) {
+ return $result;
+ }
+ }
+ return false;
+ }
+
+/**
+ * loads the configured authentication objects.
+ *
+ * @return mixed either null on empty authenticate value, or an array of loaded objects.
+ * @throws CakeException
+ */
+ public function constructAuthenticate() {
+ if (empty($this->authenticate)) {
+ return;
+ }
+ $this->_authenticateObjects = array();
+ $config = Hash::normalize((array)$this->authenticate);
+ $global = array();
+ if (isset($config[AuthComponent::ALL])) {
+ $global = $config[AuthComponent::ALL];
+ unset($config[AuthComponent::ALL]);
+ }
+ foreach ($config as $class => $settings) {
+ list($plugin, $class) = pluginSplit($class, true);
+ $className = $class . 'Authenticate';
+ App::uses($className, $plugin . 'Controller/Component/Auth');
+ if (!class_exists($className)) {
+ throw new CakeException(__d('cake_dev', 'Authentication adapter "%s" was not found.', $class));
+ }
+ if (!method_exists($className, 'authenticate')) {
+ throw new CakeException(__d('cake_dev', 'Authentication objects must implement an authenticate method.'));
+ }
+ $settings = array_merge($global, (array)$settings);
+ $this->_authenticateObjects[] = new $className($this->_Collection, $settings);
+ }
+ return $this->_authenticateObjects;
+ }
+
+/**
+ * Hash a password with the application's salt value (as defined with Configure::write('Security.salt');
+ *
+ * This method is intended as a convenience wrapper for Security::hash(). If you want to use
+ * a hashing/encryption system not supported by that method, do not use this method.
+ *
+ * @param string $password Password to hash
+ * @return string Hashed password
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#hashing-passwords
+ */
+ public static function password($password) {
+ return Security::hash($password, null, true);
+ }
+
+/**
+ * Component shutdown. If user is logged in, wipe out redirect.
+ *
+ * @param Controller $controller Instantiating controller
+ * @return void
+ */
+ public function shutdown(Controller $controller) {
+ if ($this->loggedIn()) {
+ $this->Session->delete('Auth.redirect');
+ }
+ }
+
+/**
+ * Check whether or not the current user has data in the session, and is considered logged in.
+ *
+ * @return boolean true if the user is logged in, false otherwise
+ */
+ public function loggedIn() {
+ return $this->user() != array();
+ }
+
+/**
+ * Set a flash message. Uses the Session component, and values from AuthComponent::$flash.
+ *
+ * @param string $message The message to set.
+ * @return void
+ */
+ public function flash($message) {
+ $this->Session->setFlash($message, $this->flash['element'], $this->flash['params'], $this->flash['key']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php
new file mode 100644
index 0000000..9f0879f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/CookieComponent.php
@@ -0,0 +1,523 @@
+<?php
+/**
+ * Cookie Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.4213
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('Security', 'Utility');
+App::uses('Hash', 'Utility');
+
+/**
+ * Cookie Component.
+ *
+ * Cookie handling for the controller.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html
+ *
+ */
+class CookieComponent extends Component {
+
+/**
+ * The name of the cookie.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->name = 'CookieName';
+ *
+ * @var string
+ */
+ public $name = 'CakeCookie';
+
+/**
+ * The time a cookie will remain valid.
+ *
+ * Can be either integer Unix timestamp or a date string.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->time = '5 Days';
+ *
+ * @var mixed
+ */
+ public $time = null;
+
+/**
+ * Cookie path.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->path = '/';
+ *
+ * The path on the server in which the cookie will be available on.
+ * If public $cookiePath is set to '/foo/', the cookie will only be available
+ * within the /foo/ directory and all sub-directories such as /foo/bar/ of domain.
+ * The default value is the entire domain.
+ *
+ * @var string
+ */
+ public $path = '/';
+
+/**
+ * Domain path.
+ *
+ * The domain that the cookie is available.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->domain = '.example.com';
+ *
+ * To make the cookie available on all subdomains of example.com.
+ * Set $this->Cookie->domain = '.example.com'; in your controller beforeFilter
+ *
+ * @var string
+ */
+ public $domain = '';
+
+/**
+ * Secure HTTPS only cookie.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->secure = true;
+ *
+ * Indicates that the cookie should only be transmitted over a secure HTTPS connection.
+ * When set to true, the cookie will only be set if a secure connection exists.
+ *
+ * @var boolean
+ */
+ public $secure = false;
+
+/**
+ * Encryption key.
+ *
+ * Overridden with the controller beforeFilter();
+ * $this->Cookie->key = 'SomeRandomString';
+ *
+ * @var string
+ */
+ public $key = null;
+
+/**
+ * HTTP only cookie
+ *
+ * Set to true to make HTTP only cookies. Cookies that are HTTP only
+ * are not accessible in Javascript.
+ *
+ * @var boolean
+ */
+ public $httpOnly = false;
+
+/**
+ * Values stored in the cookie.
+ *
+ * Accessed in the controller using $this->Cookie->read('Name.key');
+ *
+ * @see CookieComponent::read();
+ * @var string
+ */
+ protected $_values = array();
+
+/**
+ * Type of encryption to use.
+ *
+ * Currently two methods are available: cipher and rijndael
+ * Defaults to Security::cipher();
+ *
+ * @var string
+ */
+ protected $_type = 'cipher';
+
+/**
+ * Used to reset cookie time if $expire is passed to CookieComponent::write()
+ *
+ * @var string
+ */
+ protected $_reset = null;
+
+/**
+ * Expire time of the cookie
+ *
+ * This is controlled by CookieComponent::time;
+ *
+ * @var string
+ */
+ protected $_expires = 0;
+
+/**
+ * A reference to the Controller's CakeResponse object
+ *
+ * @var CakeResponse
+ */
+ protected $_response = null;
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection for this component
+ * @param array $settings Array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->key = Configure::read('Security.salt');
+ parent::__construct($collection, $settings);
+ if (isset($this->time)) {
+ $this->_expire($this->time);
+ }
+
+ $controller = $collection->getController();
+ if ($controller && isset($controller->response)) {
+ $this->_response = $controller->response;
+ } else {
+ $this->_response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ }
+ }
+
+/**
+ * Start CookieComponent for use in the controller
+ *
+ * @param Controller $controller
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ $this->_expire($this->time);
+
+ $this->_values[$this->name] = array();
+ if (isset($_COOKIE[$this->name])) {
+ $this->_values[$this->name] = $this->_decrypt($_COOKIE[$this->name]);
+ }
+ }
+
+/**
+ * Write a value to the $_COOKIE[$key];
+ *
+ * Optional [Name.], required key, optional $value, optional $encrypt, optional $expires
+ * $this->Cookie->write('[Name.]key, $value);
+ *
+ * By default all values are encrypted.
+ * You must pass $encrypt false to store values in clear test
+ *
+ * You must use this method before any output is sent to the browser.
+ * Failure to do so will result in header already sent errors.
+ *
+ * @param string|array $key Key for the value
+ * @param mixed $value Value
+ * @param boolean $encrypt Set to true to encrypt value, false otherwise
+ * @param integer|string $expires Can be either Unix timestamp, or date string
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::write
+ */
+ public function write($key, $value = null, $encrypt = true, $expires = null) {
+ if (empty($this->_values[$this->name])) {
+ $this->read();
+ }
+
+ if (is_null($encrypt)) {
+ $encrypt = true;
+ }
+ $this->_encrypted = $encrypt;
+ $this->_expire($expires);
+
+ if (!is_array($key)) {
+ $key = array($key => $value);
+ }
+
+ foreach ($key as $name => $value) {
+ if (strpos($name, '.') === false) {
+ $this->_values[$this->name][$name] = $value;
+ $this->_write("[$name]", $value);
+ } else {
+ $names = explode('.', $name, 2);
+ if (!isset($this->_values[$this->name][$names[0]])) {
+ $this->_values[$this->name][$names[0]] = array();
+ }
+ $this->_values[$this->name][$names[0]] = Hash::insert($this->_values[$this->name][$names[0]], $names[1], $value);
+ $this->_write('[' . implode('][', $names) . ']', $value);
+ }
+ }
+ $this->_encrypted = true;
+ }
+
+/**
+ * Read the value of the $_COOKIE[$key];
+ *
+ * Optional [Name.], required key
+ * $this->Cookie->read(Name.key);
+ *
+ * @param string $key Key of the value to be obtained. If none specified, obtain map key => values
+ * @return string or null, value for specified key
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::read
+ */
+ public function read($key = null) {
+ if (empty($this->_values[$this->name]) && isset($_COOKIE[$this->name])) {
+ $this->_values[$this->name] = $this->_decrypt($_COOKIE[$this->name]);
+ }
+ if (empty($this->_values[$this->name])) {
+ $this->_values[$this->name] = array();
+ }
+ if (is_null($key)) {
+ return $this->_values[$this->name];
+ }
+
+ if (strpos($key, '.') !== false) {
+ $names = explode('.', $key, 2);
+ $key = $names[0];
+ }
+ if (!isset($this->_values[$this->name][$key])) {
+ return null;
+ }
+
+ if (!empty($names[1])) {
+ return Hash::get($this->_values[$this->name][$key], $names[1]);
+ }
+ return $this->_values[$this->name][$key];
+ }
+
+/**
+ * Delete a cookie value
+ *
+ * Optional [Name.], required key
+ * $this->Cookie->read('Name.key);
+ *
+ * You must use this method before any output is sent to the browser.
+ * Failure to do so will result in header already sent errors.
+ *
+ * @param string $key Key of the value to be deleted
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::delete
+ */
+ public function delete($key) {
+ if (empty($this->_values[$this->name])) {
+ $this->read();
+ }
+ if (strpos($key, '.') === false) {
+ if (isset($this->_values[$this->name][$key]) && is_array($this->_values[$this->name][$key])) {
+ foreach ($this->_values[$this->name][$key] as $idx => $val) {
+ $this->_delete("[$key][$idx]");
+ }
+ }
+ $this->_delete("[$key]");
+ unset($this->_values[$this->name][$key]);
+ return;
+ }
+ $names = explode('.', $key, 2);
+ if (isset($this->_values[$this->name][$names[0]])) {
+ $this->_values[$this->name][$names[0]] = Hash::remove($this->_values[$this->name][$names[0]], $names[1]);
+ }
+ $this->_delete('[' . implode('][', $names) . ']');
+ }
+
+/**
+ * Destroy current cookie
+ *
+ * You must use this method before any output is sent to the browser.
+ * Failure to do so will result in header already sent errors.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::destroy
+ */
+ public function destroy() {
+ if (isset($_COOKIE[$this->name])) {
+ $this->_values[$this->name] = $this->_decrypt($_COOKIE[$this->name]);
+ }
+
+ foreach ($this->_values[$this->name] as $name => $value) {
+ if (is_array($value)) {
+ foreach ($value as $key => $val) {
+ unset($this->_values[$this->name][$name][$key]);
+ $this->_delete("[$name][$key]");
+ }
+ }
+ unset($this->_values[$this->name][$name]);
+ $this->_delete("[$name]");
+ }
+ }
+
+/**
+ * Will allow overriding default encryption method. Use this method
+ * in ex: AppController::beforeFilter() before you have read or
+ * written any cookies.
+ *
+ * @param string $type Encryption method
+ * @return void
+ */
+ public function type($type = 'cipher') {
+ $availableTypes = array(
+ 'cipher',
+ 'rijndael'
+ );
+ if (!in_array($type, $availableTypes)) {
+ trigger_error(__d('cake_dev', 'You must use cipher or rijndael for cookie encryption type'), E_USER_WARNING);
+ $type = 'cipher';
+ }
+ $this->_type = $type;
+ }
+
+/**
+ * Set the expire time for a session variable.
+ *
+ * Creates a new expire time for a session variable.
+ * $expire can be either integer Unix timestamp or a date string.
+ *
+ * Used by write()
+ * CookieComponent::write(string, string, boolean, 8400);
+ * CookieComponent::write(string, string, boolean, '5 Days');
+ *
+ * @param integer|string $expires Can be either Unix timestamp, or date string
+ * @return integer Unix timestamp
+ */
+ protected function _expire($expires = null) {
+ $now = time();
+ if (is_null($expires)) {
+ return $this->_expires;
+ }
+ $this->_reset = $this->_expires;
+
+ if ($expires == 0) {
+ return $this->_expires = 0;
+ }
+
+ if (is_integer($expires) || is_numeric($expires)) {
+ return $this->_expires = $now + intval($expires);
+ }
+ return $this->_expires = strtotime($expires, $now);
+ }
+
+/**
+ * Set cookie
+ *
+ * @param string $name Name for cookie
+ * @param string $value Value for cookie
+ * @return void
+ */
+ protected function _write($name, $value) {
+ $this->_response->cookie(array(
+ 'name' => $this->name . $name,
+ 'value' => $this->_encrypt($value),
+ 'expire' => $this->_expires,
+ 'path' => $this->path,
+ 'domain' => $this->domain,
+ 'secure' => $this->secure,
+ 'httpOnly' => $this->httpOnly
+ ));
+
+ if (!is_null($this->_reset)) {
+ $this->_expires = $this->_reset;
+ $this->_reset = null;
+ }
+ }
+
+/**
+ * Sets a cookie expire time to remove cookie value
+ *
+ * @param string $name Name of cookie
+ * @return void
+ */
+ protected function _delete($name) {
+ $this->_response->cookie(array(
+ 'name' => $this->name . $name,
+ 'value' => '',
+ 'expire' => time() - 42000,
+ 'path' => $this->path,
+ 'domain' => $this->domain,
+ 'secure' => $this->secure,
+ 'httpOnly' => $this->httpOnly
+ ));
+ }
+
+/**
+ * Encrypts $value using public $type method in Security class
+ *
+ * @param string $value Value to encrypt
+ * @return string encrypted string
+ * @return string Encoded values
+ */
+ protected function _encrypt($value) {
+ if (is_array($value)) {
+ $value = $this->_implode($value);
+ }
+
+ if ($this->_encrypted === true) {
+ $type = $this->_type;
+ $value = "Q2FrZQ==." . base64_encode(Security::$type($value, $this->key, 'encrypt'));
+ }
+ return $value;
+ }
+
+/**
+ * Decrypts $value using public $type method in Security class
+ *
+ * @param array $values Values to decrypt
+ * @return string decrypted string
+ */
+ protected function _decrypt($values) {
+ $decrypted = array();
+ $type = $this->_type;
+
+ foreach ((array)$values as $name => $value) {
+ if (is_array($value)) {
+ foreach ($value as $key => $val) {
+ $pos = strpos($val, 'Q2FrZQ==.');
+ $decrypted[$name][$key] = $this->_explode($val);
+
+ if ($pos !== false) {
+ $val = substr($val, 8);
+ $decrypted[$name][$key] = $this->_explode(Security::$type(base64_decode($val), $this->key, 'decrypt'));
+ }
+ }
+ } else {
+ $pos = strpos($value, 'Q2FrZQ==.');
+ $decrypted[$name] = $this->_explode($value);
+
+ if ($pos !== false) {
+ $value = substr($value, 8);
+ $decrypted[$name] = $this->_explode(Security::$type(base64_decode($value), $this->key, 'decrypt'));
+ }
+ }
+ }
+ return $decrypted;
+ }
+
+/**
+ * Implode method to keep keys are multidimensional arrays
+ *
+ * @param array $array Map of key and values
+ * @return string A json encoded string.
+ */
+ protected function _implode(array $array) {
+ return json_encode($array);
+ }
+
+/**
+ * Explode method to return array from string set in CookieComponent::_implode()
+ * Maintains reading backwards compatibility with 1.x CookieComponent::_implode().
+ *
+ * @param string $string A string containing JSON encoded data, or a bare string.
+ * @return array Map of key and values
+ */
+ protected function _explode($string) {
+ $first = substr($string, 0, 1);
+ if ($first === '{' || $first === '[') {
+ $ret = json_decode($string, true);
+ return ($ret != null) ? $ret : $string;
+ }
+ $array = array();
+ foreach (explode(',', $string) as $pair) {
+ $key = explode('|', $pair);
+ if (!isset($key[1])) {
+ return $key[0];
+ }
+ $array[$key[0]] = $key[1];
+ }
+ return $array;
+ }
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php
new file mode 100644
index 0000000..d0f55ef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/EmailComponent.php
@@ -0,0 +1,464 @@
+<?php
+/**
+ * Email Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.3467
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('Multibyte', 'I18n');
+App::uses('CakeEmail', 'Network/Email');
+
+/**
+ * EmailComponent
+ *
+ * This component is used for handling Internet Message Format based
+ * based on the standard outlined in http://www.rfc-editor.org/rfc/rfc2822.txt
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/email.html
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/email.html
+ * @deprecated Use Network/CakeEmail
+ */
+class EmailComponent extends Component {
+
+/**
+ * Recipient of the email
+ *
+ * @var string
+ */
+ public $to = null;
+
+/**
+ * The mail which the email is sent from
+ *
+ * @var string
+ */
+ public $from = null;
+
+/**
+ * The email the recipient will reply to
+ *
+ * @var string
+ */
+ public $replyTo = null;
+
+/**
+ * The read receipt email
+ *
+ * @var string
+ */
+ public $readReceipt = null;
+
+/**
+ * The mail that will be used in case of any errors like
+ * - Remote mailserver down
+ * - Remote user has exceeded his quota
+ * - Unknown user
+ *
+ * @var string
+ */
+ public $return = null;
+
+/**
+ * Carbon Copy
+ *
+ * List of email's that should receive a copy of the email.
+ * The Recipient WILL be able to see this list
+ *
+ * @var array
+ */
+ public $cc = array();
+
+/**
+ * Blind Carbon Copy
+ *
+ * List of email's that should receive a copy of the email.
+ * The Recipient WILL NOT be able to see this list
+ *
+ * @var array
+ */
+ public $bcc = array();
+
+/**
+ * The date to put in the Date: header. This should be a date
+ * conforming with the RFC2822 standard. Leave null, to have
+ * today's date generated.
+ *
+ * @var string
+ */
+ public $date = null;
+
+/**
+ * The subject of the email
+ *
+ * @var string
+ */
+ public $subject = null;
+
+/**
+ * Associative array of a user defined headers
+ * Keys will be prefixed 'X-' as per RFC2822 Section 4.7.5
+ *
+ * @var array
+ */
+ public $headers = array();
+
+/**
+ * List of additional headers
+ *
+ * These will NOT be used if you are using safemode and mail()
+ *
+ * @var string
+ */
+ public $additionalParams = null;
+
+/**
+ * Layout for the View
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Template for the view
+ *
+ * @var string
+ */
+ public $template = null;
+
+/**
+ * Line feed character(s) to be used when sending using mail() function
+ * By default PHP_EOL is used.
+ * RFC2822 requires it to be CRLF but some Unix
+ * mail transfer agents replace LF by CRLF automatically
+ * (which leads to doubling CR if CRLF is used).
+ *
+ * @var string
+ */
+ public $lineFeed = PHP_EOL;
+
+/**
+ * What format should the email be sent in
+ *
+ * Supported formats:
+ * - text
+ * - html
+ * - both
+ *
+ * @var string
+ */
+ public $sendAs = 'text';
+
+/**
+ * What method should the email be sent by
+ *
+ * Supported methods:
+ * - mail
+ * - smtp
+ * - debug
+ *
+ * @var string
+ */
+ public $delivery = 'mail';
+
+/**
+ * charset the email is sent in
+ *
+ * @var string
+ */
+ public $charset = 'utf-8';
+
+/**
+ * List of files that should be attached to the email.
+ *
+ * Can be both absolute and relative paths
+ *
+ * @var array
+ */
+ public $attachments = array();
+
+/**
+ * What mailer should EmailComponent identify itself as
+ *
+ * @var string
+ */
+ public $xMailer = 'CakePHP Email Component';
+
+/**
+ * The list of paths to search if an attachment isn't absolute
+ *
+ * @var array
+ */
+ public $filePaths = array();
+
+/**
+ * List of options to use for smtp mail method
+ *
+ * Options is:
+ * - port
+ * - host
+ * - timeout
+ * - username
+ * - password
+ * - client
+ *
+ * @var array
+ */
+ public $smtpOptions = array();
+
+/**
+ * Contains the rendered plain text message if one was sent.
+ *
+ * @var string
+ */
+ public $textMessage = null;
+
+/**
+ * Contains the rendered HTML message if one was sent.
+ *
+ * @var string
+ */
+ public $htmlMessage = null;
+
+/**
+ * Whether to generate a Message-ID header for the
+ * e-mail. True to generate a Message-ID, False to let
+ * it be handled by sendmail (or similar) or a string
+ * to completely override the Message-ID.
+ *
+ * If you are sending Email from a shell, be sure to set this value. As you
+ * could encounter delivery issues if you do not.
+ *
+ * @var mixed
+ */
+ public $messageId = true;
+
+/**
+ * Controller reference
+ *
+ * @var Controller
+ */
+ protected $_controller = null;
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
+ * @param array $settings Array of configuration settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $this->_controller = $collection->getController();
+ parent::__construct($collection, $settings);
+ }
+
+/**
+ * Initialize component
+ *
+ * @param Controller $controller Instantiating controller
+ * @return void
+ */
+ public function initialize(Controller $controller) {
+ if (Configure::read('App.encoding') !== null) {
+ $this->charset = Configure::read('App.encoding');
+ }
+ }
+
+/**
+ * Send an email using the specified content, template and layout
+ *
+ * @param string|array $content Either an array of text lines, or a string with contents
+ * If you are rendering a template this variable will be sent to the templates as `$content`
+ * @param string $template Template to use when sending email
+ * @param string $layout Layout to use to enclose email body
+ * @return boolean Success
+ */
+ public function send($content = null, $template = null, $layout = null) {
+ $lib = new CakeEmail();
+ $lib->charset = $this->charset;
+
+ $lib->from($this->_formatAddresses((array)$this->from));
+ if (!empty($this->to)) {
+ $lib->to($this->_formatAddresses((array)$this->to));
+ }
+ if (!empty($this->cc)) {
+ $lib->cc($this->_formatAddresses((array)$this->cc));
+ }
+ if (!empty($this->bcc)) {
+ $lib->bcc($this->_formatAddresses((array)$this->bcc));
+ }
+ if (!empty($this->replyTo)) {
+ $lib->replyTo($this->_formatAddresses((array)$this->replyTo));
+ }
+ if (!empty($this->return)) {
+ $lib->returnPath($this->_formatAddresses((array)$this->return));
+ }
+ if (!empty($readReceipt)) {
+ $lib->readReceipt($this->_formatAddresses((array)$this->readReceipt));
+ }
+
+ $lib->subject($this->subject)->messageID($this->messageId);
+ $lib->helpers($this->_controller->helpers);
+
+ $headers = array('X-Mailer' => $this->xMailer);
+ foreach ($this->headers as $key => $value) {
+ $headers['X-' . $key] = $value;
+ }
+ if ($this->date != false) {
+ $headers['Date'] = $this->date;
+ }
+ $lib->setHeaders($headers);
+
+ if ($template) {
+ $this->template = $template;
+ }
+ if ($layout) {
+ $this->layout = $layout;
+ }
+ $lib->template($this->template, $this->layout)->viewVars($this->_controller->viewVars)->emailFormat($this->sendAs);
+
+ if (!empty($this->attachments)) {
+ $lib->attachments($this->_formatAttachFiles());
+ }
+
+ $lib->transport(ucfirst($this->delivery));
+ if ($this->delivery === 'mail') {
+ $lib->config(array('eol' => $this->lineFeed, 'additionalParameters' => $this->additionalParams));
+ } elseif ($this->delivery === 'smtp') {
+ $lib->config($this->smtpOptions);
+ } else {
+ $lib->config(array());
+ }
+
+ $sent = $lib->send($content);
+
+ $this->htmlMessage = $lib->message(CakeEmail::MESSAGE_HTML);
+ if (empty($this->htmlMessage)) {
+ $this->htmlMessage = null;
+ }
+ $this->textMessage = $lib->message(CakeEmail::MESSAGE_TEXT);
+ if (empty($this->textMessage)) {
+ $this->textMessage = null;
+ }
+
+ $this->_header = array();
+ $this->_message = array();
+
+ return $sent;
+ }
+
+/**
+ * Reset all EmailComponent internal variables to be able to send out a new email.
+ *
+ * @return void
+ */
+ public function reset() {
+ $this->template = null;
+ $this->to = array();
+ $this->from = null;
+ $this->replyTo = null;
+ $this->return = null;
+ $this->cc = array();
+ $this->bcc = array();
+ $this->subject = null;
+ $this->additionalParams = null;
+ $this->date = null;
+ $this->attachments = array();
+ $this->htmlMessage = null;
+ $this->textMessage = null;
+ $this->messageId = true;
+ $this->delivery = 'mail';
+ }
+
+/**
+ * Format the attach array
+ *
+ * @return array
+ */
+ protected function _formatAttachFiles() {
+ $files = array();
+ foreach ($this->attachments as $filename => $attachment) {
+ $file = $this->_findFiles($attachment);
+ if (!empty($file)) {
+ if (is_int($filename)) {
+ $filename = basename($file);
+ }
+ $files[$filename] = $file;
+ }
+ }
+ return $files;
+ }
+
+/**
+ * Find the specified attachment in the list of file paths
+ *
+ * @param string $attachment Attachment file name to find
+ * @return string Path to located file
+ */
+ protected function _findFiles($attachment) {
+ if (file_exists($attachment)) {
+ return $attachment;
+ }
+ foreach ($this->filePaths as $path) {
+ if (file_exists($path . DS . $attachment)) {
+ $file = $path . DS . $attachment;
+ return $file;
+ }
+ }
+ return null;
+ }
+
+/**
+ * Format addresses to be an array with email as key and alias as value
+ *
+ * @param array $addresses
+ * @return array
+ */
+ protected function _formatAddresses($addresses) {
+ $formatted = array();
+ foreach ($addresses as $address) {
+ if (preg_match('/((.*))?\s?<(.+)>/', $address, $matches) && !empty($matches[2])) {
+ $formatted[$this->_strip($matches[3])] = $matches[2];
+ } else {
+ $address = $this->_strip($address);
+ $formatted[$address] = $address;
+ }
+ }
+ return $formatted;
+ }
+
+/**
+ * Remove certain elements (such as bcc:, to:, %0a) from given value.
+ * Helps prevent header injection / manipulation on user content.
+ *
+ * @param string $value Value to strip
+ * @param boolean $message Set to true to indicate main message content
+ * @return string Stripped value
+ */
+ protected function _strip($value, $message = false) {
+ $search = '%0a|%0d|Content-(?:Type|Transfer-Encoding)\:';
+ $search .= '|charset\=|mime-version\:|multipart/mixed|(?:[^a-z]to|b?cc)\:.*';
+
+ if ($message !== true) {
+ $search .= '|\r|\n';
+ }
+ $search = '#(?:' . $search . ')#i';
+ while (preg_match($search, $value)) {
+ $value = preg_replace($search, '', $value);
+ }
+ return $value;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php
new file mode 100644
index 0000000..bd3d31c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/PaginatorComponent.php
@@ -0,0 +1,383 @@
+<?php
+/**
+ * Paginator Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Hash', 'Utility');
+
+/**
+ * This component is used to handle automatic model data pagination. The primary way to use this
+ * component is to call the paginate() method. There is a convenience wrapper on Controller as well.
+ *
+ * ### Configuring pagination
+ *
+ * You configure pagination using the PaginatorComponent::$settings. This allows you to configure
+ * the default pagination behavior in general or for a specific model. General settings are used when there
+ * are no specific model configuration, or the model you are paginating does not have specific settings.
+ *
+ * {{{
+ * $this->Paginator->settings = array(
+ * 'limit' => 20,
+ * 'maxLimit' => 100
+ * );
+ * }}}
+ *
+ * The above settings will be used to paginate any model. You can configure model specific settings by
+ * keying the settings with the model name.
+ *
+ * {{{
+ * $this->Paginator->settings = array(
+ * 'Post' => array(
+ * 'limit' => 20,
+ * 'maxLimit' => 100
+ * ),
+ * 'Comment' => array( ... )
+ * );
+ * }}}
+ *
+ * This would allow you to have different pagination settings for `Comment` and `Post` models.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html
+ */
+class PaginatorComponent extends Component {
+
+/**
+ * Pagination settings. These settings control pagination at a general level.
+ * You can also define sub arrays for pagination settings for specific models.
+ *
+ * - `maxLimit` The maximum limit users can choose to view. Defaults to 100
+ * - `limit` The initial number of items per page. Defaults to 20.
+ * - `page` The starting page, defaults to 1.
+ * - `paramType` What type of parameters you want pagination to use?
+ * - `named` Use named parameters / routed parameters.
+ * - `querystring` Use query string parameters.
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'paramType' => 'named'
+ );
+
+/**
+ * A list of parameters users are allowed to set using request parameters. Modifying
+ * this list will allow users to have more influence over pagination,
+ * be careful with what you permit.
+ *
+ * @var array
+ */
+ public $whitelist = array(
+ 'limit', 'sort', 'page', 'direction'
+ );
+
+/**
+ * Constructor
+ *
+ * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
+ * @param array $settings Array of configuration settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $settings = array_merge($this->settings, (array)$settings);
+ $this->Controller = $collection->getController();
+ parent::__construct($collection, $settings);
+ }
+
+/**
+ * Handles automatic pagination of model records.
+ *
+ * @param Model|string $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
+ * @param string|array $scope Additional find conditions to use while paginating
+ * @param array $whitelist List of allowed fields for ordering. This allows you to prevent ordering
+ * on non-indexed, or undesirable columns.
+ * @return array Model query results
+ * @throws MissingModelException
+ */
+ public function paginate($object = null, $scope = array(), $whitelist = array()) {
+ if (is_array($object)) {
+ $whitelist = $scope;
+ $scope = $object;
+ $object = null;
+ }
+
+ $object = $this->_getObject($object);
+
+ if (!is_object($object)) {
+ throw new MissingModelException($object);
+ }
+
+ $options = $this->mergeOptions($object->alias);
+ $options = $this->validateSort($object, $options, $whitelist);
+ $options = $this->checkLimit($options);
+
+ $conditions = $fields = $order = $limit = $page = $recursive = null;
+
+ if (!isset($options['conditions'])) {
+ $options['conditions'] = array();
+ }
+
+ $type = 'all';
+
+ if (isset($options[0])) {
+ $type = $options[0];
+ unset($options[0]);
+ }
+
+ extract($options);
+
+ if (is_array($scope) && !empty($scope)) {
+ $conditions = array_merge($conditions, $scope);
+ } elseif (is_string($scope)) {
+ $conditions = array($conditions, $scope);
+ }
+ if ($recursive === null) {
+ $recursive = $object->recursive;
+ }
+
+ $extra = array_diff_key($options, compact(
+ 'conditions', 'fields', 'order', 'limit', 'page', 'recursive'
+ ));
+ if ($type !== 'all') {
+ $extra['type'] = $type;
+ }
+
+ if (intval($page) < 1) {
+ $page = 1;
+ }
+ $page = $options['page'] = (int)$page;
+
+ if ($object->hasMethod('paginate')) {
+ $results = $object->paginate(
+ $conditions, $fields, $order, $limit, $page, $recursive, $extra
+ );
+ } else {
+ $parameters = compact('conditions', 'fields', 'order', 'limit', 'page');
+ if ($recursive != $object->recursive) {
+ $parameters['recursive'] = $recursive;
+ }
+ $results = $object->find($type, array_merge($parameters, $extra));
+ }
+ $defaults = $this->getDefaults($object->alias);
+ unset($defaults[0]);
+
+ if ($object->hasMethod('paginateCount')) {
+ $count = $object->paginateCount($conditions, $recursive, $extra);
+ } else {
+ $parameters = compact('conditions');
+ if ($recursive != $object->recursive) {
+ $parameters['recursive'] = $recursive;
+ }
+ $count = $object->find('count', array_merge($parameters, $extra));
+ }
+ $pageCount = intval(ceil($count / $limit));
+ $page = max(min($page, $pageCount), 1);
+
+ $paging = array(
+ 'page' => $page,
+ 'current' => count($results),
+ 'count' => $count,
+ 'prevPage' => ($page > 1),
+ 'nextPage' => ($count > ($page * $limit)),
+ 'pageCount' => $pageCount,
+ 'order' => $order,
+ 'limit' => $limit,
+ 'options' => Hash::diff($options, $defaults),
+ 'paramType' => $options['paramType']
+ );
+ if (!isset($this->Controller->request['paging'])) {
+ $this->Controller->request['paging'] = array();
+ }
+ $this->Controller->request['paging'] = array_merge(
+ (array)$this->Controller->request['paging'],
+ array($object->alias => $paging)
+ );
+
+ if (
+ !in_array('Paginator', $this->Controller->helpers) &&
+ !array_key_exists('Paginator', $this->Controller->helpers)
+ ) {
+ $this->Controller->helpers[] = 'Paginator';
+ }
+ return $results;
+ }
+
+/**
+ * Get the object pagination will occur on.
+ *
+ * @param string|Model $object The object you are looking for.
+ * @return mixed The model object to paginate on.
+ */
+ protected function _getObject($object) {
+ if (is_string($object)) {
+ $assoc = null;
+ if (strpos($object, '.') !== false) {
+ list($object, $assoc) = pluginSplit($object);
+ }
+
+ if ($assoc && isset($this->Controller->{$object}->{$assoc})) {
+ $object = $this->Controller->{$object}->{$assoc};
+ } elseif (
+ $assoc && isset($this->Controller->{$this->Controller->modelClass}) &&
+ isset($this->Controller->{$this->Controller->modelClass}->{$assoc}
+ )) {
+ $object = $this->Controller->{$this->Controller->modelClass}->{$assoc};
+ } elseif (isset($this->Controller->{$object})) {
+ $object = $this->Controller->{$object};
+ } elseif (
+ isset($this->Controller->{$this->Controller->modelClass}) && isset($this->Controller->{$this->Controller->modelClass}->{$object}
+ )) {
+ $object = $this->Controller->{$this->Controller->modelClass}->{$object};
+ }
+ } elseif (empty($object) || $object === null) {
+ if (isset($this->Controller->{$this->Controller->modelClass})) {
+ $object = $this->Controller->{$this->Controller->modelClass};
+ } else {
+ $className = null;
+ $name = $this->Controller->uses[0];
+ if (strpos($this->Controller->uses[0], '.') !== false) {
+ list($name, $className) = explode('.', $this->Controller->uses[0]);
+ }
+ if ($className) {
+ $object = $this->Controller->{$className};
+ } else {
+ $object = $this->Controller->{$name};
+ }
+ }
+ }
+ return $object;
+ }
+
+/**
+ * Merges the various options that Pagination uses.
+ * Pulls settings together from the following places:
+ *
+ * - General pagination settings
+ * - Model specific settings.
+ * - Request parameters
+ *
+ * The result of this method is the aggregate of all the option sets combined together. You can change
+ * PaginatorComponent::$whitelist to modify which options/values can be set using request parameters.
+ *
+ * @param string $alias Model alias being paginated, if the general settings has a key with this value
+ * that key's settings will be used for pagination instead of the general ones.
+ * @return array Array of merged options.
+ */
+ public function mergeOptions($alias) {
+ $defaults = $this->getDefaults($alias);
+ switch ($defaults['paramType']) {
+ case 'named':
+ $request = $this->Controller->request->params['named'];
+ break;
+ case 'querystring':
+ $request = $this->Controller->request->query;
+ break;
+ }
+ $request = array_intersect_key($request, array_flip($this->whitelist));
+ return array_merge($defaults, $request);
+ }
+
+/**
+ * Get the default settings for a $model. If there are no settings for a specific model, the general settings
+ * will be used.
+ *
+ * @param string $alias Model name to get default settings for.
+ * @return array An array of pagination defaults for a model, or the general settings.
+ */
+ public function getDefaults($alias) {
+ if (isset($this->settings[$alias])) {
+ $defaults = $this->settings[$alias];
+ } else {
+ $defaults = $this->settings;
+ }
+ return array_merge(
+ array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named'),
+ $defaults
+ );
+ }
+
+/**
+ * Validate that the desired sorting can be performed on the $object. Only fields or
+ * virtualFields can be sorted on. The direction param will also be sanitized. Lastly
+ * sort + direction keys will be converted into the model friendly order key.
+ *
+ * You can use the whitelist parameter to control which columns/fields are available for sorting.
+ * This helps prevent users from ordering large result sets on un-indexed values.
+ *
+ * @param Model $object The model being paginated.
+ * @param array $options The pagination options being used for this request.
+ * @param array $whitelist The list of columns that can be used for sorting. If empty all keys are allowed.
+ * @return array An array of options with sort + direction removed and replaced with order if possible.
+ */
+ public function validateSort($object, $options, $whitelist = array()) {
+ if (isset($options['sort'])) {
+ $direction = null;
+ if (isset($options['direction'])) {
+ $direction = strtolower($options['direction']);
+ }
+ if ($direction != 'asc' && $direction != 'desc') {
+ $direction = 'asc';
+ }
+ $options['order'] = array($options['sort'] => $direction);
+ }
+
+ if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
+ $field = key($options['order']);
+ if (!in_array($field, $whitelist)) {
+ $options['order'] = null;
+ }
+ }
+
+ if (!empty($options['order']) && is_array($options['order'])) {
+ $order = array();
+ foreach ($options['order'] as $key => $value) {
+ $field = $key;
+ $alias = $object->alias;
+ if (strpos($key, '.') !== false) {
+ list($alias, $field) = explode('.', $key);
+ }
+
+ if ($object->hasField($field)) {
+ $order[$alias . '.' . $field] = $value;
+ } elseif ($object->hasField($key, true)) {
+ $order[$field] = $value;
+ } elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
+ $order[$alias . '.' . $field] = $value;
+ }
+ }
+ $options['order'] = $order;
+ }
+
+ return $options;
+ }
+
+/**
+ * Check the limit parameter and ensure its within the maxLimit bounds.
+ *
+ * @param array $options An array of options with a limit key to be checked.
+ * @return array An array of options for pagination
+ */
+ public function checkLimit($options) {
+ $options['limit'] = (int)$options['limit'];
+ if (empty($options['limit']) || $options['limit'] < 1) {
+ $options['limit'] = 1;
+ }
+ $options['limit'] = min($options['limit'], $options['maxLimit']);
+ return $options;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php
new file mode 100644
index 0000000..544e01c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/RequestHandlerComponent.php
@@ -0,0 +1,730 @@
+<?php
+/**
+ * Request object for handling alternative HTTP requests
+ *
+ * Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers,
+ * and the like. These units have no use for Ajax requests, and this Component can tell how Cake
+ * should respond to the different needs of a handheld computer and a desktop machine.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.4.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Xml', 'Utility');
+
+/**
+ * Request object for handling alternative HTTP requests
+ *
+ * Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers,
+ * and the like. These units have no use for Ajax requests, and this Component can tell how Cake
+ * should respond to the different needs of a handheld computer and a desktop machine.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/request-handling.html
+ *
+ */
+class RequestHandlerComponent extends Component {
+
+/**
+ * The layout that will be switched to for Ajax requests
+ *
+ * @var string
+ * @see RequestHandler::setAjax()
+ */
+ public $ajaxLayout = 'ajax';
+
+/**
+ * Determines whether or not callbacks will be fired on this component
+ *
+ * @var boolean
+ */
+ public $enabled = true;
+
+/**
+ * Holds the reference to Controller::$request
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Holds the reference to Controller::$response
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * Contains the file extension parsed out by the Router
+ *
+ * @var string
+ * @see Router::parseExtensions()
+ */
+ public $ext = null;
+
+/**
+ * The template to use when rendering the given content type.
+ *
+ * @var string
+ */
+ protected $_renderType = null;
+
+/**
+ * A mapping between extensions and deserializers for request bodies of that type.
+ * By default only JSON and XML are mapped, use RequestHandlerComponent::addInputType()
+ *
+ * @var array
+ */
+ protected $_inputTypeMap = array(
+ 'json' => array('json_decode', true)
+ );
+
+/**
+ * Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT
+ *
+ * @param ComponentCollection $collection ComponentCollection object.
+ * @param array $settings Array of settings.
+ */
+ public function __construct(ComponentCollection $collection, $settings = array()) {
+ $default = array('checkHttpCache' => true);
+ parent::__construct($collection, $settings + $default);
+ $this->addInputType('xml', array(array($this, 'convertXml')));
+
+ $Controller = $collection->getController();
+ $this->request = $Controller->request;
+ $this->response = $Controller->response;
+ }
+
+/**
+ * Checks to see if a file extension has been parsed by the Router, or if the
+ * HTTP_ACCEPT_TYPE has matches only one content type with the supported extensions.
+ * If there is only one matching type between the supported content types & extensions,
+ * and the requested mime-types, RequestHandler::$ext is set to that value.
+ *
+ * @param Controller $controller A reference to the controller
+ * @param array $settings Array of settings to _set().
+ * @return void
+ * @see Router::parseExtensions()
+ */
+ public function initialize(Controller $controller, $settings = array()) {
+ if (isset($this->request->params['ext'])) {
+ $this->ext = $this->request->params['ext'];
+ }
+ if (empty($this->ext) || $this->ext == 'html') {
+ $this->_setExtension();
+ }
+ $this->params = $controller->params;
+ $this->_set($settings);
+ }
+
+/**
+ * Set the extension based on the accept headers.
+ * Compares the accepted types and configured extensions.
+ * If there is one common type, that is assigned as the ext/content type
+ * for the response.
+ *
+ * If html is one of the preferred types, no content type will be set, this
+ * is to avoid issues with browsers that prefer html and several other content types.
+ *
+ * @return void
+ */
+ protected function _setExtension() {
+ $accept = $this->request->parseAccept();
+ if (empty($accept)) {
+ return;
+ }
+ $extensions = Router::extensions();
+ $preferred = array_shift($accept);
+ $preferredTypes = $this->response->mapType($preferred);
+ $similarTypes = array_intersect($extensions, $preferredTypes);
+ if (count($similarTypes) === 1 && !in_array('xhtml', $preferredTypes) && !in_array('html', $preferredTypes)) {
+ $this->ext = array_shift($similarTypes);
+ }
+ }
+
+/**
+ * The startup method of the RequestHandler enables several automatic behaviors
+ * related to the detection of certain properties of the HTTP request, including:
+ *
+ * - Disabling layout rendering for Ajax requests (based on the HTTP_X_REQUESTED_WITH header)
+ * - If Router::parseExtensions() is enabled, the layout and template type are
+ * switched based on the parsed extension or Accept-Type header. For example, if `controller/action.xml`
+ * is requested, the view path becomes `app/View/Controller/xml/action.ctp`. Also if
+ * `controller/action` is requested with `Accept-Type: application/xml` in the headers
+ * the view path will become `app/View/Controller/xml/action.ctp`. Layout and template
+ * types will only switch to mime-types recognized by CakeResponse. If you need to declare
+ * additional mime-types, you can do so using CakeResponse::type() in your controllers beforeFilter()
+ * method.
+ * - If a helper with the same name as the extension exists, it is added to the controller.
+ * - If the extension is of a type that RequestHandler understands, it will set that
+ * Content-type in the response header.
+ * - If the XML data is POSTed, the data is parsed into an XML object, which is assigned
+ * to the $data property of the controller, which can then be saved to a model object.
+ *
+ * @param Controller $controller A reference to the controller
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ $controller->request->params['isAjax'] = $this->request->is('ajax');
+ $isRecognized = (
+ !in_array($this->ext, array('html', 'htm')) &&
+ $this->response->getMimeType($this->ext)
+ );
+
+ if (!empty($this->ext) && $isRecognized) {
+ $this->renderAs($controller, $this->ext);
+ } elseif ($this->request->is('ajax')) {
+ $this->renderAs($controller, 'ajax');
+ } elseif (empty($this->ext) || in_array($this->ext, array('html', 'htm'))) {
+ $this->respondAs('html', array('charset' => Configure::read('App.encoding')));
+ }
+
+ foreach ($this->_inputTypeMap as $type => $handler) {
+ if ($this->requestedWith($type)) {
+ $input = call_user_func_array(array($controller->request, 'input'), $handler);
+ $controller->request->data = $input;
+ }
+ }
+ }
+
+/**
+ * Helper method to parse xml input data, due to lack of anonymous functions
+ * this lives here.
+ *
+ * @param string $xml
+ * @return array Xml array data
+ */
+ public function convertXml($xml) {
+ try {
+ $xml = Xml::build($xml);
+ if (isset($xml->data)) {
+ return Xml::toArray($xml->data);
+ }
+ return Xml::toArray($xml);
+ } catch (XmlException $e) {
+ return array();
+ }
+ }
+
+/**
+ * Handles (fakes) redirects for Ajax requests using requestAction()
+ *
+ * @param Controller $controller A reference to the controller
+ * @param string|array $url A string or array containing the redirect location
+ * @param integer|array $status HTTP Status for redirect
+ * @param boolean $exit
+ * @return void
+ */
+ public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
+ if (!$this->request->is('ajax')) {
+ return;
+ }
+ foreach ($_POST as $key => $val) {
+ unset($_POST[$key]);
+ }
+ if (is_array($url)) {
+ $url = Router::url($url + array('base' => false));
+ }
+ if (!empty($status)) {
+ $statusCode = $this->response->httpCodes($status);
+ $code = key($statusCode);
+ $this->response->statusCode($code);
+ }
+ $this->response->body($this->requestAction($url, array('return', 'bare' => false)));
+ $this->response->send();
+ $this->_stop();
+ }
+
+/**
+ * Checks if the response can be considered different according to the request
+ * headers, and the caching response headers. If it was not modified, then the
+ * render process is skipped. And the client will get a blank response with a
+ * "304 Not Modified" header.
+ *
+ * @params Controller $controller
+ * @return boolean false if the render process should be aborted
+ **/
+ public function beforeRender(Controller $controller) {
+ $shouldCheck = $this->settings['checkHttpCache'];
+ if ($shouldCheck && $this->response->checkNotModified($this->request)) {
+ return false;
+ }
+ }
+
+/**
+ * Returns true if the current HTTP request is Ajax, false otherwise
+ *
+ * @return boolean True if call is Ajax
+ * @deprecated use `$this->request->is('ajax')` instead.
+ */
+ public function isAjax() {
+ return $this->request->is('ajax');
+ }
+
+/**
+ * Returns true if the current HTTP request is coming from a Flash-based client
+ *
+ * @return boolean True if call is from Flash
+ * @deprecated use `$this->request->is('flash')` instead.
+ */
+ public function isFlash() {
+ return $this->request->is('flash');
+ }
+
+/**
+ * Returns true if the current request is over HTTPS, false otherwise.
+ *
+ * @return boolean True if call is over HTTPS
+ * @deprecated use `$this->request->is('ssl')` instead.
+ */
+ public function isSSL() {
+ return $this->request->is('ssl');
+ }
+
+/**
+ * Returns true if the current call accepts an XML response, false otherwise
+ *
+ * @return boolean True if client accepts an XML response
+ */
+ public function isXml() {
+ return $this->prefers('xml');
+ }
+
+/**
+ * Returns true if the current call accepts an RSS response, false otherwise
+ *
+ * @return boolean True if client accepts an RSS response
+ */
+ public function isRss() {
+ return $this->prefers('rss');
+ }
+
+/**
+ * Returns true if the current call accepts an Atom response, false otherwise
+ *
+ * @return boolean True if client accepts an RSS response
+ */
+ public function isAtom() {
+ return $this->prefers('atom');
+ }
+
+/**
+ * Returns true if user agent string matches a mobile web browser, or if the
+ * client accepts WAP content.
+ *
+ * @return boolean True if user agent is a mobile web browser
+ */
+ public function isMobile() {
+ return $this->request->is('mobile') || $this->accepts('wap');
+ }
+
+/**
+ * Returns true if the client accepts WAP content
+ *
+ * @return boolean
+ */
+ public function isWap() {
+ return $this->prefers('wap');
+ }
+
+/**
+ * Returns true if the current call a POST request
+ *
+ * @return boolean True if call is a POST
+ * @deprecated Use $this->request->is('post'); from your controller.
+ */
+ public function isPost() {
+ return $this->request->is('post');
+ }
+
+/**
+ * Returns true if the current call a PUT request
+ *
+ * @return boolean True if call is a PUT
+ * @deprecated Use $this->request->is('put'); from your controller.
+ */
+ public function isPut() {
+ return $this->request->is('put');
+ }
+
+/**
+ * Returns true if the current call a GET request
+ *
+ * @return boolean True if call is a GET
+ * @deprecated Use $this->request->is('get'); from your controller.
+ */
+ public function isGet() {
+ return $this->request->is('get');
+ }
+
+/**
+ * Returns true if the current call a DELETE request
+ *
+ * @return boolean True if call is a DELETE
+ * @deprecated Use $this->request->is('delete'); from your controller.
+ */
+ public function isDelete() {
+ return $this->request->is('delete');
+ }
+
+/**
+ * Gets Prototype version if call is Ajax, otherwise empty string.
+ * The Prototype library sets a special "Prototype version" HTTP header.
+ *
+ * @return string Prototype version of component making Ajax call
+ */
+ public function getAjaxVersion() {
+ if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
+ return env('HTTP_X_PROTOTYPE_VERSION');
+ }
+ return false;
+ }
+
+/**
+ * Adds/sets the Content-type(s) for the given name. This method allows
+ * content-types to be mapped to friendly aliases (or extensions), which allows
+ * RequestHandler to automatically respond to requests of that type in the
+ * startup method.
+ *
+ * @param string $name The name of the Content-type, i.e. "html", "xml", "css"
+ * @param string|array $type The Content-type or array of Content-types assigned to the name,
+ * i.e. "text/html", or "application/xml"
+ * @return void
+ * @deprecated use `$this->response->type()` instead.
+ */
+ public function setContent($name, $type = null) {
+ $this->response->type(array($name => $type));
+ }
+
+/**
+ * Gets the server name from which this request was referred
+ *
+ * @return string Server address
+ * @deprecated use $this->request->referer() from your controller instead
+ */
+ public function getReferer() {
+ return $this->request->referer(false);
+ }
+
+/**
+ * Gets remote client IP
+ *
+ * @param boolean $safe
+ * @return string Client IP address
+ * @deprecated use $this->request->clientIp() from your, controller instead.
+ */
+ public function getClientIP($safe = true) {
+ return $this->request->clientIp($safe);
+ }
+
+/**
+ * Determines which content types the client accepts. Acceptance is based on
+ * the file extension parsed by the Router (if present), and by the HTTP_ACCEPT
+ * header. Unlike CakeRequest::accepts() this method deals entirely with mapped content types.
+ *
+ * Usage:
+ *
+ * `$this->RequestHandler->accepts(array('xml', 'html', 'json'));`
+ *
+ * Returns true if the client accepts any of the supplied types.
+ *
+ * `$this->RequestHandler->accepts('xml');`
+ *
+ * Returns true if the client accepts xml.
+ *
+ * @param string|array $type Can be null (or no parameter), a string type name, or an
+ * array of types
+ * @return mixed If null or no parameter is passed, returns an array of content
+ * types the client accepts. If a string is passed, returns true
+ * if the client accepts it. If an array is passed, returns true
+ * if the client accepts one or more elements in the array.
+ * @see RequestHandlerComponent::setContent()
+ */
+ public function accepts($type = null) {
+ $accepted = $this->request->accepts();
+
+ if ($type == null) {
+ return $this->mapType($accepted);
+ } elseif (is_array($type)) {
+ foreach ($type as $t) {
+ $t = $this->mapAlias($t);
+ if (in_array($t, $accepted)) {
+ return true;
+ }
+ }
+ return false;
+ } elseif (is_string($type)) {
+ $type = $this->mapAlias($type);
+ return in_array($type, $accepted);
+ }
+ return false;
+ }
+
+/**
+ * Determines the content type of the data the client has sent (i.e. in a POST request)
+ *
+ * @param string|array $type Can be null (or no parameter), a string type name, or an array of types
+ * @return mixed If a single type is supplied a boolean will be returned. If no type is provided
+ * The mapped value of CONTENT_TYPE will be returned. If an array is supplied the first type
+ * in the request content type will be returned.
+ */
+ public function requestedWith($type = null) {
+ if (!$this->request->is('post') && !$this->request->is('put')) {
+ return null;
+ }
+
+ list($contentType) = explode(';', env('CONTENT_TYPE'));
+ if ($type == null) {
+ return $this->mapType($contentType);
+ } elseif (is_array($type)) {
+ foreach ($type as $t) {
+ if ($this->requestedWith($t)) {
+ return $t;
+ }
+ }
+ return false;
+ } elseif (is_string($type)) {
+ return ($type == $this->mapType($contentType));
+ }
+ }
+
+/**
+ * Determines which content-types the client prefers. If no parameters are given,
+ * the single content-type that the client most likely prefers is returned. If $type is
+ * an array, the first item in the array that the client accepts is returned.
+ * Preference is determined primarily by the file extension parsed by the Router
+ * if provided, and secondarily by the list of content-types provided in
+ * HTTP_ACCEPT.
+ *
+ * @param string|array $type An optional array of 'friendly' content-type names, i.e.
+ * 'html', 'xml', 'js', etc.
+ * @return mixed If $type is null or not provided, the first content-type in the
+ * list, based on preference, is returned. If a single type is provided
+ * a boolean will be returned if that type is preferred.
+ * If an array of types are provided then the first preferred type is returned.
+ * If no type is provided the first preferred type is returned.
+ * @see RequestHandlerComponent::setContent()
+ */
+ public function prefers($type = null) {
+ $acceptRaw = $this->request->parseAccept();
+
+ if (empty($acceptRaw)) {
+ return $this->ext;
+ }
+ $accepts = array_shift($acceptRaw);
+ $accepts = $this->mapType($accepts);
+
+ if ($type == null) {
+ if (empty($this->ext) && !empty($accepts)) {
+ return $accepts[0];
+ }
+ return $this->ext;
+ }
+
+ $types = (array)$type;
+
+ if (count($types) === 1) {
+ if (!empty($this->ext)) {
+ return in_array($this->ext, $types);
+ }
+ return in_array($types[0], $accepts);
+ }
+
+ $intersect = array_values(array_intersect($accepts, $types));
+ if (empty($intersect)) {
+ return false;
+ }
+ return $intersect[0];
+ }
+
+/**
+ * Sets the layout and template paths for the content type defined by $type.
+ *
+ * ### Usage:
+ *
+ * Render the response as an 'ajax' response.
+ *
+ * `$this->RequestHandler->renderAs($this, 'ajax');`
+ *
+ * Render the response as an xml file and force the result as a file download.
+ *
+ * `$this->RequestHandler->renderAs($this, 'xml', array('attachment' => 'myfile.xml');`
+ *
+ * @param Controller $controller A reference to a controller object
+ * @param string $type Type of response to send (e.g: 'ajax')
+ * @param array $options Array of options to use
+ * @return void
+ * @see RequestHandlerComponent::setContent()
+ * @see RequestHandlerComponent::respondAs()
+ */
+ public function renderAs(Controller $controller, $type, $options = array()) {
+ $defaults = array('charset' => 'UTF-8');
+
+ if (Configure::read('App.encoding') !== null) {
+ $defaults['charset'] = Configure::read('App.encoding');
+ }
+ $options = array_merge($defaults, $options);
+
+ if ($type == 'ajax') {
+ $controller->layout = $this->ajaxLayout;
+ return $this->respondAs('html', $options);
+ }
+ $controller->ext = '.ctp';
+
+ $viewClass = Inflector::classify($type);
+ $viewName = $viewClass . 'View';
+ if (!class_exists($viewName)) {
+ App::uses($viewName, 'View');
+ }
+ if (class_exists($viewName)) {
+ $controller->viewClass = $viewClass;
+ } elseif (empty($this->_renderType)) {
+ $controller->viewPath .= DS . $type;
+ } else {
+ $remove = preg_replace("/([\/\\\\]{$this->_renderType})$/", DS . $type, $controller->viewPath);
+ $controller->viewPath = $remove;
+ }
+ $this->_renderType = $type;
+ $controller->layoutPath = $type;
+
+ if ($this->response->getMimeType($type)) {
+ $this->respondAs($type, $options);
+ }
+
+ $helper = ucfirst($type);
+ $isAdded = (
+ in_array($helper, $controller->helpers) ||
+ array_key_exists($helper, $controller->helpers)
+ );
+
+ if (!$isAdded) {
+ App::uses('AppHelper', 'View/Helper');
+ App::uses($helper . 'Helper', 'View/Helper');
+ if (class_exists($helper . 'Helper')) {
+ $controller->helpers[] = $helper;
+ }
+ }
+ }
+
+/**
+ * Sets the response header based on type map index name. This wraps several methods
+ * available on CakeResponse. It also allows you to use Content-Type aliases.
+ *
+ * @param string|array $type Friendly type name, i.e. 'html' or 'xml', or a full content-type,
+ * like 'application/x-shockwave'.
+ * @param array $options If $type is a friendly type name that is associated with
+ * more than one type of content, $index is used to select which content-type to use.
+ * @return boolean Returns false if the friendly type name given in $type does
+ * not exist in the type map, or if the Content-type header has
+ * already been set by this method.
+ * @see RequestHandlerComponent::setContent()
+ */
+ public function respondAs($type, $options = array()) {
+ $defaults = array('index' => null, 'charset' => null, 'attachment' => false);
+ $options = $options + $defaults;
+
+ if (strpos($type, '/') === false) {
+ $cType = $this->response->getMimeType($type);
+ if ($cType === false) {
+ return false;
+ }
+ if (is_array($cType) && isset($cType[$options['index']])) {
+ $cType = $cType[$options['index']];
+ }
+ if (is_array($cType)) {
+ if ($this->prefers($cType)) {
+ $cType = $this->prefers($cType);
+ } else {
+ $cType = $cType[0];
+ }
+ }
+ } else {
+ $cType = $type;
+ }
+
+ if ($cType != null) {
+ if (empty($this->request->params['requested'])) {
+ $this->response->type($cType);
+ }
+
+ if (!empty($options['charset'])) {
+ $this->response->charset($options['charset']);
+ }
+ if (!empty($options['attachment'])) {
+ $this->response->download($options['attachment']);
+ }
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Returns the current response type (Content-type header), or null if not alias exists
+ *
+ * @return mixed A string content type alias, or raw content type if no alias map exists,
+ * otherwise null
+ */
+ public function responseType() {
+ return $this->mapType($this->response->type());
+ }
+
+/**
+ * Maps a content-type back to an alias
+ *
+ * @param string|array $cType Either a string content type to map, or an array of types.
+ * @return string|array Aliases for the types provided.
+ * @deprecated Use $this->response->mapType() in your controller instead.
+ */
+ public function mapType($cType) {
+ return $this->response->mapType($cType);
+ }
+
+/**
+ * Maps a content type alias back to its mime-type(s)
+ *
+ * @param string|array $alias String alias to convert back into a content type. Or an array of aliases to map.
+ * @return string Null on an undefined alias. String value of the mapped alias type. If an
+ * alias maps to more than one content type, the first one will be returned.
+ */
+ public function mapAlias($alias) {
+ if (is_array($alias)) {
+ return array_map(array($this, 'mapAlias'), $alias);
+ }
+ $type = $this->response->getMimeType($alias);
+ if ($type) {
+ if (is_array($type)) {
+ return $type[0];
+ }
+ return $type;
+ }
+ return null;
+ }
+
+/**
+ * Add a new mapped input type. Mapped input types are automatically
+ * converted by RequestHandlerComponent during the startup() callback.
+ *
+ * @param string $type The type alias being converted, ie. json
+ * @param array $handler The handler array for the type. The first index should
+ * be the handling callback, all other arguments should be additional parameters
+ * for the handler.
+ * @return void
+ * @throws CakeException
+ */
+ public function addInputType($type, $handler) {
+ if (!is_array($handler) || !isset($handler[0]) || !is_callable($handler[0])) {
+ throw new CakeException(__d('cake_dev', 'You must give a handler callback.'));
+ }
+ $this->_inputTypeMap[$type] = $handler;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php
new file mode 100644
index 0000000..3b5eb86
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SecurityComponent.php
@@ -0,0 +1,598 @@
+<?php
+/**
+ * Security Component
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.8.2156
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('String', 'Utility');
+App::uses('Hash', 'Utility');
+App::uses('Security', 'Utility');
+
+/**
+ * The Security Component creates an easy way to integrate tighter security in
+ * your application. It provides methods for various tasks like:
+ *
+ * - Restricting which HTTP methods your application accepts.
+ * - CSRF protection.
+ * - Form tampering protection
+ * - Requiring that SSL be used.
+ * - Limiting cross controller communication.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html
+ */
+class SecurityComponent extends Component {
+
+/**
+ * The controller method that will be called if this request is black-hole'd
+ *
+ * @var string
+ */
+ public $blackHoleCallback = null;
+
+/**
+ * List of controller actions for which a POST request is required
+ *
+ * @var array
+ * @see SecurityComponent::requirePost()
+ */
+ public $requirePost = array();
+
+/**
+ * List of controller actions for which a GET request is required
+ *
+ * @var array
+ * @see SecurityComponent::requireGet()
+ */
+ public $requireGet = array();
+
+/**
+ * List of controller actions for which a PUT request is required
+ *
+ * @var array
+ * @see SecurityComponent::requirePut()
+ */
+ public $requirePut = array();
+
+/**
+ * List of controller actions for which a DELETE request is required
+ *
+ * @var array
+ * @see SecurityComponent::requireDelete()
+ */
+ public $requireDelete = array();
+
+/**
+ * List of actions that require an SSL-secured connection
+ *
+ * @var array
+ * @see SecurityComponent::requireSecure()
+ */
+ public $requireSecure = array();
+
+/**
+ * List of actions that require a valid authentication key
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ public $requireAuth = array();
+
+/**
+ * Controllers from which actions of the current controller are allowed to receive
+ * requests.
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ public $allowedControllers = array();
+
+/**
+ * Actions from which actions of the current controller are allowed to receive
+ * requests.
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ public $allowedActions = array();
+
+/**
+ * Deprecated property, superseded by unlockedFields.
+ *
+ * @var array
+ * @deprecated
+ * @see SecurityComponent::$unlockedFields
+ */
+ public $disabledFields = array();
+
+/**
+ * Form fields to exclude from POST validation. Fields can be unlocked
+ * either in the Component, or with FormHelper::unlockField().
+ * Fields that have been unlocked are not required to be part of the POST
+ * and hidden unlocked fields do not have their values checked.
+ *
+ * @var array
+ */
+ public $unlockedFields = array();
+
+/**
+ * Whether to validate POST data. Set to false to disable for data coming from 3rd party
+ * services, etc.
+ *
+ * @var boolean
+ */
+ public $validatePost = true;
+
+/**
+ * Whether to use CSRF protected forms. Set to false to disable CSRF protection on forms.
+ *
+ * @var boolean
+ * @see http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
+ * @see SecurityComponent::$csrfExpires
+ */
+ public $csrfCheck = true;
+
+/**
+ * The duration from when a CSRF token is created that it will expire on.
+ * Each form/page request will generate a new token that can only be submitted once unless
+ * it expires. Can be any value compatible with strtotime()
+ *
+ * @var string
+ */
+ public $csrfExpires = '+30 minutes';
+
+/**
+ * Controls whether or not CSRF tokens are use and burn. Set to false to not generate
+ * new tokens on each request. One token will be reused until it expires. This reduces
+ * the chances of users getting invalid requests because of token consumption.
+ * It has the side effect of making CSRF less secure, as tokens are reusable.
+ *
+ * @var boolean
+ */
+ public $csrfUseOnce = true;
+
+/**
+ * Control the number of tokens a user can keep open.
+ * This is most useful with one-time use tokens. Since new tokens
+ * are created on each request, having a hard limit on the number of open tokens
+ * can be useful in controlling the size of the session file.
+ *
+ * When tokens are evicted, the oldest ones will be removed, as they are the most likely
+ * to be dead/expired.
+ *
+ * @var integer
+ */
+ public $csrfLimit = 100;
+
+/**
+ * Other components used by the Security component
+ *
+ * @var array
+ */
+ public $components = array('Session');
+
+/**
+ * Holds the current action of the controller
+ *
+ * @var string
+ */
+ protected $_action = null;
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Component startup. All security checking happens here.
+ *
+ * @param Controller $controller Instantiating controller
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ $this->request = $controller->request;
+ $this->_action = $this->request->params['action'];
+ $this->_methodsRequired($controller);
+ $this->_secureRequired($controller);
+ $this->_authRequired($controller);
+
+ $isPost = ($this->request->is('post') || $this->request->is('put'));
+ $isNotRequestAction = (
+ !isset($controller->request->params['requested']) ||
+ $controller->request->params['requested'] != 1
+ );
+
+ if ($isPost && $isNotRequestAction && $this->validatePost) {
+ if ($this->_validatePost($controller) === false) {
+ return $this->blackHole($controller, 'auth');
+ }
+ }
+ if ($isPost && $isNotRequestAction && $this->csrfCheck) {
+ if ($this->_validateCsrf($controller) === false) {
+ return $this->blackHole($controller, 'csrf');
+ }
+ }
+ $this->generateToken($controller->request);
+ if ($isPost && is_array($controller->request->data)) {
+ unset($controller->request->data['_Token']);
+ }
+ }
+
+/**
+ * Sets the actions that require a POST request, or empty for all actions
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requirePost
+ */
+ public function requirePost() {
+ $args = func_get_args();
+ $this->_requireMethod('Post', $args);
+ }
+
+/**
+ * Sets the actions that require a GET request, or empty for all actions
+ *
+ * @return void
+ */
+ public function requireGet() {
+ $args = func_get_args();
+ $this->_requireMethod('Get', $args);
+ }
+
+/**
+ * Sets the actions that require a PUT request, or empty for all actions
+ *
+ * @return void
+ */
+ public function requirePut() {
+ $args = func_get_args();
+ $this->_requireMethod('Put', $args);
+ }
+
+/**
+ * Sets the actions that require a DELETE request, or empty for all actions
+ *
+ * @return void
+ */
+ public function requireDelete() {
+ $args = func_get_args();
+ $this->_requireMethod('Delete', $args);
+ }
+
+/**
+ * Sets the actions that require a request that is SSL-secured, or empty for all actions
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requireSecure
+ */
+ public function requireSecure() {
+ $args = func_get_args();
+ $this->_requireMethod('Secure', $args);
+ }
+
+/**
+ * Sets the actions that require an authenticated request, or empty for all actions
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::requireAuth
+ */
+ public function requireAuth() {
+ $args = func_get_args();
+ $this->_requireMethod('Auth', $args);
+ }
+
+/**
+ * Black-hole an invalid request with a 400 error or custom callback. If SecurityComponent::$blackHoleCallback
+ * is specified, it will use this callback by executing the method indicated in $error
+ *
+ * @param Controller $controller Instantiating controller
+ * @param string $error Error method
+ * @return mixed If specified, controller blackHoleCallback's response, or no return otherwise
+ * @see SecurityComponent::$blackHoleCallback
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#handling-blackhole-callbacks
+ * @throws BadRequestException
+ */
+ public function blackHole(Controller $controller, $error = '') {
+ if ($this->blackHoleCallback == null) {
+ throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
+ } else {
+ return $this->_callback($controller, $this->blackHoleCallback, array($error));
+ }
+ }
+
+/**
+ * Sets the actions that require a $method HTTP request, or empty for all actions
+ *
+ * @param string $method The HTTP method to assign controller actions to
+ * @param array $actions Controller actions to set the required HTTP method to.
+ * @return void
+ */
+ protected function _requireMethod($method, $actions = array()) {
+ if (isset($actions[0]) && is_array($actions[0])) {
+ $actions = $actions[0];
+ }
+ $this->{'require' . $method} = (empty($actions)) ? array('*'): $actions;
+ }
+
+/**
+ * Check if HTTP methods are required
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if $method is required
+ */
+ protected function _methodsRequired(Controller $controller) {
+ foreach (array('Post', 'Get', 'Put', 'Delete') as $method) {
+ $property = 'require' . $method;
+ if (is_array($this->$property) && !empty($this->$property)) {
+ $require = $this->$property;
+ if (in_array($this->_action, $require) || $this->$property == array('*')) {
+ if (!$this->request->is($method)) {
+ if (!$this->blackHole($controller, $method)) {
+ return null;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Check if access requires secure connection
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if secure connection required
+ */
+ protected function _secureRequired(Controller $controller) {
+ if (is_array($this->requireSecure) && !empty($this->requireSecure)) {
+ $requireSecure = $this->requireSecure;
+
+ if (in_array($this->_action, $requireSecure) || $this->requireSecure == array('*')) {
+ if (!$this->request->is('ssl')) {
+ if (!$this->blackHole($controller, 'secure')) {
+ return null;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Check if authentication is required
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if authentication required
+ */
+ protected function _authRequired(Controller $controller) {
+ if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($this->request->data)) {
+ $requireAuth = $this->requireAuth;
+
+ if (in_array($this->request->params['action'], $requireAuth) || $this->requireAuth == array('*')) {
+ if (!isset($controller->request->data['_Token'] )) {
+ if (!$this->blackHole($controller, 'auth')) {
+ return null;
+ }
+ }
+
+ if ($this->Session->check('_Token')) {
+ $tData = $this->Session->read('_Token');
+
+ if (
+ !empty($tData['allowedControllers']) &&
+ !in_array($this->request->params['controller'], $tData['allowedControllers']) ||
+ !empty($tData['allowedActions']) &&
+ !in_array($this->request->params['action'], $tData['allowedActions'])
+ ) {
+ if (!$this->blackHole($controller, 'auth')) {
+ return null;
+ }
+ }
+ } else {
+ if (!$this->blackHole($controller, 'auth')) {
+ return null;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Validate submitted form
+ *
+ * @param Controller $controller Instantiating controller
+ * @return boolean true if submitted form is valid
+ */
+ protected function _validatePost(Controller $controller) {
+ if (empty($controller->request->data)) {
+ return true;
+ }
+ $data = $controller->request->data;
+
+ if (!isset($data['_Token']) || !isset($data['_Token']['fields']) || !isset($data['_Token']['unlocked'])) {
+ return false;
+ }
+
+ $locked = '';
+ $check = $controller->request->data;
+ $token = urldecode($check['_Token']['fields']);
+ $unlocked = urldecode($check['_Token']['unlocked']);
+
+ if (strpos($token, ':')) {
+ list($token, $locked) = explode(':', $token, 2);
+ }
+ unset($check['_Token']);
+
+ $locked = explode('|', $locked);
+ $unlocked = explode('|', $unlocked);
+
+ $lockedFields = array();
+ $fields = Hash::flatten($check);
+ $fieldList = array_keys($fields);
+ $multi = array();
+
+ foreach ($fieldList as $i => $key) {
+ if (preg_match('/(\.\d+)+$/', $key)) {
+ $multi[$i] = preg_replace('/(\.\d+)+$/', '', $key);
+ unset($fieldList[$i]);
+ }
+ }
+ if (!empty($multi)) {
+ $fieldList += array_unique($multi);
+ }
+
+ $unlockedFields = array_unique(
+ array_merge((array)$this->disabledFields, (array)$this->unlockedFields, $unlocked)
+ );
+
+ foreach ($fieldList as $i => $key) {
+ $isLocked = (is_array($locked) && in_array($key, $locked));
+
+ if (!empty($unlockedFields)) {
+ foreach ($unlockedFields as $off) {
+ $off = explode('.', $off);
+ $field = array_values(array_intersect(explode('.', $key), $off));
+ $isUnlocked = ($field === $off);
+ if ($isUnlocked) {
+ break;
+ }
+ }
+ }
+
+ if ($isUnlocked || $isLocked) {
+ unset($fieldList[$i]);
+ if ($isLocked) {
+ $lockedFields[$key] = $fields[$key];
+ }
+ }
+ }
+ sort($unlocked, SORT_STRING);
+ sort($fieldList, SORT_STRING);
+ ksort($lockedFields, SORT_STRING);
+
+ $fieldList += $lockedFields;
+ $unlocked = implode('|', $unlocked);
+ $check = Security::hash(serialize($fieldList) . $unlocked . Configure::read('Security.salt'));
+ return ($token === $check);
+ }
+
+/**
+ * Manually add CSRF token information into the provided request object.
+ *
+ * @param CakeRequest $request The request object to add into.
+ * @return boolean
+ */
+ public function generateToken(CakeRequest $request) {
+ if (isset($request->params['requested']) && $request->params['requested'] === 1) {
+ if ($this->Session->check('_Token')) {
+ $request->params['_Token'] = $this->Session->read('_Token');
+ }
+ return false;
+ }
+ $authKey = Security::generateAuthKey();
+ $token = array(
+ 'key' => $authKey,
+ 'allowedControllers' => $this->allowedControllers,
+ 'allowedActions' => $this->allowedActions,
+ 'unlockedFields' => array_merge($this->disabledFields, $this->unlockedFields),
+ 'csrfTokens' => array()
+ );
+
+ $tokenData = array();
+ if ($this->Session->check('_Token')) {
+ $tokenData = $this->Session->read('_Token');
+ if (!empty($tokenData['csrfTokens']) && is_array($tokenData['csrfTokens'])) {
+ $token['csrfTokens'] = $this->_expireTokens($tokenData['csrfTokens']);
+ }
+ }
+ if ($this->csrfUseOnce || empty($token['csrfTokens'])) {
+ $token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
+ }
+ if (!$this->csrfUseOnce) {
+ $csrfTokens = array_keys($token['csrfTokens']);
+ $token['key'] = $csrfTokens[0];
+ }
+ $this->Session->write('_Token', $token);
+ $request->params['_Token'] = array(
+ 'key' => $token['key'],
+ 'unlockedFields' => $token['unlockedFields']
+ );
+ return true;
+ }
+
+/**
+ * Validate that the controller has a CSRF token in the POST data
+ * and that the token is legit/not expired. If the token is valid
+ * it will be removed from the list of valid tokens.
+ *
+ * @param Controller $controller A controller to check
+ * @return boolean Valid csrf token.
+ */
+ protected function _validateCsrf(Controller $controller) {
+ $token = $this->Session->read('_Token');
+ $requestToken = $controller->request->data('_Token.key');
+ if (isset($token['csrfTokens'][$requestToken]) && $token['csrfTokens'][$requestToken] >= time()) {
+ if ($this->csrfUseOnce) {
+ $this->Session->delete('_Token.csrfTokens.' . $requestToken);
+ }
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Expire CSRF nonces and remove them from the valid tokens.
+ * Uses a simple timeout to expire the tokens.
+ *
+ * @param array $tokens An array of nonce => expires.
+ * @return array An array of nonce => expires.
+ */
+ protected function _expireTokens($tokens) {
+ $now = time();
+ foreach ($tokens as $nonce => $expires) {
+ if ($expires < $now) {
+ unset($tokens[$nonce]);
+ }
+ }
+ $overflow = count($tokens) - $this->csrfLimit;
+ if ($overflow > 0) {
+ $tokens = array_slice($tokens, $overflow + 1, null, true);
+ }
+ return $tokens;
+ }
+
+/**
+ * Calls a controller callback method
+ *
+ * @param Controller $controller Controller to run callback on
+ * @param string $method Method to execute
+ * @param array $params Parameters to send to method
+ * @return mixed Controller callback method's response
+ * @throws BadRequestException When a the blackholeCallback is not callable.
+ */
+ protected function _callback(Controller $controller, $method, $params = array()) {
+ if (is_callable(array($controller, $method))) {
+ return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
+ } else {
+ throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php
new file mode 100644
index 0000000..ed42bff
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Component/SessionComponent.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * SessionComponent. Provides access to Sessions from the Controller layer
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller.Component
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('CakeSession', 'Model/Datasource');
+
+/**
+ * The CakePHP SessionComponent provides a way to persist client data between
+ * page requests. It acts as a wrapper for the `$_SESSION` as well as providing
+ * convenience methods for several `$_SESSION` related functions.
+ *
+ * @package Cake.Controller.Component
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html
+ * @link http://book.cakephp.org/2.0/en/development/sessions.html
+ */
+class SessionComponent extends Component {
+
+/**
+ * Get / Set the userAgent
+ *
+ * @param string $userAgent Set the userAgent
+ * @return void
+ */
+ public function userAgent($userAgent = null) {
+ return CakeSession::userAgent($userAgent);
+ }
+
+/**
+ * Used to write a value to a session key.
+ *
+ * In your controller: $this->Session->write('Controller.sessKey', 'session value');
+ *
+ * @param string $name The name of the key your are setting in the session.
+ * This should be in a Controller.key format for better organizing
+ * @param string $value The value you want to store in a session.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::write
+ */
+ public function write($name, $value = null) {
+ return CakeSession::write($name, $value);
+ }
+
+/**
+ * Used to read a session values for a key or return values for all keys.
+ *
+ * In your controller: $this->Session->read('Controller.sessKey');
+ * Calling the method without a param will return all session vars
+ *
+ * @param string $name the name of the session key you want to read
+ * @return mixed value from the session vars
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::read
+ */
+ public function read($name = null) {
+ return CakeSession::read($name);
+ }
+
+/**
+ * Wrapper for SessionComponent::del();
+ *
+ * In your controller: $this->Session->delete('Controller.sessKey');
+ *
+ * @param string $name the name of the session key you want to delete
+ * @return boolean true is session variable is set and can be deleted, false is variable was not set.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::delete
+ */
+ public function delete($name) {
+ return CakeSession::delete($name);
+ }
+
+/**
+ * Used to check if a session variable is set
+ *
+ * In your controller: $this->Session->check('Controller.sessKey');
+ *
+ * @param string $name the name of the session key you want to check
+ * @return boolean true is session variable is set, false if not
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::check
+ */
+ public function check($name) {
+ return CakeSession::check($name);
+ }
+
+/**
+ * Used to determine the last error in a session.
+ *
+ * In your controller: $this->Session->error();
+ *
+ * @return string Last session error
+ */
+ public function error() {
+ return CakeSession::error();
+ }
+
+/**
+ * Used to set a session variable that can be used to output messages in the view.
+ *
+ * In your controller: $this->Session->setFlash('This has been saved');
+ *
+ * Additional params below can be passed to customize the output, or the Message.[key].
+ * You can also set additional parameters when rendering flash messages. See SessionHelper::flash()
+ * for more information on how to do that.
+ *
+ * @param string $message Message to be flashed
+ * @param string $element Element to wrap flash message in.
+ * @param array $params Parameters to be sent to layout as view variables
+ * @param string $key Message key, default is 'flash'
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#creating-notification-messages
+ */
+ public function setFlash($message, $element = 'default', $params = array(), $key = 'flash') {
+ CakeSession::write('Message.' . $key, compact('message', 'element', 'params'));
+ }
+
+/**
+ * Used to renew a session id
+ *
+ * In your controller: $this->Session->renew();
+ *
+ * @return void
+ */
+ public function renew() {
+ return CakeSession::renew();
+ }
+
+/**
+ * Used to check for a valid session.
+ *
+ * In your controller: $this->Session->valid();
+ *
+ * @return boolean true is session is valid, false is session is invalid
+ */
+ public function valid() {
+ return CakeSession::valid();
+ }
+
+/**
+ * Used to destroy sessions
+ *
+ * In your controller: $this->Session->destroy();
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::destroy
+ */
+ public function destroy() {
+ return CakeSession::destroy();
+ }
+
+/**
+ * Get/Set the session id.
+ *
+ * When fetching the session id, the session will be started
+ * if it has not already been started. When setting the session id,
+ * the session will not be started.
+ *
+ * @param string $id Id to use (optional)
+ * @return string The current session id.
+ */
+ public function id($id = null) {
+ if (empty($id)) {
+ CakeSession::start();
+ }
+ return CakeSession::id($id);
+ }
+
+/**
+ * Returns a bool, whether or not the session has been started.
+ *
+ * @return boolean
+ */
+ public function started() {
+ return CakeSession::started();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php
new file mode 100644
index 0000000..43dca08
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/ComponentCollection.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * Components collection is used as a registry for loaded components and handles loading
+ * and constructing component class objects.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+App::uses('Component', 'Controller');
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * Components collection is used as a registry for loaded components and handles loading
+ * and constructing component class objects.
+ *
+ * @package Cake.Controller
+ */
+class ComponentCollection extends ObjectCollection implements CakeEventListener {
+
+/**
+ * The controller that this collection was initialized with.
+ *
+ * @var Controller
+ */
+ protected $_Controller = null;
+
+/**
+ * Initializes all the Components for a controller.
+ * Attaches a reference of each component to the Controller.
+ *
+ * @param Controller $Controller Controller to initialize components for.
+ * @return void
+ */
+ public function init(Controller $Controller) {
+ if (empty($Controller->components)) {
+ return;
+ }
+ $this->_Controller = $Controller;
+ $components = ComponentCollection::normalizeObjectArray($Controller->components);
+ foreach ($components as $name => $properties) {
+ $Controller->{$name} = $this->load($properties['class'], $properties['settings']);
+ }
+ }
+
+/**
+ * Get the controller associated with the collection.
+ *
+ * @return Controller.
+ */
+ public function getController() {
+ return $this->_Controller;
+ }
+
+/**
+ * Loads/constructs a component. Will return the instance in the registry if it already exists.
+ * You can use `$settings['enabled'] = false` to disable callbacks on a component when loading it.
+ * Callbacks default to on. Disabled component methods work as normal, only callbacks are disabled.
+ *
+ * You can alias your component as an existing component by setting the 'className' key, i.e.,
+ * {{{
+ * public $components = array(
+ * 'Email' => array(
+ * 'className' => 'AliasedEmail'
+ * );
+ * );
+ * }}}
+ * All calls to the `Email` component would use `AliasedEmail` instead.
+ *
+ * @param string $component Component name to load
+ * @param array $settings Settings for the component.
+ * @return Component A component object, Either the existing loaded component or a new one.
+ * @throws MissingComponentException when the component could not be found
+ */
+ public function load($component, $settings = array()) {
+ if (is_array($settings) && isset($settings['className'])) {
+ $alias = $component;
+ $component = $settings['className'];
+ }
+ list($plugin, $name) = pluginSplit($component, true);
+ if (!isset($alias)) {
+ $alias = $name;
+ }
+ if (isset($this->_loaded[$alias])) {
+ return $this->_loaded[$alias];
+ }
+ $componentClass = $name . 'Component';
+ App::uses($componentClass, $plugin . 'Controller/Component');
+ if (!class_exists($componentClass)) {
+ throw new MissingComponentException(array(
+ 'class' => $componentClass,
+ 'plugin' => substr($plugin, 0, -1)
+ ));
+ }
+ $this->_loaded[$alias] = new $componentClass($this, $settings);
+ $enable = isset($settings['enabled']) ? $settings['enabled'] : true;
+ if ($enable) {
+ $this->enable($alias);
+ }
+ return $this->_loaded[$alias];
+ }
+
+/**
+ * Returns the implemented events that will get routed to the trigger function
+ * in order to dispatch them separately on each component
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'Controller.initialize' => array('callable' => 'trigger'),
+ 'Controller.startup' => array('callable' => 'trigger'),
+ 'Controller.beforeRender' => array('callable' => 'trigger'),
+ 'Controller.beforeRedirect' => array('callable' => 'trigger'),
+ 'Controller.shutdown' => array('callable' => 'trigger'),
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php
new file mode 100644
index 0000000..fa8b7da
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Controller.php
@@ -0,0 +1,1228 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeResponse', 'Network');
+App::uses('ClassRegistry', 'Utility');
+App::uses('ComponentCollection', 'Controller');
+App::uses('View', 'View');
+App::uses('CakeEvent', 'Event');
+App::uses('CakeEventListener', 'Event');
+App::uses('CakeEventManager', 'Event');
+
+/**
+ * Application controller class for organization of business logic.
+ * Provides basic functionality, such as rendering views inside layouts,
+ * automatic model availability, redirection, callbacks, and more.
+ *
+ * Controllers should provide a number of 'action' methods. These are public methods on the controller
+ * that are not prefixed with a '_' and not part of Controller. Each action serves as an endpoint for
+ * performing a specific action on a resource or collection of resources. For example adding or editing a new
+ * object, or listing a set of objects.
+ *
+ * You can access request parameters, using `$this->request`. The request object contains all the POST, GET and FILES
+ * that were part of the request.
+ *
+ * After performing the required actions, controllers are responsible for creating a response. This usually
+ * takes the form of a generated View, or possibly a redirection to another controller action. In either case
+ * `$this->response` allows you to manipulate all aspects of the response.
+ *
+ * Controllers are created by Dispatcher based on request parameters and routing. By default controllers and actions
+ * use conventional names. For example `/posts/index` maps to `PostsController::index()`. You can re-map urls
+ * using Router::connect().
+ *
+ * @package Cake.Controller
+ * @property AclComponent $Acl
+ * @property AuthComponent $Auth
+ * @property CookieComponent $Cookie
+ * @property EmailComponent $Email
+ * @property PaginatorComponent $Paginator
+ * @property RequestHandlerComponent $RequestHandler
+ * @property SecurityComponent $Security
+ * @property SessionComponent $Session
+ * @link http://book.cakephp.org/2.0/en/controllers.html
+ */
+class Controller extends Object implements CakeEventListener {
+
+/**
+ * The name of this controller. Controller names are plural, named after the model they manipulate.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/controllers.html#controller-attributes
+ */
+ public $name = null;
+
+/**
+ * An array containing the class names of models this controller uses.
+ *
+ * Example: `public $uses = array('Product', 'Post', 'Comment');`
+ *
+ * Can be set to several values to express different options:
+ *
+ * - `true` Use the default inflected model name.
+ * - `array()` Use only models defined in the parent class.
+ * - `false` Use no models at all, do not merge with parent class either.
+ * - `array('Post', 'Comment')` Use only the Post and Comment models. Models
+ * Will also be merged with the parent class.
+ *
+ * The default value is `true`.
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
+ */
+ public $uses = true;
+
+/**
+ * An array containing the names of helpers this controller uses. The array elements should
+ * not contain the "Helper" part of the classname.
+ *
+ * Example: `public $helpers = array('Html', 'Javascript', 'Time', 'Ajax');`
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
+ */
+ public $helpers = array();
+
+/**
+ * An instance of a CakeRequest object that contains information about the current request.
+ * This object contains all the information about a request and several methods for reading
+ * additional information about the request.
+ *
+ * @var CakeRequest
+ * @link http://book.cakephp.org/2.0/en/controllers/request-response.html#cakerequest
+ */
+ public $request;
+
+/**
+ * An instance of a CakeResponse object that contains information about the impending response
+ *
+ * @var CakeResponse
+ * @link http://book.cakephp.org/2.0/en/controllers/request-response.html#cakeresponse
+ */
+ public $response;
+
+/**
+ * The classname to use for creating the response object.
+ *
+ * @var string
+ */
+ protected $_responseClass = 'CakeResponse';
+
+/**
+ * The name of the views subfolder containing views for this controller.
+ *
+ * @var string
+ */
+ public $viewPath = null;
+
+/**
+ * The name of the layouts subfolder containing layouts for this controller.
+ *
+ * @var string
+ */
+ public $layoutPath = null;
+
+/**
+ * Contains variables to be handed to the view.
+ *
+ * @var array
+ */
+ public $viewVars = array();
+
+/**
+ * The name of the view file to render. The name specified
+ * is the filename in /app/View/<SubFolder> without the .ctp extension.
+ *
+ * @var string
+ */
+ public $view = null;
+
+/**
+ * The name of the layout file to render the view inside of. The name specified
+ * is the filename of the layout in /app/View/Layouts without the .ctp
+ * extension.
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Set to true to automatically render the view
+ * after action logic.
+ *
+ * @var boolean
+ */
+ public $autoRender = true;
+
+/**
+ * Set to true to automatically render the layout around views.
+ *
+ * @var boolean
+ */
+ public $autoLayout = true;
+
+/**
+ * Instance of ComponentCollection used to handle callbacks.
+ *
+ * @var ComponentCollection
+ */
+ public $Components = null;
+
+/**
+ * Array containing the names of components this controller uses. Component names
+ * should not contain the "Component" portion of the classname.
+ *
+ * Example: `public $components = array('Session', 'RequestHandler', 'Acl');`
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/controllers/components.html
+ */
+ public $components = array('Session');
+
+/**
+ * The name of the View class this controller sends output to.
+ *
+ * @var string
+ */
+ public $viewClass = 'View';
+
+/**
+ * Instance of the View created during rendering. Won't be set until after
+ * Controller::render() is called.
+ *
+ * @var View
+ */
+ public $View;
+
+/**
+ * File extension for view templates. Defaults to Cake's conventional ".ctp".
+ *
+ * @var string
+ */
+ public $ext = '.ctp';
+
+/**
+ * Automatically set to the name of a plugin.
+ *
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Used to define methods a controller that will be cached. To cache a
+ * single action, the value is set to an array containing keys that match
+ * action names and values that denote cache expiration times (in seconds).
+ *
+ * Example:
+ *
+ * {{{
+ * public $cacheAction = array(
+ * 'view/23/' => 21600,
+ * 'recalled/' => 86400
+ * );
+ * }}}
+ *
+ * $cacheAction can also be set to a strtotime() compatible string. This
+ * marks all the actions in the controller for view caching.
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html#additional-configuration-options
+ */
+ public $cacheAction = false;
+
+/**
+ * Holds all params passed and named.
+ *
+ * @var mixed
+ */
+ public $passedArgs = array();
+
+/**
+ * Triggers Scaffolding
+ *
+ * @var mixed
+ * @link http://book.cakephp.org/2.0/en/controllers/scaffolding.html
+ */
+ public $scaffold = false;
+
+/**
+ * Holds current methods of the controller. This is a list of all the methods reachable
+ * via url. Modifying this array, will allow you to change which methods can be reached.
+ *
+ * @var array
+ */
+ public $methods = array();
+
+/**
+ * This controller's primary model class name, the Inflector::singularize()'ed version of
+ * the controller's $name property.
+ *
+ * Example: For a controller named 'Comments', the modelClass would be 'Comment'
+ *
+ * @var string
+ */
+ public $modelClass = null;
+
+/**
+ * This controller's model key name, an underscored version of the controller's $modelClass property.
+ *
+ * Example: For a controller named 'ArticleComments', the modelKey would be 'article_comment'
+ *
+ * @var string
+ */
+ public $modelKey = null;
+
+/**
+ * Holds any validation errors produced by the last call of the validateErrors() method/
+ *
+ * @var array Validation errors, or false if none
+ */
+ public $validationErrors = null;
+
+/**
+ * The class name of the parent class you wish to merge with.
+ * Typically this is AppController, but you may wish to merge vars with a different
+ * parent class.
+ *
+ * @var string
+ */
+ protected $_mergeParent = 'AppController';
+
+/**
+ * Instance of the CakeEventManager this controller is using
+ * to dispatch inner events.
+ *
+ * @var CakeEventManager
+ */
+ protected $_eventManager = null;
+
+/**
+ * Constructor.
+ *
+ * @param CakeRequest $request Request object for this controller. Can be null for testing,
+ * but expect that features that use the request parameters will not work.
+ * @param CakeResponse $response Response object for this controller.
+ */
+ public function __construct($request = null, $response = null) {
+ if ($this->name === null) {
+ $this->name = substr(get_class($this), 0, -10);
+ }
+
+ if ($this->viewPath == null) {
+ $this->viewPath = $this->name;
+ }
+
+ $this->modelClass = Inflector::singularize($this->name);
+ $this->modelKey = Inflector::underscore($this->modelClass);
+ $this->Components = new ComponentCollection();
+
+ $childMethods = get_class_methods($this);
+ $parentMethods = get_class_methods('Controller');
+
+ $this->methods = array_diff($childMethods, $parentMethods);
+
+ if ($request instanceof CakeRequest) {
+ $this->setRequest($request);
+ }
+ if ($response instanceof CakeResponse) {
+ $this->response = $response;
+ }
+ parent::__construct();
+ }
+
+/**
+ * Provides backwards compatibility to avoid problems with empty and isset to alias properties.
+ * Lazy loads models using the loadModel() method if declared in $uses
+ *
+ * @param string $name
+ * @return void
+ */
+ public function __isset($name) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ case 'action':
+ case 'params':
+ return true;
+ }
+
+ if (is_array($this->uses)) {
+ foreach ($this->uses as $modelClass) {
+ list($plugin, $class) = pluginSplit($modelClass, true);
+ if ($name === $class) {
+ return $this->loadModel($modelClass);
+ }
+ }
+ }
+
+ if ($name === $this->modelClass) {
+ list($plugin, $class) = pluginSplit($name, true);
+ if (!$plugin) {
+ $plugin = $this->plugin ? $this->plugin . '.' : null;
+ }
+ return $this->loadModel($plugin . $this->modelClass);
+ }
+
+ return false;
+ }
+
+/**
+ * Provides backwards compatibility access to the request object properties.
+ * Also provides the params alias.
+ *
+ * @param string $name
+ * @return void
+ */
+ public function __get($name) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name};
+ case 'action':
+ return isset($this->request->params['action']) ? $this->request->params['action'] : '';
+ case 'params':
+ return $this->request;
+ case 'paginate':
+ return $this->Components->load('Paginator')->settings;
+ }
+
+ if (isset($this->{$name})) {
+ return $this->{$name};
+ }
+
+ return null;
+ }
+
+/**
+ * Provides backwards compatibility access for setting values to the request object.
+ *
+ * @param string $name
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name} = $value;
+ case 'action':
+ return $this->request->params['action'] = $value;
+ case 'params':
+ return $this->request->params = $value;
+ case 'paginate':
+ return $this->Components->load('Paginator')->settings = $value;
+ }
+ return $this->{$name} = $value;
+ }
+
+/**
+ * Sets the request objects and configures a number of controller properties
+ * based on the contents of the request. The properties that get set are
+ *
+ * - $this->request - To the $request parameter
+ * - $this->plugin - To the $request->params['plugin']
+ * - $this->view - To the $request->params['action']
+ * - $this->autoLayout - To the false if $request->params['bare']; is set.
+ * - $this->autoRender - To false if $request->params['return'] == 1
+ * - $this->passedArgs - The the combined results of params['named'] and params['pass]
+ *
+ * @param CakeRequest $request
+ * @return void
+ */
+ public function setRequest(CakeRequest $request) {
+ $this->request = $request;
+ $this->plugin = isset($request->params['plugin']) ? Inflector::camelize($request->params['plugin']) : null;
+ $this->view = isset($request->params['action']) ? $request->params['action'] : null;
+ if (isset($request->params['pass']) && isset($request->params['named'])) {
+ $this->passedArgs = array_merge($request->params['pass'], $request->params['named']);
+ }
+
+ if (array_key_exists('return', $request->params) && $request->params['return'] == 1) {
+ $this->autoRender = false;
+ }
+ if (!empty($request->params['bare'])) {
+ $this->autoLayout = false;
+ }
+ }
+
+/**
+ * Dispatches the controller action. Checks that the action
+ * exists and isn't private.
+ *
+ * @param CakeRequest $request
+ * @return mixed The resulting response.
+ * @throws PrivateActionException When actions are not public or prefixed by _
+ * @throws MissingActionException When actions are not defined and scaffolding is
+ * not enabled.
+ */
+ public function invokeAction(CakeRequest $request) {
+ try {
+ $method = new ReflectionMethod($this, $request->params['action']);
+
+ if ($this->_isPrivateAction($method, $request)) {
+ throw new PrivateActionException(array(
+ 'controller' => $this->name . "Controller",
+ 'action' => $request->params['action']
+ ));
+ }
+ return $method->invokeArgs($this, $request->params['pass']);
+
+ } catch (ReflectionException $e) {
+ if ($this->scaffold !== false) {
+ return $this->_getScaffold($request);
+ }
+ throw new MissingActionException(array(
+ 'controller' => $this->name . "Controller",
+ 'action' => $request->params['action']
+ ));
+ }
+ }
+
+/**
+ * Check if the request's action is marked as private, with an underscore,
+ * or if the request is attempting to directly accessing a prefixed action.
+ *
+ * @param ReflectionMethod $method The method to be invoked.
+ * @param CakeRequest $request The request to check.
+ * @return boolean
+ */
+ protected function _isPrivateAction(ReflectionMethod $method, CakeRequest $request) {
+ $privateAction = (
+ $method->name[0] === '_' ||
+ !$method->isPublic() ||
+ !in_array($method->name, $this->methods)
+ );
+ $prefixes = Router::prefixes();
+
+ if (!$privateAction && !empty($prefixes)) {
+ if (empty($request->params['prefix']) && strpos($request->params['action'], '_') > 0) {
+ list($prefix) = explode('_', $request->params['action']);
+ $privateAction = in_array($prefix, $prefixes);
+ }
+ }
+ return $privateAction;
+ }
+
+/**
+ * Returns a scaffold object to use for dynamically scaffolded controllers.
+ *
+ * @param CakeRequest $request
+ * @return Scaffold
+ */
+ protected function _getScaffold(CakeRequest $request) {
+ return new Scaffold($this, $request);
+ }
+
+/**
+ * Merge components, helpers, and uses vars from
+ * Controller::$_mergeParent and PluginAppController.
+ *
+ * @return void
+ */
+ protected function _mergeControllerVars() {
+ $pluginController = $pluginDot = null;
+ $mergeParent = is_subclass_of($this, $this->_mergeParent);
+ $pluginVars = array();
+ $appVars = array();
+
+ if (!empty($this->plugin)) {
+ $pluginController = $this->plugin . 'AppController';
+ if (!is_subclass_of($this, $pluginController)) {
+ $pluginController = null;
+ }
+ $pluginDot = $this->plugin . '.';
+ }
+
+ if ($pluginController) {
+ $merge = array('components', 'helpers');
+ $this->_mergeVars($merge, $pluginController);
+ }
+
+ if ($mergeParent || !empty($pluginController)) {
+ $appVars = get_class_vars($this->_mergeParent);
+ $uses = $appVars['uses'];
+ $merge = array('components', 'helpers');
+ $this->_mergeVars($merge, $this->_mergeParent, true);
+ }
+
+ if ($this->uses === null) {
+ $this->uses = false;
+ }
+ if ($this->uses === true) {
+ $this->uses = array($pluginDot . $this->modelClass);
+ }
+ if (isset($appVars['uses']) && $appVars['uses'] === $this->uses) {
+ array_unshift($this->uses, $pluginDot . $this->modelClass);
+ }
+ if ($pluginController) {
+ $pluginVars = get_class_vars($pluginController);
+ }
+ if ($this->uses !== false) {
+ $this->_mergeUses($pluginVars);
+ $this->_mergeUses($appVars);
+ } else {
+ $this->uses = array();
+ $this->modelClass = '';
+ }
+ }
+
+/**
+ * Helper method for merging the $uses property together.
+ *
+ * Merges the elements not already in $this->uses into
+ * $this->uses.
+ *
+ * @param array $merge The data to merge in.
+ * @return void
+ */
+ protected function _mergeUses($merge) {
+ if (!isset($merge['uses'])) {
+ return;
+ }
+ if ($merge['uses'] === true) {
+ return;
+ }
+ $this->uses = array_merge(
+ $this->uses,
+ array_diff($merge['uses'], $this->uses)
+ );
+ }
+
+/**
+ * Returns a list of all events that will fire in the controller during it's lifecycle.
+ * You can override this function to add you own listener callbacks
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'Controller.initialize' => 'beforeFilter',
+ 'Controller.beforeRender' => 'beforeRender',
+ 'Controller.beforeRedirect' => array('callable' => 'beforeRedirect', 'passParams' => true),
+ 'Controller.shutdown' => 'afterFilter'
+ );
+ }
+
+/**
+ * Loads Model classes based on the uses property
+ * see Controller::loadModel(); for more info.
+ * Loads Components and prepares them for initialization.
+ *
+ * @return mixed true if models found and instance created.
+ * @see Controller::loadModel()
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::constructClasses
+ * @throws MissingModelException
+ */
+ public function constructClasses() {
+ $this->_mergeControllerVars();
+ $this->Components->init($this);
+ if ($this->uses) {
+ $this->uses = (array)$this->uses;
+ list(, $this->modelClass) = pluginSplit(current($this->uses));
+ }
+ return true;
+ }
+
+/**
+ * Returns the CakeEventManager manager instance that is handling any callbacks.
+ * You can use this instance to register any new listeners or callbacks to the
+ * controller events, or create your own events and trigger them at will.
+ *
+ * @return CakeEventManager
+ */
+ public function getEventManager() {
+ if (empty($this->_eventManager)) {
+ $this->_eventManager = new CakeEventManager();
+ $this->_eventManager->attach($this->Components);
+ $this->_eventManager->attach($this);
+ }
+ return $this->_eventManager;
+ }
+
+/**
+ * Perform the startup process for this controller.
+ * Fire the Components and Controller callbacks in the correct order.
+ *
+ * - Initializes components, which fires their `initialize` callback
+ * - Calls the controller `beforeFilter`.
+ * - triggers Component `startup` methods.
+ *
+ * @return void
+ */
+ public function startupProcess() {
+ $this->getEventManager()->dispatch(new CakeEvent('Controller.initialize', $this));
+ $this->getEventManager()->dispatch(new CakeEvent('Controller.startup', $this));
+ }
+
+/**
+ * Perform the various shutdown processes for this controller.
+ * Fire the Components and Controller callbacks in the correct order.
+ *
+ * - triggers the component `shutdown` callback.
+ * - calls the Controller's `afterFilter` method.
+ *
+ * @return void
+ */
+ public function shutdownProcess() {
+ $this->getEventManager()->dispatch(new CakeEvent('Controller.shutdown', $this));
+ }
+
+/**
+ * Queries & sets valid HTTP response codes & messages.
+ *
+ * @param integer|array $code If $code is an integer, then the corresponding code/message is
+ * returned if it exists, null if it does not exist. If $code is an array,
+ * then the 'code' and 'message' keys of each nested array are added to the default
+ * HTTP codes. Example:
+ *
+ * httpCodes(404); // returns array(404 => 'Not Found')
+ *
+ * httpCodes(array(
+ * 701 => 'Unicorn Moved',
+ * 800 => 'Unexpected Minotaur'
+ * )); // sets these new values, and returns true
+ *
+ * @return array Associative array of the HTTP codes as keys, and the message
+ * strings as values, or null of the given $code does not exist.
+ * @deprecated Use CakeResponse::httpCodes();
+ */
+ public function httpCodes($code = null) {
+ return $this->response->httpCodes($code);
+ }
+
+/**
+ * Loads and instantiates models required by this controller.
+ * If the model is non existent, it will throw a missing database table error, as Cake generates
+ * dynamic models for the time being.
+ *
+ * @param string $modelClass Name of model class to load
+ * @param integer|string $id Initial ID the instanced model class should have
+ * @return mixed true when single model found and instance created, error returned if model not found.
+ * @throws MissingModelException if the model class cannot be found.
+ */
+ public function loadModel($modelClass = null, $id = null) {
+ if ($modelClass === null) {
+ $modelClass = $this->modelClass;
+ }
+
+ $this->uses = ($this->uses) ? (array)$this->uses : array();
+ if (!in_array($modelClass, $this->uses)) {
+ $this->uses[] = $modelClass;
+ }
+
+ list($plugin, $modelClass) = pluginSplit($modelClass, true);
+
+ $this->{$modelClass} = ClassRegistry::init(array(
+ 'class' => $plugin . $modelClass, 'alias' => $modelClass, 'id' => $id
+ ));
+ if (!$this->{$modelClass}) {
+ throw new MissingModelException($modelClass);
+ }
+ return true;
+ }
+
+/**
+ * Redirects to given $url, after turning off $this->autoRender.
+ * Script execution is halted after the redirect.
+ *
+ * @param string|array $url A string or array-based URL pointing to another location within the app,
+ * or an absolute URL
+ * @param integer $status Optional HTTP status code (eg: 404)
+ * @param boolean $exit If true, exit() will be called after the redirect
+ * @return mixed void if $exit = false. Terminates script if $exit = true
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::redirect
+ */
+ public function redirect($url, $status = null, $exit = true) {
+ $this->autoRender = false;
+
+ if (is_array($status)) {
+ extract($status, EXTR_OVERWRITE);
+ }
+ $event = new CakeEvent('Controller.beforeRedirect', $this, array($url, $status, $exit));
+ //TODO: Remove the following line when the events are fully migrated to the CakeEventManager
+ list($event->break, $event->breakOn, $event->collectReturn) = array(true, false, true);
+ $this->getEventManager()->dispatch($event);
+
+ if ($event->isStopped()) {
+ return;
+ }
+ $response = $event->result;
+ extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
+
+ if ($url !== null) {
+ $this->response->header('Location', Router::url($url, true));
+ }
+
+ if (is_string($status)) {
+ $codes = array_flip($this->response->httpCodes());
+ if (isset($codes[$status])) {
+ $status = $codes[$status];
+ }
+ }
+
+ if ($status) {
+ $this->response->statusCode($status);
+ }
+
+ if ($exit) {
+ $this->response->send();
+ $this->_stop();
+ }
+ }
+
+/**
+ * Parse beforeRedirect Response
+ *
+ * @param mixed $response Response from beforeRedirect callback
+ * @param string|array $url The same value of beforeRedirect
+ * @param integer $status The same value of beforeRedirect
+ * @param boolean $exit The same value of beforeRedirect
+ * @return array Array with keys url, status and exit
+ */
+ protected function _parseBeforeRedirect($response, $url, $status, $exit) {
+ if (is_array($response) && isset($response[0])) {
+ foreach ($response as $resp) {
+ if (is_array($resp) && isset($resp['url'])) {
+ extract($resp, EXTR_OVERWRITE);
+ } elseif ($resp !== null) {
+ $url = $resp;
+ }
+ }
+ } elseif (is_array($response)) {
+ extract($response, EXTR_OVERWRITE);
+ }
+ return compact('url', 'status', 'exit');
+ }
+
+/**
+ * Convenience and object wrapper method for CakeResponse::header().
+ *
+ * @param string $status The header message that is being set.
+ * @return void
+ * @deprecated Use CakeResponse::header()
+ */
+ public function header($status) {
+ $this->response->header($status);
+ }
+
+/**
+ * Saves a variable for use inside a view template.
+ *
+ * @param string|array $one A string or an array of data.
+ * @param string|array $two Value in case $one is a string (which then works as the key).
+ * Unused if $one is an associative array, otherwise serves as the values to $one's keys.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#interacting-with-views
+ */
+ public function set($one, $two = null) {
+ if (is_array($one)) {
+ if (is_array($two)) {
+ $data = array_combine($one, $two);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($one => $two);
+ }
+ $this->viewVars = $data + $this->viewVars;
+ }
+
+/**
+ * Internally redirects one action to another. Does not perform another HTTP request unlike Controller::redirect()
+ *
+ * Examples:
+ *
+ * {{{
+ * setAction('another_action');
+ * setAction('action_with_parameters', $parameter1);
+ * }}}
+ *
+ * @param string $action The new action to be 'redirected' to
+ * @param mixed Any other parameters passed to this method will be passed as
+ * parameters to the new action.
+ * @return mixed Returns the return value of the called action
+ */
+ public function setAction($action) {
+ $this->request->params['action'] = $action;
+ $this->view = $action;
+ $args = func_get_args();
+ unset($args[0]);
+ return call_user_func_array(array(&$this, $action), $args);
+ }
+
+/**
+ * Returns number of errors in a submitted FORM.
+ *
+ * @return integer Number of errors
+ */
+ public function validate() {
+ $args = func_get_args();
+ $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
+
+ if ($errors === false) {
+ return 0;
+ }
+ return count($errors);
+ }
+
+/**
+ * Validates models passed by parameters. Example:
+ *
+ * `$errors = $this->validateErrors($this->Article, $this->User);`
+ *
+ * @param mixed A list of models as a variable argument
+ * @return array Validation errors, or false if none
+ */
+ public function validateErrors() {
+ $objects = func_get_args();
+
+ if (empty($objects)) {
+ return false;
+ }
+
+ $errors = array();
+ foreach ($objects as $object) {
+ if (isset($this->{$object->alias})) {
+ $object = $this->{$object->alias};
+ }
+ $object->set($object->data);
+ $errors = array_merge($errors, $object->invalidFields());
+ }
+
+ return $this->validationErrors = (!empty($errors) ? $errors : false);
+ }
+
+/**
+ * Instantiates the correct view class, hands it its data, and uses it to render the view output.
+ *
+ * @param string $view View to use for rendering
+ * @param string $layout Layout to use
+ * @return CakeResponse A response object containing the rendered view.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::render
+ */
+ public function render($view = null, $layout = null) {
+ $event = new CakeEvent('Controller.beforeRender', $this);
+ $this->getEventManager()->dispatch($event);
+ if ($event->isStopped()) {
+ $this->autoRender = false;
+ return $this->response;
+ }
+
+ if (!empty($this->uses) && is_array($this->uses)) {
+ foreach ($this->uses as $model) {
+ list($plugin, $className) = pluginSplit($model);
+ $this->request->params['models'][$className] = compact('plugin', 'className');
+ }
+ }
+
+ $viewClass = $this->viewClass;
+ if ($this->viewClass != 'View') {
+ list($plugin, $viewClass) = pluginSplit($viewClass, true);
+ $viewClass = $viewClass . 'View';
+ App::uses($viewClass, $plugin . 'View');
+ }
+
+ $View = new $viewClass($this);
+
+ $models = ClassRegistry::keys();
+ foreach ($models as $currentModel) {
+ $currentObject = ClassRegistry::getObject($currentModel);
+ if (is_a($currentObject, 'Model')) {
+ $className = get_class($currentObject);
+ list($plugin) = pluginSplit(App::location($className));
+ $this->request->params['models'][$currentObject->alias] = compact('plugin', 'className');
+ $View->validationErrors[$currentObject->alias] =& $currentObject->validationErrors;
+ }
+ }
+
+ $this->autoRender = false;
+ $this->View = $View;
+ $this->response->body($View->render($view, $layout));
+ return $this->response;
+ }
+
+/**
+ * Returns the referring URL for this request.
+ *
+ * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers
+ * @param boolean $local If true, restrict referring URLs to local server
+ * @return string Referring URL
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::referer
+ */
+ public function referer($default = null, $local = false) {
+ if ($this->request) {
+ $referer = $this->request->referer($local);
+ if ($referer == '/' && $default != null) {
+ return Router::url($default, true);
+ }
+ return $referer;
+ }
+ return '/';
+ }
+
+/**
+ * Forces the user's browser not to cache the results of the current request.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::disableCache
+ * @deprecated Use CakeResponse::disableCache()
+ */
+ public function disableCache() {
+ $this->response->disableCache();
+ }
+
+/**
+ * Shows a message to the user for $pause seconds, then redirects to $url.
+ * Uses flash.ctp as the default layout for the message.
+ * Does not work if the current debug level is higher than 0.
+ *
+ * @param string $message Message to display to the user
+ * @param string|array $url Relative string or array-based URL to redirect to after the time expires
+ * @param integer $pause Time to show the message
+ * @param string $layout Layout you want to use, defaults to 'flash'
+ * @return void Renders flash layout
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::flash
+ */
+ public function flash($message, $url, $pause = 1, $layout = 'flash') {
+ $this->autoRender = false;
+ $this->set('url', Router::url($url));
+ $this->set('message', $message);
+ $this->set('pause', $pause);
+ $this->set('page_title', $message);
+ $this->render(false, $layout);
+ }
+
+/**
+ * Converts POST'ed form data to a model conditions array, suitable for use in a Model::find() call.
+ *
+ * @param array $data POST'ed data organized by model and field
+ * @param string|array $op A string containing an SQL comparison operator, or an array matching operators
+ * to fields
+ * @param string $bool SQL boolean operator: AND, OR, XOR, etc.
+ * @param boolean $exclusive If true, and $op is an array, fields not included in $op will not be
+ * included in the returned conditions
+ * @return array An array of model conditions
+ * @deprecated
+ */
+ public function postConditions($data = array(), $op = null, $bool = 'AND', $exclusive = false) {
+ if (!is_array($data) || empty($data)) {
+ if (!empty($this->request->data)) {
+ $data = $this->request->data;
+ } else {
+ return null;
+ }
+ }
+ $cond = array();
+
+ if ($op === null) {
+ $op = '';
+ }
+
+ $arrayOp = is_array($op);
+ foreach ($data as $model => $fields) {
+ foreach ($fields as $field => $value) {
+ $key = $model . '.' . $field;
+ $fieldOp = $op;
+ if ($arrayOp) {
+ if (array_key_exists($key, $op)) {
+ $fieldOp = $op[$key];
+ } elseif (array_key_exists($field, $op)) {
+ $fieldOp = $op[$field];
+ } else {
+ $fieldOp = false;
+ }
+ }
+ if ($exclusive && $fieldOp === false) {
+ continue;
+ }
+ $fieldOp = strtoupper(trim($fieldOp));
+ if ($fieldOp === 'LIKE') {
+ $key = $key . ' LIKE';
+ $value = '%' . $value . '%';
+ } elseif ($fieldOp && $fieldOp != '=') {
+ $key = $key . ' ' . $fieldOp;
+ }
+ $cond[$key] = $value;
+ }
+ }
+ if ($bool != null && strtoupper($bool) != 'AND') {
+ $cond = array($bool => $cond);
+ }
+ return $cond;
+ }
+
+/**
+ * Handles automatic pagination of model records.
+ *
+ * @param Model|string $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
+ * @param string|array $scope Conditions to use while paginating
+ * @param array $whitelist List of allowed options for paging
+ * @return array Model query results
+ * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::paginate
+ * @deprecated Use PaginatorComponent instead
+ */
+ public function paginate($object = null, $scope = array(), $whitelist = array()) {
+ return $this->Components->load('Paginator', $this->paginate)->paginate($object, $scope, $whitelist);
+ }
+
+/**
+ * Called before the controller action. You can use this method to configure and customize components
+ * or perform logic that needs to happen before each controller action.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function beforeFilter() {
+ }
+
+/**
+ * Called after the controller action is run, but before the view is rendered. You can use this method
+ * to perform logic or set view variables that are required on every request.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function beforeRender() {
+ }
+
+/**
+ * The beforeRedirect method is invoked when the controller's redirect method is called but before any
+ * further action. If this method returns false the controller will not continue on to redirect the request.
+ * The $url, $status and $exit variables have same meaning as for the controller's method. You can also
+ * return a string which will be interpreted as the url to redirect to or return associative array with
+ * key 'url' and optionally 'status' and 'exit'.
+ *
+ * @param string|array $url A string or array-based URL pointing to another location within the app,
+ * or an absolute URL
+ * @param integer $status Optional HTTP status code (eg: 404)
+ * @param boolean $exit If true, exit() will be called after the redirect
+ * @return mixed
+ * false to stop redirection event,
+ * string controllers a new redirection url or
+ * array with the keys url, status and exit to be used by the redirect method.
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function beforeRedirect($url, $status = null, $exit = true) {
+ }
+
+/**
+ * Called after the controller action is run and rendered.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
+ */
+ public function afterFilter() {
+ }
+
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called example index, edit, etc.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function beforeScaffold($method) {
+ return true;
+ }
+
+/**
+ * Alias to beforeScaffold()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::beforeScaffold()
+ * @deprecated
+ */
+ protected function _beforeScaffold($method) {
+ return $this->beforeScaffold($method);
+ }
+
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called either edit or update.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function afterScaffoldSave($method) {
+ return true;
+ }
+
+/**
+ * Alias to afterScaffoldSave()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::afterScaffoldSave()
+ * @deprecated
+ */
+ protected function _afterScaffoldSave($method) {
+ return $this->afterScaffoldSave($method);
+ }
+
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called either edit or update.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function afterScaffoldSaveError($method) {
+ return true;
+ }
+
+/**
+ * Alias to afterScaffoldSaveError()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::afterScaffoldSaveError()
+ * @deprecated
+ */
+ protected function _afterScaffoldSaveError($method) {
+ return $this->afterScaffoldSaveError($method);
+ }
+
+/**
+ * This method should be overridden in child classes.
+ * If not it will render a scaffold error.
+ * Method MUST return true in child classes
+ *
+ * @param string $method name of method called example index, edit, etc.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/controllers.html#callbacks
+ */
+ public function scaffoldError($method) {
+ return false;
+ }
+
+/**
+ * Alias to scaffoldError()
+ *
+ * @param string $method
+ * @return boolean
+ * @see Controller::scaffoldError()
+ * @deprecated
+ */
+ protected function _scaffoldError($method) {
+ return $this->scaffoldError($method);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php
new file mode 100644
index 0000000..8543126
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Controller/Scaffold.php
@@ -0,0 +1,447 @@
+<?php
+/**
+ * Scaffold.
+ *
+ * Automatic forms and actions generation for rapid web application development.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since Cake v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Scaffold', 'View');
+
+/**
+ * Scaffolding is a set of automatic actions for starting web development work faster.
+ *
+ * Scaffold inspects your database tables, and making educated guesses, sets up a
+ * number of pages for each of your Models. These pages have data forms that work,
+ * and afford the web developer an early look at the data, and the possibility to over-ride
+ * scaffolded actions with custom-made ones.
+ *
+ * @package Cake.Controller
+ */
+class Scaffold {
+
+/**
+ * Controller object
+ *
+ * @var Controller
+ */
+ public $controller = null;
+
+/**
+ * Name of the controller to scaffold
+ *
+ * @var string
+ */
+ public $name = null;
+
+/**
+ * Name of current model this view context is attached to
+ *
+ * @var string
+ */
+ public $model = null;
+
+/**
+ * Path to View.
+ *
+ * @var string
+ */
+ public $viewPath;
+
+/**
+ * Name of layout to use with this View.
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Valid session.
+ *
+ * @var boolean
+ */
+ protected $_validSession = null;
+
+/**
+ * List of variables to collect from the associated controller
+ *
+ * @var array
+ */
+ protected $_passedVars = array(
+ 'layout', 'name', 'viewPath', 'request'
+ );
+
+/**
+ * Title HTML element for current scaffolded view
+ *
+ * @var string
+ */
+ public $scaffoldTitle = null;
+
+/**
+ * Construct and set up given controller with given parameters.
+ *
+ * @param Controller $controller Controller to scaffold
+ * @param CakeRequest $request Request parameters.
+ * @throws MissingModelException
+ */
+ public function __construct(Controller $controller, CakeRequest $request) {
+ $this->controller = $controller;
+
+ $count = count($this->_passedVars);
+ for ($j = 0; $j < $count; $j++) {
+ $var = $this->_passedVars[$j];
+ $this->{$var} = $controller->{$var};
+ }
+
+ $this->redirect = array('action' => 'index');
+
+ $this->modelClass = $controller->modelClass;
+ $this->modelKey = $controller->modelKey;
+
+ if (!is_object($this->controller->{$this->modelClass})) {
+ throw new MissingModelException($this->modelClass);
+ }
+
+ $this->ScaffoldModel = $this->controller->{$this->modelClass};
+ $this->scaffoldTitle = Inflector::humanize(Inflector::underscore($this->viewPath));
+ $this->scaffoldActions = $controller->scaffold;
+ $title = __d('cake', 'Scaffold :: ') . Inflector::humanize($request->action) . ' :: ' . $this->scaffoldTitle;
+ $modelClass = $this->controller->modelClass;
+ $primaryKey = $this->ScaffoldModel->primaryKey;
+ $displayField = $this->ScaffoldModel->displayField;
+ $singularVar = Inflector::variable($modelClass);
+ $pluralVar = Inflector::variable($this->controller->name);
+ $singularHumanName = Inflector::humanize(Inflector::underscore($modelClass));
+ $pluralHumanName = Inflector::humanize(Inflector::underscore($this->controller->name));
+ $scaffoldFields = array_keys($this->ScaffoldModel->schema());
+ $associations = $this->_associations();
+
+ $this->controller->set(compact(
+ 'title_for_layout', 'modelClass', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
+ 'singularHumanName', 'pluralHumanName', 'scaffoldFields', 'associations'
+ ));
+ $this->controller->set('title_for_layout', $title);
+
+ if ($this->controller->viewClass) {
+ $this->controller->viewClass = 'Scaffold';
+ }
+ $this->_validSession = (
+ isset($this->controller->Session) && $this->controller->Session->valid() != false
+ );
+ $this->_scaffold($request);
+ }
+
+/**
+ * Renders a view action of scaffolded model.
+ *
+ * @param CakeRequest $request Request Object for scaffolding
+ * @return mixed A rendered view of a row from Models database table
+ * @throws NotFoundException
+ */
+ protected function _scaffoldView(CakeRequest $request) {
+ if ($this->controller->beforeScaffold('view')) {
+ if (isset($request->params['pass'][0])) {
+ $this->ScaffoldModel->id = $request->params['pass'][0];
+ }
+ if (!$this->ScaffoldModel->exists()) {
+ throw new NotFoundException(__d('cake', 'Invalid %s', Inflector::humanize($this->modelKey)));
+ }
+ $this->ScaffoldModel->recursive = 1;
+ $this->controller->request->data = $this->ScaffoldModel->read();
+ $this->controller->set(
+ Inflector::variable($this->controller->modelClass), $this->request->data
+ );
+ $this->controller->render($this->request['action'], $this->layout);
+ } elseif ($this->controller->scaffoldError('view') === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Renders index action of scaffolded model.
+ *
+ * @param array $params Parameters for scaffolding
+ * @return mixed A rendered view listing rows from Models database table
+ */
+ protected function _scaffoldIndex($params) {
+ if ($this->controller->beforeScaffold('index')) {
+ $this->ScaffoldModel->recursive = 0;
+ $this->controller->set(
+ Inflector::variable($this->controller->name), $this->controller->paginate()
+ );
+ $this->controller->render($this->request['action'], $this->layout);
+ } elseif ($this->controller->scaffoldError('index') === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Renders an add or edit action for scaffolded model.
+ *
+ * @param string $action Action (add or edit)
+ * @return mixed A rendered view with a form to edit or add a record in the Models database table
+ */
+ protected function _scaffoldForm($action = 'edit') {
+ $this->controller->viewVars['scaffoldFields'] = array_merge(
+ $this->controller->viewVars['scaffoldFields'],
+ array_keys($this->ScaffoldModel->hasAndBelongsToMany)
+ );
+ $this->controller->render($action, $this->layout);
+ }
+
+/**
+ * Saves or updates the scaffolded model.
+ *
+ * @param CakeRequest $request Request Object for scaffolding
+ * @param string $action add or edit
+ * @return mixed Success on save/update, add/edit form if data is empty or error if save or update fails
+ * @throws NotFoundException
+ */
+ protected function _scaffoldSave(CakeRequest $request, $action = 'edit') {
+ $formAction = 'edit';
+ $success = __d('cake', 'updated');
+ if ($action === 'add') {
+ $formAction = 'add';
+ $success = __d('cake', 'saved');
+ }
+
+ if ($this->controller->beforeScaffold($action)) {
+ if ($action == 'edit') {
+ if (isset($request->params['pass'][0])) {
+ $this->ScaffoldModel->id = $request['pass'][0];
+ }
+ if (!$this->ScaffoldModel->exists()) {
+ throw new NotFoundException(__d('cake', 'Invalid %s', Inflector::humanize($this->modelKey)));
+ }
+ }
+
+ if (!empty($request->data)) {
+ if ($action == 'create') {
+ $this->ScaffoldModel->create();
+ }
+
+ if ($this->ScaffoldModel->save($request->data)) {
+ if ($this->controller->afterScaffoldSave($action)) {
+ $message = __d('cake',
+ 'The %1$s has been %2$s',
+ Inflector::humanize($this->modelKey),
+ $success
+ );
+ return $this->_sendMessage($message);
+ } else {
+ return $this->controller->afterScaffoldSaveError($action);
+ }
+ } else {
+ if ($this->_validSession) {
+ $this->controller->Session->setFlash(__d('cake', 'Please correct errors below.'));
+ }
+ }
+ }
+
+ if (empty($request->data)) {
+ if ($this->ScaffoldModel->id) {
+ $this->controller->data = $request->data = $this->ScaffoldModel->read();
+ } else {
+ $this->controller->data = $request->data = $this->ScaffoldModel->create();
+ }
+ }
+
+ foreach ($this->ScaffoldModel->belongsTo as $assocName => $assocData) {
+ $varName = Inflector::variable(Inflector::pluralize(
+ preg_replace('/(?:_id)$/', '', $assocData['foreignKey'])
+ ));
+ $this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
+ }
+ foreach ($this->ScaffoldModel->hasAndBelongsToMany as $assocName => $assocData) {
+ $varName = Inflector::variable(Inflector::pluralize($assocName));
+ $this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
+ }
+
+ return $this->_scaffoldForm($formAction);
+ } elseif ($this->controller->scaffoldError($action) === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Performs a delete on given scaffolded Model.
+ *
+ * @param CakeRequest $request Request for scaffolding
+ * @return mixed Success on delete, error if delete fails
+ * @throws MethodNotAllowedException When HTTP method is not a DELETE
+ * @throws NotFoundException When id being deleted does not exist.
+ */
+ protected function _scaffoldDelete(CakeRequest $request) {
+ if ($this->controller->beforeScaffold('delete')) {
+ if (!$request->is('post')) {
+ throw new MethodNotAllowedException();
+ }
+ $id = false;
+ if (isset($request->params['pass'][0])) {
+ $id = $request->params['pass'][0];
+ }
+ $this->ScaffoldModel->id = $id;
+ if (!$this->ScaffoldModel->exists()) {
+ throw new NotFoundException(__d('cake', 'Invalid %s', Inflector::humanize($this->modelClass)));
+ }
+ if ($this->ScaffoldModel->delete()) {
+ $message = __d('cake', 'The %1$s with id: %2$s has been deleted.', Inflector::humanize($this->modelClass), $id);
+ return $this->_sendMessage($message);
+ } else {
+ $message = __d('cake',
+ 'There was an error deleting the %1$s with id: %2$s',
+ Inflector::humanize($this->modelClass),
+ $id
+ );
+ return $this->_sendMessage($message);
+ }
+ } elseif ($this->controller->scaffoldError('delete') === false) {
+ return $this->_scaffoldError();
+ }
+ }
+
+/**
+ * Sends a message to the user. Either uses Sessions or flash messages depending
+ * on the availability of a session
+ *
+ * @param string $message Message to display
+ * @return void
+ */
+ protected function _sendMessage($message) {
+ if ($this->_validSession) {
+ $this->controller->Session->setFlash($message);
+ $this->controller->redirect($this->redirect);
+ } else {
+ $this->controller->flash($message, $this->redirect);
+ }
+ }
+
+/**
+ * Show a scaffold error
+ *
+ * @return mixed A rendered view showing the error
+ */
+ protected function _scaffoldError() {
+ return $this->controller->render('error', $this->layout);
+ }
+
+/**
+ * When methods are now present in a controller
+ * scaffoldView is used to call default Scaffold methods if:
+ * `public $scaffold;` is placed in the controller's class definition.
+ *
+ * @param CakeRequest $request Request object for scaffolding
+ * @return mixed A rendered view of scaffold action, or showing the error
+ * @throws MissingActionException When methods are not scaffolded.
+ * @throws MissingDatabaseException When the database connection is undefined.
+ */
+ protected function _scaffold(CakeRequest $request) {
+ $db = ConnectionManager::getDataSource($this->ScaffoldModel->useDbConfig);
+ $prefixes = Configure::read('Routing.prefixes');
+ $scaffoldPrefix = $this->scaffoldActions;
+
+ if (isset($db)) {
+ if (empty($this->scaffoldActions)) {
+ $this->scaffoldActions = array(
+ 'index', 'list', 'view', 'add', 'create', 'edit', 'update', 'delete'
+ );
+ } elseif (!empty($prefixes) && in_array($scaffoldPrefix, $prefixes)) {
+ $this->scaffoldActions = array(
+ $scaffoldPrefix . '_index',
+ $scaffoldPrefix . '_list',
+ $scaffoldPrefix . '_view',
+ $scaffoldPrefix . '_add',
+ $scaffoldPrefix . '_create',
+ $scaffoldPrefix . '_edit',
+ $scaffoldPrefix . '_update',
+ $scaffoldPrefix . '_delete'
+ );
+ }
+
+ if (in_array($request->params['action'], $this->scaffoldActions)) {
+ if (!empty($prefixes)) {
+ $request->params['action'] = str_replace($scaffoldPrefix . '_', '', $request->params['action']);
+ }
+ switch ($request->params['action']) {
+ case 'index':
+ case 'list':
+ $this->_scaffoldIndex($request);
+ break;
+ case 'view':
+ $this->_scaffoldView($request);
+ break;
+ case 'add':
+ case 'create':
+ $this->_scaffoldSave($request, 'add');
+ break;
+ case 'edit':
+ case 'update':
+ $this->_scaffoldSave($request, 'edit');
+ break;
+ case 'delete':
+ $this->_scaffoldDelete($request);
+ break;
+ }
+ } else {
+ throw new MissingActionException(array(
+ 'controller' => $this->controller->name,
+ 'action' => $request->action
+ ));
+ }
+ } else {
+ throw new MissingDatabaseException(array('connection' => $this->ScaffoldModel->useDbConfig));
+ }
+ }
+
+/**
+ * Returns associations for controllers models.
+ *
+ * @return array Associations for model
+ */
+ protected function _associations() {
+ $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+ $associations = array();
+
+ foreach ($keys as $key => $type) {
+ foreach ($this->ScaffoldModel->{$type} as $assocKey => $assocData) {
+ $associations[$type][$assocKey]['primaryKey'] =
+ $this->ScaffoldModel->{$assocKey}->primaryKey;
+
+ $associations[$type][$assocKey]['displayField'] =
+ $this->ScaffoldModel->{$assocKey}->displayField;
+
+ $associations[$type][$assocKey]['foreignKey'] =
+ $assocData['foreignKey'];
+
+ $associations[$type][$assocKey]['controller'] =
+ Inflector::pluralize(Inflector::underscore($assocData['className']));
+
+ if ($type == 'hasAndBelongsToMany') {
+ $associations[$type][$assocKey]['with'] = $assocData['with'];
+ }
+ }
+ }
+ return $associations;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/App.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/App.php
new file mode 100644
index 0000000..7619bef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/App.php
@@ -0,0 +1,929 @@
+<?php
+/**
+ * App class
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Core
+ * @since CakePHP(tm) v 1.2.0.6001
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * App is responsible for path management, class location and class loading.
+ *
+ * ### Adding paths
+ *
+ * You can add paths to the search indexes App uses to find classes using `App::build()`. Adding
+ * additional controller paths for example would alter where CakePHP looks for controllers.
+ * This allows you to split your application up across the filesystem.
+ *
+ * ### Packages
+ *
+ * CakePHP is organized around the idea of packages, each class belongs to a package or folder where other
+ * classes reside. You can configure each package location in your application using `App::build('APackage/SubPackage', $paths)`
+ * to inform the framework where should each class be loaded. Almost every class in the CakePHP framework can be swapped
+ * by your own compatible implementation. If you wish to use you own class instead of the classes the framework provides,
+ * just add the class to your libs folder mocking the directory location of where CakePHP expects to find it.
+ *
+ * For instance if you'd like to use your own HttpSocket class, put it under
+ *
+ * app/Network/Http/HttpSocket.php
+ *
+ * ### Inspecting loaded paths
+ *
+ * You can inspect the currently loaded paths using `App::path('Controller')` for example to see loaded
+ * controller paths.
+ *
+ * It is also possible to inspect paths for plugin classes, for instance, to see a plugin's helpers you would call
+ * `App::path('View/Helper', 'MyPlugin')`
+ *
+ * ### Locating plugins and themes
+ *
+ * Plugins and Themes can be located with App as well. Using App::pluginPath('DebugKit') for example, will
+ * give you the full path to the DebugKit plugin. App::themePath('purple'), would give the full path to the
+ * `purple` theme.
+ *
+ * ### Inspecting known objects
+ *
+ * You can find out which objects App knows about using App::objects('Controller') for example to find
+ * which application controllers App knows about.
+ *
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html
+ * @package Cake.Core
+ */
+class App {
+
+/**
+ * Append paths
+ *
+ * @constant APPEND
+ */
+ const APPEND = 'append';
+
+/**
+ * Prepend paths
+ *
+ * @constant PREPEND
+ */
+ const PREPEND = 'prepend';
+
+/**
+ * Register package
+ *
+ * @constant REGISTER
+ */
+ const REGISTER = 'register';
+
+/**
+ * Reset paths instead of merging
+ *
+ * @constant RESET
+ */
+ const RESET = true;
+
+/**
+ * List of object types and their properties
+ *
+ * @var array
+ */
+ public static $types = array(
+ 'class' => array('extends' => null, 'core' => true),
+ 'file' => array('extends' => null, 'core' => true),
+ 'model' => array('extends' => 'AppModel', 'core' => false),
+ 'behavior' => array('suffix' => 'Behavior', 'extends' => 'Model/ModelBehavior', 'core' => true),
+ 'controller' => array('suffix' => 'Controller', 'extends' => 'AppController', 'core' => true),
+ 'component' => array('suffix' => 'Component', 'extends' => null, 'core' => true),
+ 'lib' => array('extends' => null, 'core' => true),
+ 'view' => array('suffix' => 'View', 'extends' => null, 'core' => true),
+ 'helper' => array('suffix' => 'Helper', 'extends' => 'AppHelper', 'core' => true),
+ 'vendor' => array('extends' => null, 'core' => true),
+ 'shell' => array('suffix' => 'Shell', 'extends' => 'AppShell', 'core' => true),
+ 'plugin' => array('extends' => null, 'core' => true)
+ );
+
+/**
+ * Paths to search for files.
+ *
+ * @var array
+ */
+ public static $search = array();
+
+/**
+ * Whether or not to return the file that is loaded.
+ *
+ * @var boolean
+ */
+ public static $return = false;
+
+/**
+ * Holds key/value pairs of $type => file path.
+ *
+ * @var array
+ */
+ protected static $_map = array();
+
+/**
+ * Holds and key => value array of object types.
+ *
+ * @var array
+ */
+ protected static $_objects = array();
+
+/**
+ * Holds the location of each class
+ *
+ * @var array
+ */
+ protected static $_classMap = array();
+
+/**
+ * Holds the possible paths for each package name
+ *
+ * @var array
+ */
+ protected static $_packages = array();
+
+/**
+ * Holds the templates for each customizable package path in the application
+ *
+ * @var array
+ */
+ protected static $_packageFormat = array();
+
+/**
+ * Maps an old style CakePHP class type to the corresponding package
+ *
+ * @var array
+ */
+ public static $legacy = array(
+ 'models' => 'Model',
+ 'behaviors' => 'Model/Behavior',
+ 'datasources' => 'Model/Datasource',
+ 'controllers' => 'Controller',
+ 'components' => 'Controller/Component',
+ 'views' => 'View',
+ 'helpers' => 'View/Helper',
+ 'shells' => 'Console/Command',
+ 'libs' => 'Lib',
+ 'vendors' => 'Vendor',
+ 'plugins' => 'Plugin',
+ 'locales' => 'Locale'
+ );
+
+/**
+ * Indicates whether the class cache should be stored again because of an addition to it
+ *
+ * @var boolean
+ */
+ protected static $_cacheChange = false;
+
+/**
+ * Indicates whether the object cache should be stored again because of an addition to it
+ *
+ * @var boolean
+ */
+ protected static $_objectCacheChange = false;
+
+/**
+ * Indicates the the Application is in the bootstrapping process. Used to better cache
+ * loaded classes while the cache libraries have not been yet initialized
+ *
+ * @var boolean
+ */
+ public static $bootstrapping = false;
+
+/**
+ * Used to read information stored path
+ *
+ * Usage:
+ *
+ * `App::path('Model'); will return all paths for models`
+ *
+ * `App::path('Model/Datasource', 'MyPlugin'); will return the path for datasources under the 'MyPlugin' plugin`
+ *
+ * @param string $type type of path
+ * @param string $plugin name of plugin
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::path
+ */
+ public static function path($type, $plugin = null) {
+ if (!empty(self::$legacy[$type])) {
+ $type = self::$legacy[$type];
+ }
+
+ if (!empty($plugin)) {
+ $path = array();
+ $pluginPath = self::pluginPath($plugin);
+ $packageFormat = self::_packageFormat();
+ if (!empty($packageFormat[$type])) {
+ foreach ($packageFormat[$type] as $f) {
+ $path[] = sprintf($f, $pluginPath);
+ }
+ }
+ return $path;
+ }
+
+ if (!isset(self::$_packages[$type])) {
+ return array();
+ }
+ return self::$_packages[$type];
+ }
+
+/**
+ * Get all the currently loaded paths from App. Useful for inspecting
+ * or storing all paths App knows about. For a paths to a specific package
+ * use App::path()
+ *
+ * @return array An array of packages and their associated paths.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::paths
+ */
+ public static function paths() {
+ return self::$_packages;
+ }
+
+/**
+ * Sets up each package location on the file system. You can configure multiple search paths
+ * for each package, those will be used to look for files one folder at a time in the specified order
+ * All paths should be terminated with a Directory separator
+ *
+ * Usage:
+ *
+ * `App::build(array(Model' => array('/a/full/path/to/models/'))); will setup a new search path for the Model package`
+ *
+ * `App::build(array('Model' => array('/path/to/models/')), App::RESET); will setup the path as the only valid path for searching models`
+ *
+ * `App::build(array('View/Helper' => array('/path/to/helpers/', '/another/path/'))); will setup multiple search paths for helpers`
+ *
+ * `App::build(array('Service' => array('%s' . 'Service' . DS)), App::REGISTER); will register new package 'Service'`
+ *
+ * If reset is set to true, all loaded plugins will be forgotten and they will be needed to be loaded again.
+ *
+ * @param array $paths associative array with package names as keys and a list of directories for new search paths
+ * @param boolean|string $mode App::RESET will set paths, App::APPEND with append paths, App::PREPEND will prepend paths (default)
+ * App::REGISTER will register new packages and their paths, %s in path will be replaced by APP path
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::build
+ */
+ public static function build($paths = array(), $mode = App::PREPEND) {
+ //Provides Backwards compatibility for old-style package names
+ $legacyPaths = array();
+ foreach ($paths as $type => $path) {
+ if (!empty(self::$legacy[$type])) {
+ $type = self::$legacy[$type];
+ }
+ $legacyPaths[$type] = $path;
+ }
+ $paths = $legacyPaths;
+
+ if ($mode === App::RESET) {
+ foreach ($paths as $type => $new) {
+ self::$_packages[$type] = (array)$new;
+ self::objects($type, null, false);
+ }
+ return;
+ }
+
+ if (empty($paths)) {
+ self::$_packageFormat = null;
+ }
+
+ $packageFormat = self::_packageFormat();
+
+ if ($mode === App::REGISTER) {
+ foreach ($paths as $package => $formats) {
+ if (empty($packageFormat[$package])) {
+ $packageFormat[$package] = $formats;
+ } else {
+ $formats = array_merge($packageFormat[$package], $formats);
+ $packageFormat[$package] = array_values(array_unique($formats));
+ }
+ }
+ self::$_packageFormat = $packageFormat;
+ }
+
+ $defaults = array();
+ foreach ($packageFormat as $package => $format) {
+ foreach ($format as $f) {
+ $defaults[$package][] = sprintf($f, APP);
+ }
+ }
+
+ if (empty($paths)) {
+ self::$_packages = $defaults;
+ return;
+ }
+
+ if ($mode === App::REGISTER) {
+ $paths = array();
+ }
+
+ foreach ($defaults as $type => $default) {
+ if (!empty(self::$_packages[$type])) {
+ $path = self::$_packages[$type];
+ } else {
+ $path = $default;
+ }
+
+ if (!empty($paths[$type])) {
+ $newPath = (array)$paths[$type];
+
+ if ($mode === App::PREPEND) {
+ $path = array_merge($newPath, $path);
+ } else {
+ $path = array_merge($path, $newPath);
+ }
+
+ $path = array_values(array_unique($path));
+ }
+
+ self::$_packages[$type] = $path;
+ }
+ }
+
+/**
+ * Gets the path that a plugin is on. Searches through the defined plugin paths.
+ *
+ * Usage:
+ *
+ * `App::pluginPath('MyPlugin'); will return the full path to 'MyPlugin' plugin'`
+ *
+ * @param string $plugin CamelCased/lower_cased plugin name to find the path of.
+ * @return string full path to the plugin.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::pluginPath
+ */
+ public static function pluginPath($plugin) {
+ return CakePlugin::path($plugin);
+ }
+
+/**
+ * Finds the path that a theme is on. Searches through the defined theme paths.
+ *
+ * Usage:
+ *
+ * `App::themePath('MyTheme'); will return the full path to the 'MyTheme' theme`
+ *
+ * @param string $theme theme name to find the path of.
+ * @return string full path to the theme.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::themePath
+ */
+ public static function themePath($theme) {
+ $themeDir = 'Themed' . DS . Inflector::camelize($theme);
+ foreach (self::$_packages['View'] as $path) {
+ if (is_dir($path . $themeDir)) {
+ return $path . $themeDir . DS;
+ }
+ }
+ return self::$_packages['View'][0] . $themeDir . DS;
+ }
+
+/**
+ * Returns the full path to a package inside the CakePHP core
+ *
+ * Usage:
+ *
+ * `App::core('Cache/Engine'); will return the full path to the cache engines package`
+ *
+ * @param string $type
+ * @return array full path to package
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::core
+ */
+ public static function core($type) {
+ return array(CAKE . str_replace('/', DS, $type) . DS);
+ }
+
+/**
+ * Returns an array of objects of the given type.
+ *
+ * Example usage:
+ *
+ * `App::objects('plugin');` returns `array('DebugKit', 'Blog', 'User');`
+ *
+ * `App::objects('Controller');` returns `array('PagesController', 'BlogController');`
+ *
+ * You can also search only within a plugin's objects by using the plugin dot
+ * syntax.
+ *
+ * `App::objects('MyPlugin.Model');` returns `array('MyPluginPost', 'MyPluginComment');`
+ *
+ * When scanning directories, files and directories beginning with `.` will be excluded as these
+ * are commonly used by version control systems.
+ *
+ * @param string $type Type of object, i.e. 'Model', 'Controller', 'View/Helper', 'file', 'class' or 'plugin'
+ * @param string|array $path Optional Scan only the path given. If null, paths for the chosen type will be used.
+ * @param boolean $cache Set to false to rescan objects of the chosen type. Defaults to true.
+ * @return mixed Either false on incorrect / miss. Or an array of found objects.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::objects
+ */
+ public static function objects($type, $path = null, $cache = true) {
+ $extension = '/\.php$/';
+ $includeDirectories = false;
+ $name = $type;
+
+ if ($type === 'plugin') {
+ $type = 'plugins';
+ }
+
+ if ($type == 'plugins') {
+ $extension = '/.*/';
+ $includeDirectories = true;
+ }
+
+ list($plugin, $type) = pluginSplit($type);
+
+ if (isset(self::$legacy[$type . 's'])) {
+ $type = self::$legacy[$type . 's'];
+ }
+
+ if ($type === 'file' && !$path) {
+ return false;
+ } elseif ($type === 'file') {
+ $extension = '/\.php$/';
+ $name = $type . str_replace(DS, '', $path);
+ }
+
+ if (empty(self::$_objects) && $cache === true) {
+ self::$_objects = Cache::read('object_map', '_cake_core_');
+ }
+
+ $cacheLocation = empty($plugin) ? 'app' : $plugin;
+
+ if ($cache !== true || !isset(self::$_objects[$cacheLocation][$name])) {
+ $objects = array();
+
+ if (empty($path)) {
+ $path = self::path($type, $plugin);
+ }
+
+ foreach ((array)$path as $dir) {
+ if ($dir != APP && is_dir($dir)) {
+ $files = new RegexIterator(new DirectoryIterator($dir), $extension);
+ foreach ($files as $file) {
+ $fileName = basename($file);
+ if (!$file->isDot() && $fileName[0] !== '.') {
+ $isDir = $file->isDir();
+ if ($isDir && $includeDirectories) {
+ $objects[] = $fileName;
+ } elseif (!$includeDirectories && !$isDir) {
+ $objects[] = substr($fileName, 0, -4);
+ }
+ }
+ }
+ }
+ }
+
+ if ($type !== 'file') {
+ foreach ($objects as $key => $value) {
+ $objects[$key] = Inflector::camelize($value);
+ }
+ }
+
+ sort($objects);
+ if ($plugin) {
+ return $objects;
+ }
+
+ self::$_objects[$cacheLocation][$name] = $objects;
+ if ($cache) {
+ self::$_objectCacheChange = true;
+ }
+ }
+
+ return self::$_objects[$cacheLocation][$name];
+ }
+
+/**
+ * Declares a package for a class. This package location will be used
+ * by the automatic class loader if the class is tried to be used
+ *
+ * Usage:
+ *
+ * `App::uses('MyCustomController', 'Controller');` will setup the class to be found under Controller package
+ *
+ * `App::uses('MyHelper', 'MyPlugin.View/Helper');` will setup the helper class to be found in plugin's helper package
+ *
+ * @param string $className the name of the class to configure package for
+ * @param string $location the package name
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::uses
+ */
+ public static function uses($className, $location) {
+ self::$_classMap[$className] = $location;
+ }
+
+/**
+ * Method to handle the automatic class loading. It will look for each class' package
+ * defined using App::uses() and with this information it will resolve the package name to a full path
+ * to load the class from. File name for each class should follow the class name. For instance,
+ * if a class is name `MyCustomClass` the file name should be `MyCustomClass.php`
+ *
+ * @param string $className the name of the class to load
+ * @return boolean
+ */
+ public static function load($className) {
+ if (!isset(self::$_classMap[$className])) {
+ return false;
+ }
+
+ $parts = explode('.', self::$_classMap[$className], 2);
+ list($plugin, $package) = count($parts) > 1 ? $parts : array(null, current($parts));
+
+ if ($file = self::_mapped($className, $plugin)) {
+ return include $file;
+ }
+ $paths = self::path($package, $plugin);
+
+ if (empty($plugin)) {
+ $appLibs = empty(self::$_packages['Lib']) ? APPLIBS : current(self::$_packages['Lib']);
+ $paths[] = $appLibs . $package . DS;
+ $paths[] = APP . $package . DS;
+ $paths[] = CAKE . $package . DS;
+ } else {
+ $pluginPath = self::pluginPath($plugin);
+ $paths[] = $pluginPath . 'Lib' . DS . $package . DS;
+ $paths[] = $pluginPath . $package . DS;
+ }
+
+ $normalizedClassName = str_replace('\\', DS, $className);
+ foreach ($paths as $path) {
+ $file = $path . $normalizedClassName . '.php';
+ if (file_exists($file)) {
+ self::_map($file, $className, $plugin);
+ return include $file;
+ }
+ }
+
+ return false;
+ }
+
+/**
+ * Returns the package name where a class was defined to be located at
+ *
+ * @param string $className name of the class to obtain the package name from
+ * @return string package name or null if not declared
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::location
+ */
+ public static function location($className) {
+ if (!empty(self::$_classMap[$className])) {
+ return self::$_classMap[$className];
+ }
+ return null;
+ }
+
+/**
+ * Finds classes based on $name or specific file(s) to search. Calling App::import() will
+ * not construct any classes contained in the files. It will only find and require() the file.
+ *
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#including-files-with-app-import
+ * @param string|array $type The type of Class if passed as a string, or all params can be passed as
+ * an single array to $type,
+ * @param string $name Name of the Class or a unique name for the file
+ * @param boolean|array $parent boolean true if Class Parent should be searched, accepts key => value
+ * array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext');
+ * $ext allows setting the extension of the file name
+ * based on Inflector::underscore($name) . ".$ext";
+ * @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
+ * @param string $file full name of the file to search for including extension
+ * @param boolean $return Return the loaded file, the file must have a return
+ * statement in it to work: return $variable;
+ * @return boolean true if Class is already in memory or if file is found and loaded, false if not
+ */
+ public static function import($type = null, $name = null, $parent = true, $search = array(), $file = null, $return = false) {
+ $ext = null;
+
+ if (is_array($type)) {
+ extract($type, EXTR_OVERWRITE);
+ }
+
+ if (is_array($parent)) {
+ extract($parent, EXTR_OVERWRITE);
+ }
+
+ if ($name == null && $file == null) {
+ return false;
+ }
+
+ if (is_array($name)) {
+ foreach ($name as $class) {
+ if (!App::import(compact('type', 'parent', 'search', 'file', 'return') + array('name' => $class))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ $originalType = strtolower($type);
+ $specialPackage = in_array($originalType, array('file', 'vendor'));
+ if (!$specialPackage && isset(self::$legacy[$originalType . 's'])) {
+ $type = self::$legacy[$originalType . 's'];
+ }
+ list($plugin, $name) = pluginSplit($name);
+ if (!empty($plugin)) {
+ if (!CakePlugin::loaded($plugin)) {
+ return false;
+ }
+ }
+
+ if (!$specialPackage) {
+ return self::_loadClass($name, $plugin, $type, $originalType, $parent);
+ }
+
+ if ($originalType == 'file' && !empty($file)) {
+ return self::_loadFile($name, $plugin, $search, $file, $return);
+ }
+
+ if ($originalType == 'vendor') {
+ return self::_loadVendor($name, $plugin, $file, $ext);
+ }
+
+ return false;
+ }
+
+/**
+ * Helper function to include classes
+ * This is a compatibility wrapper around using App::uses() and automatic class loading
+ *
+ * @param string $name unique name of the file for identifying it inside the application
+ * @param string $plugin camel cased plugin name if any
+ * @param string $type name of the packed where the class is located
+ * @param string $originalType type name as supplied initially by the user
+ * @param boolean $parent whether to load the class parent or not
+ * @return boolean true indicating the successful load and existence of the class
+ */
+ protected static function _loadClass($name, $plugin, $type, $originalType, $parent) {
+ if ($type == 'Console/Command' && $name == 'Shell') {
+ $type = 'Console';
+ } elseif (isset(self::$types[$originalType]['suffix'])) {
+ $suffix = self::$types[$originalType]['suffix'];
+ $name .= ($suffix == $name) ? '' : $suffix;
+ }
+ if ($parent && isset(self::$types[$originalType]['extends'])) {
+ $extends = self::$types[$originalType]['extends'];
+ $extendType = $type;
+ if (strpos($extends, '/') !== false) {
+ $parts = explode('/', $extends);
+ $extends = array_pop($parts);
+ $extendType = implode('/', $parts);
+ }
+ App::uses($extends, $extendType);
+ if ($plugin && in_array($originalType, array('controller', 'model'))) {
+ App::uses($plugin . $extends, $plugin . '.' . $type);
+ }
+ }
+ if ($plugin) {
+ $plugin .= '.';
+ }
+ $name = Inflector::camelize($name);
+ App::uses($name, $plugin . $type);
+ return class_exists($name);
+ }
+
+/**
+ * Helper function to include single files
+ *
+ * @param string $name unique name of the file for identifying it inside the application
+ * @param string $plugin camel cased plugin name if any
+ * @param array $search list of paths to search the file into
+ * @param string $file filename if known, the $name param will be used otherwise
+ * @param boolean $return whether this function should return the contents of the file after being parsed by php or just a success notice
+ * @return mixed if $return contents of the file after php parses it, boolean indicating success otherwise
+ */
+ protected static function _loadFile($name, $plugin, $search, $file, $return) {
+ $mapped = self::_mapped($name, $plugin);
+ if ($mapped) {
+ $file = $mapped;
+ } elseif (!empty($search)) {
+ foreach ($search as $path) {
+ $found = false;
+ if (file_exists($path . $file)) {
+ $file = $path . $file;
+ $found = true;
+ break;
+ }
+ if (empty($found)) {
+ $file = false;
+ }
+ }
+ }
+ if (!empty($file) && file_exists($file)) {
+ self::_map($file, $name, $plugin);
+ $returnValue = include $file;
+ if ($return) {
+ return $returnValue;
+ }
+ return (bool)$returnValue;
+ }
+ return false;
+ }
+
+/**
+ * Helper function to load files from vendors folders
+ *
+ * @param string $name unique name of the file for identifying it inside the application
+ * @param string $plugin camel cased plugin name if any
+ * @param string $file file name if known
+ * @param string $ext file extension if known
+ * @return boolean true if the file was loaded successfully, false otherwise
+ */
+ protected static function _loadVendor($name, $plugin, $file, $ext) {
+ if ($mapped = self::_mapped($name, $plugin)) {
+ return (bool)include_once $mapped;
+ }
+ $fileTries = array();
+ $paths = ($plugin) ? App::path('vendors', $plugin) : App::path('vendors');
+ if (empty($ext)) {
+ $ext = 'php';
+ }
+ if (empty($file)) {
+ $fileTries[] = $name . '.' . $ext;
+ $fileTries[] = Inflector::underscore($name) . '.' . $ext;
+ } else {
+ $fileTries[] = $file;
+ }
+
+ foreach ($fileTries as $file) {
+ foreach ($paths as $path) {
+ if (file_exists($path . $file)) {
+ self::_map($path . $file, $name, $plugin);
+ return (bool)include $path . $file;
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Initializes the cache for App, registers a shutdown function.
+ *
+ * @return void
+ */
+ public static function init() {
+ self::$_map += (array)Cache::read('file_map', '_cake_core_');
+ self::$_objects += (array)Cache::read('object_map', '_cake_core_');
+ register_shutdown_function(array('App', 'shutdown'));
+ }
+
+/**
+ * Maps the $name to the $file.
+ *
+ * @param string $file full path to file
+ * @param string $name unique name for this map
+ * @param string $plugin camelized if object is from a plugin, the name of the plugin
+ * @return void
+ */
+ protected static function _map($file, $name, $plugin = null) {
+ $key = $name;
+ if ($plugin) {
+ $key = 'plugin.' . $name;
+ }
+ if ($plugin && empty(self::$_map[$name])) {
+ self::$_map[$key] = $file;
+ }
+ if (!$plugin && empty(self::$_map['plugin.' . $name])) {
+ self::$_map[$key] = $file;
+ }
+ if (!self::$bootstrapping) {
+ self::$_cacheChange = true;
+ }
+ }
+
+/**
+ * Returns a file's complete path.
+ *
+ * @param string $name unique name
+ * @param string $plugin camelized if object is from a plugin, the name of the plugin
+ * @return mixed file path if found, false otherwise
+ */
+ protected static function _mapped($name, $plugin = null) {
+ $key = $name;
+ if ($plugin) {
+ $key = 'plugin.' . $name;
+ }
+ return isset(self::$_map[$key]) ? self::$_map[$key] : false;
+ }
+
+/**
+ * Sets then returns the templates for each customizable package path
+ *
+ * @return array templates for each customizable package path
+ */
+ protected static function _packageFormat() {
+ if (empty(self::$_packageFormat)) {
+ self::$_packageFormat = array(
+ 'Model' => array(
+ '%s' . 'Model' . DS
+ ),
+ 'Model/Behavior' => array(
+ '%s' . 'Model' . DS . 'Behavior' . DS
+ ),
+ 'Model/Datasource' => array(
+ '%s' . 'Model' . DS . 'Datasource' . DS
+ ),
+ 'Model/Datasource/Database' => array(
+ '%s' . 'Model' . DS . 'Datasource' . DS . 'Database' . DS
+ ),
+ 'Model/Datasource/Session' => array(
+ '%s' . 'Model' . DS . 'Datasource' . DS . 'Session' . DS
+ ),
+ 'Controller' => array(
+ '%s' . 'Controller' . DS
+ ),
+ 'Controller/Component' => array(
+ '%s' . 'Controller' . DS . 'Component' . DS
+ ),
+ 'Controller/Component/Auth' => array(
+ '%s' . 'Controller' . DS . 'Component' . DS . 'Auth' . DS
+ ),
+ 'Controller/Component/Acl' => array(
+ '%s' . 'Controller' . DS . 'Component' . DS . 'Acl' . DS
+ ),
+ 'View' => array(
+ '%s' . 'View' . DS
+ ),
+ 'View/Helper' => array(
+ '%s' . 'View' . DS . 'Helper' . DS
+ ),
+ 'Console' => array(
+ '%s' . 'Console' . DS
+ ),
+ 'Console/Command' => array(
+ '%s' . 'Console' . DS . 'Command' . DS
+ ),
+ 'Console/Command/Task' => array(
+ '%s' . 'Console' . DS . 'Command' . DS . 'Task' . DS
+ ),
+ 'Lib' => array(
+ '%s' . 'Lib' . DS
+ ),
+ 'Locale' => array(
+ '%s' . 'Locale' . DS
+ ),
+ 'Vendor' => array(
+ '%s' . 'Vendor' . DS,
+ dirname(dirname(CAKE)) . DS . 'vendors' . DS,
+ ),
+ 'Plugin' => array(
+ APP . 'Plugin' . DS,
+ dirname(dirname(CAKE)) . DS . 'plugins' . DS
+ )
+ );
+ }
+
+ return self::$_packageFormat;
+ }
+
+/**
+ * Object destructor.
+ *
+ * Writes cache file if changes have been made to the $_map. Also, check if a fatal
+ * error happened and call the handler.
+ *
+ * @return void
+ */
+ public static function shutdown() {
+ if (self::$_cacheChange) {
+ Cache::write('file_map', array_filter(self::$_map), '_cake_core_');
+ }
+ if (self::$_objectCacheChange) {
+ Cache::write('object_map', self::$_objects, '_cake_core_');
+ }
+
+ self::_checkFatalError();
+ }
+
+/**
+ * Check if a fatal error happened and trigger the configured handler if configured
+ *
+ * @return void
+ */
+ protected static function _checkFatalError() {
+ $lastError = error_get_last();
+ if (!is_array($lastError)) {
+ return;
+ }
+
+ list(, $log) = ErrorHandler::mapErrorCode($lastError['type']);
+ if ($log !== LOG_ERR) {
+ return;
+ }
+
+ if (PHP_SAPI === 'cli') {
+ $errorHandler = Configure::read('Error.consoleHandler');
+ } else {
+ $errorHandler = Configure::read('Error.handler');
+ }
+ if (!is_callable($errorHandler)) {
+ return;
+ }
+ call_user_func($errorHandler, $lastError['type'], $lastError['message'], $lastError['file'], $lastError['line'], array());
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/CakePlugin.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/CakePlugin.php
new file mode 100644
index 0000000..5242c9f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/CakePlugin.php
@@ -0,0 +1,228 @@
+<?php
+/**
+ * CakePlugin class
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Core
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * CakePlugin is responsible for loading and unloading plugins. It also can
+ * retrieve plugin paths and load their bootstrap and routes files.
+ *
+ * @package Cake.Core
+ * @link http://book.cakephp.org/2.0/en/plugins.html
+ */
+class CakePlugin {
+
+/**
+ * Holds a list of all loaded plugins and their configuration
+ *
+ * @var array
+ */
+ protected static $_plugins = array();
+
+/**
+ * Loads a plugin and optionally loads bootstrapping, routing files or loads a initialization function
+ *
+ * Examples:
+ *
+ * `CakePlugin::load('DebugKit')` will load the DebugKit plugin and will not load any bootstrap nor route files
+ * `CakePlugin::load('DebugKit', array('bootstrap' => true, 'routes' => true))` will load the bootstrap.php and routes.php files
+ * `CakePlugin::load('DebugKit', array('bootstrap' => false, 'routes' => true))` will load routes.php file but not bootstrap.php
+ * `CakePlugin::load('DebugKit', array('bootstrap' => array('config1', 'config2')))` will load config1.php and config2.php files
+ * `CakePlugin::load('DebugKit', array('bootstrap' => 'aCallableMethod'))` will run the aCallableMethod function to initialize it
+ *
+ * Bootstrap initialization functions can be expressed as a PHP callback type, including closures. Callbacks will receive two
+ * parameters (plugin name, plugin configuration)
+ *
+ * It is also possible to load multiple plugins at once. Examples:
+ *
+ * `CakePlugin::load(array('DebugKit', 'ApiGenerator'))` will load the DebugKit and ApiGenerator plugins
+ * `CakePlugin::load(array('DebugKit', 'ApiGenerator'), array('bootstrap' => true))` will load bootstrap file for both plugins
+ *
+ * {{{
+ * CakePlugin::load(array(
+ * 'DebugKit' => array('routes' => true),
+ * 'ApiGenerator'
+ * ), array('bootstrap' => true))
+ * }}}
+ *
+ * Will only load the bootstrap for ApiGenerator and only the routes for DebugKit
+ *
+ * @param string|array $plugin name of the plugin to be loaded in CamelCase format or array or plugins to load
+ * @param array $config configuration options for the plugin
+ * @throws MissingPluginException if the folder for the plugin to be loaded is not found
+ * @return void
+ */
+ public static function load($plugin, $config = array()) {
+ if (is_array($plugin)) {
+ foreach ($plugin as $name => $conf) {
+ list($name, $conf) = (is_numeric($name)) ? array($conf, $config) : array($name, $conf);
+ self::load($name, $conf);
+ }
+ return;
+ }
+ $config += array('bootstrap' => false, 'routes' => false);
+ if (empty($config['path'])) {
+ foreach (App::path('plugins') as $path) {
+ if (is_dir($path . $plugin)) {
+ self::$_plugins[$plugin] = $config + array('path' => $path . $plugin . DS);
+ break;
+ }
+
+ //Backwards compatibility to make easier to migrate to 2.0
+ $underscored = Inflector::underscore($plugin);
+ if (is_dir($path . $underscored)) {
+ self::$_plugins[$plugin] = $config + array('path' => $path . $underscored . DS);
+ break;
+ }
+ }
+ } else {
+ self::$_plugins[$plugin] = $config;
+ }
+
+ if (empty(self::$_plugins[$plugin]['path'])) {
+ throw new MissingPluginException(array('plugin' => $plugin));
+ }
+ if (!empty(self::$_plugins[$plugin]['bootstrap'])) {
+ self::bootstrap($plugin);
+ }
+ }
+
+/**
+ * Will load all the plugins located in the configured plugins folders
+ * If passed an options array, it will be used as a common default for all plugins to be loaded
+ * It is possible to set specific defaults for each plugins in the options array. Examples:
+ *
+ * {{{
+ * CakePlugin::loadAll(array(
+ * array('bootstrap' => true),
+ * 'DebugKit' => array('routes' => true),
+ * ))
+ * }}}
+ *
+ * The above example will load the bootstrap file for all plugins, but for DebugKit it will only load the routes file
+ * and will not look for any bootstrap script.
+ *
+ * @param array $options
+ * @return void
+ */
+ public static function loadAll($options = array()) {
+ $plugins = App::objects('plugins');
+ foreach ($plugins as $p) {
+ $opts = isset($options[$p]) ? $options[$p] : null;
+ if ($opts === null && isset($options[0])) {
+ $opts = $options[0];
+ }
+ self::load($p, (array)$opts);
+ }
+ }
+
+/**
+ * Returns the filesystem path for a plugin
+ *
+ * @param string $plugin name of the plugin in CamelCase format
+ * @return string path to the plugin folder
+ * @throws MissingPluginException if the folder for plugin was not found or plugin has not been loaded
+ */
+ public static function path($plugin) {
+ if (empty(self::$_plugins[$plugin])) {
+ throw new MissingPluginException(array('plugin' => $plugin));
+ }
+ return self::$_plugins[$plugin]['path'];
+ }
+
+/**
+ * Loads the bootstrapping files for a plugin, or calls the initialization setup in the configuration
+ *
+ * @param string $plugin name of the plugin
+ * @return mixed
+ * @see CakePlugin::load() for examples of bootstrap configuration
+ */
+ public static function bootstrap($plugin) {
+ $config = self::$_plugins[$plugin];
+ if ($config['bootstrap'] === false) {
+ return false;
+ }
+ if (is_callable($config['bootstrap'])) {
+ return call_user_func_array($config['bootstrap'], array($plugin, $config));
+ }
+
+ $path = self::path($plugin);
+ if ($config['bootstrap'] === true) {
+ return include $path . 'Config' . DS . 'bootstrap.php';
+ }
+
+ $bootstrap = (array)$config['bootstrap'];
+ foreach ($bootstrap as $file) {
+ include $path . 'Config' . DS . $file . '.php';
+ }
+
+ return true;
+ }
+
+/**
+ * Loads the routes file for a plugin, or all plugins configured to load their respective routes file
+ *
+ * @param string $plugin name of the plugin, if null will operate on all plugins having enabled the
+ * loading of routes files
+ * @return boolean
+ */
+ public static function routes($plugin = null) {
+ if ($plugin === null) {
+ foreach (self::loaded() as $p) {
+ self::routes($p);
+ }
+ return true;
+ }
+ $config = self::$_plugins[$plugin];
+ if ($config['routes'] === false) {
+ return false;
+ }
+ return (bool)include self::path($plugin) . 'Config' . DS . 'routes.php';
+ }
+
+/**
+ * Returns true if the plugin $plugin is already loaded
+ * If plugin is null, it will return a list of all loaded plugins
+ *
+ * @param string $plugin
+ * @return mixed boolean true if $plugin is already loaded.
+ * If $plugin is null, returns a list of plugins that have been loaded
+ */
+ public static function loaded($plugin = null) {
+ if ($plugin) {
+ return isset(self::$_plugins[$plugin]);
+ }
+ $return = array_keys(self::$_plugins);
+ sort($return);
+ return $return;
+ }
+
+/**
+ * Forgets a loaded plugin or all of them if first parameter is null
+ *
+ * @param string $plugin name of the plugin to forget
+ * @return void
+ */
+ public static function unload($plugin = null) {
+ if (is_null($plugin)) {
+ self::$_plugins = array();
+ } else {
+ unset(self::$_plugins[$plugin]);
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Configure.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Configure.php
new file mode 100644
index 0000000..ad24125
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Configure.php
@@ -0,0 +1,402 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Core
+ * @since CakePHP(tm) v 1.0.0.2363
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Hash', 'Utility');
+App::uses('ConfigReaderInterface', 'Configure');
+/**
+ * Compatibility with 2.1, which expects Configure to load Set.
+ */
+App::uses('Set', 'Utility');
+
+/**
+ * Configuration class. Used for managing runtime configuration information.
+ *
+ * Provides features for reading and writing to the runtime configuration, as well
+ * as methods for loading additional configuration files or storing runtime configuration
+ * for future use.
+ *
+ * @package Cake.Core
+ * @link http://book.cakephp.org/2.0/en/development/configuration.html#configure-class
+ */
+class Configure {
+
+/**
+ * Array of values currently stored in Configure.
+ *
+ * @var array
+ */
+ protected static $_values = array(
+ 'debug' => 0
+ );
+
+/**
+ * Configured reader classes, used to load config files from resources
+ *
+ * @var array
+ * @see Configure::load()
+ */
+ protected static $_readers = array();
+
+/**
+ * Initializes configure and runs the bootstrap process.
+ * Bootstrapping includes the following steps:
+ *
+ * - Setup App array in Configure.
+ * - Include app/Config/core.php.
+ * - Configure core cache configurations.
+ * - Load App cache files.
+ * - Include app/Config/bootstrap.php.
+ * - Setup error/exception handlers.
+ *
+ * @param boolean $boot
+ * @return void
+ */
+ public static function bootstrap($boot = true) {
+ if ($boot) {
+ self::write('App', array(
+ 'base' => false,
+ 'baseUrl' => false,
+ 'dir' => APP_DIR,
+ 'webroot' => WEBROOT_DIR,
+ 'www_root' => WWW_ROOT
+ ));
+
+ if (!include APP . 'Config' . DS . 'core.php') {
+ trigger_error(__d('cake_dev', "Can't find application core file. Please create %score.php, and make sure it is readable by PHP.", APP . 'Config' . DS), E_USER_ERROR);
+ }
+ App::$bootstrapping = false;
+ App::init();
+ App::build();
+
+ $exception = array(
+ 'handler' => 'ErrorHandler::handleException',
+ );
+ $error = array(
+ 'handler' => 'ErrorHandler::handleError',
+ 'level' => E_ALL & ~E_DEPRECATED,
+ );
+ self::_setErrorHandlers($error, $exception);
+
+ if (!include APP . 'Config' . DS . 'bootstrap.php') {
+ trigger_error(__d('cake_dev', "Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP.", APP . 'Config' . DS), E_USER_ERROR);
+ }
+ restore_error_handler();
+
+ self::_setErrorHandlers(
+ self::$_values['Error'],
+ self::$_values['Exception']
+ );
+
+ // Preload Debugger + String in case of E_STRICT errors when loading files.
+ if (self::$_values['debug'] > 0) {
+ class_exists('Debugger');
+ class_exists('String');
+ }
+ }
+ }
+
+/**
+ * Used to store a dynamic variable in Configure.
+ *
+ * Usage:
+ * {{{
+ * Configure::write('One.key1', 'value of the Configure::One[key1]');
+ * Configure::write(array('One.key1' => 'value of the Configure::One[key1]'));
+ * Configure::write('One', array(
+ * 'key1' => 'value of the Configure::One[key1]',
+ * 'key2' => 'value of the Configure::One[key2]'
+ * );
+ *
+ * Configure::write(array(
+ * 'One.key1' => 'value of the Configure::One[key1]',
+ * 'One.key2' => 'value of the Configure::One[key2]'
+ * ));
+ * }}}
+ *
+ * @link http://book.cakephp.org/2.0/en/development/configuration.html#Configure::write
+ * @param array $config Name of var to write
+ * @param mixed $value Value to set for var
+ * @return boolean True if write was successful
+ */
+ public static function write($config, $value = null) {
+ if (!is_array($config)) {
+ $config = array($config => $value);
+ }
+
+ foreach ($config as $name => $value) {
+ self::$_values = Hash::insert(self::$_values, $name, $value);
+ }
+
+ if (isset($config['debug']) && function_exists('ini_set')) {
+ if (self::$_values['debug']) {
+ ini_set('display_errors', 1);
+ } else {
+ ini_set('display_errors', 0);
+ }
+ }
+ return true;
+ }
+
+/**
+ * Used to read information stored in Configure. Its not
+ * possible to store `null` values in Configure.
+ *
+ * Usage:
+ * {{{
+ * Configure::read('Name'); will return all values for Name
+ * Configure::read('Name.key'); will return only the value of Configure::Name[key]
+ * }}}
+ *
+ * @linkhttp://book.cakephp.org/2.0/en/development/configuration.html#Configure::read
+ * @param string $var Variable to obtain. Use '.' to access array elements.
+ * @return mixed value stored in configure, or null.
+ */
+ public static function read($var = null) {
+ if ($var === null) {
+ return self::$_values;
+ }
+ return Hash::get(self::$_values, $var);
+ }
+
+/**
+ * Used to delete a variable from Configure.
+ *
+ * Usage:
+ * {{{
+ * Configure::delete('Name'); will delete the entire Configure::Name
+ * Configure::delete('Name.key'); will delete only the Configure::Name[key]
+ * }}}
+ *
+ * @link http://book.cakephp.org/2.0/en/development/configuration.html#Configure::delete
+ * @param string $var the var to be deleted
+ * @return void
+ */
+ public static function delete($var = null) {
+ $keys = explode('.', $var);
+ $last = array_pop($keys);
+ self::$_values = Hash::remove(self::$_values, $var);
+ }
+
+/**
+ * Add a new reader to Configure. Readers allow you to read configuration
+ * files in various formats/storage locations. CakePHP comes with two built-in readers
+ * PhpReader and IniReader. You can also implement your own reader classes in your application.
+ *
+ * To add a new reader to Configure:
+ *
+ * `Configure::config('ini', new IniReader());`
+ *
+ * @param string $name The name of the reader being configured. This alias is used later to
+ * read values from a specific reader.
+ * @param ConfigReaderInterface $reader The reader to append.
+ * @return void
+ */
+ public static function config($name, ConfigReaderInterface $reader) {
+ self::$_readers[$name] = $reader;
+ }
+
+/**
+ * Gets the names of the configured reader objects.
+ *
+ * @param string $name
+ * @return array Array of the configured reader objects.
+ */
+ public static function configured($name = null) {
+ if ($name) {
+ return isset(self::$_readers[$name]);
+ }
+ return array_keys(self::$_readers);
+ }
+
+/**
+ * Remove a configured reader. This will unset the reader
+ * and make any future attempts to use it cause an Exception.
+ *
+ * @param string $name Name of the reader to drop.
+ * @return boolean Success
+ */
+ public static function drop($name) {
+ if (!isset(self::$_readers[$name])) {
+ return false;
+ }
+ unset(self::$_readers[$name]);
+ return true;
+ }
+
+/**
+ * Loads stored configuration information from a resource. You can add
+ * config file resource readers with `Configure::config()`.
+ *
+ * Loaded configuration information will be merged with the current
+ * runtime configuration. You can load configuration files from plugins
+ * by preceding the filename with the plugin name.
+ *
+ * `Configure::load('Users.user', 'default')`
+ *
+ * Would load the 'user' config file using the default config reader. You can load
+ * app config files by giving the name of the resource you want loaded.
+ *
+ * `Configure::load('setup', 'default');`
+ *
+ * If using `default` config and no reader has been configured for it yet,
+ * one will be automatically created using PhpReader
+ *
+ * @link http://book.cakephp.org/2.0/en/development/configuration.html#Configure::load
+ * @param string $key name of configuration resource to load.
+ * @param string $config Name of the configured reader to use to read the resource identified by $key.
+ * @param boolean $merge if config files should be merged instead of simply overridden
+ * @return mixed false if file not found, void if load successful.
+ * @throws ConfigureException Will throw any exceptions the reader raises.
+ */
+ public static function load($key, $config = 'default', $merge = true) {
+ if (!isset(self::$_readers[$config])) {
+ if ($config === 'default') {
+ App::uses('PhpReader', 'Configure');
+ self::$_readers[$config] = new PhpReader();
+ } else {
+ return false;
+ }
+ }
+ $values = self::$_readers[$config]->read($key);
+
+ if ($merge) {
+ $keys = array_keys($values);
+ foreach ($keys as $key) {
+ if (($c = self::read($key)) && is_array($values[$key]) && is_array($c)) {
+ $values[$key] = Hash::merge($c, $values[$key]);
+ }
+ }
+ }
+
+ return self::write($values);
+ }
+
+/**
+ * Dump data currently in Configure into $filename. The serialization format
+ * is decided by the config reader attached as $config. For example, if the
+ * 'default' adapter is a PhpReader, the generated file will be a PHP
+ * configuration file loadable by the PhpReader.
+ *
+ * ## Usage
+ *
+ * Given that the 'default' reader is an instance of PhpReader.
+ * Save all data in Configure to the file `my_config.php`:
+ *
+ * `Configure::dump('my_config.php', 'default');`
+ *
+ * Save only the error handling configuration:
+ *
+ * `Configure::dump('error.php', 'default', array('Error', 'Exception');`
+ *
+ * @param string $key The identifier to create in the config adapter.
+ * This could be a filename or a cache key depending on the adapter being used.
+ * @param string $config The name of the configured adapter to dump data with.
+ * @param array $keys The name of the top-level keys you want to dump.
+ * This allows you save only some data stored in Configure.
+ * @return boolean success
+ * @throws ConfigureException if the adapter does not implement a `dump` method.
+ */
+ public static function dump($key, $config = 'default', $keys = array()) {
+ if (empty(self::$_readers[$config])) {
+ throw new ConfigureException(__d('cake', 'There is no "%s" adapter.', $config));
+ }
+ if (!method_exists(self::$_readers[$config], 'dump')) {
+ throw new ConfigureException(__d('cake', 'The "%s" adapter, does not have a dump() method.', $config));
+ }
+ $values = self::$_values;
+ if (!empty($keys) && is_array($keys)) {
+ $values = array_intersect_key($values, array_flip($keys));
+ }
+ return (bool)self::$_readers[$config]->dump($key, $values);
+ }
+
+/**
+ * Used to determine the current version of CakePHP.
+ *
+ * Usage `Configure::version();`
+ *
+ * @return string Current version of CakePHP
+ */
+ public static function version() {
+ if (!isset(self::$_values['Cake']['version'])) {
+ require CAKE . 'Config' . DS . 'config.php';
+ self::write($config);
+ }
+ return self::$_values['Cake']['version'];
+ }
+
+/**
+ * Used to write runtime configuration into Cache. Stored runtime configuration can be
+ * restored using `Configure::restore()`. These methods can be used to enable configuration managers
+ * frontends, or other GUI type interfaces for configuration.
+ *
+ * @param string $name The storage name for the saved configuration.
+ * @param string $cacheConfig The cache configuration to save into. Defaults to 'default'
+ * @param array $data Either an array of data to store, or leave empty to store all values.
+ * @return boolean Success
+ */
+ public static function store($name, $cacheConfig = 'default', $data = null) {
+ if ($data === null) {
+ $data = self::$_values;
+ }
+ return Cache::write($name, $data, $cacheConfig);
+ }
+
+/**
+ * Restores configuration data stored in the Cache into configure. Restored
+ * values will overwrite existing ones.
+ *
+ * @param string $name Name of the stored config file to load.
+ * @param string $cacheConfig Name of the Cache configuration to read from.
+ * @return boolean Success.
+ */
+ public static function restore($name, $cacheConfig = 'default') {
+ $values = Cache::read($name, $cacheConfig);
+ if ($values) {
+ return self::write($values);
+ }
+ return false;
+ }
+
+/**
+ * Clear all values stored in Configure.
+ *
+ * @return boolean success.
+ */
+ public static function clear() {
+ self::$_values = array();
+ return true;
+ }
+/**
+ * Set the error and exception handlers.
+ *
+ * @param array $error The Error handling configuration.
+ * @param array $exception The exception handling configuration.
+ * @return void
+ */
+ protected static function _setErrorHandlers($error, $exception) {
+ $level = -1;
+ if (isset($error['level'])) {
+ error_reporting($error['level']);
+ $level = $error['level'];
+ }
+ if (!empty($error['handler'])) {
+ set_error_handler($error['handler'], $level);
+ }
+ if (!empty($exception['handler'])) {
+ set_exception_handler($exception['handler']);
+ }
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Object.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Object.php
new file mode 100644
index 0000000..9723a28
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Core/Object.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Core
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Set', 'Utility');
+
+/**
+ * Object class provides a few generic methods used in several subclasses.
+ *
+ * Also includes methods for logging and the special method RequestAction,
+ * to call other Controllers' Actions from anywhere.
+ *
+ * @package Cake.Core
+ */
+class Object {
+
+/**
+ * constructor, no-op
+ *
+ */
+ public function __construct() {
+ }
+
+/**
+ * Object-to-string conversion.
+ * Each class can override this method as necessary.
+ *
+ * @return string The name of this class
+ */
+ public function toString() {
+ $class = get_class($this);
+ return $class;
+ }
+
+/**
+ * Calls a controller's method from any location. Can be used to connect controllers together
+ * or tie plugins into a main application. requestAction can be used to return rendered views
+ * or fetch the return value from controller actions.
+ *
+ * Under the hood this method uses Router::reverse() to convert the $url parameter into a string
+ * URL. You should use URL formats that are compatible with Router::reverse()
+ *
+ * #### Passing POST and GET data
+ *
+ * POST and GET data can be simulated in requestAction. Use `$extra['url']` for
+ * GET data. The `$extra['data']` parameter allows POST data simulation.
+ *
+ * @param string|array $url String or array-based url. Unlike other url arrays in CakePHP, this
+ * url will not automatically handle passed and named arguments in the $url parameter.
+ * @param array $extra if array includes the key "return" it sets the AutoRender to true. Can
+ * also be used to submit GET/POST data, and named/passed arguments.
+ * @return mixed Boolean true or false on success/failure, or contents
+ * of rendered action if 'return' is set in $extra.
+ */
+ public function requestAction($url, $extra = array()) {
+ if (empty($url)) {
+ return false;
+ }
+ App::uses('Dispatcher', 'Routing');
+ if (($index = array_search('return', $extra)) !== false) {
+ $extra['return'] = 0;
+ $extra['autoRender'] = 1;
+ unset($extra[$index]);
+ }
+ if (is_array($url) && !isset($extra['url'])) {
+ $extra['url'] = array();
+ }
+ $extra = array_merge(array('autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1), $extra);
+ $data = isset($extra['data']) ? $extra['data'] : null;
+ unset($extra['data']);
+
+ if (is_string($url) && strpos($url, FULL_BASE_URL) === 0) {
+ $url = Router::normalize(str_replace(FULL_BASE_URL, '', $url));
+ }
+ if (is_string($url)) {
+ $request = new CakeRequest($url);
+ } elseif (is_array($url)) {
+ $params = $url + array('pass' => array(), 'named' => array(), 'base' => false);
+ $params = array_merge($params, $extra);
+ $request = new CakeRequest(Router::reverse($params), false);
+ }
+ if (isset($data)) {
+ $request->data = $data;
+ }
+ $dispatcher = new Dispatcher();
+ $result = $dispatcher->dispatch($request, new CakeResponse(), $extra);
+ Router::popRequest();
+ return $result;
+ }
+
+/**
+ * Calls a method on this object with the given parameters. Provides an OO wrapper
+ * for `call_user_func_array`
+ *
+ * @param string $method Name of the method to call
+ * @param array $params Parameter list to use when calling $method
+ * @return mixed Returns the result of the method call
+ */
+ public function dispatchMethod($method, $params = array()) {
+ switch (count($params)) {
+ case 0:
+ return $this->{$method}();
+ case 1:
+ return $this->{$method}($params[0]);
+ case 2:
+ return $this->{$method}($params[0], $params[1]);
+ case 3:
+ return $this->{$method}($params[0], $params[1], $params[2]);
+ case 4:
+ return $this->{$method}($params[0], $params[1], $params[2], $params[3]);
+ case 5:
+ return $this->{$method}($params[0], $params[1], $params[2], $params[3], $params[4]);
+ default:
+ return call_user_func_array(array(&$this, $method), $params);
+ break;
+ }
+ }
+
+/**
+ * Stop execution of the current script. Wraps exit() making
+ * testing easier.
+ *
+ * @param integer|string $status see http://php.net/exit for values
+ * @return void
+ */
+ protected function _stop($status = 0) {
+ exit($status);
+ }
+
+/**
+ * Convenience method to write a message to CakeLog. See CakeLog::write()
+ * for more information on writing to logs.
+ *
+ * @param string $msg Log message
+ * @param integer $type Error type constant. Defined in app/Config/core.php.
+ * @return boolean Success of log write
+ */
+ public function log($msg, $type = LOG_ERR) {
+ App::uses('CakeLog', 'Log');
+ if (!is_string($msg)) {
+ $msg = print_r($msg, true);
+ }
+ return CakeLog::write($type, $msg);
+ }
+
+/**
+ * Allows setting of multiple properties of the object in a single line of code. Will only set
+ * properties that are part of a class declaration.
+ *
+ * @param array $properties An associative array containing properties and corresponding values.
+ * @return void
+ */
+ protected function _set($properties = array()) {
+ if (is_array($properties) && !empty($properties)) {
+ $vars = get_object_vars($this);
+ foreach ($properties as $key => $val) {
+ if (array_key_exists($key, $vars)) {
+ $this->{$key} = $val;
+ }
+ }
+ }
+ }
+
+/**
+ * Merges this objects $property with the property in $class' definition.
+ * This classes value for the property will be merged on top of $class'
+ *
+ * This provides some of the DRY magic CakePHP provides. If you want to shut it off, redefine
+ * this method as an empty function.
+ *
+ * @param array $properties The name of the properties to merge.
+ * @param string $class The class to merge the property with.
+ * @param boolean $normalize Set to true to run the properties through Hash::normalize() before merging.
+ * @return void
+ */
+ protected function _mergeVars($properties, $class, $normalize = true) {
+ $classProperties = get_class_vars($class);
+ foreach ($properties as $var) {
+ if (
+ isset($classProperties[$var]) &&
+ !empty($classProperties[$var]) &&
+ is_array($this->{$var}) &&
+ $this->{$var} != $classProperties[$var]
+ ) {
+ if ($normalize) {
+ $classProperties[$var] = Hash::normalize($classProperties[$var]);
+ $this->{$var} = Hash::normalize($this->{$var});
+ }
+ $this->{$var} = Hash::merge($classProperties[$var], $this->{$var});
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ErrorHandler.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ErrorHandler.php
new file mode 100644
index 0000000..dcc0973
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ErrorHandler.php
@@ -0,0 +1,261 @@
+<?php
+/**
+ * Error handler
+ *
+ * Provides Error Capturing for Framework errors.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Error
+ * @since CakePHP(tm) v 0.10.5.1732
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Debugger', 'Utility');
+App::uses('CakeLog', 'Log');
+App::uses('ExceptionRenderer', 'Error');
+App::uses('AppController', 'Controller');
+
+/**
+ *
+ * Error Handler provides basic error and exception handling for your application. It captures and
+ * handles all unhandled exceptions and errors. Displays helpful framework errors when debug > 1.
+ *
+ * ### Uncaught exceptions
+ *
+ * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown
+ * and it is a type that ErrorHandler does not know about it will be treated as a 500 error.
+ *
+ * ### Implementing application specific exception handling
+ *
+ * You can implement application specific exception handling in one of a few ways. Each approach
+ * gives you different amounts of control over the exception handling process.
+ *
+ * - Set Configure::write('Exception.handler', 'YourClass::yourMethod');
+ * - Create AppController::appError();
+ * - Set Configure::write('Exception.renderer', 'YourClass');
+ *
+ * #### Create your own Exception handler with `Exception.handler`
+ *
+ * This gives you full control over the exception handling process. The class you choose should be
+ * loaded in your app/Config/bootstrap.php, so its available to handle any exceptions. You can
+ * define the handler as any callback type. Using Exception.handler overrides all other exception
+ * handling settings and logic.
+ *
+ * #### Using `AppController::appError();`
+ *
+ * This controller method is called instead of the default exception rendering. It receives the
+ * thrown exception as its only argument. You should implement your error handling in that method.
+ * Using AppController::appError(), will supersede any configuration for Exception.renderer.
+ *
+ * #### Using a custom renderer with `Exception.renderer`
+ *
+ * If you don't want to take control of the exception handling, but want to change how exceptions are
+ * rendered you can use `Exception.renderer` to choose a class to render exception pages. By default
+ * `ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/Lib/Error.
+ *
+ * Your custom renderer should expect an exception in its constructor, and implement a render method.
+ * Failing to do so will cause additional errors.
+ *
+ * #### Logging exceptions
+ *
+ * Using the built-in exception handling, you can log all the exceptions
+ * that are dealt with by ErrorHandler by setting `Exception.log` to true in your core.php.
+ * Enabling this will log every exception to CakeLog and the configured loggers.
+ *
+ * ### PHP errors
+ *
+ * Error handler also provides the built in features for handling php errors (trigger_error).
+ * While in debug mode, errors will be output to the screen using debugger. While in production mode,
+ * errors will be logged to CakeLog. You can control which errors are logged by setting
+ * `Error.level` in your core.php.
+ *
+ * #### Logging errors
+ *
+ * When ErrorHandler is used for handling errors, you can enable error logging by setting `Error.log` to true.
+ * This will log all errors to the configured log handlers.
+ *
+ * #### Controlling what errors are logged/displayed
+ *
+ * You can control which errors are logged / displayed by ErrorHandler by setting `Error.level`. Setting this
+ * to one or a combination of a few of the E_* constants will only enable the specified errors.
+ *
+ * e.g. `Configure::write('Error.level', E_ALL & ~E_NOTICE);`
+ *
+ * Would enable handling for all non Notice errors.
+ *
+ * @package Cake.Error
+ * @see ExceptionRenderer for more information on how to customize exception rendering.
+ */
+class ErrorHandler {
+
+/**
+ * Set as the default exception handler by the CakePHP bootstrap process.
+ *
+ * This will either use custom exception renderer class if configured,
+ * or use the default ExceptionRenderer.
+ *
+ * @param Exception $exception
+ * @return void
+ * @see http://php.net/manual/en/function.set-exception-handler.php
+ */
+ public static function handleException(Exception $exception) {
+ $config = Configure::read('Exception');
+ if (!empty($config['log'])) {
+ $message = sprintf("[%s] %s\n%s",
+ get_class($exception),
+ $exception->getMessage(),
+ $exception->getTraceAsString()
+ );
+ CakeLog::write(LOG_ERR, $message);
+ }
+ $renderer = $config['renderer'];
+ if ($renderer !== 'ExceptionRenderer') {
+ list($plugin, $renderer) = pluginSplit($renderer, true);
+ App::uses($renderer, $plugin . 'Error');
+ }
+ try {
+ $error = new $renderer($exception);
+ $error->render();
+ } catch (Exception $e) {
+ set_error_handler(Configure::read('Error.handler')); // Should be using configured ErrorHandler
+ Configure::write('Error.trace', false); // trace is useless here since it's internal
+ $message = sprintf("[%s] %s\n%s", // Keeping same message format
+ get_class($e),
+ $e->getMessage(),
+ $e->getTraceAsString()
+ );
+ trigger_error($message, E_USER_ERROR);
+ }
+ }
+
+/**
+ * Set as the default error handler by CakePHP. Use Configure::write('Error.handler', $callback), to use your own
+ * error handling methods. This function will use Debugger to display errors when debug > 0. And
+ * will log errors to CakeLog, when debug == 0.
+ *
+ * You can use Configure::write('Error.level', $value); to set what type of errors will be handled here.
+ * Stack traces for errors can be enabled with Configure::write('Error.trace', true);
+ *
+ * @param integer $code Code of error
+ * @param string $description Error description
+ * @param string $file File on which error occurred
+ * @param integer $line Line that triggered the error
+ * @param array $context Context
+ * @return boolean true if error was handled
+ */
+ public static function handleError($code, $description, $file = null, $line = null, $context = null) {
+ if (error_reporting() === 0) {
+ return false;
+ }
+ $errorConfig = Configure::read('Error');
+ list($error, $log) = self::mapErrorCode($code);
+ if ($log === LOG_ERR) {
+ return self::handleFatalError($code, $description, $file, $line);
+ }
+
+ $debug = Configure::read('debug');
+ if ($debug) {
+ $data = array(
+ 'level' => $log,
+ 'code' => $code,
+ 'error' => $error,
+ 'description' => $description,
+ 'file' => $file,
+ 'line' => $line,
+ 'context' => $context,
+ 'start' => 2,
+ 'path' => Debugger::trimPath($file)
+ );
+ return Debugger::getInstance()->outputError($data);
+ } else {
+ $message = $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
+ if (!empty($errorConfig['trace'])) {
+ $trace = Debugger::trace(array('start' => 1, 'format' => 'log'));
+ $message .= "\nTrace:\n" . $trace . "\n";
+ }
+ return CakeLog::write($log, $message);
+ }
+ }
+
+/**
+ * Generate an error page when some fatal error happens.
+ *
+ * @param integer $code Code of error
+ * @param string $description Error description
+ * @param string $file File on which error occurred
+ * @param integer $line Line that triggered the error
+ * @return boolean
+ */
+ public static function handleFatalError($code, $description, $file, $line) {
+ $logMessage = 'Fatal Error (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
+ CakeLog::write(LOG_ERR, $logMessage);
+
+ $exceptionHandler = Configure::read('Exception.handler');
+ if (!is_callable($exceptionHandler)) {
+ return false;
+ }
+
+ if (ob_get_level()) {
+ ob_clean();
+ }
+
+ if (Configure::read('debug')) {
+ call_user_func($exceptionHandler, new FatalErrorException($description, 500, $file, $line));
+ } else {
+ call_user_func($exceptionHandler, new InternalErrorException());
+ }
+ return false;
+ }
+
+/**
+ * Map an error code into an Error word, and log location.
+ *
+ * @param integer $code Error code to map
+ * @return array Array of error word, and log location.
+ */
+ public static function mapErrorCode($code) {
+ $error = $log = null;
+ switch ($code) {
+ case E_PARSE:
+ case E_ERROR:
+ case E_CORE_ERROR:
+ case E_COMPILE_ERROR:
+ case E_USER_ERROR:
+ $error = 'Fatal Error';
+ $log = LOG_ERR;
+ break;
+ case E_WARNING:
+ case E_USER_WARNING:
+ case E_COMPILE_WARNING:
+ case E_RECOVERABLE_ERROR:
+ $error = 'Warning';
+ $log = LOG_WARNING;
+ break;
+ case E_NOTICE:
+ case E_USER_NOTICE:
+ $error = 'Notice';
+ $log = LOG_NOTICE;
+ break;
+ case E_STRICT:
+ $error = 'Strict';
+ $log = LOG_NOTICE;
+ break;
+ case E_DEPRECATED:
+ case E_USER_DEPRECATED:
+ $error = 'Deprecated';
+ $log = LOG_NOTICE;
+ break;
+ }
+ return array($error, $log);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ExceptionRenderer.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ExceptionRenderer.php
new file mode 100644
index 0000000..b158b05
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/ExceptionRenderer.php
@@ -0,0 +1,301 @@
+<?php
+/**
+ * Exception Renderer
+ *
+ * Provides Exception rendering features. Which allow exceptions to be rendered
+ * as HTML pages.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Error
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Sanitize', 'Utility');
+App::uses('Router', 'Routing');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * Exception Renderer.
+ *
+ * Captures and handles all unhandled exceptions. Displays helpful framework errors when debug > 1.
+ * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown
+ * and it is a type that ExceptionHandler does not know about it will be treated as a 500 error.
+ *
+ * ### Implementing application specific exception rendering
+ *
+ * You can implement application specific exception handling in one of a few ways:
+ *
+ * - Create a AppController::appError();
+ * - Create a subclass of ExceptionRenderer and configure it to be the `Exception.renderer`
+ *
+ * #### Using AppController::appError();
+ *
+ * This controller method is called instead of the default exception handling. It receives the
+ * thrown exception as its only argument. You should implement your error handling in that method.
+ *
+ * #### Using a subclass of ExceptionRenderer
+ *
+ * Using a subclass of ExceptionRenderer gives you full control over how Exceptions are rendered, you
+ * can configure your class in your core.php, with `Configure::write('Exception.renderer', 'MyClass');`
+ * You should place any custom exception renderers in `app/Lib/Error`.
+ *
+ * @package Cake.Error
+ */
+class ExceptionRenderer {
+
+/**
+ * Controller instance.
+ *
+ * @var Controller
+ */
+ public $controller = null;
+
+/**
+ * template to render for CakeException
+ *
+ * @var string
+ */
+ public $template = '';
+
+/**
+ * The method corresponding to the Exception this object is for.
+ *
+ * @var string
+ */
+ public $method = '';
+
+/**
+ * The exception being handled.
+ *
+ * @var Exception
+ */
+ public $error = null;
+
+/**
+ * Creates the controller to perform rendering on the error response.
+ * If the error is a CakeException it will be converted to either a 400 or a 500
+ * code error depending on the code used to construct the error.
+ *
+ * @param Exception $exception Exception
+ */
+ public function __construct(Exception $exception) {
+ $this->controller = $this->_getController($exception);
+
+ if (method_exists($this->controller, 'apperror')) {
+ return $this->controller->appError($exception);
+ }
+ $method = $template = Inflector::variable(str_replace('Exception', '', get_class($exception)));
+ $code = $exception->getCode();
+
+ $methodExists = method_exists($this, $method);
+
+ if ($exception instanceof CakeException && !$methodExists) {
+ $method = '_cakeError';
+ if (empty($template)) {
+ $template = 'error500';
+ }
+ if ($template == 'internalError') {
+ $template = 'error500';
+ }
+ } elseif ($exception instanceof PDOException) {
+ $method = 'pdoError';
+ $template = 'pdo_error';
+ $code = 500;
+ } elseif (!$methodExists) {
+ $method = 'error500';
+ if ($code >= 400 && $code < 500) {
+ $method = 'error400';
+ }
+ }
+
+ if (Configure::read('debug') == 0) {
+ if ($method == '_cakeError') {
+ $method = 'error400';
+ }
+ if ($code == 500) {
+ $method = 'error500';
+ }
+ }
+ $this->template = $template;
+ $this->method = $method;
+ $this->error = $exception;
+ }
+
+/**
+ * Get the controller instance to handle the exception.
+ * Override this method in subclasses to customize the controller used.
+ * This method returns the built in `CakeErrorController` normally, or if an error is repeated
+ * a bare controller will be used.
+ *
+ * @param Exception $exception The exception to get a controller for.
+ * @return Controller
+ */
+ protected function _getController($exception) {
+ App::uses('CakeErrorController', 'Controller');
+ if (!$request = Router::getRequest(true)) {
+ $request = new CakeRequest();
+ }
+ $response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ try {
+ if (class_exists('AppController')) {
+ $controller = new CakeErrorController($request, $response);
+ }
+ } catch (Exception $e) {
+ }
+ if (empty($controller)) {
+ $controller = new Controller($request, $response);
+ $controller->viewPath = 'Errors';
+ }
+ return $controller;
+ }
+
+/**
+ * Renders the response for the exception.
+ *
+ * @return void
+ */
+ public function render() {
+ if ($this->method) {
+ call_user_func_array(array($this, $this->method), array($this->error));
+ }
+ }
+
+/**
+ * Generic handler for the internal framework errors CakePHP can generate.
+ *
+ * @param CakeException $error
+ * @return void
+ */
+ protected function _cakeError(CakeException $error) {
+ $url = $this->controller->request->here();
+ $code = ($error->getCode() >= 400 && $error->getCode() < 506) ? $error->getCode() : 500;
+ $this->controller->response->statusCode($code);
+ $this->controller->set(array(
+ 'code' => $code,
+ 'url' => h($url),
+ 'name' => $error->getMessage(),
+ 'error' => $error,
+ '_serialize' => array('code', 'url', 'name')
+ ));
+ $this->controller->set($error->getAttributes());
+ $this->_outputMessage($this->template);
+ }
+
+/**
+ * Convenience method to display a 400 series page.
+ *
+ * @param Exception $error
+ * @return void
+ */
+ public function error400($error) {
+ $message = $error->getMessage();
+ if (Configure::read('debug') == 0 && $error instanceof CakeException) {
+ $message = __d('cake', 'Not Found');
+ }
+ $url = $this->controller->request->here();
+ $this->controller->response->statusCode($error->getCode());
+ $this->controller->set(array(
+ 'name' => $message,
+ 'url' => h($url),
+ 'error' => $error,
+ '_serialize' => array('name', 'url')
+ ));
+ $this->_outputMessage('error400');
+ }
+
+/**
+ * Convenience method to display a 500 page.
+ *
+ * @param Exception $error
+ * @return void
+ */
+ public function error500($error) {
+ $message = $error->getMessage();
+ if (Configure::read('debug') == 0) {
+ $message = __d('cake', 'An Internal Error Has Occurred.');
+ }
+ $url = $this->controller->request->here();
+ $code = ($error->getCode() > 500 && $error->getCode() < 506) ? $error->getCode() : 500;
+ $this->controller->response->statusCode($code);
+ $this->controller->set(array(
+ 'name' => $message,
+ 'message' => h($url),
+ 'error' => $error,
+ '_serialize' => array('name', 'message')
+ ));
+ $this->_outputMessage('error500');
+ }
+
+/**
+ * Convenience method to display a PDOException.
+ *
+ * @param PDOException $error
+ * @return void
+ */
+ public function pdoError(PDOException $error) {
+ $url = $this->controller->request->here();
+ $code = 500;
+ $this->controller->response->statusCode($code);
+ $this->controller->set(array(
+ 'code' => $code,
+ 'url' => h($url),
+ 'name' => $error->getMessage(),
+ 'error' => $error,
+ '_serialize' => array('code', 'url', 'name', 'error')
+ ));
+ $this->_outputMessage($this->template);
+ }
+
+/**
+ * Generate the response using the controller object.
+ *
+ * @param string $template The template to render.
+ * @return void
+ */
+ protected function _outputMessage($template) {
+ try {
+ $this->controller->render($template);
+ $this->controller->afterFilter();
+ $this->controller->response->send();
+ } catch (MissingViewException $e) {
+ try {
+ $this->_outputMessage('error500');
+ } catch (Exception $e) {
+ $this->_outputMessageSafe('error500');
+ }
+ } catch (Exception $e) {
+ $this->_outputMessageSafe('error500');
+ }
+ }
+
+/**
+ * A safer way to render error messages, replaces all helpers, with basics
+ * and doesn't call component methods.
+ *
+ * @param string $template The template to render
+ * @return void
+ */
+ protected function _outputMessageSafe($template) {
+ $this->controller->layoutPath = null;
+ $this->controller->subDir = null;
+ $this->controller->viewPath = 'Errors/';
+ $this->controller->viewClass = 'View';
+ $this->controller->layout = 'error';
+ $this->controller->helpers = array('Form', 'Html', 'Session');
+
+ $this->controller->render($template);
+ $this->controller->response->type('html');
+ $this->controller->response->send();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/exceptions.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/exceptions.php
new file mode 100644
index 0000000..94952f1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Error/exceptions.php
@@ -0,0 +1,579 @@
+<?php
+/**
+ * Exceptions file. Contains the various exceptions CakePHP will throw until they are
+ * moved into their permanent location.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html
+ * @package Cake.Error
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Parent class for all of the HTTP related exceptions in CakePHP.
+ * All HTTP status/error related exceptions should extend this class so
+ * catch blocks can be specifically typed.
+ *
+ * @package Cake.Error
+ */
+if (!class_exists('HttpException')) {
+ class HttpException extends RuntimeException {
+ }
+}
+
+/**
+ * Represents an HTTP 400 error.
+ *
+ * @package Cake.Error
+ */
+class BadRequestException extends HttpException {
+
+/**
+ * Constructor
+ *
+ * @param string $message If no message is given 'Bad Request' will be the message
+ * @param string $code Status code, defaults to 400
+ */
+ public function __construct($message = null, $code = 400) {
+ if (empty($message)) {
+ $message = 'Bad Request';
+ }
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Represents an HTTP 401 error.
+ *
+ * @package Cake.Error
+ */
+class UnauthorizedException extends HttpException {
+
+/**
+ * Constructor
+ *
+ * @param string $message If no message is given 'Unauthorized' will be the message
+ * @param string $code Status code, defaults to 401
+ */
+ public function __construct($message = null, $code = 401) {
+ if (empty($message)) {
+ $message = 'Unauthorized';
+ }
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Represents an HTTP 403 error.
+ *
+ * @package Cake.Error
+ */
+class ForbiddenException extends HttpException {
+
+/**
+ * Constructor
+ *
+ * @param string $message If no message is given 'Forbidden' will be the message
+ * @param string $code Status code, defaults to 403
+ */
+ public function __construct($message = null, $code = 403) {
+ if (empty($message)) {
+ $message = 'Forbidden';
+ }
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Represents an HTTP 404 error.
+ *
+ * @package Cake.Error
+ */
+class NotFoundException extends HttpException {
+
+/**
+ * Constructor
+ *
+ * @param string $message If no message is given 'Not Found' will be the message
+ * @param string $code Status code, defaults to 404
+ */
+ public function __construct($message = null, $code = 404) {
+ if (empty($message)) {
+ $message = 'Not Found';
+ }
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Represents an HTTP 405 error.
+ *
+ * @package Cake.Error
+ */
+class MethodNotAllowedException extends HttpException {
+
+/**
+ * Constructor
+ *
+ * @param string $message If no message is given 'Method Not Allowed' will be the message
+ * @param string $code Status code, defaults to 405
+ */
+ public function __construct($message = null, $code = 405) {
+ if (empty($message)) {
+ $message = 'Method Not Allowed';
+ }
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Represents an HTTP 500 error.
+ *
+ * @package Cake.Error
+ */
+class InternalErrorException extends HttpException {
+
+/**
+ * Constructor
+ *
+ * @param string $message If no message is given 'Internal Server Error' will be the message
+ * @param string $code Status code, defaults to 500
+ */
+ public function __construct($message = null, $code = 500) {
+ if (empty($message)) {
+ $message = 'Internal Server Error';
+ }
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * CakeException is used a base class for CakePHP's internal exceptions.
+ * In general framework errors are interpreted as 500 code errors.
+ *
+ * @package Cake.Error
+ */
+class CakeException extends RuntimeException {
+
+/**
+ * Array of attributes that are passed in from the constructor, and
+ * made available in the view when a development error is displayed.
+ *
+ * @var array
+ */
+ protected $_attributes = array();
+
+/**
+ * Template string that has attributes sprintf()'ed into it.
+ *
+ * @var string
+ */
+ protected $_messageTemplate = '';
+
+/**
+ * Constructor.
+ *
+ * Allows you to create exceptions that are treated as framework errors and disabled
+ * when debug = 0.
+ *
+ * @param string|array $message Either the string of the error message, or an array of attributes
+ * that are made available in the view, and sprintf()'d into CakeException::$_messageTemplate
+ * @param string $code The code of the error, is also the HTTP status code for the error.
+ */
+ public function __construct($message, $code = 500) {
+ if (is_array($message)) {
+ $this->_attributes = $message;
+ $message = __d('cake_dev', $this->_messageTemplate, $message);
+ }
+ parent::__construct($message, $code);
+ }
+
+/**
+ * Get the passed in attributes
+ *
+ * @return array
+ */
+ public function getAttributes() {
+ return $this->_attributes;
+ }
+
+}
+
+/**
+ * Missing Controller exception - used when a controller
+ * cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingControllerException extends CakeException {
+
+ protected $_messageTemplate = 'Controller class %s could not be found.';
+
+ public function __construct($message, $code = 404) {
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Missing Action exception - used when a controller action
+ * cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingActionException extends CakeException {
+
+ protected $_messageTemplate = 'Action %s::%s() could not be found.';
+
+ public function __construct($message, $code = 404) {
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Private Action exception - used when a controller action
+ * starts with a `_`.
+ *
+ * @package Cake.Error
+ */
+class PrivateActionException extends CakeException {
+
+ protected $_messageTemplate = 'Private Action %s::%s() is not directly accessible.';
+
+ public function __construct($message, $code = 404, Exception $previous = null) {
+ parent::__construct($message, $code, $previous);
+ }
+
+}
+
+/**
+ * Used when a component cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingComponentException extends CakeException {
+
+ protected $_messageTemplate = 'Component class %s could not be found.';
+
+}
+
+/**
+ * Used when a behavior cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingBehaviorException extends CakeException {
+
+ protected $_messageTemplate = 'Behavior class %s could not be found.';
+
+}
+
+/**
+ * Used when a view file cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingViewException extends CakeException {
+
+ protected $_messageTemplate = 'View file "%s" is missing.';
+
+}
+
+/**
+ * Used when a layout file cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingLayoutException extends CakeException {
+
+ protected $_messageTemplate = 'Layout file "%s" is missing.';
+
+}
+
+/**
+ * Used when a helper cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingHelperException extends CakeException {
+
+ protected $_messageTemplate = 'Helper class %s could not be found.';
+
+}
+
+/**
+ * Runtime Exceptions for ConnectionManager
+ *
+ * @package Cake.Error
+ */
+class MissingDatabaseException extends CakeException {
+
+ protected $_messageTemplate = 'Database connection "%s" could not be found.';
+
+}
+
+/**
+ * Used when no connections can be found.
+ *
+ * @package Cake.Error
+ */
+class MissingConnectionException extends CakeException {
+
+ protected $_messageTemplate = 'Database connection "%s" is missing, or could not be created.';
+
+ public function __construct($message, $code = 500) {
+ if (is_array($message)) {
+ $message += array('enabled' => true);
+ }
+ parent::__construct($message, $code);
+ }
+
+}
+
+/**
+ * Used when a Task cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingTaskException extends CakeException {
+
+ protected $_messageTemplate = 'Task class %s could not be found.';
+
+}
+
+/**
+ * Used when a shell method cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingShellMethodException extends CakeException {
+
+ protected $_messageTemplate = "Unknown command %1\$s %2\$s.\nFor usage try `cake %1\$s --help`";
+
+}
+
+/**
+ * Used when a shell cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingShellException extends CakeException {
+
+ protected $_messageTemplate = 'Shell class %s could not be found.';
+
+}
+
+/**
+ * Exception class to be thrown when a datasource configuration is not found
+ *
+ * @package Cake.Error
+ */
+class MissingDatasourceConfigException extends CakeException {
+
+ protected $_messageTemplate = 'The datasource configuration "%s" was not found in database.php';
+
+}
+
+/**
+ * Used when a datasource cannot be found.
+ *
+ * @package Cake.Error
+ */
+class MissingDatasourceException extends CakeException {
+
+ protected $_messageTemplate = 'Datasource class %s could not be found.';
+
+}
+
+/**
+ * Exception class to be thrown when a database table is not found in the datasource
+ *
+ * @package Cake.Error
+ */
+class MissingTableException extends CakeException {
+
+ protected $_messageTemplate = 'Table %s for model %s was not found in datasource %s.';
+
+}
+
+/**
+ * Exception raised when a Model could not be found.
+ *
+ * @package Cake.Error
+ */
+class MissingModelException extends CakeException {
+
+ protected $_messageTemplate = 'Model %s could not be found.';
+
+}
+
+/**
+ * Exception raised when a test loader could not be found
+ *
+ * @package Cake.Error
+ */
+class MissingTestLoaderException extends CakeException {
+
+ protected $_messageTemplate = 'Test loader %s could not be found.';
+
+}
+
+/**
+ * Exception raised when a plugin could not be found
+ *
+ * @package Cake.Error
+ */
+class MissingPluginException extends CakeException {
+
+ protected $_messageTemplate = 'Plugin %s could not be found.';
+
+}
+
+/**
+ * Exception raised when a Dispatcher filter could not be found
+ *
+ * @package Cake.Error
+ */
+class MissingDispatcherFilterException extends CakeException {
+
+ protected $_messageTemplate = 'Dispatcher filter %s could not be found.';
+
+}
+
+/**
+ * Exception class for AclComponent and Interface implementations.
+ *
+ * @package Cake.Error
+ */
+class AclException extends CakeException {
+}
+
+/**
+ * Exception class for Cache. This exception will be thrown from Cache when it
+ * encounters an error.
+ *
+ * @package Cake.Error
+ */
+class CacheException extends CakeException {
+}
+
+/**
+ * Exception class for Router. This exception will be thrown from Router when it
+ * encounters an error.
+ *
+ * @package Cake.Error
+ */
+class RouterException extends CakeException {
+}
+
+/**
+ * Exception class for CakeLog. This exception will be thrown from CakeLog when it
+ * encounters an error.
+ *
+ * @package Cake.Error
+ */
+class CakeLogException extends CakeException {
+}
+
+/**
+ * Exception class for CakeSession. This exception will be thrown from CakeSession when it
+ * encounters an error.
+ *
+ * @package Cake.Error
+ */
+class CakeSessionException extends CakeException {
+}
+
+/**
+ * Exception class for Configure. This exception will be thrown from Configure when it
+ * encounters an error.
+ *
+ * @package Cake.Error
+ */
+class ConfigureException extends CakeException {
+}
+
+/**
+ * Exception class for Socket. This exception will be thrown from CakeSocket, CakeEmail, HttpSocket
+ * SmtpTransport, MailTransport and HttpResponse when it encounters an error.
+ *
+ * @package Cake.Error
+ */
+class SocketException extends CakeException {
+}
+
+/**
+ * Exception class for Xml. This exception will be thrown from Xml when it
+ * encounters an error.
+ *
+ * @package Cake.Error
+ */
+class XmlException extends CakeException {
+}
+
+/**
+ * Exception class for Console libraries. This exception will be thrown from Console library
+ * classes when they encounter an error.
+ *
+ * @package Cake.Error
+ */
+class ConsoleException extends CakeException {
+}
+
+/**
+ * Represents a fatal error
+ *
+ * @package Cake.Error
+ */
+class FatalErrorException extends CakeException {
+
+/**
+ * Constructor
+ *
+ * @param string $message
+ * @param integer $code
+ * @param string $file
+ * @param integer $line
+ */
+ public function __construct($message, $code = 500, $file = null, $line = null) {
+ parent::__construct($message, $code);
+ if ($file) {
+ $this->file = $file;
+ }
+ if ($line) {
+ $this->line = $line;
+ }
+ }
+
+}
+
+/**
+ * Not Implemented Exception - used when an API method is not implemented
+ *
+ * @package Cake.Error
+ */
+class NotImplementedException extends CakeException {
+
+ protected $_messageTemplate = '%s is not implemented.';
+
+ public function __construct($message, $code = 501) {
+ parent::__construct($message, $code);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEvent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEvent.php
new file mode 100644
index 0000000..52de3cf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEvent.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Observer
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Represent the transport class of events across the system, it receives a name, and subject and an optional
+ * payload. The name can be any string that uniquely identifies the event across the application, while the subject
+ * represents the object that the event is applying to.
+ *
+ * @package Cake.Event
+ */
+class CakeEvent {
+
+/**
+ * Name of the event
+ *
+ * @var string $name
+ */
+ protected $_name = null;
+
+/**
+ * The object this event applies to (usually the same object that generates the event)
+ *
+ * @var object
+ */
+ protected $_subject;
+
+/**
+ * Custom data for the method that receives the event
+ *
+ * @var mixed $data
+ */
+ public $data = null;
+
+/**
+ * Property used to retain the result value of the event listeners
+ *
+ * @var mixed $result
+ */
+ public $result = null;
+
+/**
+ * Flags an event as stopped or not, default is false
+ *
+ * @var boolean
+ */
+ protected $_stopped = false;
+
+/**
+ * Constructor
+ *
+ * @param string $name Name of the event
+ * @param object $subject the object that this event applies to (usually the object that is generating the event)
+ * @param mixed $data any value you wish to be transported with this event to it can be read by listeners
+ *
+ * ## Examples of usage:
+ *
+ * {{{
+ * $event = new CakeEvent('Order.afterBuy', $this, array('buyer' => $userData));
+ * $event = new CakeEvent('User.afterRegister', $UserModel);
+ * }}}
+ *
+ */
+ public function __construct($name, $subject = null, $data = null) {
+ $this->_name = $name;
+ $this->data = $data;
+ $this->_subject = $subject;
+ }
+
+/**
+ * Dynamically returns the name and subject if accessed directly
+ *
+ * @param string $attribute
+ * @return mixed
+ */
+ public function __get($attribute) {
+ if ($attribute === 'name' || $attribute === 'subject') {
+ return $this->{$attribute}();
+ }
+ }
+
+/**
+ * Returns the name of this event. This is usually used as the event identifier
+ *
+ * @return string
+ */
+ public function name() {
+ return $this->_name;
+ }
+
+/**
+ * Returns the subject of this event
+ *
+ * @return string
+ */
+ public function subject() {
+ return $this->_subject;
+ }
+
+/**
+ * Stops the event from being used anymore
+ *
+ * @return void
+ */
+ public function stopPropagation() {
+ return $this->_stopped = true;
+ }
+
+/**
+ * Check if the event is stopped
+ *
+ * @return boolean True if the event is stopped
+ */
+ public function isStopped() {
+ return $this->_stopped;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventListener.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventListener.php
new file mode 100644
index 0000000..c491594
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventListener.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Observer
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Objects implementing this interface should declare the `implementedEvents` function
+ * to hint the event manager what methods should be called when an event is triggered.
+ *
+ * @package Cake.Event
+ */
+interface CakeEventListener {
+
+/**
+ * Returns a list of events this object is implementing, when the class is registered
+ * in an event manager, each individual method will be associated to the respective event.
+ *
+ * ## Example:
+ *
+ * {{{
+ * public function implementedEvents() {
+ * return array(
+ * 'Order.complete' => 'sendEmail',
+ * 'Article.afterBuy' => 'decrementInventory',
+ * 'User.onRegister' => array('callable' => 'logRegistration', 'priority' => 20, 'passParams' => true)
+ * );
+ * }
+ * }}}
+ *
+ * @return array associative array or event key names pointing to the function
+ * that should be called in the object when the respective event is fired
+ */
+ public function implementedEvents();
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventManager.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventManager.php
new file mode 100644
index 0000000..252364d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Event/CakeEventManager.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Event
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * The event manager is responsible for keeping track of event listeners and pass the correct
+ * data to them, and fire them in the correct order, when associated events are triggered. You
+ * can create multiple instances of this objects to manage local events or keep a single instance
+ * and pass it around to manage all events in your app.
+ *
+ * @package Cake.Event
+ */
+class CakeEventManager {
+
+/**
+ * The default priority queue value for new attached listeners
+ *
+ * @var int
+ */
+ public static $defaultPriority = 10;
+
+/**
+ * The globally available instance, used for dispatching events attached from any scope
+ *
+ * @var CakeEventManager
+ */
+ protected static $_generalManager = null;
+
+/**
+ * List of listener callbacks associated to
+ *
+ * @var object $Listeners
+ */
+ protected $_listeners = array();
+
+/**
+ * Internal flag to distinguish a common manager from the sigleton
+ *
+ * @var boolean
+ */
+ protected $_isGlobal = false;
+
+/**
+ * Returns the globally available instance of a CakeEventManager
+ * this is used for dispatching events attached from outside the scope
+ * other managers were created. Usually for creating hook systems or inter-class
+ * communication
+ *
+ * If called with a first params, it will be set as the globally available instance
+ *
+ * @param CakeEventManager $manager
+ * @return CakeEventManager the global event manager
+ */
+ public static function instance($manager = null) {
+ if ($manager instanceof CakeEventManager) {
+ self::$_generalManager = $manager;
+ }
+ if (empty(self::$_generalManager)) {
+ self::$_generalManager = new CakeEventManager;
+ }
+
+ self::$_generalManager->_isGlobal = true;
+ return self::$_generalManager;
+ }
+
+/**
+ * Adds a new listener to an event. Listeners
+ *
+ * @param callback|CakeEventListener $callable PHP valid callback type or instance of CakeEventListener to be called
+ * when the event named with $eventKey is triggered. If a CakeEventListener instances is passed, then the `implementedEvents`
+ * method will be called on the object to register the declared events individually as methods to be managed by this class.
+ * It is possible to define multiple event handlers per event name.
+ *
+ * @param string $eventKey The event unique identifier name to with the callback will be associated. If $callable
+ * is an instance of CakeEventListener this argument will be ignored
+ *
+ * @param array $options used to set the `priority` and `passParams` flags to the listener.
+ * Priorities are handled like queues, and multiple attachments into the same priority queue will be treated in
+ * the order of insertion. `passParams` means that the event data property will be converted to function arguments
+ * when the listener is called. If $called is an instance of CakeEventListener, this parameter will be ignored
+ *
+ * @return void
+ * @throws InvalidArgumentException When event key is missing or callable is not an
+ * instance of CakeEventListener.
+ */
+ public function attach($callable, $eventKey = null, $options = array()) {
+ if (!$eventKey && !($callable instanceof CakeEventListener)) {
+ throw new InvalidArgumentException(__d('cake_dev', 'The eventKey variable is required'));
+ }
+ if ($callable instanceof CakeEventListener) {
+ $this->_attachSubscriber($callable);
+ return;
+ }
+ $options = $options + array('priority' => self::$defaultPriority, 'passParams' => false);
+ $this->_listeners[$eventKey][$options['priority']][] = array(
+ 'callable' => $callable,
+ 'passParams' => $options['passParams'],
+ );
+ }
+
+/**
+ * Auxiliary function to attach all implemented callbacks of a CakeEventListener class instance
+ * as individual methods on this manager
+ *
+ * @param CakeEventListener $subscriber
+ * @return void
+ */
+ protected function _attachSubscriber(CakeEventListener $subscriber) {
+ foreach ($subscriber->implementedEvents() as $eventKey => $function) {
+ $options = array();
+ $method = $function;
+ if (is_array($function) && isset($function['callable'])) {
+ list($method, $options) = $this->_extractCallable($function, $subscriber);
+ } elseif (is_array($function) && is_numeric(key($function))) {
+ foreach ($function as $f) {
+ list($method, $options) = $this->_extractCallable($f, $subscriber);
+ $this->attach($method, $eventKey, $options);
+ }
+ continue;
+ }
+ if (is_string($method)) {
+ $method = array($subscriber, $function);
+ }
+ $this->attach($method, $eventKey, $options);
+ }
+ }
+
+/**
+ * Auxiliary function to extract and return a PHP callback type out of the callable definition
+ * from the return value of the `implementedEvents` method on a CakeEventListener
+ *
+ * @param array $function the array taken from a handler definition for a event
+ * @param CakeEventListener $object The handler object
+ * @return callback
+ */
+ protected function _extractCallable($function, $object) {
+ $method = $function['callable'];
+ $options = $function;
+ unset($options['callable']);
+ if (is_string($method)) {
+ $method = array($object, $method);
+ }
+ return array($method, $options);
+ }
+
+/**
+ * Removes a listener from the active listeners.
+ *
+ * @param callback|CakeEventListener $callable any valid PHP callback type or an instance of CakeEventListener
+ * @return void
+ */
+ public function detach($callable, $eventKey = null) {
+ if ($callable instanceof CakeEventListener) {
+ return $this->_detachSubscriber($callable, $eventKey);
+ }
+ if (empty($eventKey)) {
+ foreach (array_keys($this->_listeners) as $eventKey) {
+ $this->detach($callable, $eventKey);
+ }
+ return;
+ }
+ if (empty($this->_listeners[$eventKey])) {
+ return;
+ }
+ foreach ($this->_listeners[$eventKey] as $priority => $callables) {
+ foreach ($callables as $k => $callback) {
+ if ($callback['callable'] === $callable) {
+ unset($this->_listeners[$eventKey][$priority][$k]);
+ break;
+ }
+ }
+ }
+ }
+
+/**
+ * Auxiliary function to help detach all listeners provided by an object implementing CakeEventListener
+ *
+ * @param CakeEventListener $subscriber the subscriber to be detached
+ * @param string $eventKey optional event key name to unsubscribe the listener from
+ * @return void
+ */
+ protected function _detachSubscriber(CakeEventListener $subscriber, $eventKey = null) {
+ $events = $subscriber->implementedEvents();
+ if (!empty($eventKey) && empty($events[$eventKey])) {
+ return;
+ } elseif (!empty($eventKey)) {
+ $events = array($eventKey => $events[$eventKey]);
+ }
+ foreach ($events as $key => $function) {
+ if (is_array($function)) {
+ if (is_numeric(key($function))) {
+ foreach ($function as $handler) {
+ $handler = isset($handler['callable']) ? $handler['callable'] : $handler;
+ $this->detach(array($subscriber, $handler), $key);
+ }
+ continue;
+ }
+ $function = $function['callable'];
+ }
+ $this->detach(array($subscriber, $function), $key);
+ }
+ }
+
+/**
+ * Dispatches a new event to all configured listeners
+ *
+ * @param string|CakeEvent $event the event key name or instance of CakeEvent
+ * @return void
+ */
+ public function dispatch($event) {
+ if (is_string($event)) {
+ $event = new CakeEvent($event);
+ }
+
+ if (!$this->_isGlobal) {
+ self::instance()->dispatch($event);
+ }
+
+ if (empty($this->_listeners[$event->name()])) {
+ return;
+ }
+
+ foreach ($this->listeners($event->name()) as $listener) {
+ if ($event->isStopped()) {
+ break;
+ }
+ if ($listener['passParams'] === true) {
+ $result = call_user_func_array($listener['callable'], $event->data);
+ } else {
+ $result = call_user_func($listener['callable'], $event);
+ }
+ if ($result === false) {
+ $event->stopPropagation();
+ }
+ if ($result !== null) {
+ $event->result = $result;
+ }
+ continue;
+ }
+ }
+
+/**
+ * Returns a list of all listeners for a eventKey in the order they should be called
+ *
+ * @param string $eventKey
+ * @return array
+ */
+ public function listeners($eventKey) {
+ if (empty($this->_listeners[$eventKey])) {
+ return array();
+ }
+ ksort($this->_listeners[$eventKey]);
+ $result = array();
+ foreach ($this->_listeners[$eventKey] as $priorityQ) {
+ $result = array_merge($result, $priorityQ);
+ }
+ return $result;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/I18n.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/I18n.php
new file mode 100644
index 0000000..7678ba6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/I18n.php
@@ -0,0 +1,631 @@
+<?php
+/**
+ * Internationalization
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.I18n
+ * @since CakePHP(tm) v 1.2.0.4116
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Included libraries.
+ */
+App::uses('CakePlugin', 'Core');
+App::uses('L10n', 'I18n');
+App::uses('Multibyte', 'I18n');
+
+if (function_exists('mb_internal_encoding')) {
+ $encoding = Configure::read('App.encoding');
+ if (!empty($encoding)) {
+ mb_internal_encoding($encoding);
+ }
+}
+
+/**
+ * I18n handles translation of Text and time format strings.
+ *
+ * @package Cake.I18n
+ */
+class I18n {
+
+/**
+ * Instance of the L10n class for localization
+ *
+ * @var L10n
+ */
+ public $l10n = null;
+
+/**
+ * Default domain of translation
+ *
+ * @var string
+ */
+ public static $defaultDomain = 'default';
+
+/**
+ * Current domain of translation
+ *
+ * @var string
+ */
+ public $domain = null;
+
+/**
+ * Current category of translation
+ *
+ * @var string
+ */
+ public $category = 'LC_MESSAGES';
+
+/**
+ * Current language used for translations
+ *
+ * @var string
+ */
+ protected $_lang = null;
+
+/**
+ * Translation strings for a specific domain read from the .mo or .po files
+ *
+ * @var array
+ */
+ protected $_domains = array();
+
+/**
+ * Set to true when I18N::_bindTextDomain() is called for the first time.
+ * If a translation file is found it is set to false again
+ *
+ * @var boolean
+ */
+ protected $_noLocale = false;
+
+/**
+ * Translation categories
+ *
+ * @var array
+ */
+ protected $_categories = array(
+ 'LC_ALL', 'LC_COLLATE', 'LC_CTYPE', 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME', 'LC_MESSAGES'
+ );
+
+ protected $_escape = null;
+
+/**
+ * Constructor, use I18n::getInstance() to get the i18n translation object.
+ *
+ * @return void
+ */
+ public function __construct() {
+ $this->l10n = new L10n();
+ }
+
+/**
+ * Return a static instance of the I18n class
+ *
+ * @return I18n
+ */
+ public static function &getInstance() {
+ static $instance = array();
+ if (!$instance) {
+ $instance[0] = new I18n();
+ }
+ return $instance[0];
+ }
+
+/**
+ * Used by the translation functions in basics.php
+ * Returns a translated string based on current language and translation files stored in locale folder
+ *
+ * @param string $singular String to translate
+ * @param string $plural Plural string (if any)
+ * @param string $domain Domain The domain of the translation. Domains are often used by plugin translations
+ * @param string $category Category The integer value of the category to use.
+ * @param integer $count Count Count is used with $plural to choose the correct plural form.
+ * @param string $language Language to translate string to.
+ * If null it checks for language in session followed by Config.language configuration variable.
+ * @return string translated string.
+ */
+ public static function translate($singular, $plural = null, $domain = null, $category = 6, $count = null, $language = null) {
+ $_this = I18n::getInstance();
+
+ if (strpos($singular, "\r\n") !== false) {
+ $singular = str_replace("\r\n", "\n", $singular);
+ }
+ if ($plural !== null && strpos($plural, "\r\n") !== false) {
+ $plural = str_replace("\r\n", "\n", $plural);
+ }
+
+ if (is_numeric($category)) {
+ $_this->category = $_this->_categories[$category];
+ }
+
+ if (empty($language)) {
+ if (!empty($_SESSION['Config']['language'])) {
+ $language = $_SESSION['Config']['language'];
+ } else {
+ $language = Configure::read('Config.language');
+ }
+ }
+
+ if (($_this->_lang && $_this->_lang !== $language) || !$_this->_lang) {
+ $lang = $_this->l10n->get($language);
+ $_this->_lang = $lang;
+ }
+
+ if (is_null($domain)) {
+ $domain = self::$defaultDomain;
+ }
+
+ $_this->domain = $domain . '_' . $_this->l10n->lang;
+
+ if (!isset($_this->_domains[$domain][$_this->_lang])) {
+ $_this->_domains[$domain][$_this->_lang] = Cache::read($_this->domain, '_cake_core_');
+ }
+
+ if (!isset($_this->_domains[$domain][$_this->_lang][$_this->category])) {
+ $_this->_bindTextDomain($domain);
+ Cache::write($_this->domain, $_this->_domains[$domain][$_this->_lang], '_cake_core_');
+ }
+
+ if ($_this->category == 'LC_TIME') {
+ return $_this->_translateTime($singular, $domain);
+ }
+
+ if (!isset($count)) {
+ $plurals = 0;
+ } elseif (!empty($_this->_domains[$domain][$_this->_lang][$_this->category]["%plural-c"]) && $_this->_noLocale === false) {
+ $header = $_this->_domains[$domain][$_this->_lang][$_this->category]["%plural-c"];
+ $plurals = $_this->_pluralGuess($header, $count);
+ } else {
+ if ($count != 1) {
+ $plurals = 1;
+ } else {
+ $plurals = 0;
+ }
+ }
+
+ if (!empty($_this->_domains[$domain][$_this->_lang][$_this->category][$singular])) {
+ if (($trans = $_this->_domains[$domain][$_this->_lang][$_this->category][$singular]) || ($plurals) && ($trans = $_this->_domains[$domain][$_this->_lang][$_this->category][$plural])) {
+ if (is_array($trans)) {
+ if (isset($trans[$plurals])) {
+ $trans = $trans[$plurals];
+ } else {
+ trigger_error(
+ __d('cake_dev',
+ 'Missing plural form translation for "%s" in "%s" domain, "%s" locale. ' .
+ ' Check your po file for correct plurals and valid Plural-Forms header.',
+ $singular,
+ $domain,
+ $_this->_lang
+ ),
+ E_USER_WARNING
+ );
+ $trans = $trans[0];
+ }
+ }
+ if (strlen($trans)) {
+ return $trans;
+ }
+ }
+ }
+
+ if (!empty($plurals)) {
+ return $plural;
+ }
+ return $singular;
+ }
+
+/**
+ * Clears the domains internal data array. Useful for testing i18n.
+ *
+ * @return void
+ */
+ public static function clear() {
+ $self = I18n::getInstance();
+ $self->_domains = array();
+ }
+
+/**
+ * Get the loaded domains cache.
+ *
+ * @return array
+ */
+ public static function domains() {
+ $self = I18n::getInstance();
+ return $self->_domains;
+ }
+
+/**
+ * Attempts to find the plural form of a string.
+ *
+ * @param string $header Type
+ * @param integer $n Number
+ * @return integer plural match
+ */
+ protected function _pluralGuess($header, $n) {
+ if (!is_string($header) || $header === "nplurals=1;plural=0;" || !isset($header[0])) {
+ return 0;
+ }
+
+ if ($header === "nplurals=2;plural=n!=1;") {
+ return $n != 1 ? 1 : 0;
+ } elseif ($header === "nplurals=2;plural=n>1;") {
+ return $n > 1 ? 1 : 0;
+ }
+
+ if (strpos($header, "plurals=3")) {
+ if (strpos($header, "100!=11")) {
+ if (strpos($header, "10<=4")) {
+ return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
+ } elseif (strpos($header, "100<10")) {
+ return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
+ }
+ return $n % 10 == 1 && $n % 100 != 11 ? 0 : ($n != 0 ? 1 : 2);
+ } elseif (strpos($header, "n==2")) {
+ return $n == 1 ? 0 : ($n == 2 ? 1 : 2);
+ } elseif (strpos($header, "n==0")) {
+ return $n == 1 ? 0 : ($n == 0 || ($n % 100 > 0 && $n % 100 < 20) ? 1 : 2);
+ } elseif (strpos($header, "n>=2")) {
+ return $n == 1 ? 0 : ($n >= 2 && $n <= 4 ? 1 : 2);
+ } elseif (strpos($header, "10>=2")) {
+ return $n == 1 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
+ }
+ return $n % 10 == 1 ? 0 : ($n % 10 == 2 ? 1 : 2);
+ } elseif (strpos($header, "plurals=4")) {
+ if (strpos($header, "100==2")) {
+ return $n % 100 == 1 ? 0 : ($n % 100 == 2 ? 1 : ($n % 100 == 3 || $n % 100 == 4 ? 2 : 3));
+ } elseif (strpos($header, "n>=3")) {
+ return $n == 1 ? 0 : ($n == 2 ? 1 : ($n == 0 || ($n >= 3 && $n <= 10) ? 2 : 3));
+ } elseif (strpos($header, "100>=1")) {
+ return $n == 1 ? 0 : ($n == 0 || ($n % 100 >= 1 && $n % 100 <= 10) ? 1 : ($n % 100 >= 11 && $n % 100 <= 20 ? 2 : 3));
+ }
+ } elseif (strpos($header, "plurals=5")) {
+ return $n == 1 ? 0 : ($n == 2 ? 1 : ($n >= 3 && $n <= 6 ? 2 : ($n >= 7 && $n <= 10 ? 3 : 4)));
+ }
+ }
+
+/**
+ * Binds the given domain to a file in the specified directory.
+ *
+ * @param string $domain Domain to bind
+ * @return string Domain binded
+ */
+ protected function _bindTextDomain($domain) {
+ $this->_noLocale = true;
+ $core = true;
+ $merge = array();
+ $searchPaths = App::path('locales');
+ $plugins = CakePlugin::loaded();
+
+ if (!empty($plugins)) {
+ foreach ($plugins as $plugin) {
+ $pluginDomain = Inflector::underscore($plugin);
+ if ($pluginDomain === $domain) {
+ $searchPaths[] = CakePlugin::path($plugin) . 'Locale' . DS;
+ $searchPaths = array_reverse($searchPaths);
+ break;
+ }
+ }
+ }
+
+ foreach ($searchPaths as $directory) {
+ foreach ($this->l10n->languagePath as $lang) {
+ $localeDef = $directory . $lang . DS . $this->category;
+ if (is_file($localeDef)) {
+ $definitions = self::loadLocaleDefinition($localeDef);
+ if ($definitions !== false) {
+ $this->_domains[$domain][$this->_lang][$this->category] = self::loadLocaleDefinition($localeDef);
+ $this->_noLocale = false;
+ return $domain;
+ }
+ }
+
+ if ($core) {
+ $app = $directory . $lang . DS . $this->category . DS . 'core';
+ $translations = false;
+
+ if (is_file($app . '.mo')) {
+ $translations = self::loadMo($app . '.mo');
+ }
+ if ($translations === false && is_file($app . '.po')) {
+ $translations = self::loadPo($app . '.po');
+ }
+
+ if ($translations !== false) {
+ $this->_domains[$domain][$this->_lang][$this->category] = $translations;
+ $merge[$domain][$this->_lang][$this->category] = $this->_domains[$domain][$this->_lang][$this->category];
+ $this->_noLocale = false;
+ $core = null;
+ }
+ }
+
+ $file = $directory . $lang . DS . $this->category . DS . $domain;
+ $translations = false;
+
+ if (is_file($file . '.mo')) {
+ $translations = self::loadMo($file . '.mo');
+ }
+ if ($translations === false && is_file($file . '.po')) {
+ $translations = self::loadPo($file . '.po');
+ }
+
+ if ($translations !== false) {
+ $this->_domains[$domain][$this->_lang][$this->category] = $translations;
+ $this->_noLocale = false;
+ break 2;
+ }
+ }
+ }
+
+ if (empty($this->_domains[$domain][$this->_lang][$this->category])) {
+ $this->_domains[$domain][$this->_lang][$this->category] = array();
+ return $domain;
+ }
+
+ if (isset($this->_domains[$domain][$this->_lang][$this->category][""])) {
+ $head = $this->_domains[$domain][$this->_lang][$this->category][""];
+
+ foreach (explode("\n", $head) as $line) {
+ $header = strtok($line,":");
+ $line = trim(strtok("\n"));
+ $this->_domains[$domain][$this->_lang][$this->category]["%po-header"][strtolower($header)] = $line;
+ }
+
+ if (isset($this->_domains[$domain][$this->_lang][$this->category]["%po-header"]["plural-forms"])) {
+ $switch = preg_replace("/(?:[() {}\\[\\]^\\s*\\]]+)/", "", $this->_domains[$domain][$this->_lang][$this->category]["%po-header"]["plural-forms"]);
+ $this->_domains[$domain][$this->_lang][$this->category]["%plural-c"] = $switch;
+ unset($this->_domains[$domain][$this->_lang][$this->category]["%po-header"]);
+ }
+ $this->_domains = Hash::mergeDiff($this->_domains, $merge);
+
+ if (isset($this->_domains[$domain][$this->_lang][$this->category][null])) {
+ unset($this->_domains[$domain][$this->_lang][$this->category][null]);
+ }
+ }
+
+ return $domain;
+ }
+
+/**
+ * Loads the binary .mo file and returns array of translations
+ *
+ * @param string $filename Binary .mo file to load
+ * @return mixed Array of translations on success or false on failure
+ */
+ public static function loadMo($filename) {
+ $translations = false;
+
+ // @codingStandardsIgnoreStart
+ // Binary files extracted makes non-standard local variables
+ if ($data = file_get_contents($filename)) {
+ $translations = array();
+ $header = substr($data, 0, 20);
+ $header = unpack("L1magic/L1version/L1count/L1o_msg/L1o_trn", $header);
+ extract($header);
+
+ if ((dechex($magic) == '950412de' || dechex($magic) == 'ffffffff950412de') && $version == 0) {
+ for ($n = 0; $n < $count; $n++) {
+ $r = unpack("L1len/L1offs", substr($data, $o_msg + $n * 8, 8));
+ $msgid = substr($data, $r["offs"], $r["len"]);
+ unset($msgid_plural);
+
+ if (strpos($msgid, "\000")) {
+ list($msgid, $msgid_plural) = explode("\000", $msgid);
+ }
+ $r = unpack("L1len/L1offs", substr($data, $o_trn + $n * 8, 8));
+ $msgstr = substr($data, $r["offs"], $r["len"]);
+
+ if (strpos($msgstr, "\000")) {
+ $msgstr = explode("\000", $msgstr);
+ }
+ $translations[$msgid] = $msgstr;
+
+ if (isset($msgid_plural)) {
+ $translations[$msgid_plural] =& $translations[$msgid];
+ }
+ }
+ }
+ }
+ // @codingStandardsIgnoreEnd
+
+ return $translations;
+ }
+
+/**
+ * Loads the text .po file and returns array of translations
+ *
+ * @param string $filename Text .po file to load
+ * @return mixed Array of translations on success or false on failure
+ */
+ public static function loadPo($filename) {
+ if (!$file = fopen($filename, "r")) {
+ return false;
+ }
+
+ $type = 0;
+ $translations = array();
+ $translationKey = "";
+ $plural = 0;
+ $header = "";
+
+ do {
+ $line = trim(fgets($file));
+ if ($line == "" || $line[0] == "#") {
+ continue;
+ }
+ if (preg_match("/msgid[[:space:]]+\"(.+)\"$/i", $line, $regs)) {
+ $type = 1;
+ $translationKey = stripcslashes($regs[1]);
+ } elseif (preg_match("/msgid[[:space:]]+\"\"$/i", $line, $regs)) {
+ $type = 2;
+ $translationKey = "";
+ } elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && ($type == 1 || $type == 2 || $type == 3)) {
+ $type = 3;
+ $translationKey .= stripcslashes($regs[1]);
+ } elseif (preg_match("/msgstr[[:space:]]+\"(.+)\"$/i", $line, $regs) && ($type == 1 || $type == 3) && $translationKey) {
+ $translations[$translationKey] = stripcslashes($regs[1]);
+ $type = 4;
+ } elseif (preg_match("/msgstr[[:space:]]+\"\"$/i", $line, $regs) && ($type == 1 || $type == 3) && $translationKey) {
+ $type = 4;
+ $translations[$translationKey] = "";
+ } elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 4 && $translationKey) {
+ $translations[$translationKey] .= stripcslashes($regs[1]);
+ } elseif (preg_match("/msgid_plural[[:space:]]+\".*\"$/i", $line, $regs)) {
+ $type = 6;
+ } elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 6 && $translationKey) {
+ $type = 6;
+ } elseif (preg_match("/msgstr\[(\d+)\][[:space:]]+\"(.+)\"$/i", $line, $regs) && ($type == 6 || $type == 7) && $translationKey) {
+ $plural = $regs[1];
+ $translations[$translationKey][$plural] = stripcslashes($regs[2]);
+ $type = 7;
+ } elseif (preg_match("/msgstr\[(\d+)\][[:space:]]+\"\"$/i", $line, $regs) && ($type == 6 || $type == 7) && $translationKey) {
+ $plural = $regs[1];
+ $translations[$translationKey][$plural] = "";
+ $type = 7;
+ } elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 7 && $translationKey) {
+ $translations[$translationKey][$plural] .= stripcslashes($regs[1]);
+ } elseif (preg_match("/msgstr[[:space:]]+\"(.+)\"$/i", $line, $regs) && $type == 2 && !$translationKey) {
+ $header .= stripcslashes($regs[1]);
+ $type = 5;
+ } elseif (preg_match("/msgstr[[:space:]]+\"\"$/i", $line, $regs) && !$translationKey) {
+ $header = "";
+ $type = 5;
+ } elseif (preg_match("/^\"(.*)\"$/i", $line, $regs) && $type == 5) {
+ $header .= stripcslashes($regs[1]);
+ } else {
+ unset($translations[$translationKey]);
+ $type = 0;
+ $translationKey = "";
+ $plural = 0;
+ }
+ } while (!feof($file));
+ fclose($file);
+
+ $merge[""] = $header;
+ return array_merge($merge, $translations);
+ }
+
+/**
+ * Parses a locale definition file following the POSIX standard
+ *
+ * @param string $filename Locale definition filename
+ * @return mixed Array of definitions on success or false on failure
+ */
+ public static function loadLocaleDefinition($filename) {
+ if (!$file = fopen($filename, "r")) {
+ return false;
+ }
+
+ $definitions = array();
+ $comment = '#';
+ $escape = '\\';
+ $currentToken = false;
+ $value = '';
+ $_this = I18n::getInstance();
+ while ($line = fgets($file)) {
+ $line = trim($line);
+ if (empty($line) || $line[0] === $comment) {
+ continue;
+ }
+ $parts = preg_split("/[[:space:]]+/", $line);
+ if ($parts[0] === 'comment_char') {
+ $comment = $parts[1];
+ continue;
+ }
+ if ($parts[0] === 'escape_char') {
+ $escape = $parts[1];
+ continue;
+ }
+ $count = count($parts);
+ if ($count == 2) {
+ $currentToken = $parts[0];
+ $value = $parts[1];
+ } elseif ($count == 1) {
+ $value .= $parts[0];
+ } else {
+ continue;
+ }
+
+ $len = strlen($value) - 1;
+ if ($value[$len] === $escape) {
+ $value = substr($value, 0, $len);
+ continue;
+ }
+
+ $mustEscape = array($escape . ',', $escape . ';', $escape . '<', $escape . '>', $escape . $escape);
+ $replacements = array_map('crc32', $mustEscape);
+ $value = str_replace($mustEscape, $replacements, $value);
+ $value = explode(';', $value);
+ $_this->_escape = $escape;
+ foreach ($value as $i => $val) {
+ $val = trim($val, '"');
+ $val = preg_replace_callback('/(?:<)?(.[^>]*)(?:>)?/', array(&$_this, '_parseLiteralValue'), $val);
+ $val = str_replace($replacements, $mustEscape, $val);
+ $value[$i] = $val;
+ }
+ if (count($value) == 1) {
+ $definitions[$currentToken] = array_pop($value);
+ } else {
+ $definitions[$currentToken] = $value;
+ }
+ }
+
+ return $definitions;
+ }
+
+/**
+ * Auxiliary function to parse a symbol from a locale definition file
+ *
+ * @param string $string Symbol to be parsed
+ * @return string parsed symbol
+ */
+ protected function _parseLiteralValue($string) {
+ $string = $string[1];
+ if (substr($string, 0, 2) === $this->_escape . 'x') {
+ $delimiter = $this->_escape . 'x';
+ return join('', array_map('chr', array_map('hexdec',array_filter(explode($delimiter, $string)))));
+ }
+ if (substr($string, 0, 2) === $this->_escape . 'd') {
+ $delimiter = $this->_escape . 'd';
+ return join('', array_map('chr', array_filter(explode($delimiter, $string))));
+ }
+ if ($string[0] === $this->_escape && isset($string[1]) && is_numeric($string[1])) {
+ $delimiter = $this->_escape;
+ return join('', array_map('chr', array_filter(explode($delimiter, $string))));
+ }
+ if (substr($string, 0, 3) === 'U00') {
+ $delimiter = 'U00';
+ return join('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
+ }
+ if (preg_match('/U([0-9a-fA-F]{4})/', $string, $match)) {
+ return Multibyte::ascii(array(hexdec($match[1])));
+ }
+ return $string;
+ }
+
+/**
+ * Returns a Time format definition from corresponding domain
+ *
+ * @param string $format Format to be translated
+ * @param string $domain Domain where format is stored
+ * @return mixed translated format string if only value or array of translated strings for corresponding format.
+ */
+ protected function _translateTime($format, $domain) {
+ if (!empty($this->_domains[$domain][$this->_lang]['LC_TIME'][$format])) {
+ if (($trans = $this->_domains[$domain][$this->_lang][$this->category][$format])) {
+ return $trans;
+ }
+ }
+ return $format;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/L10n.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/L10n.php
new file mode 100644
index 0000000..275cb4c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/L10n.php
@@ -0,0 +1,480 @@
+<?php
+/**
+ * Localization
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.I18n
+ * @since CakePHP(tm) v 1.2.0.4116
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeRequest', 'Network');
+
+/**
+ * Localization
+ *
+ * @package Cake.I18n
+ */
+class L10n {
+
+/**
+ * The language for current locale
+ *
+ * @var string
+ */
+ public $language = 'English (United States)';
+
+/**
+ * Locale search paths
+ *
+ * @var array
+ */
+ public $languagePath = array('eng');
+
+/**
+ * ISO 639-3 for current locale
+ *
+ * @var string
+ */
+ public $lang = 'eng';
+
+/**
+ * Locale
+ *
+ * @var string
+ */
+ public $locale = 'en_us';
+
+/**
+ * Default ISO 639-3 language.
+ *
+ * DEFAULT_LANGUAGE is defined in an application this will be set as a fall back
+ *
+ * @var string
+ */
+ public $default = null;
+
+/**
+ * Encoding used for current locale
+ *
+ * @var string
+ */
+ public $charset = 'utf-8';
+
+/**
+ * Text direction for current locale
+ *
+ * @var string
+ */
+ public $direction = 'ltr';
+
+/**
+ * Set to true if a locale is found
+ *
+ * @var string
+ */
+ public $found = false;
+
+/**
+ * Maps ISO 639-3 to I10n::_l10nCatalog
+ *
+ * @var array
+ */
+ protected $_l10nMap = array(
+ /* Afrikaans */ 'afr' => 'af',
+ /* Albanian */ 'alb' => 'sq',
+ /* Arabic */ 'ara' => 'ar',
+ /* Armenian - Armenia */ 'hye' => 'hy',
+ /* Basque */ 'baq' => 'eu',
+ /* Tibetan */ 'bod' => 'bo',
+ /* Bosnian */ 'bos' => 'bs',
+ /* Bulgarian */ 'bul' => 'bg',
+ /* Byelorussian */ 'bel' => 'be',
+ /* Catalan */ 'cat' => 'ca',
+ /* Chinese */ 'chi' => 'zh',
+ /* Chinese */ 'zho' => 'zh',
+ /* Croatian */ 'hrv' => 'hr',
+ /* Czech */ 'cze' => 'cs',
+ /* Czech */ 'ces' => 'cs',
+ /* Danish */ 'dan' => 'da',
+ /* Dutch (Standard) */ 'dut' => 'nl',
+ /* Dutch (Standard) */ 'nld' => 'nl',
+ /* English */ 'eng' => 'en',
+ /* Estonian */ 'est' => 'et',
+ /* Faeroese */ 'fao' => 'fo',
+ /* Farsi */ 'fas' => 'fa',
+ /* Farsi */ 'per' => 'fa',
+ /* Finnish */ 'fin' => 'fi',
+ /* French (Standard) */ 'fre' => 'fr',
+ /* French (Standard) */ 'fra' => 'fr',
+ /* Gaelic (Scots) */ 'gla' => 'gd',
+ /* Galician */ 'glg' => 'gl',
+ /* German (Standard) */ 'deu' => 'de',
+ /* German (Standard) */ 'ger' => 'de',
+ /* Greek */ 'gre' => 'el',
+ /* Greek */ 'ell' => 'el',
+ /* Hebrew */ 'heb' => 'he',
+ /* Hindi */ 'hin' => 'hi',
+ /* Hungarian */ 'hun' => 'hu',
+ /* Icelandic */ 'ice' => 'is',
+ /* Icelandic */ 'isl' => 'is',
+ /* Indonesian */ 'ind' => 'id',
+ /* Irish */ 'gle' => 'ga',
+ /* Italian */ 'ita' => 'it',
+ /* Japanese */ 'jpn' => 'ja',
+ /* Korean */ 'kor' => 'ko',
+ /* Latvian */ 'lav' => 'lv',
+ /* Lithuanian */ 'lit' => 'lt',
+ /* Macedonian */ 'mac' => 'mk',
+ /* Macedonian */ 'mkd' => 'mk',
+ /* Malaysian */ 'may' => 'ms',
+ /* Malaysian */ 'msa' => 'ms',
+ /* Maltese */ 'mlt' => 'mt',
+ /* Norwegian */ 'nor' => 'no',
+ /* Norwegian Bokmal */ 'nob' => 'nb',
+ /* Norwegian Nynorsk */ 'nno' => 'nn',
+ /* Polish */ 'pol' => 'pl',
+ /* Portuguese (Portugal) */ 'por' => 'pt',
+ /* Rhaeto-Romanic */ 'roh' => 'rm',
+ /* Romanian */ 'rum' => 'ro',
+ /* Romanian */ 'ron' => 'ro',
+ /* Russian */ 'rus' => 'ru',
+ /* Sami (Lappish) */ 'smi' => 'sz',
+ /* Serbian */ 'scc' => 'sr',
+ /* Serbian */ 'srp' => 'sr',
+ /* Slovak */ 'slo' => 'sk',
+ /* Slovak */ 'slk' => 'sk',
+ /* Slovenian */ 'slv' => 'sl',
+ /* Sorbian */ 'wen' => 'sb',
+ /* Spanish (Spain - Traditional) */ 'spa' => 'es',
+ /* Swedish */ 'swe' => 'sv',
+ /* Thai */ 'tha' => 'th',
+ /* Tsonga */ 'tso' => 'ts',
+ /* Tswana */ 'tsn' => 'tn',
+ /* Turkish */ 'tur' => 'tr',
+ /* Ukrainian */ 'ukr' => 'uk',
+ /* Urdu */ 'urd' => 'ur',
+ /* Venda */ 'ven' => 've',
+ /* Vietnamese */ 'vie' => 'vi',
+ /* Welsh */ 'cym' => 'cy',
+ /* Xhosa */ 'xho' => 'xh',
+ /* Yiddish */ 'yid' => 'yi',
+ /* Zulu */ 'zul' => 'zu'
+ );
+
+/**
+ * HTTP_ACCEPT_LANGUAGE catalog
+ *
+ * holds all information related to a language
+ *
+ * @var array
+ */
+ protected $_l10nCatalog = array(
+ 'af' => array('language' => 'Afrikaans', 'locale' => 'afr', 'localeFallback' => 'afr', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ar' => array('language' => 'Arabic', 'locale' => 'ara', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ae' => array('language' => 'Arabic (U.A.E.)', 'locale' => 'ar_ae', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-bh' => array('language' => 'Arabic (Bahrain)', 'locale' => 'ar_bh', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-dz' => array('language' => 'Arabic (Algeria)', 'locale' => 'ar_dz', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-eg' => array('language' => 'Arabic (Egypt)', 'locale' => 'ar_eg', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-iq' => array('language' => 'Arabic (Iraq)', 'locale' => 'ar_iq', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-jo' => array('language' => 'Arabic (Jordan)', 'locale' => 'ar_jo', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-kw' => array('language' => 'Arabic (Kuwait)', 'locale' => 'ar_kw', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-lb' => array('language' => 'Arabic (Lebanon)', 'locale' => 'ar_lb', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ly' => array('language' => 'Arabic (Libya)', 'locale' => 'ar_ly', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ma' => array('language' => 'Arabic (Morocco)', 'locale' => 'ar_ma', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-om' => array('language' => 'Arabic (Oman)', 'locale' => 'ar_om', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-qa' => array('language' => 'Arabic (Qatar)', 'locale' => 'ar_qa', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-sa' => array('language' => 'Arabic (Saudi Arabia)', 'locale' => 'ar_sa', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-sy' => array('language' => 'Arabic (Syria)', 'locale' => 'ar_sy', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-tn' => array('language' => 'Arabic (Tunisia)', 'locale' => 'ar_tn', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ye' => array('language' => 'Arabic (Yemen)', 'locale' => 'ar_ye', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'be' => array('language' => 'Byelorussian', 'locale' => 'bel', 'localeFallback' => 'bel', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'bg' => array('language' => 'Bulgarian', 'locale' => 'bul', 'localeFallback' => 'bul', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'bo' => array('language' => 'Tibetan', 'locale' => 'bod', 'localeFallback' => 'bod', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'bo-cn' => array('language' => 'Tibetan (China)', 'locale' => 'bo_cn', 'localeFallback' => 'bod', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'bo-in' => array('language' => 'Tibetan (India)', 'locale' => 'bo_in', 'localeFallback' => 'bod', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'bs' => array('language' => 'Bosnian', 'locale' => 'bos', 'localeFallback' => 'bos', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ca' => array('language' => 'Catalan', 'locale' => 'cat', 'localeFallback' => 'cat', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'cs' => array('language' => 'Czech', 'locale' => 'cze', 'localeFallback' => 'cze', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'da' => array('language' => 'Danish', 'locale' => 'dan', 'localeFallback' => 'dan', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de' => array('language' => 'German (Standard)', 'locale' => 'deu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-at' => array('language' => 'German (Austria)', 'locale' => 'de_at', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-ch' => array('language' => 'German (Swiss)', 'locale' => 'de_ch', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-de' => array('language' => 'German (Germany)', 'locale' => 'de_de', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-li' => array('language' => 'German (Liechtenstein)', 'locale' => 'de_li', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-lu' => array('language' => 'German (Luxembourg)', 'locale' => 'de_lu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'e' => array('language' => 'Greek', 'locale' => 'gre', 'localeFallback' => 'gre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'el' => array('language' => 'Greek', 'locale' => 'gre', 'localeFallback' => 'gre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en' => array('language' => 'English', 'locale' => 'eng', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-au' => array('language' => 'English (Australian)', 'locale' => 'en_au', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-bz' => array('language' => 'English (Belize)', 'locale' => 'en_bz', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-ca' => array('language' => 'English (Canadian)', 'locale' => 'en_ca', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-gb' => array('language' => 'English (British)', 'locale' => 'en_gb', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-ie' => array('language' => 'English (Ireland)', 'locale' => 'en_ie', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-jm' => array('language' => 'English (Jamaica)', 'locale' => 'en_jm', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-nz' => array('language' => 'English (New Zealand)', 'locale' => 'en_nz', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-tt' => array('language' => 'English (Trinidad)', 'locale' => 'en_tt', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-us' => array('language' => 'English (United States)', 'locale' => 'en_us', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-za' => array('language' => 'English (South Africa)', 'locale' => 'en_za', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es' => array('language' => 'Spanish (Spain - Traditional)', 'locale' => 'spa', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ar' => array('language' => 'Spanish (Argentina)', 'locale' => 'es_ar', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-bo' => array('language' => 'Spanish (Bolivia)', 'locale' => 'es_bo', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-cl' => array('language' => 'Spanish (Chile)', 'locale' => 'es_cl', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-co' => array('language' => 'Spanish (Colombia)', 'locale' => 'es_co', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-cr' => array('language' => 'Spanish (Costa Rica)', 'locale' => 'es_cr', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-do' => array('language' => 'Spanish (Dominican Republic)', 'locale' => 'es_do', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ec' => array('language' => 'Spanish (Ecuador)', 'locale' => 'es_ec', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-es' => array('language' => 'Spanish (Spain)', 'locale' => 'es_es', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-gt' => array('language' => 'Spanish (Guatemala)', 'locale' => 'es_gt', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-hn' => array('language' => 'Spanish (Honduras)', 'locale' => 'es_hn', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-mx' => array('language' => 'Spanish (Mexican)', 'locale' => 'es_mx', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ni' => array('language' => 'Spanish (Nicaragua)', 'locale' => 'es_ni', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-pa' => array('language' => 'Spanish (Panama)', 'locale' => 'es_pa', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-pe' => array('language' => 'Spanish (Peru)', 'locale' => 'es_pe', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-pr' => array('language' => 'Spanish (Puerto Rico)', 'locale' => 'es_pr', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-py' => array('language' => 'Spanish (Paraguay)', 'locale' => 'es_py', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-sv' => array('language' => 'Spanish (El Salvador)', 'locale' => 'es_sv', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-uy' => array('language' => 'Spanish (Uruguay)', 'locale' => 'es_uy', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ve' => array('language' => 'Spanish (Venezuela)', 'locale' => 'es_ve', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'et' => array('language' => 'Estonian', 'locale' => 'est', 'localeFallback' => 'est', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'eu' => array('language' => 'Basque', 'locale' => 'baq', 'localeFallback' => 'baq', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fa' => array('language' => 'Farsi', 'locale' => 'per', 'localeFallback' => 'per', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'fi' => array('language' => 'Finnish', 'locale' => 'fin', 'localeFallback' => 'fin', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fo' => array('language' => 'Faeroese', 'locale' => 'fao', 'localeFallback' => 'fao', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr' => array('language' => 'French (Standard)', 'locale' => 'fre', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-be' => array('language' => 'French (Belgium)', 'locale' => 'fr_be', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-ca' => array('language' => 'French (Canadian)', 'locale' => 'fr_ca', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-ch' => array('language' => 'French (Swiss)', 'locale' => 'fr_ch', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-fr' => array('language' => 'French (France)', 'locale' => 'fr_fr', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-lu' => array('language' => 'French (Luxembourg)', 'locale' => 'fr_lu', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ga' => array('language' => 'Irish', 'locale' => 'gle', 'localeFallback' => 'gle', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'gd' => array('language' => 'Gaelic (Scots)', 'locale' => 'gla', 'localeFallback' => 'gla', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'gd-ie' => array('language' => 'Gaelic (Irish)', 'locale' => 'gd_ie', 'localeFallback' => 'gla', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'gl' => array('language' => 'Galician', 'locale' => 'glg', 'localeFallback' => 'glg', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'he' => array('language' => 'Hebrew', 'locale' => 'heb', 'localeFallback' => 'heb', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'hi' => array('language' => 'Hindi', 'locale' => 'hin', 'localeFallback' => 'hin', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'hr' => array('language' => 'Croatian', 'locale' => 'hrv', 'localeFallback' => 'hrv', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'hu' => array('language' => 'Hungarian', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'hy' => array('language' => 'Armenian - Armenia', 'locale' => 'hye', 'localeFallback' => 'hye', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'id' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'in' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'is' => array('language' => 'Icelandic', 'locale' => 'ice', 'localeFallback' => 'ice', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'it' => array('language' => 'Italian', 'locale' => 'ita', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'it-ch' => array('language' => 'Italian (Swiss) ', 'locale' => 'it_ch', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ja' => array('language' => 'Japanese', 'locale' => 'jpn', 'localeFallback' => 'jpn', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ko' => array('language' => 'Korean', 'locale' => 'kor', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
+ 'ko-kp' => array('language' => 'Korea (North)', 'locale' => 'ko_kp', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
+ 'ko-kr' => array('language' => 'Korea (South)', 'locale' => 'ko_kr', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
+ 'koi8-r' => array('language' => 'Russian', 'locale' => 'koi8_r', 'localeFallback' => 'rus', 'charset' => 'koi8-r', 'direction' => 'ltr'),
+ 'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mk', 'localeFallback' => 'mac', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'mk-mk' => array('language' => 'Macedonian', 'locale' => 'mk_mk', 'localeFallback' => 'mac', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ms' => array('language' => 'Malaysian', 'locale' => 'may', 'localeFallback' => 'may', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'mt' => array('language' => 'Maltese', 'locale' => 'mlt', 'localeFallback' => 'mlt', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'n' => array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'nb' => array('language' => 'Norwegian Bokmal', 'locale' => 'nob', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'nl' => array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'nl-be' => array('language' => 'Dutch (Belgium)', 'locale' => 'nl_be', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'nn' => array('language' => 'Norwegian Nynorsk', 'locale' => 'nno', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'no' => array('language' => 'Norwegian', 'locale' => 'nor', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'p' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'pl' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'pt' => array('language' => 'Portuguese (Portugal)', 'locale' => 'por', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'pt-br' => array('language' => 'Portuguese (Brazil)', 'locale' => 'pt_br', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'rm' => array('language' => 'Rhaeto-Romanic', 'locale' => 'roh', 'localeFallback' => 'roh', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ro' => array('language' => 'Romanian', 'locale' => 'rum', 'localeFallback' => 'rum', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ro-mo' => array('language' => 'Romanian (Moldavia)', 'locale' => 'ro_mo', 'localeFallback' => 'rum', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ru' => array('language' => 'Russian', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ru-mo' => array('language' => 'Russian (Moldavia)', 'locale' => 'ru_mo', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sb' => array('language' => 'Sorbian', 'locale' => 'wen', 'localeFallback' => 'wen', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sk' => array('language' => 'Slovak', 'locale' => 'slo', 'localeFallback' => 'slo', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sl' => array('language' => 'Slovenian', 'locale' => 'slv', 'localeFallback' => 'slv', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sq' => array('language' => 'Albanian', 'locale' => 'alb', 'localeFallback' => 'alb', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sr' => array('language' => 'Serbian', 'locale' => 'scc', 'localeFallback' => 'scc', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sv' => array('language' => 'Swedish', 'locale' => 'swe', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sv-fi' => array('language' => 'Swedish (Finland)', 'locale' => 'sv_fi', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sx' => array('language' => 'Sutu', 'locale' => 'sx', 'localeFallback' => 'sx', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sz' => array('language' => 'Sami (Lappish)', 'locale' => 'smi', 'localeFallback' => 'smi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'th' => array('language' => 'Thai', 'locale' => 'tha', 'localeFallback' => 'tha', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'tn' => array('language' => 'Tswana', 'locale' => 'tsn', 'localeFallback' => 'tsn', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'tr' => array('language' => 'Turkish', 'locale' => 'tur', 'localeFallback' => 'tur', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ts' => array('language' => 'Tsonga', 'locale' => 'tso', 'localeFallback' => 'tso', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'uk' => array('language' => 'Ukrainian', 'locale' => 'ukr', 'localeFallback' => 'ukr', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ur' => array('language' => 'Urdu', 'locale' => 'urd', 'localeFallback' => 'urd', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 've' => array('language' => 'Venda', 'locale' => 'ven', 'localeFallback' => 'ven', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'vi' => array('language' => 'Vietnamese', 'locale' => 'vie', 'localeFallback' => 'vie', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'cy' => array('language' => 'Welsh', 'locale' => 'cym', 'localeFallback' => 'cym', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'xh' => array('language' => 'Xhosa', 'locale' => 'xho', 'localeFallback' => 'xho', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'yi' => array('language' => 'Yiddish', 'locale' => 'yid', 'localeFallback' => 'yid', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zh' => array('language' => 'Chinese', 'locale' => 'chi', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zh-cn' => array('language' => 'Chinese (PRC)', 'locale' => 'zh_cn', 'localeFallback' => 'chi', 'charset' => 'GB2312', 'direction' => 'ltr'),
+ 'zh-hk' => array('language' => 'Chinese (Hong Kong)', 'locale' => 'zh_hk', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zh-sg' => array('language' => 'Chinese (Singapore)', 'locale' => 'zh_sg', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zh-tw' => array('language' => 'Chinese (Taiwan)', 'locale' => 'zh_tw', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zu' => array('language' => 'Zulu', 'locale' => 'zul', 'localeFallback' => 'zul', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+
+/**
+ * Class constructor
+ */
+ public function __construct() {
+ if (defined('DEFAULT_LANGUAGE')) {
+ $this->default = DEFAULT_LANGUAGE;
+ }
+ }
+
+/**
+ * Gets the settings for $language.
+ * If $language is null it attempt to get settings from L10n::_autoLanguage(); if this fails
+ * the method will get the settings from L10n::_setLanguage();
+ *
+ * @param string $language Language (if null will use DEFAULT_LANGUAGE if defined)
+ * @return mixed
+ */
+ public function get($language = null) {
+ if ($language !== null) {
+ return $this->_setLanguage($language);
+ }
+
+ if (!$this->_autoLanguage()) {
+ $this->_setLanguage();
+ }
+ return $this->lang;
+ }
+
+/**
+ * Sets the class vars to correct values for $language.
+ * If $language is null it will use the DEFAULT_LANGUAGE if defined
+ *
+ * @param string $language Language (if null will use DEFAULT_LANGUAGE if defined)
+ * @return mixed
+ */
+ protected function _setLanguage($language = null) {
+ $langKey = null;
+ if ($language !== null && isset($this->_l10nMap[$language]) && isset($this->_l10nCatalog[$this->_l10nMap[$language]])) {
+ $langKey = $this->_l10nMap[$language];
+ } elseif ($language !== null && isset($this->_l10nCatalog[$language])) {
+ $langKey = $language;
+ } elseif (defined('DEFAULT_LANGUAGE')) {
+ $langKey = $language = DEFAULT_LANGUAGE;
+ }
+
+ if ($langKey !== null && isset($this->_l10nCatalog[$langKey])) {
+ $this->language = $this->_l10nCatalog[$langKey]['language'];
+ $this->languagePath = array(
+ $this->_l10nCatalog[$langKey]['locale'],
+ $this->_l10nCatalog[$langKey]['localeFallback']
+ );
+ $this->lang = $language;
+ $this->locale = $this->_l10nCatalog[$langKey]['locale'];
+ $this->charset = $this->_l10nCatalog[$langKey]['charset'];
+ $this->direction = $this->_l10nCatalog[$langKey]['direction'];
+ } else {
+ $this->lang = $language;
+ $this->languagePath = array($language);
+ }
+
+ if ($this->default) {
+ if (isset($this->_l10nMap[$this->default]) && isset($this->_l10nCatalog[$this->_l10nMap[$this->default]])) {
+ $this->languagePath[] = $this->_l10nCatalog[$this->_l10nMap[$this->default]]['localeFallback'];
+ } elseif (isset($this->_l10nCatalog[$this->default])) {
+ $this->languagePath[] = $this->_l10nCatalog[$this->default]['localeFallback'];
+ }
+ }
+ $this->found = true;
+
+ if (Configure::read('Config.language') === null) {
+ Configure::write('Config.language', $this->lang);
+ }
+
+ if ($language) {
+ return $language;
+ }
+ }
+
+/**
+ * Attempts to find the locale settings based on the HTTP_ACCEPT_LANGUAGE variable
+ *
+ * @return boolean Success
+ */
+ protected function _autoLanguage() {
+ $_detectableLanguages = CakeRequest::acceptLanguage();
+ foreach ($_detectableLanguages as $key => $langKey) {
+ if (isset($this->_l10nCatalog[$langKey])) {
+ $this->_setLanguage($langKey);
+ return true;
+ } elseif (strpos($langKey, '-') !== false) {
+ $langKey = substr($langKey, 0, 2);
+ if (isset($this->_l10nCatalog[$langKey])) {
+ $this->_setLanguage($langKey);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Attempts to find locale for language, or language for locale
+ *
+ * @param string|array $mixed 2/3 char string (language/locale), array of those strings, or null
+ * @return string|array|boolean string language/locale, array of those values, whole map as an array,
+ * or false when language/locale doesn't exist
+ */
+ public function map($mixed = null) {
+ if (is_array($mixed)) {
+ $result = array();
+ foreach ($mixed as $_mixed) {
+ if ($_result = $this->map($_mixed)) {
+ $result[$_mixed] = $_result;
+ }
+ }
+ return $result;
+ } elseif (is_string($mixed)) {
+ if (strlen($mixed) === 2 && in_array($mixed, $this->_l10nMap)) {
+ return array_search($mixed, $this->_l10nMap);
+ } elseif (isset($this->_l10nMap[$mixed])) {
+ return $this->_l10nMap[$mixed];
+ }
+ return false;
+ }
+ return $this->_l10nMap;
+ }
+
+/**
+ * Attempts to find catalog record for requested language
+ *
+ * @param string|array $language string requested language, array of requested languages, or null for whole catalog
+ * @return array|boolean array catalog record for requested language, array of catalog records, whole catalog,
+ * or false when language doesn't exist
+ */
+ public function catalog($language = null) {
+ if (is_array($language)) {
+ $result = array();
+ foreach ($language as $_language) {
+ if ($_result = $this->catalog($_language)) {
+ $result[$_language] = $_result;
+ }
+ }
+ return $result;
+ } elseif (is_string($language)) {
+ if (isset($this->_l10nCatalog[$language])) {
+ return $this->_l10nCatalog[$language];
+ } elseif (isset($this->_l10nMap[$language]) && isset($this->_l10nCatalog[$this->_l10nMap[$language]])) {
+ return $this->_l10nCatalog[$this->_l10nMap[$language]];
+ }
+ return false;
+ }
+ return $this->_l10nCatalog;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/Multibyte.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/Multibyte.php
new file mode 100644
index 0000000..b741ef4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/I18n/Multibyte.php
@@ -0,0 +1,1134 @@
+<?php
+/**
+ * Multibyte handling methods.
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.I18n
+ * @since CakePHP(tm) v 1.2.0.6833
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+if (!function_exists('mb_stripos')) {
+
+/**
+ * Find position of first occurrence of a case-insensitive string.
+ *
+ * @param string $haystack The string from which to get the position of the first occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param integer $offset The position in $haystack to start searching.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string, or false
+ * if $needle is not found.
+ */
+ function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) {
+ return Multibyte::stripos($haystack, $needle, $offset);
+ }
+
+}
+
+if (!function_exists('mb_stristr')) {
+
+/**
+ * Finds first occurrence of a string within another, case insensitive.
+ *
+ * @param string $haystack The string from which to get the first occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
+ * If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
+ * Default value is false.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return string|boolean The portion of $haystack, or false if $needle is not found.
+ */
+ function mb_stristr($haystack, $needle, $part = false, $encoding = null) {
+ return Multibyte::stristr($haystack, $needle, $part);
+ }
+
+}
+
+if (!function_exists('mb_strlen')) {
+
+/**
+ * Get string length.
+ *
+ * @param string $string The string being checked for length.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return integer The number of characters in string $string having character encoding encoding.
+ * A multi-byte character is counted as 1.
+ */
+ function mb_strlen($string, $encoding = null) {
+ return Multibyte::strlen($string);
+ }
+
+}
+
+if (!function_exists('mb_strpos')) {
+
+/**
+ * Find position of first occurrence of a string.
+ *
+ * @param string $haystack The string being checked.
+ * @param string $needle The position counted from the beginning of haystack.
+ * @param integer $offset The search offset. If it is not specified, 0 is used.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string.
+ * If $needle is not found, it returns false.
+ */
+ function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) {
+ return Multibyte::strpos($haystack, $needle, $offset);
+ }
+
+}
+
+if (!function_exists('mb_strrchr')) {
+
+/**
+ * Finds the last occurrence of a character in a string within another.
+ *
+ * @param string $haystack The string from which to get the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
+ * If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
+ * Default value is false.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return string|boolean The portion of $haystack. or false if $needle is not found.
+ */
+ function mb_strrchr($haystack, $needle, $part = false, $encoding = null) {
+ return Multibyte::strrchr($haystack, $needle, $part);
+ }
+
+}
+
+if (!function_exists('mb_strrichr')) {
+
+/**
+ * Finds the last occurrence of a character in a string within another, case insensitive.
+ *
+ * @param string $haystack The string from which to get the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
+ * If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
+ * Default value is false.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return string|boolean The portion of $haystack. or false if $needle is not found.
+ */
+ function mb_strrichr($haystack, $needle, $part = false, $encoding = null) {
+ return Multibyte::strrichr($haystack, $needle, $part);
+ }
+
+}
+
+if (!function_exists('mb_strripos')) {
+
+/**
+ * Finds position of last occurrence of a string within another, case insensitive
+ *
+ * @param string $haystack The string from which to get the position of the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param integer $offset The position in $haystack to start searching.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string,
+ * or false if $needle is not found.
+ */
+ function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) {
+ return Multibyte::strripos($haystack, $needle, $offset);
+ }
+
+}
+
+if (!function_exists('mb_strrpos')) {
+
+/**
+ * Find position of last occurrence of a string in a string.
+ *
+ * @param string $haystack The string being checked, for the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param integer $offset May be specified to begin searching an arbitrary number of characters into the string.
+ * Negative values will stop searching at an arbitrary point prior to the end of the string.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string.
+ * If $needle is not found, it returns false.
+ */
+ function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) {
+ return Multibyte::strrpos($haystack, $needle, $offset);
+ }
+
+}
+
+if (!function_exists('mb_strstr')) {
+
+/**
+ * Finds first occurrence of a string within another
+ *
+ * @param string $haystack The string from which to get the first occurrence of $needle.
+ * @param string $needle The string to find in $haystack
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
+ * If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
+ * Default value is FALSE.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return string|boolean The portion of $haystack, or true if $needle is not found.
+ */
+ function mb_strstr($haystack, $needle, $part = false, $encoding = null) {
+ return Multibyte::strstr($haystack, $needle, $part);
+ }
+
+}
+
+if (!function_exists('mb_strtolower')) {
+
+/**
+ * Make a string lowercase
+ *
+ * @param string $string The string being lowercased.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return string with all alphabetic characters converted to lowercase.
+ */
+ function mb_strtolower($string, $encoding = null) {
+ return Multibyte::strtolower($string);
+ }
+
+}
+
+if (!function_exists('mb_strtoupper')) {
+
+/**
+ * Make a string uppercase
+ *
+ * @param string $string The string being uppercased.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return string with all alphabetic characters converted to uppercase.
+ */
+ function mb_strtoupper($string, $encoding = null) {
+ return Multibyte::strtoupper($string);
+ }
+
+}
+
+if (!function_exists('mb_substr_count')) {
+
+/**
+ * Count the number of substring occurrences
+ *
+ * @param string $haystack The string being checked.
+ * @param string $needle The string being found.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return integer The number of times the $needle substring occurs in the $haystack string.
+ */
+ function mb_substr_count($haystack, $needle, $encoding = null) {
+ return Multibyte::substrCount($haystack, $needle);
+ }
+
+}
+
+if (!function_exists('mb_substr')) {
+
+/**
+ * Get part of string
+ *
+ * @param string $string The string being checked.
+ * @param integer $start The first position used in $string.
+ * @param integer $length The maximum length of the returned string.
+ * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
+ * @return string The portion of $string specified by the $string and $length parameters.
+ */
+ function mb_substr($string, $start, $length = null, $encoding = null) {
+ return Multibyte::substr($string, $start, $length);
+ }
+
+}
+
+if (!function_exists('mb_encode_mimeheader')) {
+
+/**
+ * Encode string for MIME header
+ *
+ * @param string $str The string being encoded
+ * @param string $charset specifies the name of the character set in which str is represented in.
+ * The default value is determined by the current NLS setting (mbstring.language).
+ * @param string $transfer_encoding specifies the scheme of MIME encoding.
+ * It should be either "B" (Base64) or "Q" (Quoted-Printable). Falls back to "B" if not given.
+ * @param string $linefeed specifies the EOL (end-of-line) marker with which
+ * mb_encode_mimeheader() performs line-folding
+ * (a » RFC term, the act of breaking a line longer than a certain length into multiple lines.
+ * The length is currently hard-coded to 74 characters). Falls back to "\r\n" (CRLF) if not given.
+ * @param integer $indent [definition unknown and appears to have no affect]
+ * @return string A converted version of the string represented in ASCII.
+ */
+ function mb_encode_mimeheader($str, $charset = 'UTF-8', $transferEncoding = 'B', $linefeed = "\r\n", $indent = 1) {
+ return Multibyte::mimeEncode($str, $charset, $linefeed);
+ }
+
+}
+
+/**
+ * Multibyte handling methods.
+ *
+ * @package Cake.I18n
+ */
+class Multibyte {
+
+/**
+ * Holds the case folding values
+ *
+ * @var array
+ */
+ protected static $_caseFold = array();
+
+/**
+ * Holds an array of Unicode code point ranges
+ *
+ * @var array
+ */
+ protected static $_codeRange = array();
+
+/**
+ * Holds the current code point range
+ *
+ * @var string
+ */
+ protected static $_table = null;
+
+/**
+ * Converts a multibyte character string
+ * to the decimal value of the character
+ *
+ * @param string $string
+ * @return array
+ */
+ public static function utf8($string) {
+ $map = array();
+
+ $values = array();
+ $find = 1;
+ $length = strlen($string);
+
+ for ($i = 0; $i < $length; $i++) {
+ $value = ord($string[$i]);
+
+ if ($value < 128) {
+ $map[] = $value;
+ } else {
+ if (empty($values)) {
+ $find = ($value < 224) ? 2 : 3;
+ }
+ $values[] = $value;
+
+ if (count($values) === $find) {
+ if ($find == 3) {
+ $map[] = (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64);
+ } else {
+ $map[] = (($values[0] % 32) * 64) + ($values[1] % 64);
+ }
+ $values = array();
+ $find = 1;
+ }
+ }
+ }
+ return $map;
+ }
+
+/**
+ * Converts the decimal value of a multibyte character string
+ * to a string
+ *
+ * @param array $array
+ * @return string
+ */
+ public static function ascii($array) {
+ $ascii = '';
+
+ foreach ($array as $utf8) {
+ if ($utf8 < 128) {
+ $ascii .= chr($utf8);
+ } elseif ($utf8 < 2048) {
+ $ascii .= chr(192 + (($utf8 - ($utf8 % 64)) / 64));
+ $ascii .= chr(128 + ($utf8 % 64));
+ } else {
+ $ascii .= chr(224 + (($utf8 - ($utf8 % 4096)) / 4096));
+ $ascii .= chr(128 + ((($utf8 % 4096) - ($utf8 % 64)) / 64));
+ $ascii .= chr(128 + ($utf8 % 64));
+ }
+ }
+ return $ascii;
+ }
+
+/**
+ * Find position of first occurrence of a case-insensitive string.
+ *
+ * @param string $haystack The string from which to get the position of the first occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param integer $offset The position in $haystack to start searching.
+ * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string,
+ * or false if $needle is not found.
+ */
+ public static function stripos($haystack, $needle, $offset = 0) {
+ if (Multibyte::checkMultibyte($haystack)) {
+ $haystack = Multibyte::strtoupper($haystack);
+ $needle = Multibyte::strtoupper($needle);
+ return Multibyte::strpos($haystack, $needle, $offset);
+ }
+ return stripos($haystack, $needle, $offset);
+ }
+
+/**
+ * Finds first occurrence of a string within another, case insensitive.
+ *
+ * @param string $haystack The string from which to get the first occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
+ * If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
+ * Default value is false.
+ * @return integer|boolean The portion of $haystack, or false if $needle is not found.
+ */
+ public static function stristr($haystack, $needle, $part = false) {
+ $php = (PHP_VERSION < 5.3);
+
+ if (($php && $part) || Multibyte::checkMultibyte($haystack)) {
+ $check = Multibyte::strtoupper($haystack);
+ $check = Multibyte::utf8($check);
+ $found = false;
+
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+
+ $needle = Multibyte::strtoupper($needle);
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ $parts = array();
+ $position = 0;
+
+ while (($found === false) && ($position < $haystackCount)) {
+ if (isset($needle[0]) && $needle[0] === $check[$position]) {
+ for ($i = 1; $i < $needleCount; $i++) {
+ if ($needle[$i] !== $check[$position + $i]) {
+ break;
+ }
+ }
+ if ($i === $needleCount) {
+ $found = true;
+ }
+ }
+ if (!$found) {
+ $parts[] = $haystack[$position];
+ unset($haystack[$position]);
+ }
+ $position++;
+ }
+
+ if ($found && $part && !empty($parts)) {
+ return Multibyte::ascii($parts);
+ } elseif ($found && !empty($haystack)) {
+ return Multibyte::ascii($haystack);
+ }
+ return false;
+ }
+
+ if (!$php) {
+ return stristr($haystack, $needle, $part);
+ }
+ return stristr($haystack, $needle);
+ }
+
+/**
+ * Get string length.
+ *
+ * @param string $string The string being checked for length.
+ * @return integer The number of characters in string $string
+ */
+ public static function strlen($string) {
+ if (Multibyte::checkMultibyte($string)) {
+ $string = Multibyte::utf8($string);
+ return count($string);
+ }
+ return strlen($string);
+ }
+
+/**
+ * Find position of first occurrence of a string.
+ *
+ * @param string $haystack The string being checked.
+ * @param string $needle The position counted from the beginning of haystack.
+ * @param integer $offset The search offset. If it is not specified, 0 is used.
+ * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string.
+ * If $needle is not found, it returns false.
+ */
+ public static function strpos($haystack, $needle, $offset = 0) {
+ if (Multibyte::checkMultibyte($haystack)) {
+ $found = false;
+
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ $position = $offset;
+
+ while (($found === false) && ($position < $haystackCount)) {
+ if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
+ for ($i = 1; $i < $needleCount; $i++) {
+ if ($needle[$i] !== $haystack[$position + $i]) {
+ break;
+ }
+ }
+ if ($i === $needleCount) {
+ $found = true;
+ $position--;
+ }
+ }
+ $position++;
+ }
+ if ($found) {
+ return $position;
+ }
+ return false;
+ }
+ return strpos($haystack, $needle, $offset);
+ }
+
+/**
+ * Finds the last occurrence of a character in a string within another.
+ *
+ * @param string $haystack The string from which to get the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
+ * If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
+ * Default value is false.
+ * @return string|boolean The portion of $haystack. or false if $needle is not found.
+ */
+ public static function strrchr($haystack, $needle, $part = false) {
+ $check = Multibyte::utf8($haystack);
+ $found = false;
+
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+
+ $matches = array_count_values($check);
+
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ $parts = array();
+ $position = 0;
+
+ while (($found === false) && ($position < $haystackCount)) {
+ if (isset($needle[0]) && $needle[0] === $check[$position]) {
+ for ($i = 1; $i < $needleCount; $i++) {
+ if ($needle[$i] !== $check[$position + $i]) {
+ if ($needle[$i] === $check[($position + $i) - 1]) {
+ $found = true;
+ }
+ unset($parts[$position - 1]);
+ $haystack = array_merge(array($haystack[$position]), $haystack);
+ break;
+ }
+ }
+ if (isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
+ $matches[$needle[0]] = $matches[$needle[0]] - 1;
+ } elseif ($i === $needleCount) {
+ $found = true;
+ }
+ }
+
+ if (!$found && isset($haystack[$position])) {
+ $parts[] = $haystack[$position];
+ unset($haystack[$position]);
+ }
+ $position++;
+ }
+
+ if ($found && $part && !empty($parts)) {
+ return Multibyte::ascii($parts);
+ } elseif ($found && !empty($haystack)) {
+ return Multibyte::ascii($haystack);
+ }
+ return false;
+ }
+
+/**
+ * Finds the last occurrence of a character in a string within another, case insensitive.
+ *
+ * @param string $haystack The string from which to get the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
+ * If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
+ * Default value is false.
+ * @return string|boolean The portion of $haystack. or false if $needle is not found.
+ */
+ public static function strrichr($haystack, $needle, $part = false) {
+ $check = Multibyte::strtoupper($haystack);
+ $check = Multibyte::utf8($check);
+ $found = false;
+
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+
+ $matches = array_count_values($check);
+
+ $needle = Multibyte::strtoupper($needle);
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ $parts = array();
+ $position = 0;
+
+ while (($found === false) && ($position < $haystackCount)) {
+ if (isset($needle[0]) && $needle[0] === $check[$position]) {
+ for ($i = 1; $i < $needleCount; $i++) {
+ if ($needle[$i] !== $check[$position + $i]) {
+ if ($needle[$i] === $check[($position + $i) - 1]) {
+ $found = true;
+ }
+ unset($parts[$position - 1]);
+ $haystack = array_merge(array($haystack[$position]), $haystack);
+ break;
+ }
+ }
+ if (isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
+ $matches[$needle[0]] = $matches[$needle[0]] - 1;
+ } elseif ($i === $needleCount) {
+ $found = true;
+ }
+ }
+
+ if (!$found && isset($haystack[$position])) {
+ $parts[] = $haystack[$position];
+ unset($haystack[$position]);
+ }
+ $position++;
+ }
+
+ if ($found && $part && !empty($parts)) {
+ return Multibyte::ascii($parts);
+ } elseif ($found && !empty($haystack)) {
+ return Multibyte::ascii($haystack);
+ }
+ return false;
+ }
+
+/**
+ * Finds position of last occurrence of a string within another, case insensitive
+ *
+ * @param string $haystack The string from which to get the position of the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param integer $offset The position in $haystack to start searching.
+ * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string,
+ * or false if $needle is not found.
+ */
+ public static function strripos($haystack, $needle, $offset = 0) {
+ if (Multibyte::checkMultibyte($haystack)) {
+ $found = false;
+ $haystack = Multibyte::strtoupper($haystack);
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+
+ $matches = array_count_values($haystack);
+
+ $needle = Multibyte::strtoupper($needle);
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ $position = $offset;
+
+ while (($found === false) && ($position < $haystackCount)) {
+ if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
+ for ($i = 1; $i < $needleCount; $i++) {
+ if ($needle[$i] !== $haystack[$position + $i]) {
+ if ($needle[$i] === $haystack[($position + $i) - 1]) {
+ $position--;
+ $found = true;
+ continue;
+ }
+ }
+ }
+
+ if (!$offset && isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
+ $matches[$needle[0]] = $matches[$needle[0]] - 1;
+ } elseif ($i === $needleCount) {
+ $found = true;
+ $position--;
+ }
+ }
+ $position++;
+ }
+ return ($found) ? $position : false;
+ }
+ return strripos($haystack, $needle, $offset);
+ }
+
+/**
+ * Find position of last occurrence of a string in a string.
+ *
+ * @param string $haystack The string being checked, for the last occurrence of $needle.
+ * @param string $needle The string to find in $haystack.
+ * @param integer $offset May be specified to begin searching an arbitrary number of characters into the string.
+ * Negative values will stop searching at an arbitrary point prior to the end of the string.
+ * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string.
+ * If $needle is not found, it returns false.
+ */
+ public static function strrpos($haystack, $needle, $offset = 0) {
+ if (Multibyte::checkMultibyte($haystack)) {
+ $found = false;
+
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+
+ $matches = array_count_values($haystack);
+
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ $position = $offset;
+
+ while (($found === false) && ($position < $haystackCount)) {
+ if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
+ for ($i = 1; $i < $needleCount; $i++) {
+ if ($needle[$i] !== $haystack[$position + $i]) {
+ if ($needle[$i] === $haystack[($position + $i) - 1]) {
+ $position--;
+ $found = true;
+ continue;
+ }
+ }
+ }
+
+ if (!$offset && isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
+ $matches[$needle[0]] = $matches[$needle[0]] - 1;
+ } elseif ($i === $needleCount) {
+ $found = true;
+ $position--;
+ }
+ }
+ $position++;
+ }
+ return ($found) ? $position : false;
+ }
+ return strrpos($haystack, $needle, $offset);
+ }
+
+/**
+ * Finds first occurrence of a string within another
+ *
+ * @param string $haystack The string from which to get the first occurrence of $needle.
+ * @param string $needle The string to find in $haystack
+ * @param boolean $part Determines which portion of $haystack this function returns.
+ * If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
+ * If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
+ * Default value is FALSE.
+ * @return string|boolean The portion of $haystack, or true if $needle is not found.
+ */
+ public static function strstr($haystack, $needle, $part = false) {
+ $php = (PHP_VERSION < 5.3);
+
+ if (($php && $part) || Multibyte::checkMultibyte($haystack)) {
+ $check = Multibyte::utf8($haystack);
+ $found = false;
+
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ $parts = array();
+ $position = 0;
+
+ while (($found === false) && ($position < $haystackCount)) {
+ if (isset($needle[0]) && $needle[0] === $check[$position]) {
+ for ($i = 1; $i < $needleCount; $i++) {
+ if ($needle[$i] !== $check[$position + $i]) {
+ break;
+ }
+ }
+ if ($i === $needleCount) {
+ $found = true;
+ }
+ }
+ if (!$found) {
+ $parts[] = $haystack[$position];
+ unset($haystack[$position]);
+ }
+ $position++;
+ }
+
+ if ($found && $part && !empty($parts)) {
+ return Multibyte::ascii($parts);
+ } elseif ($found && !empty($haystack)) {
+ return Multibyte::ascii($haystack);
+ }
+ return false;
+ }
+
+ if (!$php) {
+ return strstr($haystack, $needle, $part);
+ }
+ return strstr($haystack, $needle);
+ }
+
+/**
+ * Make a string lowercase
+ *
+ * @param string $string The string being lowercased.
+ * @return string with all alphabetic characters converted to lowercase.
+ */
+ public static function strtolower($string) {
+ $utf8Map = Multibyte::utf8($string);
+
+ $length = count($utf8Map);
+ $lowerCase = array();
+
+ for ($i = 0; $i < $length; $i++) {
+ $char = $utf8Map[$i];
+
+ if ($char < 128) {
+ $str = strtolower(chr($char));
+ $strlen = strlen($str);
+ for ($ii = 0; $ii < $strlen; $ii++) {
+ $lower = ord(substr($str, $ii, 1));
+ }
+ $lowerCase[] = $lower;
+ $matched = true;
+ } else {
+ $matched = false;
+ $keys = self::_find($char, 'upper');
+
+ if (!empty($keys)) {
+ foreach ($keys as $key => $value) {
+ if ($keys[$key]['upper'] == $char && count($keys[$key]['lower'][0]) === 1) {
+ $lowerCase[] = $keys[$key]['lower'][0];
+ $matched = true;
+ break 1;
+ }
+ }
+ }
+ }
+ if ($matched === false) {
+ $lowerCase[] = $char;
+ }
+ }
+ return Multibyte::ascii($lowerCase);
+ }
+
+/**
+ * Make a string uppercase
+ *
+ * @param string $string The string being uppercased.
+ * @return string with all alphabetic characters converted to uppercase.
+ */
+ public static function strtoupper($string) {
+ $utf8Map = Multibyte::utf8($string);
+
+ $length = count($utf8Map);
+ $replaced = array();
+ $upperCase = array();
+
+ for ($i = 0; $i < $length; $i++) {
+ $char = $utf8Map[$i];
+
+ if ($char < 128) {
+ $str = strtoupper(chr($char));
+ $strlen = strlen($str);
+ for ($ii = 0; $ii < $strlen; $ii++) {
+ $upper = ord(substr($str, $ii, 1));
+ }
+ $upperCase[] = $upper;
+ $matched = true;
+
+ } else {
+ $matched = false;
+ $keys = self::_find($char);
+ $keyCount = count($keys);
+
+ if (!empty($keys)) {
+ foreach ($keys as $key => $value) {
+ $matched = false;
+ $replace = 0;
+ if ($length > 1 && count($keys[$key]['lower']) > 1) {
+ $j = 0;
+
+ for ($ii = 0, $count = count($keys[$key]['lower']); $ii < $count; $ii++) {
+ $nextChar = $utf8Map[$i + $ii];
+
+ if (isset($nextChar) && ($nextChar == $keys[$key]['lower'][$j + $ii])) {
+ $replace++;
+ }
+ }
+ if ($replace == $count) {
+ $upperCase[] = $keys[$key]['upper'];
+ $replaced = array_merge($replaced, array_values($keys[$key]['lower']));
+ $matched = true;
+ break 1;
+ }
+ } elseif ($length > 1 && $keyCount > 1) {
+ $j = 0;
+ for ($ii = 1; $ii < $keyCount; $ii++) {
+ $nextChar = $utf8Map[$i + $ii - 1];
+
+ if (in_array($nextChar, $keys[$ii]['lower'])) {
+
+ for ($jj = 0, $count = count($keys[$ii]['lower']); $jj < $count; $jj++) {
+ $nextChar = $utf8Map[$i + $jj];
+
+ if (isset($nextChar) && ($nextChar == $keys[$ii]['lower'][$j + $jj])) {
+ $replace++;
+ }
+ }
+ if ($replace == $count) {
+ $upperCase[] = $keys[$ii]['upper'];
+ $replaced = array_merge($replaced, array_values($keys[$ii]['lower']));
+ $matched = true;
+ break 2;
+ }
+ }
+ }
+ }
+ if ($keys[$key]['lower'][0] == $char) {
+ $upperCase[] = $keys[$key]['upper'];
+ $matched = true;
+ break 1;
+ }
+ }
+ }
+ }
+ if ($matched === false && !in_array($char, $replaced, true)) {
+ $upperCase[] = $char;
+ }
+ }
+ return Multibyte::ascii($upperCase);
+ }
+
+/**
+ * Count the number of substring occurrences
+ *
+ * @param string $haystack The string being checked.
+ * @param string $needle The string being found.
+ * @return integer The number of times the $needle substring occurs in the $haystack string.
+ */
+ public static function substrCount($haystack, $needle) {
+ $count = 0;
+ $haystack = Multibyte::utf8($haystack);
+ $haystackCount = count($haystack);
+ $matches = array_count_values($haystack);
+ $needle = Multibyte::utf8($needle);
+ $needleCount = count($needle);
+
+ if ($needleCount === 1 && isset($matches[$needle[0]])) {
+ return $matches[$needle[0]];
+ }
+
+ for ($i = 0; $i < $haystackCount; $i++) {
+ if (isset($needle[0]) && $needle[0] === $haystack[$i]) {
+ for ($ii = 1; $ii < $needleCount; $ii++) {
+ if ($needle[$ii] === $haystack[$i + 1]) {
+ if ((isset($needle[$ii + 1]) && $haystack[$i + 2]) && $needle[$ii + 1] !== $haystack[$i + 2]) {
+ $count--;
+ } else {
+ $count++;
+ }
+ }
+ }
+ }
+ }
+ return $count;
+ }
+
+/**
+ * Get part of string
+ *
+ * @param string $string The string being checked.
+ * @param integer $start The first position used in $string.
+ * @param integer $length The maximum length of the returned string.
+ * @return string The portion of $string specified by the $string and $length parameters.
+ */
+ public static function substr($string, $start, $length = null) {
+ if ($start === 0 && $length === null) {
+ return $string;
+ }
+
+ $string = Multibyte::utf8($string);
+
+ for ($i = 1; $i <= $start; $i++) {
+ unset($string[$i - 1]);
+ }
+
+ if ($length === null || count($string) < $length) {
+ return Multibyte::ascii($string);
+ }
+ $string = array_values($string);
+
+ $value = array();
+ for ($i = 0; $i < $length; $i++) {
+ $value[] = $string[$i];
+ }
+ return Multibyte::ascii($value);
+ }
+
+/**
+ * Prepare a string for mail transport, using the provided encoding
+ *
+ * @param string $string value to encode
+ * @param string $charset charset to use for encoding. defaults to UTF-8
+ * @param string $newline
+ * @return string
+ * @TODO: add support for 'Q'('Quoted Printable') encoding
+ */
+ public static function mimeEncode($string, $charset = null, $newline = "\r\n") {
+ if (!Multibyte::checkMultibyte($string) && strlen($string) < 75) {
+ return $string;
+ }
+
+ if (empty($charset)) {
+ $charset = Configure::read('App.encoding');
+ }
+ $charset = strtoupper($charset);
+
+ $start = '=?' . $charset . '?B?';
+ $end = '?=';
+ $spacer = $end . $newline . ' ' . $start;
+
+ $length = 75 - strlen($start) - strlen($end);
+ $length = $length - ($length % 4);
+ if ($charset == 'UTF-8') {
+ $parts = array();
+ $maxchars = floor(($length * 3) / 4);
+ while (strlen($string) > $maxchars) {
+ $i = (int)$maxchars;
+ $test = ord($string[$i]);
+ while ($test >= 128 && $test <= 191) {
+ $i--;
+ $test = ord($string[$i]);
+ }
+ $parts[] = base64_encode(substr($string, 0, $i));
+ $string = substr($string, $i);
+ }
+ $parts[] = base64_encode($string);
+ $string = implode($spacer, $parts);
+ } else {
+ $string = chunk_split(base64_encode($string), $length, $spacer);
+ $string = preg_replace('/' . preg_quote($spacer) . '$/', '', $string);
+ }
+ return $start . $string . $end;
+ }
+
+/**
+ * Return the Code points range for Unicode characters
+ *
+ * @param integer $decimal
+ * @return string
+ */
+ protected static function _codepoint($decimal) {
+ if ($decimal > 128 && $decimal < 256) {
+ $return = '0080_00ff'; // Latin-1 Supplement
+ } elseif ($decimal < 384) {
+ $return = '0100_017f'; // Latin Extended-A
+ } elseif ($decimal < 592) {
+ $return = '0180_024F'; // Latin Extended-B
+ } elseif ($decimal < 688) {
+ $return = '0250_02af'; // IPA Extensions
+ } elseif ($decimal >= 880 && $decimal < 1024) {
+ $return = '0370_03ff'; // Greek and Coptic
+ } elseif ($decimal < 1280) {
+ $return = '0400_04ff'; // Cyrillic
+ } elseif ($decimal < 1328) {
+ $return = '0500_052f'; // Cyrillic Supplement
+ } elseif ($decimal < 1424) {
+ $return = '0530_058f'; // Armenian
+ } elseif ($decimal >= 7680 && $decimal < 7936) {
+ $return = '1e00_1eff'; // Latin Extended Additional
+ } elseif ($decimal < 8192) {
+ $return = '1f00_1fff'; // Greek Extended
+ } elseif ($decimal >= 8448 && $decimal < 8528) {
+ $return = '2100_214f'; // Letterlike Symbols
+ } elseif ($decimal < 8592) {
+ $return = '2150_218f'; // Number Forms
+ } elseif ($decimal >= 9312 && $decimal < 9472) {
+ $return = '2460_24ff'; // Enclosed Alphanumerics
+ } elseif ($decimal >= 11264 && $decimal < 11360) {
+ $return = '2c00_2c5f'; // Glagolitic
+ } elseif ($decimal < 11392) {
+ $return = '2c60_2c7f'; // Latin Extended-C
+ } elseif ($decimal < 11520) {
+ $return = '2c80_2cff'; // Coptic
+ } elseif ($decimal >= 65280 && $decimal < 65520) {
+ $return = 'ff00_ffef'; // Halfwidth and Fullwidth Forms
+ } else {
+ $return = false;
+ }
+ self::$_codeRange[$decimal] = $return;
+ return $return;
+ }
+
+/**
+ * Find the related code folding values for $char
+ *
+ * @param integer $char decimal value of character
+ * @param string $type
+ * @return array
+ */
+ protected static function _find($char, $type = 'lower') {
+ $found = array();
+ if (!isset(self::$_codeRange[$char])) {
+ $range = self::_codepoint($char);
+ if ($range === false) {
+ return null;
+ }
+ if (!Configure::configured('_cake_core_')) {
+ App::uses('PhpReader', 'Configure');
+ Configure::config('_cake_core_', new PhpReader(CAKE . 'Config' . DS));
+ }
+ Configure::load('unicode' . DS . 'casefolding' . DS . $range, '_cake_core_');
+ self::$_caseFold[$range] = Configure::read($range);
+ Configure::delete($range);
+ }
+
+ if (!self::$_codeRange[$char]) {
+ return null;
+ }
+ self::$_table = self::$_codeRange[$char];
+ $count = count(self::$_caseFold[self::$_table]);
+
+ for ($i = 0; $i < $count; $i++) {
+ if ($type === 'lower' && self::$_caseFold[self::$_table][$i][$type][0] === $char) {
+ $found[] = self::$_caseFold[self::$_table][$i];
+ } elseif ($type === 'upper' && self::$_caseFold[self::$_table][$i][$type] === $char) {
+ $found[] = self::$_caseFold[self::$_table][$i];
+ }
+ }
+ return $found;
+ }
+
+/**
+ * Check the $string for multibyte characters
+ * @param string $string value to test
+ * @return boolean
+ */
+ public static function checkMultibyte($string) {
+ $length = strlen($string);
+
+ for ($i = 0; $i < $length; $i++ ) {
+ $value = ord(($string[$i]));
+ if ($value > 128) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/LICENSE.txt b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/LICENSE.txt
index 4787242..b4d0c66 100644
--- a/poc/poc02-compiling-cake/src/vendor/cake_1.1.20.7692/cake/LICENSE.txt
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/LICENSE.txt
@@ -1,9 +1,7 @@
The MIT License
-CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
-Copyright 2005-2007, Cake Software Foundation, Inc.
- 1785 E. Sahara Avenue, Suite 490-204
- Las Vegas, Nevada 89104
+CakePHP(tm) : The Rapid Development PHP Framework (http://cakephp.org)
+Copyright 2005-2012, Cake Software Foundation, Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLog.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLog.php
new file mode 100644
index 0000000..7881e07
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLog.php
@@ -0,0 +1,550 @@
+<?php
+/**
+ * Logging.
+ *
+ * Log messages to text files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Log
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('LogEngineCollection', 'Log');
+
+/**
+ * Logs messages to configured Log adapters. One or more adapters
+ * can be configured using CakeLogs's methods. If you don't
+ * configure any adapters, and write to the logs a default
+ * FileLog will be autoconfigured for you.
+ *
+ * ### Configuring Log adapters
+ *
+ * You can configure log adapters in your applications `bootstrap.php` file.
+ * A sample configuration would look like:
+ *
+ * {{{
+ * CakeLog::config('my_log', array('engine' => 'FileLog'));
+ * }}}
+ *
+ * See the documentation on CakeLog::config() for more detail.
+ *
+ * ### Writing to the log
+ *
+ * You write to the logs using CakeLog::write(). See its documentation for more
+ * information.
+ *
+ * ### Logging Levels
+ *
+ * By default CakeLog supports all the log levels defined in
+ * RFC 5424. When logging messages you can either use the named methods,
+ * or the correct constants with `write()`:
+ *
+ * {{{
+ * CakeLog::error('Something horrible happened');
+ * CakeLog::write(LOG_ERR, 'Something horrible happened');
+ * }}}
+ *
+ * If you require custom logging levels, you can use CakeLog::levels() to
+ * append additoinal logging levels.
+ *
+ * ### Logging scopes
+ *
+ * When logging messages and configuring log adapters, you can specify
+ * 'scopes' that the logger will handle. You can think of scopes as subsystems
+ * in your application that may require different logging setups. For
+ * example in an e-commerce application you may want to handle logged errors
+ * in the cart and ordering subsystems differently than the rest of the
+ * application. By using scopes you can control logging for each part
+ * of your application and still keep standard log levels.
+ *
+ * See CakeLog::config() and CakeLog::write() for more information
+ * on scopes
+ *
+ * @package Cake.Log
+ */
+class CakeLog {
+
+/**
+ * LogEngineCollection class
+ *
+ * @var LogEngineCollection
+ */
+ protected static $_Collection;
+
+/**
+ * Default log levels as detailed in RFC 5424
+ * http://tools.ietf.org/html/rfc5424
+ *
+ * @var array
+ */
+ protected static $_defaultLevels = array(
+ LOG_EMERG => 'emergency',
+ LOG_ALERT => 'alert',
+ LOG_CRIT => 'critical',
+ LOG_ERR => 'error',
+ LOG_WARNING => 'warning',
+ LOG_NOTICE => 'notice',
+ LOG_INFO => 'info',
+ LOG_DEBUG => 'debug',
+ );
+
+/**
+ * Active log levels for this instance.
+ *
+ * @var array
+ */
+ protected static $_levels;
+
+/**
+ * Mapped log levels
+ *
+ * @var array
+ */
+ protected static $_levelMap;
+
+/**
+ * initialize ObjectCollection
+ *
+ * @return void
+ */
+ protected static function _init() {
+ self::$_levels = self::defaultLevels();
+ self::$_Collection = new LogEngineCollection();
+ }
+
+/**
+ * Configure and add a new logging stream to CakeLog
+ * You can use add loggers from app/Log/Engine use app.loggername, or any
+ * plugin/Log/Engine using plugin.loggername.
+ *
+ * ### Usage:
+ *
+ * {{{
+ * CakeLog::config('second_file', array(
+ * 'engine' => 'FileLog',
+ * 'path' => '/var/logs/my_app/'
+ * ));
+ * }}}
+ *
+ * Will configure a FileLog instance to use the specified path.
+ * All options that are not `engine` are passed onto the logging adapter,
+ * and handled there. Any class can be configured as a logging
+ * adapter as long as it implements the methods in CakeLogInterface.
+ *
+ * ### Logging levels
+ *
+ * When configuring loggers, you can set which levels a logger will handle.
+ * This allows you to disable debug messages in production for example:
+ *
+ * {{{
+ * CakeLog::config('default', array(
+ * 'engine' => 'File',
+ * 'path' => LOGS,
+ * 'levels' => array('error', 'critical', 'alert', 'emergency')
+ * ));
+ * }}}
+ *
+ * The above logger would only log error messages or higher. Any
+ * other log messages would be discarded.
+ *
+ * ### Logging scopes
+ *
+ * When configuring loggers you can define the active scopes the logger
+ * is for. If defined only the listed scopes will be handled by the
+ * logger. If you don't define any scopes an adapter will catch
+ * all scopes that match the handled levels.
+ *
+ * {{{
+ * CakeLog::config('payments', array(
+ * 'engine' => 'File',
+ * 'scopes' => array('payment', 'order')
+ * ));
+ * }}}
+ *
+ * The above logger will only capture log entries made in the
+ * `payment` and `order` scopes. All other scopes including the
+ * undefined scope will be ignored.
+ *
+ * @param string $key The keyname for this logger, used to remove the
+ * logger later.
+ * @param array $config Array of configuration information for the logger
+ * @return boolean success of configuration.
+ * @throws CakeLogException
+ */
+ public static function config($key, $config) {
+ if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $key)) {
+ throw new CakeLogException(__d('cake_dev', 'Invalid key name'));
+ }
+ if (empty($config['engine'])) {
+ throw new CakeLogException(__d('cake_dev', 'Missing logger classname'));
+ }
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ self::$_Collection->load($key, $config);
+ return true;
+ }
+
+/**
+ * Returns the keynames of the currently active streams
+ *
+ * @return array Array of configured log streams.
+ */
+ public static function configured() {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ return self::$_Collection->attached();
+ }
+
+/**
+ * Gets/sets log levels
+ *
+ * Call this method without arguments, eg: `CakeLog::levels()` to obtain current
+ * level configuration.
+ *
+ * To append additional level 'user0' and 'user1' to to default log levels:
+ *
+ * {{{
+ * CakeLog::levels(array('user0, 'user1'));
+ * // or
+ * CakeLog::levels(array('user0, 'user1'), true);
+ * }}}
+ *
+ * will result in:
+ *
+ * {{{
+ * array(
+ * 0 => 'emergency',
+ * 1 => 'alert',
+ * ...
+ * 8 => 'user0',
+ * 9 => 'user1',
+ * );
+ * }}}
+ *
+ * To set/replace existing configuration, pass an array with the second argument
+ * set to false.
+ *
+ * {{{
+ * CakeLog::levels(array('user0, 'user1'), false);
+ * }}}
+ *
+ * will result in:
+ *
+ * {{{
+ * array(
+ * 0 => 'user0',
+ * 1 => 'user1',
+ * );
+ * }}}
+ *
+ * @param array $levels array
+ * @param bool $append true to append, false to replace
+ * @return array active log levels
+ */
+ public static function levels($levels = array(), $append = true) {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ if (empty($levels)) {
+ return self::$_levels;
+ }
+ $levels = array_values($levels);
+ if ($append) {
+ self::$_levels = array_merge(self::$_levels, $levels);
+ } else {
+ self::$_levels = $levels;
+ }
+ self::$_levelMap = array_flip(self::$_levels);
+ return self::$_levels;
+ }
+
+/**
+ * Reset log levels to the original value
+ *
+ * @return array default log levels
+ */
+ public static function defaultLevels() {
+ self::$_levels = self::$_defaultLevels;
+ self::$_levelMap = array_flip(self::$_levels);
+ return self::$_levels;
+ }
+
+/**
+ * Removes a stream from the active streams. Once a stream has been removed
+ * it will no longer have messages sent to it.
+ *
+ * @param string $streamName Key name of a configured stream to remove.
+ * @return void
+ */
+ public static function drop($streamName) {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ self::$_Collection->unload($streamName);
+ }
+
+/**
+ * Checks wether $streamName is enabled
+ *
+ * @param string $streamName to check
+ * @return bool
+ * @throws CakeLogException
+ */
+ public static function enabled($streamName) {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ if (!isset(self::$_Collection->{$streamName})) {
+ throw new CakeLogException(__d('cake_dev', 'Stream %s not found', $streamName));
+ }
+ return self::$_Collection->enabled($streamName);
+ }
+
+/**
+ * Enable stream. Streams that were previously disabled
+ * can be re-enabled with this method.
+ *
+ * @param string $streamName to enable
+ * @return void
+ * @throws CakeLogException
+ */
+ public static function enable($streamName) {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ if (!isset(self::$_Collection->{$streamName})) {
+ throw new CakeLogException(__d('cake_dev', 'Stream %s not found', $streamName));
+ }
+ self::$_Collection->enable($streamName);
+ }
+
+/**
+ * Disable stream. Disabling a stream will
+ * prevent that log stream from receiving any messages until
+ * its re-enabled.
+ *
+ * @param string $streamName to disable
+ * @return void
+ * @throws CakeLogException
+ */
+ public static function disable($streamName) {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ if (!isset(self::$_Collection->{$streamName})) {
+ throw new CakeLogException(__d('cake_dev', 'Stream %s not found', $streamName));
+ }
+ self::$_Collection->disable($streamName);
+ }
+
+/**
+ * Gets the logging engine from the active streams.
+ *
+ * @see BaseLog
+ * @param string $streamName Key name of a configured stream to get.
+ * @return $mixed instance of BaseLog or false if not found
+ */
+ public static function stream($streamName) {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+ if (!empty(self::$_Collection->{$streamName})) {
+ return self::$_Collection->{$streamName};
+ }
+ return false;
+ }
+
+/**
+ * Configures the automatic/default stream a FileLog.
+ *
+ * @return void
+ */
+ protected static function _autoConfig() {
+ self::$_Collection->load('default', array(
+ 'engine' => 'FileLog',
+ 'path' => LOGS,
+ ));
+ }
+
+/**
+ * Writes the given message and type to all of the configured log adapters.
+ * Configured adapters are passed both the $type and $message variables. $type
+ * is one of the following strings/values.
+ *
+ * ### Types:
+ *
+ * - LOG_EMERG => 'emergency',
+ * - LOG_ALERT => 'alert',
+ * - LOG_CRIT => 'critical',
+ * - `LOG_ERR` => 'error',
+ * - `LOG_WARNING` => 'warning',
+ * - `LOG_NOTICE` => 'notice',
+ * - `LOG_INFO` => 'info',
+ * - `LOG_DEBUG` => 'debug',
+ *
+ * ### Usage:
+ *
+ * Write a message to the 'warning' log:
+ *
+ * `CakeLog::write('warning', 'Stuff is broken here');`
+ *
+ * @param integer|string $type Type of message being written. When value is an integer
+ * or a string matching the recognized levels, then it will
+ * be treated log levels. Otherwise it's treated as scope.
+ * @param string $message Message content to log
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function write($type, $message, $scope = array()) {
+ if (empty(self::$_Collection)) {
+ self::_init();
+ }
+
+ if (is_int($type) && isset(self::$_levels[$type])) {
+ $type = self::$_levels[$type];
+ }
+ if (is_string($type) && empty($scope) && !in_array($type, self::$_levels)) {
+ $scope = $type;
+ }
+ $logged = false;
+ foreach (self::$_Collection->enabled() as $streamName) {
+ $logger = self::$_Collection->{$streamName};
+ $types = null;
+ $scopes = array();
+ if ($logger instanceof BaseLog) {
+ $config = $logger->config();
+ if (isset($config['types'])) {
+ $types = $config['types'];
+ }
+ if (isset($config['scopes'])) {
+ $scopes = $config['scopes'];
+ }
+ }
+ if (is_string($scope)) {
+ $inScope = in_array($scope, $scopes);
+ } else {
+ $intersect = array_intersect($scope, $scopes);
+ $inScope = !empty($intersect);
+ }
+ if (empty($types) || in_array($type, $types) || in_array($type, $scopes) && $inScope) {
+ $logger->write($type, $message);
+ $logged = true;
+ }
+ }
+ if (!$logged) {
+ self::_autoConfig();
+ self::stream('default')->write($type, $message);
+ }
+ return true;
+ }
+
+/**
+ * Convenience method to log emergency messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function emergency($message, $scope = array()) {
+ return self::write(self::$_levelMap['emergency'], $message, $scope);
+ }
+
+/**
+ * Convenience method to log alert messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function alert($message, $scope = array()) {
+ return self::write(self::$_levelMap['alert'], $message, $scope);
+ }
+
+/**
+ * Convenience method to log critical messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function critical($message, $scope = array()) {
+ return self::write(self::$_levelMap['critical'], $message, $scope);
+ }
+
+/**
+ * Convenience method to log error messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function error($message, $scope = array()) {
+ return self::write(self::$_levelMap['error'], $message, $scope);
+ }
+
+/**
+ * Convenience method to log warning messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function warning($message, $scope = array()) {
+ return self::write(self::$_levelMap['warning'], $message, $scope);
+ }
+
+/**
+ * Convenience method to log notice messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function notice($message, $scope = array()) {
+ return self::write(self::$_levelMap['notice'], $message, $scope);
+ }
+
+/**
+ * Convenience method to log debug messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function debug($message, $scope = array()) {
+ return self::write(self::$_levelMap['debug'], $message, $scope);
+ }
+
+/**
+ * Convenience method to log info messages
+ *
+ * @param string $message log message
+ * @param string|array $scope The scope(s) a log messge is being created in.
+ * See CakeLog::config() for more information on logging scopes.
+ * @return boolean Success
+ */
+ public static function info($message, $scope = array()) {
+ return self::write(self::$_levelMap['info'], $message, $scope);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLogInterface.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLogInterface.php
new file mode 100644
index 0000000..d31e863
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/CakeLogInterface.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * CakeLogInterface
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Log
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * CakeLogStreamInterface is the interface that should be implemented
+ * by all classes that are going to be used as Log streams.
+ *
+ * @package Cake.Log
+ */
+interface CakeLogInterface {
+
+/**
+ * Write method to handle writes being made to the Logger
+ *
+ * @param string $type
+ * @param string $message
+ * @return void
+ */
+ public function write($type, $message);
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/BaseLog.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/BaseLog.php
new file mode 100644
index 0000000..f731851
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/BaseLog.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Base Log Engine class
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package Cake.Log.Engine
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeLogInterface', 'Log');
+
+/**
+ * Base log engine class.
+ *
+ * @package Cake.Log.Engine
+ */
+abstract class BaseLog implements CakeLogInterface {
+
+/**
+ * Engine config
+ *
+ * @var string
+ */
+ protected $_config = array();
+
+/**
+ * __construct method
+ *
+ * @return void
+ */
+ public function __construct($config = array()) {
+ $this->config($config);
+ }
+
+/**
+ * Sets instance config. When $config is null, returns config array
+ *
+ * Config
+ *
+ * - `types` string or array, levels the engine is interested in
+ * - `scopes` string or array, scopes the engine is interested in
+ *
+ * @param array $config engine configuration
+ * @return array
+ */
+ public function config($config = array()) {
+ if (!empty($config)) {
+ if (isset($config['types']) && is_string($config['types'])) {
+ $config['types'] = array($config['types']);
+ }
+ $this->_config = $config;
+ }
+ return $this->_config;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/ConsoleLog.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/ConsoleLog.php
new file mode 100644
index 0000000..255be19
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/ConsoleLog.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Console Logging
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package Cake.Log.Engine
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseLog', 'Log/Engine');
+App::uses('ConsoleOutput', 'Console');
+
+/**
+ * Console logging. Writes logs to console output.
+ *
+ * @package Cake.Log.Engine
+ */
+class ConsoleLog extends BaseLog {
+
+/**
+ * Output stream
+ *
+ * @var ConsoleOutput
+ */
+ protected $_output = null;
+
+/**
+ * Constructs a new Console Logger.
+ *
+ * Config
+ *
+ * - `types` string or array, levels the engine is interested in
+ * - `scopes` string or array, scopes the engine is interested in
+ * - `stream` the path to save logs on.
+ * - `outputAs` integer or ConsoleOutput::[RAW|PLAIN|COLOR]
+ *
+ * @param array $config Options for the FileLog, see above.
+ * @throws CakeLogException
+ */
+ public function __construct($config = array()) {
+ parent::__construct($config);
+ if (DS == '\\' && !(bool)env('ANSICON')) {
+ $outputAs = ConsoleOutput::PLAIN;
+ } else {
+ $outputAs = ConsoleOutput::COLOR;
+ }
+ $config = Hash::merge(array(
+ 'stream' => 'php://stderr',
+ 'types' => null,
+ 'scopes' => array(),
+ 'outputAs' => $outputAs,
+ ), $this->_config);
+ $config = $this->config($config);
+ if ($config['stream'] instanceof ConsoleOutput) {
+ $this->_output = $config['stream'];
+ } elseif (is_string($config['stream'])) {
+ $this->_output = new ConsoleOutput($config['stream']);
+ } else {
+ throw new CakeLogException('`stream` not a ConsoleOutput nor string');
+ }
+ $this->_output->outputAs($config['outputAs']);
+ }
+
+/**
+ * Implements writing to console.
+ *
+ * @param string $type The type of log you are making.
+ * @param string $message The message you want to log.
+ * @return boolean success of write.
+ */
+ public function write($type, $message) {
+ $output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";
+ return $this->_output->write(sprintf('<%s>%s</%s>', $type, $output, $type), false);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/FileLog.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/FileLog.php
new file mode 100644
index 0000000..68e4526
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/Engine/FileLog.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * File Storage stream for Logging
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package Cake.Log.Engine
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseLog', 'Log/Engine');
+
+/**
+ * File Storage stream for Logging. Writes logs to different files
+ * based on the type of log it is.
+ *
+ * @package Cake.Log.Engine
+ */
+class FileLog extends BaseLog {
+
+/**
+ * Path to save log files on.
+ *
+ * @var string
+ */
+ protected $_path = null;
+
+/**
+ * Constructs a new File Logger.
+ *
+ * Config
+ *
+ * - `types` string or array, levels the engine is interested in
+ * - `scopes` string or array, scopes the engine is interested in
+ * - `file` log file name
+ * - `path` the path to save logs on.
+ *
+ * @param array $options Options for the FileLog, see above.
+ */
+ public function __construct($config = array()) {
+ parent::__construct($config);
+ $config = Hash::merge(array(
+ 'path' => LOGS,
+ 'file' => null,
+ 'types' => null,
+ 'scopes' => array(),
+ ), $this->_config);
+ $config = $this->config($config);
+ $this->_path = $config['path'];
+ $this->_file = $config['file'];
+ if (!empty($this->_file) && !preg_match('/\.log$/', $this->_file)) {
+ $this->_file .= '.log';
+ }
+ }
+
+/**
+ * Implements writing to log files.
+ *
+ * @param string $type The type of log you are making.
+ * @param string $message The message you want to log.
+ * @return boolean success of write.
+ */
+ public function write($type, $message) {
+ $debugTypes = array('notice', 'info', 'debug');
+
+ if (!empty($this->_file)) {
+ $filename = $this->_path . $this->_file;
+ } elseif ($type == 'error' || $type == 'warning') {
+ $filename = $this->_path . 'error.log';
+ } elseif (in_array($type, $debugTypes)) {
+ $filename = $this->_path . 'debug.log';
+ } elseif (in_array($type, $this->_config['scopes'])) {
+ $filename = $this->_path . $this->_file;
+ } else {
+ $filename = $this->_path . $type . '.log';
+ }
+ $output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";
+ return file_put_contents($filename, $output, FILE_APPEND);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/LogEngineCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/LogEngineCollection.php
new file mode 100644
index 0000000..ce9e273
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Log/LogEngineCollection.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Registry of loaded log engines
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Log
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+
+/**
+ * Registry of loaded log engines
+ *
+ * @package Cake.Log
+ */
+class LogEngineCollection extends ObjectCollection {
+
+/**
+ * Loads/constructs a Log engine.
+ *
+ * @param string $name instance identifier
+ * @param array $options Setting for the Log Engine
+ * @return BaseLog BaseLog engine instance
+ * @throws CakeLogException when logger class does not implement a write method
+ */
+ public function load($name, $options = array()) {
+ $enable = isset($options['enabled']) ? $options['enabled'] : true;
+ $loggerName = $options['engine'];
+ unset($options['engine']);
+ $className = $this->_getLogger($loggerName);
+ $logger = new $className($options);
+ if (!$logger instanceof CakeLogInterface) {
+ throw new CakeLogException(sprintf(
+ __d('cake_dev', 'logger class %s does not implement a write method.'), $loggerName
+ ));
+ }
+ $this->_loaded[$name] = $logger;
+ if ($enable) {
+ $this->enable($name);
+ }
+ return $logger;
+ }
+
+/**
+ * Attempts to import a logger class from the various paths it could be on.
+ * Checks that the logger class implements a write method as well.
+ *
+ * @param string $loggerName the plugin.className of the logger class you want to build.
+ * @return mixed boolean false on any failures, string of classname to use if search was successful.
+ * @throws CakeLogException
+ */
+ protected static function _getLogger($loggerName) {
+ list($plugin, $loggerName) = pluginSplit($loggerName, true);
+
+ App::uses($loggerName, $plugin . 'Log/Engine');
+ if (!class_exists($loggerName)) {
+ throw new CakeLogException(__d('cake_dev', 'Could not load class %s', $loggerName));
+ }
+ return $loggerName;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AclNode.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AclNode.php
new file mode 100644
index 0000000..ca3357c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AclNode.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+
+/**
+ * ACL Node
+ *
+ * @package Cake.Model
+ */
+class AclNode extends Model {
+
+/**
+ * Explicitly disable in-memory query caching for ACL models
+ *
+ * @var boolean
+ */
+ public $cacheQueries = false;
+
+/**
+ * ACL models use the Tree behavior
+ *
+ * @var array
+ */
+ public $actsAs = array('Tree' => array('type' => 'nested'));
+
+/**
+ * Constructor
+ *
+ */
+ public function __construct() {
+ $config = Configure::read('Acl.database');
+ if (isset($config)) {
+ $this->useDbConfig = $config;
+ }
+ parent::__construct();
+ }
+
+/**
+ * Retrieves the Aro/Aco node for this model
+ *
+ * @param string|array|Model $ref Array with 'model' and 'foreign_key', model object, or string value
+ * @return array Node found in database
+ * @throws CakeException when binding to a model that doesn't exist.
+ */
+ public function node($ref = null) {
+ $db = $this->getDataSource();
+ $type = $this->alias;
+ $result = null;
+
+ if (!empty($this->useTable)) {
+ $table = $this->useTable;
+ } else {
+ $table = Inflector::pluralize(Inflector::underscore($type));
+ }
+
+ if (empty($ref)) {
+ return null;
+ } elseif (is_string($ref)) {
+ $path = explode('/', $ref);
+ $start = $path[0];
+ unset($path[0]);
+
+ $queryData = array(
+ 'conditions' => array(
+ $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
+ $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")),
+ 'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
+ 'joins' => array(array(
+ 'table' => $table,
+ 'alias' => "{$type}0",
+ 'type' => 'LEFT',
+ 'conditions' => array("{$type}0.alias" => $start)
+ )),
+ 'order' => $db->name("{$type}.lft") . ' DESC'
+ );
+
+ foreach ($path as $i => $alias) {
+ $j = $i - 1;
+
+ $queryData['joins'][] = array(
+ 'table' => $table,
+ 'alias' => "{$type}{$i}",
+ 'type' => 'LEFT',
+ 'conditions' => array(
+ $db->name("{$type}{$i}.lft") . ' > ' . $db->name("{$type}{$j}.lft"),
+ $db->name("{$type}{$i}.rght") . ' < ' . $db->name("{$type}{$j}.rght"),
+ $db->name("{$type}{$i}.alias") . ' = ' . $db->value($alias, 'string'),
+ $db->name("{$type}{$j}.id") . ' = ' . $db->name("{$type}{$i}.parent_id")
+ )
+ );
+
+ $queryData['conditions'] = array('or' => array(
+ $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght"),
+ $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}{$i}.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}{$i}.rght"))
+ );
+ }
+ $result = $db->read($this, $queryData, -1);
+ $path = array_values($path);
+
+ if (
+ !isset($result[0][$type]) ||
+ (!empty($path) && $result[0][$type]['alias'] != $path[count($path) - 1]) ||
+ (empty($path) && $result[0][$type]['alias'] != $start)
+ ) {
+ return false;
+ }
+ } elseif (is_object($ref) && is_a($ref, 'Model')) {
+ $ref = array('model' => $ref->name, 'foreign_key' => $ref->id);
+ } elseif (is_array($ref) && !(isset($ref['model']) && isset($ref['foreign_key']))) {
+ $name = key($ref);
+ list($plugin, $alias) = pluginSplit($name);
+
+ $model = ClassRegistry::init(array('class' => $name, 'alias' => $alias));
+
+ if (empty($model)) {
+ throw new CakeException('cake_dev', "Model class '%s' not found in AclNode::node() when trying to bind %s object", $type, $this->alias);
+ }
+
+ $tmpRef = null;
+ if (method_exists($model, 'bindNode')) {
+ $tmpRef = $model->bindNode($ref);
+ }
+ if (empty($tmpRef)) {
+ $ref = array('model' => $alias, 'foreign_key' => $ref[$name][$model->primaryKey]);
+ } else {
+ if (is_string($tmpRef)) {
+ return $this->node($tmpRef);
+ }
+ $ref = $tmpRef;
+ }
+ }
+ if (is_array($ref)) {
+ if (is_array(current($ref)) && is_string(key($ref))) {
+ $name = key($ref);
+ $ref = current($ref);
+ }
+ foreach ($ref as $key => $val) {
+ if (strpos($key, $type) !== 0 && strpos($key, '.') === false) {
+ unset($ref[$key]);
+ $ref["{$type}0.{$key}"] = $val;
+ }
+ }
+ $queryData = array(
+ 'conditions' => $ref,
+ 'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
+ 'joins' => array(array(
+ 'table' => $table,
+ 'alias' => "{$type}0",
+ 'type' => 'LEFT',
+ 'conditions' => array(
+ $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
+ $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")
+ )
+ )),
+ 'order' => $db->name("{$type}.lft") . ' DESC'
+ );
+ $result = $db->read($this, $queryData, -1);
+
+ if (!$result) {
+ throw new CakeException(__d('cake_dev', "AclNode::node() - Couldn't find %s node identified by \"%s\"", $type, print_r($ref, true)));
+ }
+ }
+ return $result;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aco.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aco.php
new file mode 100644
index 0000000..0ee696e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aco.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AclNode', 'Model');
+
+/**
+ * Access Control Object
+ *
+ * @package Cake.Model
+ */
+class Aco extends AclNode {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'Aco';
+
+/**
+ * Binds to ARO nodes through permissions settings
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Aro' => array('with' => 'Permission'));
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AcoAction.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AcoAction.php
new file mode 100644
index 0000000..2783600
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/AcoAction.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppModel', 'Model');
+
+/**
+ * Action for Access Control Object
+ *
+ * @package Cake.Model
+ */
+class AcoAction extends AppModel {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'AcoAction';
+
+/**
+ * ACO Actions belong to ACOs
+ *
+ * @var array
+ */
+ public $belongsTo = array('Aco');
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aro.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aro.php
new file mode 100644
index 0000000..6c03f46
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Aro.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AclNode', 'Model');
+
+/**
+ * Access Request Object
+ *
+ * @package Cake.Model
+ */
+class Aro extends AclNode {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'Aro';
+
+/**
+ * AROs are linked to ACOs by means of Permission
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Aco' => array('with' => 'Permission'));
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/AclBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/AclBehavior.php
new file mode 100644
index 0000000..d0f0a4c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/AclBehavior.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * ACL behavior class.
+ *
+ * Enables objects to easily tie into an ACL system
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Model.Behavior
+ * @since CakePHP v 1.2.0.4487
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('AclNode', 'Model');
+App::uses('Hash', 'Utility');
+
+/**
+ * ACL behavior
+ *
+ * Enables objects to easily tie into an ACL system
+ *
+ * @package Cake.Model.Behavior
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/acl.html
+ */
+class AclBehavior extends ModelBehavior {
+
+/**
+ * Maps ACL type options to ACL models
+ *
+ * @var array
+ */
+ protected $_typeMaps = array('requester' => 'Aro', 'controlled' => 'Aco', 'both' => array('Aro', 'Aco'));
+
+/**
+ * Sets up the configuration for the model, and loads ACL models if they haven't been already
+ *
+ * @param Model $model
+ * @param array $config
+ * @return void
+ */
+ public function setup(Model $model, $config = array()) {
+ if (isset($config[0])) {
+ $config['type'] = $config[0];
+ unset($config[0]);
+ }
+ $this->settings[$model->name] = array_merge(array('type' => 'controlled'), $config);
+ $this->settings[$model->name]['type'] = strtolower($this->settings[$model->name]['type']);
+
+ $types = $this->_typeMaps[$this->settings[$model->name]['type']];
+
+ if (!is_array($types)) {
+ $types = array($types);
+ }
+ foreach ($types as $type) {
+ $model->{$type} = ClassRegistry::init($type);
+ }
+ if (!method_exists($model, 'parentNode')) {
+ trigger_error(__d('cake_dev', 'Callback parentNode() not defined in %s', $model->alias), E_USER_WARNING);
+ }
+ }
+
+/**
+ * Retrieves the Aro/Aco node for this model
+ *
+ * @param Model $model
+ * @param string|array|Model $ref Array with 'model' and 'foreign_key', model object, or string value
+ * @param string $type Only needed when Acl is set up as 'both', specify 'Aro' or 'Aco' to get the correct node
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/acl.html#node
+ */
+ public function node(Model $model, $ref = null, $type = null) {
+ if (empty($type)) {
+ $type = $this->_typeMaps[$this->settings[$model->name]['type']];
+ if (is_array($type)) {
+ trigger_error(__d('cake_dev', 'AclBehavior is setup with more then one type, please specify type parameter for node()'), E_USER_WARNING);
+ return null;
+ }
+ }
+ if (empty($ref)) {
+ $ref = array('model' => $model->name, 'foreign_key' => $model->id);
+ }
+ return $model->{$type}->node($ref);
+ }
+
+/**
+ * Creates a new ARO/ACO node bound to this record
+ *
+ * @param Model $model
+ * @param boolean $created True if this is a new record
+ * @return void
+ */
+ public function afterSave(Model $model, $created) {
+ $types = $this->_typeMaps[$this->settings[$model->name]['type']];
+ if (!is_array($types)) {
+ $types = array($types);
+ }
+ foreach ($types as $type) {
+ $parent = $model->parentNode();
+ if (!empty($parent)) {
+ $parent = $this->node($model, $parent, $type);
+ }
+ $data = array(
+ 'parent_id' => isset($parent[0][$type]['id']) ? $parent[0][$type]['id'] : null,
+ 'model' => $model->name,
+ 'foreign_key' => $model->id
+ );
+ if (!$created) {
+ $node = $this->node($model, null, $type);
+ $data['id'] = isset($node[0][$type]['id']) ? $node[0][$type]['id'] : null;
+ }
+ $model->{$type}->create();
+ $model->{$type}->save($data);
+ }
+ }
+
+/**
+ * Destroys the ARO/ACO node bound to the deleted record
+ *
+ * @param Model $model
+ * @return void
+ */
+ public function afterDelete(Model $model) {
+ $types = $this->_typeMaps[$this->settings[$model->name]['type']];
+ if (!is_array($types)) {
+ $types = array($types);
+ }
+ foreach ($types as $type) {
+ $node = Hash::extract($this->node($model, null, $type), "0.{$type}.id");
+ if (!empty($node)) {
+ $model->{$type}->delete($node);
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/ContainableBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/ContainableBehavior.php
new file mode 100644
index 0000000..bb33eaf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/ContainableBehavior.php
@@ -0,0 +1,428 @@
+<?php
+/**
+ * Behavior for binding management.
+ *
+ * Behavior to simplify manipulating a model's bindings when doing a find operation
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Behavior to allow for dynamic and atomic manipulation of a Model's associations
+ * used for a find call. Most useful for limiting the amount of associations and
+ * data returned.
+ *
+ * @package Cake.Model.Behavior
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
+ */
+class ContainableBehavior extends ModelBehavior {
+
+/**
+ * Types of relationships available for models
+ *
+ * @var array
+ */
+ public $types = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+
+/**
+ * Runtime configuration for this behavior
+ *
+ * @var array
+ */
+ public $runtime = array();
+
+/**
+ * Initiate behavior for the model using specified settings.
+ *
+ * Available settings:
+ *
+ * - recursive: (boolean, optional) set to true to allow containable to automatically
+ * determine the recursiveness level needed to fetch specified models,
+ * and set the model recursiveness to this level. setting it to false
+ * disables this feature. DEFAULTS TO: true
+ * - notices: (boolean, optional) issues E_NOTICES for bindings referenced in a
+ * containable call that are not valid. DEFAULTS TO: true
+ * - autoFields: (boolean, optional) auto-add needed fields to fetch requested
+ * bindings. DEFAULTS TO: true
+ *
+ * @param Model $Model Model using the behavior
+ * @param array $settings Settings to override for model.
+ * @return void
+ */
+ public function setup(Model $Model, $settings = array()) {
+ if (!isset($this->settings[$Model->alias])) {
+ $this->settings[$Model->alias] = array('recursive' => true, 'notices' => true, 'autoFields' => true);
+ }
+ $this->settings[$Model->alias] = array_merge($this->settings[$Model->alias], $settings);
+ }
+
+/**
+ * Runs before a find() operation. Used to allow 'contain' setting
+ * as part of the find call, like this:
+ *
+ * `Model->find('all', array('contain' => array('Model1', 'Model2')));`
+ *
+ * {{{
+ * Model->find('all', array('contain' => array(
+ * 'Model1' => array('Model11', 'Model12'),
+ * 'Model2',
+ * 'Model3' => array(
+ * 'Model31' => 'Model311',
+ * 'Model32',
+ * 'Model33' => array('Model331', 'Model332')
+ * )));
+ * }}}
+ *
+ * @param Model $Model Model using the behavior
+ * @param array $query Query parameters as set by cake
+ * @return array
+ */
+ public function beforeFind(Model $Model, $query) {
+ $reset = (isset($query['reset']) ? $query['reset'] : true);
+ $noContain = (
+ (isset($this->runtime[$Model->alias]['contain']) && empty($this->runtime[$Model->alias]['contain'])) ||
+ (isset($query['contain']) && empty($query['contain']))
+ );
+ $contain = array();
+ if (isset($this->runtime[$Model->alias]['contain'])) {
+ $contain = $this->runtime[$Model->alias]['contain'];
+ unset($this->runtime[$Model->alias]['contain']);
+ }
+ if (isset($query['contain'])) {
+ $contain = array_merge($contain, (array)$query['contain']);
+ }
+ if (
+ $noContain || !$contain || in_array($contain, array(null, false), true) ||
+ (isset($contain[0]) && $contain[0] === null)
+ ) {
+ if ($noContain) {
+ $query['recursive'] = -1;
+ }
+ return $query;
+ }
+ if ((isset($contain[0]) && is_bool($contain[0])) || is_bool(end($contain))) {
+ $reset = is_bool(end($contain))
+ ? array_pop($contain)
+ : array_shift($contain);
+ }
+ $containments = $this->containments($Model, $contain);
+ $map = $this->containmentsMap($containments);
+
+ $mandatory = array();
+ foreach ($containments['models'] as $name => $model) {
+ $instance = $model['instance'];
+ $needed = $this->fieldDependencies($instance, $map, false);
+ if (!empty($needed)) {
+ $mandatory = array_merge($mandatory, $needed);
+ }
+ if ($contain) {
+ $backupBindings = array();
+ foreach ($this->types as $relation) {
+ if (!empty($instance->__backAssociation[$relation])) {
+ $backupBindings[$relation] = $instance->__backAssociation[$relation];
+ } else {
+ $backupBindings[$relation] = $instance->{$relation};
+ }
+ }
+ foreach ($this->types as $type) {
+ $unbind = array();
+ foreach ($instance->{$type} as $assoc => $options) {
+ if (!isset($model['keep'][$assoc])) {
+ $unbind[] = $assoc;
+ }
+ }
+ if (!empty($unbind)) {
+ if (!$reset && empty($instance->__backOriginalAssociation)) {
+ $instance->__backOriginalAssociation = $backupBindings;
+ }
+ $instance->unbindModel(array($type => $unbind), $reset);
+ }
+ foreach ($instance->{$type} as $assoc => $options) {
+ if (isset($model['keep'][$assoc]) && !empty($model['keep'][$assoc])) {
+ if (isset($model['keep'][$assoc]['fields'])) {
+ $model['keep'][$assoc]['fields'] = $this->fieldDependencies($containments['models'][$assoc]['instance'], $map, $model['keep'][$assoc]['fields']);
+ }
+ if (!$reset && empty($instance->__backOriginalAssociation)) {
+ $instance->__backOriginalAssociation = $backupBindings;
+ } elseif ($reset) {
+ $instance->__backAssociation[$type] = $backupBindings[$type];
+ }
+ $instance->{$type}[$assoc] = array_merge($instance->{$type}[$assoc], $model['keep'][$assoc]);
+ }
+ if (!$reset) {
+ $instance->__backInnerAssociation[] = $assoc;
+ }
+ }
+ }
+ }
+ }
+
+ if ($this->settings[$Model->alias]['recursive']) {
+ $query['recursive'] = (isset($query['recursive'])) ? $query['recursive'] : $containments['depth'];
+ }
+
+ $autoFields = ($this->settings[$Model->alias]['autoFields']
+ && !in_array($Model->findQueryType, array('list', 'count'))
+ && !empty($query['fields']));
+
+ if (!$autoFields) {
+ return $query;
+ }
+
+ $query['fields'] = (array)$query['fields'];
+ foreach (array('hasOne', 'belongsTo') as $type) {
+ if (!empty($Model->{$type})) {
+ foreach ($Model->{$type} as $assoc => $data) {
+ if ($Model->useDbConfig == $Model->{$assoc}->useDbConfig && !empty($data['fields'])) {
+ foreach ((array)$data['fields'] as $field) {
+ $query['fields'][] = (strpos($field, '.') === false ? $assoc . '.' : '') . $field;
+ }
+ }
+ }
+ }
+ }
+
+ if (!empty($mandatory[$Model->alias])) {
+ foreach ($mandatory[$Model->alias] as $field) {
+ if ($field == '--primaryKey--') {
+ $field = $Model->primaryKey;
+ } elseif (preg_match('/^.+\.\-\-[^-]+\-\-$/', $field)) {
+ list($modelName, $field) = explode('.', $field);
+ if ($Model->useDbConfig == $Model->{$modelName}->useDbConfig) {
+ $field = $modelName . '.' . (
+ ($field === '--primaryKey--') ? $Model->$modelName->primaryKey : $field
+ );
+ } else {
+ $field = null;
+ }
+ }
+ if ($field !== null) {
+ $query['fields'][] = $field;
+ }
+ }
+ }
+ $query['fields'] = array_unique($query['fields']);
+ return $query;
+ }
+
+/**
+ * Unbinds all relations from a model except the specified ones. Calling this function without
+ * parameters unbinds all related models.
+ *
+ * @param Model $Model Model on which binding restriction is being applied
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html#using-containable
+ */
+ public function contain(Model $Model) {
+ $args = func_get_args();
+ $contain = call_user_func_array('am', array_slice($args, 1));
+ $this->runtime[$Model->alias]['contain'] = $contain;
+ }
+
+/**
+ * Permanently restore the original binding settings of given model, useful
+ * for restoring the bindings after using 'reset' => false as part of the
+ * contain call.
+ *
+ * @param Model $Model Model on which to reset bindings
+ * @return void
+ */
+ public function resetBindings(Model $Model) {
+ if (!empty($Model->__backOriginalAssociation)) {
+ $Model->__backAssociation = $Model->__backOriginalAssociation;
+ unset($Model->__backOriginalAssociation);
+ }
+ $Model->resetAssociations();
+ if (!empty($Model->__backInnerAssociation)) {
+ $assocs = $Model->__backInnerAssociation;
+ $Model->__backInnerAssociation = array();
+ foreach ($assocs as $currentModel) {
+ $this->resetBindings($Model->$currentModel);
+ }
+ }
+ }
+
+/**
+ * Process containments for model.
+ *
+ * @param Model $Model Model on which binding restriction is being applied
+ * @param array $contain Parameters to use for restricting this model
+ * @param array $containments Current set of containments
+ * @param boolean $throwErrors Whether non-existent bindings show throw errors
+ * @return array Containments
+ */
+ public function containments(Model $Model, $contain, $containments = array(), $throwErrors = null) {
+ $options = array('className', 'joinTable', 'with', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery');
+ $keep = array();
+ if ($throwErrors === null) {
+ $throwErrors = (empty($this->settings[$Model->alias]) ? true : $this->settings[$Model->alias]['notices']);
+ }
+ foreach ((array)$contain as $name => $children) {
+ if (is_numeric($name)) {
+ $name = $children;
+ $children = array();
+ }
+ if (preg_match('/(?<!\.)\(/', $name)) {
+ $name = str_replace('(', '.(', $name);
+ }
+ if (strpos($name, '.') !== false) {
+ $chain = explode('.', $name);
+ $name = array_shift($chain);
+ $children = array(implode('.', $chain) => $children);
+ }
+
+ $children = (array)$children;
+ foreach ($children as $key => $val) {
+ if (is_string($key) && is_string($val) && !in_array($key, $options, true)) {
+ $children[$key] = (array)$val;
+ }
+ }
+
+ $keys = array_keys($children);
+ if ($keys && isset($children[0])) {
+ $keys = array_merge(array_values($children), $keys);
+ }
+
+ foreach ($keys as $i => $key) {
+ if (is_array($key)) {
+ continue;
+ }
+ $optionKey = in_array($key, $options, true);
+ if (!$optionKey && is_string($key) && preg_match('/^[a-z(]/', $key) && (!isset($Model->{$key}) || !is_object($Model->{$key}))) {
+ $option = 'fields';
+ $val = array($key);
+ if ($key{0} == '(') {
+ $val = preg_split('/\s*,\s*/', substr($key, 1, -1));
+ } elseif (preg_match('/ASC|DESC$/', $key)) {
+ $option = 'order';
+ $val = $Model->{$name}->alias . '.' . $key;
+ } elseif (preg_match('/[ =!]/', $key)) {
+ $option = 'conditions';
+ $val = $Model->{$name}->alias . '.' . $key;
+ }
+ $children[$option] = is_array($val) ? $val : array($val);
+ $newChildren = null;
+ if (!empty($name) && !empty($children[$key])) {
+ $newChildren = $children[$key];
+ }
+ unset($children[$key], $children[$i]);
+ $key = $option;
+ $optionKey = true;
+ if (!empty($newChildren)) {
+ $children = Hash::merge($children, $newChildren);
+ }
+ }
+ if ($optionKey && isset($children[$key])) {
+ if (!empty($keep[$name][$key]) && is_array($keep[$name][$key])) {
+ $keep[$name][$key] = array_merge((isset($keep[$name][$key]) ? $keep[$name][$key] : array()), (array)$children[$key]);
+ } else {
+ $keep[$name][$key] = $children[$key];
+ }
+ unset($children[$key]);
+ }
+ }
+
+ if (!isset($Model->{$name}) || !is_object($Model->{$name})) {
+ if ($throwErrors) {
+ trigger_error(__d('cake_dev', 'Model "%s" is not associated with model "%s"', $Model->alias, $name), E_USER_WARNING);
+ }
+ continue;
+ }
+
+ $containments = $this->containments($Model->{$name}, $children, $containments);
+ $depths[] = $containments['depth'] + 1;
+ if (!isset($keep[$name])) {
+ $keep[$name] = array();
+ }
+ }
+
+ if (!isset($containments['models'][$Model->alias])) {
+ $containments['models'][$Model->alias] = array('keep' => array(), 'instance' => &$Model);
+ }
+
+ $containments['models'][$Model->alias]['keep'] = array_merge($containments['models'][$Model->alias]['keep'], $keep);
+ $containments['depth'] = empty($depths) ? 0 : max($depths);
+ return $containments;
+ }
+
+/**
+ * Calculate needed fields to fetch the required bindings for the given model.
+ *
+ * @param Model $Model Model
+ * @param array $map Map of relations for given model
+ * @param array|boolean $fields If array, fields to initially load, if false use $Model as primary model
+ * @return array Fields
+ */
+ public function fieldDependencies(Model $Model, $map, $fields = array()) {
+ if ($fields === false) {
+ foreach ($map as $parent => $children) {
+ foreach ($children as $type => $bindings) {
+ foreach ($bindings as $dependency) {
+ if ($type == 'hasAndBelongsToMany') {
+ $fields[$parent][] = '--primaryKey--';
+ } elseif ($type == 'belongsTo') {
+ $fields[$parent][] = $dependency . '.--primaryKey--';
+ }
+ }
+ }
+ }
+ return $fields;
+ }
+ if (empty($map[$Model->alias])) {
+ return $fields;
+ }
+ foreach ($map[$Model->alias] as $type => $bindings) {
+ foreach ($bindings as $dependency) {
+ $innerFields = array();
+ switch ($type) {
+ case 'belongsTo':
+ $fields[] = $Model->{$type}[$dependency]['foreignKey'];
+ break;
+ case 'hasOne':
+ case 'hasMany':
+ $innerFields[] = $Model->$dependency->primaryKey;
+ $fields[] = $Model->primaryKey;
+ break;
+ }
+ if (!empty($innerFields) && !empty($Model->{$type}[$dependency]['fields'])) {
+ $Model->{$type}[$dependency]['fields'] = array_unique(array_merge($Model->{$type}[$dependency]['fields'], $innerFields));
+ }
+ }
+ }
+ return array_unique($fields);
+ }
+
+/**
+ * Build the map of containments
+ *
+ * @param array $containments Containments
+ * @return array Built containments
+ */
+ public function containmentsMap($containments) {
+ $map = array();
+ foreach ($containments['models'] as $name => $model) {
+ $instance = $model['instance'];
+ foreach ($this->types as $type) {
+ foreach ($instance->{$type} as $assoc => $options) {
+ if (isset($model['keep'][$assoc])) {
+ $map[$name][$type] = isset($map[$name][$type]) ? array_merge($map[$name][$type], (array)$assoc) : (array)$assoc;
+ }
+ }
+ }
+ }
+ return $map;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TranslateBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TranslateBehavior.php
new file mode 100644
index 0000000..387a37f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TranslateBehavior.php
@@ -0,0 +1,627 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.4525
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('I18n', 'I18n');
+App::uses('I18nModel', 'Model');
+
+/**
+ * Translate behavior
+ *
+ * @package Cake.Model.Behavior
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html
+ */
+class TranslateBehavior extends ModelBehavior {
+
+/**
+ * Used for runtime configuration of model
+ *
+ * @var array
+ */
+ public $runtime = array();
+
+/**
+ * Stores the joinTable object for generating joins.
+ *
+ * @var object
+ */
+ protected $_joinTable;
+
+/**
+ * Stores the runtime model for generating joins.
+ *
+ * @var Model
+ */
+ protected $_runtimeModel;
+
+/**
+ * Callback
+ *
+ * $config for TranslateBehavior should be
+ * array('fields' => array('field_one',
+ * 'field_two' => 'FieldAssoc', 'field_three'))
+ *
+ * With above example only one permanent hasMany will be joined (for field_two
+ * as FieldAssoc)
+ *
+ * $config could be empty - and translations configured dynamically by
+ * bindTranslation() method
+ *
+ * @param Model $model Model the behavior is being attached to.
+ * @param array $config Array of configuration information.
+ * @return mixed
+ */
+ public function setup(Model $model, $config = array()) {
+ $db = ConnectionManager::getDataSource($model->useDbConfig);
+ if (!$db->connected) {
+ trigger_error(
+ __d('cake_dev', 'Datasource %s for TranslateBehavior of model %s is not connected', $model->useDbConfig, $model->alias),
+ E_USER_ERROR
+ );
+ return false;
+ }
+
+ $this->settings[$model->alias] = array();
+ $this->runtime[$model->alias] = array('fields' => array());
+ $this->translateModel($model);
+ return $this->bindTranslation($model, $config, false);
+ }
+
+/**
+ * Cleanup Callback unbinds bound translations and deletes setting information.
+ *
+ * @param Model $model Model being detached.
+ * @return void
+ */
+ public function cleanup(Model $model) {
+ $this->unbindTranslation($model);
+ unset($this->settings[$model->alias]);
+ unset($this->runtime[$model->alias]);
+ }
+
+/**
+ * beforeFind Callback
+ *
+ * @param Model $model Model find is being run on.
+ * @param array $query Array of Query parameters.
+ * @return array Modified query
+ */
+ public function beforeFind(Model $model, $query) {
+ $this->runtime[$model->alias]['virtualFields'] = $model->virtualFields;
+ $locale = $this->_getLocale($model);
+ if (empty($locale)) {
+ return $query;
+ }
+ $db = $model->getDataSource();
+ $RuntimeModel = $this->translateModel($model);
+
+ if (!empty($RuntimeModel->tablePrefix)) {
+ $tablePrefix = $RuntimeModel->tablePrefix;
+ } else {
+ $tablePrefix = $db->config['prefix'];
+ }
+ $joinTable = new StdClass();
+ $joinTable->tablePrefix = $tablePrefix;
+ $joinTable->table = $RuntimeModel->table;
+ $joinTable->schemaName = $RuntimeModel->getDataSource()->getSchemaName();
+
+ $this->_joinTable = $joinTable;
+ $this->_runtimeModel = $RuntimeModel;
+
+ if (is_string($query['fields']) && 'COUNT(*) AS ' . $db->name('count') == $query['fields']) {
+ $query['fields'] = 'COUNT(DISTINCT(' . $db->name($model->alias . '.' . $model->primaryKey) . ')) ' . $db->alias . 'count';
+ $query['joins'][] = array(
+ 'type' => 'INNER',
+ 'alias' => $RuntimeModel->alias,
+ 'table' => $joinTable,
+ 'conditions' => array(
+ $model->alias . '.' . $model->primaryKey => $db->identifier($RuntimeModel->alias . '.foreign_key'),
+ $RuntimeModel->alias . '.model' => $model->name,
+ $RuntimeModel->alias . '.locale' => $locale
+ )
+ );
+ $conditionFields = $this->_checkConditions($model, $query);
+ foreach ($conditionFields as $field) {
+ $query = $this->_addJoin($model, $query, $field, $field, $locale);
+ }
+ unset($this->_joinTable, $this->_runtimeModel);
+ return $query;
+ }
+
+ $fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']);
+ $addFields = array();
+ if (empty($query['fields'])) {
+ $addFields = $fields;
+ } elseif (is_array($query['fields'])) {
+ foreach ($fields as $key => $value) {
+ $field = (is_numeric($key)) ? $value : $key;
+
+ if (in_array($model->alias . '.*', $query['fields']) || in_array($model->alias . '.' . $field, $query['fields']) || in_array($field, $query['fields'])) {
+ $addFields[] = $field;
+ }
+ }
+ }
+
+ $this->runtime[$model->alias]['virtualFields'] = $model->virtualFields;
+ if ($addFields) {
+ foreach ($addFields as $_f => $field) {
+ $aliasField = is_numeric($_f) ? $field : $_f;
+
+ foreach (array($aliasField, $model->alias . '.' . $aliasField) as $_field) {
+ $key = array_search($_field, (array)$query['fields']);
+
+ if ($key !== false) {
+ unset($query['fields'][$key]);
+ }
+ }
+ $query = $this->_addJoin($model, $query, $field, $aliasField, $locale);
+ }
+ }
+ $this->runtime[$model->alias]['beforeFind'] = $addFields;
+ unset($this->_joinTable, $this->_runtimeModel);
+ return $query;
+ }
+
+/**
+ * Check a query's conditions for translated fields.
+ * Return an array of translated fields found in the conditions.
+ *
+ * @param Model $model The model being read.
+ * @param array $query The query array.
+ * @return array The list of translated fields that are in the conditions.
+ */
+ protected function _checkConditions(Model $model, $query) {
+ $conditionFields = array();
+ if (empty($query['conditions']) || (!empty($query['conditions']) && !is_array($query['conditions'])) ) {
+ return $conditionFields;
+ }
+ foreach ($query['conditions'] as $col => $val) {
+ foreach ($this->settings[$model->alias] as $field => $assoc) {
+ if (is_numeric($field)) {
+ $field = $assoc;
+ }
+ if (strpos($col, $field) !== false) {
+ $conditionFields[] = $field;
+ }
+ }
+ }
+ return $conditionFields;
+ }
+
+/**
+ * Appends a join for translated fields and possibly a field.
+ *
+ * @param Model $model The model being worked on.
+ * @param object $joinTable The jointable object.
+ * @param array $query The query array to append a join to.
+ * @param string $field The field name being joined.
+ * @param string $aliasField The aliased field name being joined.
+ * @param string|array $locale The locale(s) having joins added.
+ * @param boolean $addField Whether or not to add a field.
+ * @return array The modfied query
+ */
+ protected function _addJoin(Model $model, $query, $field, $aliasField, $locale, $addField = false) {
+ $db = ConnectionManager::getDataSource($model->useDbConfig);
+
+ $RuntimeModel = $this->_runtimeModel;
+ $joinTable = $this->_joinTable;
+
+ if (is_array($locale)) {
+ foreach ($locale as $_locale) {
+ $model->virtualFields['i18n_' . $field . '_' . $_locale] = 'I18n__' . $field . '__' . $_locale . '.content';
+ if (!empty($query['fields']) && is_array($query['fields'])) {
+ $query['fields'][] = 'i18n_' . $field . '_' . $_locale;
+ }
+ $query['joins'][] = array(
+ 'type' => 'LEFT',
+ 'alias' => 'I18n__' . $field . '__' . $_locale,
+ 'table' => $joinTable,
+ 'conditions' => array(
+ $model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}__{$_locale}.foreign_key"),
+ 'I18n__' . $field . '__' . $_locale . '.model' => $model->name,
+ 'I18n__' . $field . '__' . $_locale . '.' . $RuntimeModel->displayField => $aliasField,
+ 'I18n__' . $field . '__' . $_locale . '.locale' => $_locale
+ )
+ );
+ }
+ } else {
+ $model->virtualFields['i18n_' . $field] = 'I18n__' . $field . '.content';
+ if (!empty($query['fields']) && is_array($query['fields'])) {
+ $query['fields'][] = 'i18n_' . $field;
+ }
+ $query['joins'][] = array(
+ 'type' => 'INNER',
+ 'alias' => 'I18n__' . $field,
+ 'table' => $joinTable,
+ 'conditions' => array(
+ $model->alias . '.' . $model->primaryKey => $db->identifier("I18n__{$field}.foreign_key"),
+ 'I18n__' . $field . '.model' => $model->name,
+ 'I18n__' . $field . '.' . $RuntimeModel->displayField => $aliasField,
+ 'I18n__' . $field . '.locale' => $locale
+ )
+ );
+ }
+ return $query;
+ }
+
+/**
+ * afterFind Callback
+ *
+ * @param Model $model Model find was run on
+ * @param array $results Array of model results.
+ * @param boolean $primary Did the find originate on $model.
+ * @return array Modified results
+ */
+ public function afterFind(Model $model, $results, $primary) {
+ $model->virtualFields = $this->runtime[$model->alias]['virtualFields'];
+ $this->runtime[$model->alias]['virtualFields'] = $this->runtime[$model->alias]['fields'] = array();
+ $locale = $this->_getLocale($model);
+
+ if (empty($locale) || empty($results) || empty($this->runtime[$model->alias]['beforeFind'])) {
+ return $results;
+ }
+ $beforeFind = $this->runtime[$model->alias]['beforeFind'];
+
+ foreach ($results as $key => &$row) {
+ $results[$key][$model->alias]['locale'] = (is_array($locale)) ? current($locale) : $locale;
+ foreach ($beforeFind as $_f => $field) {
+ $aliasField = is_numeric($_f) ? $field : $_f;
+
+ if (is_array($locale)) {
+ foreach ($locale as $_locale) {
+ if (!isset($row[$model->alias][$aliasField]) && !empty($row[$model->alias]['i18n_' . $field . '_' . $_locale])) {
+ $row[$model->alias][$aliasField] = $row[$model->alias]['i18n_' . $field . '_' . $_locale];
+ $row[$model->alias]['locale'] = $_locale;
+ }
+ unset($row[$model->alias]['i18n_' . $field . '_' . $_locale]);
+ }
+
+ if (!isset($row[$model->alias][$aliasField])) {
+ $row[$model->alias][$aliasField] = '';
+ }
+ } else {
+ $value = '';
+ if (!empty($row[$model->alias]['i18n_' . $field])) {
+ $value = $row[$model->alias]['i18n_' . $field];
+ }
+ $row[$model->alias][$aliasField] = $value;
+ unset($row[$model->alias]['i18n_' . $field]);
+ }
+ }
+ }
+ return $results;
+ }
+
+/**
+ * beforeValidate Callback
+ *
+ * @param Model $model Model invalidFields was called on.
+ * @return boolean
+ */
+ public function beforeValidate(Model $model) {
+ unset($this->runtime[$model->alias]['beforeSave']);
+ $this->_setRuntimeData($model);
+ return true;
+ }
+
+/**
+ * beforeSave callback.
+ *
+ * Copies data into the runtime property when `$options['validate']` is
+ * disabled. Or the runtime data hasn't been set yet.
+ *
+ * @param Model $model Model save was called on.
+ * @return boolean true.
+ */
+ public function beforeSave(Model $model, $options = array()) {
+ if (isset($options['validate']) && $options['validate'] == false) {
+ unset($this->runtime[$model->alias]['beforeSave']);
+ }
+ if (isset($this->runtime[$model->alias]['beforeSave'])) {
+ return true;
+ }
+ $this->_setRuntimeData($model);
+ return true;
+ }
+
+/**
+ * Sets the runtime data.
+ *
+ * Used from beforeValidate() and beforeSave() for compatibility issues,
+ * and to allow translations to be persisted even when validation
+ * is disabled.
+ *
+ * @param Model $model
+ * @return void
+ */
+ protected function _setRuntimeData(Model $model) {
+ $locale = $this->_getLocale($model);
+ if (empty($locale)) {
+ return true;
+ }
+ $fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']);
+ $tempData = array();
+
+ foreach ($fields as $key => $value) {
+ $field = (is_numeric($key)) ? $value : $key;
+
+ if (isset($model->data[$model->alias][$field])) {
+ $tempData[$field] = $model->data[$model->alias][$field];
+ if (is_array($model->data[$model->alias][$field])) {
+ if (is_string($locale) && !empty($model->data[$model->alias][$field][$locale])) {
+ $model->data[$model->alias][$field] = $model->data[$model->alias][$field][$locale];
+ } else {
+ $values = array_values($model->data[$model->alias][$field]);
+ $model->data[$model->alias][$field] = $values[0];
+ }
+ }
+ }
+ }
+ $this->runtime[$model->alias]['beforeSave'] = $tempData;
+ }
+
+/**
+ * afterSave Callback
+ *
+ * @param Model $model Model the callback is called on
+ * @param boolean $created Whether or not the save created a record.
+ * @return void
+ */
+ public function afterSave(Model $model, $created) {
+ if (!isset($this->runtime[$model->alias]['beforeValidate']) && !isset($this->runtime[$model->alias]['beforeSave'])) {
+ return true;
+ }
+ $locale = $this->_getLocale($model);
+ if (isset($this->runtime[$model->alias]['beforeValidate'])) {
+ $tempData = $this->runtime[$model->alias]['beforeValidate'];
+ } else {
+ $tempData = $this->runtime[$model->alias]['beforeSave'];
+ }
+
+ unset($this->runtime[$model->alias]['beforeValidate'], $this->runtime[$model->alias]['beforeSave']);
+ $conditions = array('model' => $model->alias, 'foreign_key' => $model->id);
+ $RuntimeModel = $this->translateModel($model);
+
+ $fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']);
+ if ($created) {
+ foreach ($fields as $field) {
+ if (!isset($tempData[$field])) {
+ //set the field value to an empty string
+ $tempData[$field] = '';
+ }
+ }
+ }
+
+ foreach ($tempData as $field => $value) {
+ unset($conditions['content']);
+ $conditions['field'] = $field;
+ if (is_array($value)) {
+ $conditions['locale'] = array_keys($value);
+ } else {
+ $conditions['locale'] = $locale;
+ if (is_array($locale)) {
+ $value = array($locale[0] => $value);
+ } else {
+ $value = array($locale => $value);
+ }
+ }
+ $translations = $RuntimeModel->find('list', array('conditions' => $conditions, 'fields' => array($RuntimeModel->alias . '.locale', $RuntimeModel->alias . '.id')));
+ foreach ($value as $_locale => $_value) {
+ $RuntimeModel->create();
+ $conditions['locale'] = $_locale;
+ $conditions['content'] = $_value;
+ if (array_key_exists($_locale, $translations)) {
+ $RuntimeModel->save(array($RuntimeModel->alias => array_merge($conditions, array('id' => $translations[$_locale]))));
+ } else {
+ $RuntimeModel->save(array($RuntimeModel->alias => $conditions));
+ }
+ }
+ }
+ }
+
+/**
+ * afterDelete Callback
+ *
+ * @param Model $model Model the callback was run on.
+ * @return void
+ */
+ public function afterDelete(Model $model) {
+ $RuntimeModel = $this->translateModel($model);
+ $conditions = array('model' => $model->alias, 'foreign_key' => $model->id);
+ $RuntimeModel->deleteAll($conditions);
+ }
+
+/**
+ * Get selected locale for model
+ *
+ * @param Model $model Model the locale needs to be set/get on.
+ * @return mixed string or false
+ */
+ protected function _getLocale(Model $model) {
+ if (!isset($model->locale) || is_null($model->locale)) {
+ $I18n = I18n::getInstance();
+ $I18n->l10n->get(Configure::read('Config.language'));
+ $model->locale = $I18n->l10n->locale;
+ }
+
+ return $model->locale;
+ }
+
+/**
+ * Get instance of model for translations.
+ *
+ * If the model has a translateModel property set, this will be used as the class
+ * name to find/use. If no translateModel property is found 'I18nModel' will be used.
+ *
+ * @param Model $model Model to get a translatemodel for.
+ * @return Model
+ */
+ public function translateModel(Model $model) {
+ if (!isset($this->runtime[$model->alias]['model'])) {
+ if (!isset($model->translateModel) || empty($model->translateModel)) {
+ $className = 'I18nModel';
+ } else {
+ $className = $model->translateModel;
+ }
+
+ $this->runtime[$model->alias]['model'] = ClassRegistry::init($className, 'Model');
+ }
+ if (!empty($model->translateTable) && $model->translateTable !== $this->runtime[$model->alias]['model']->useTable) {
+ $this->runtime[$model->alias]['model']->setSource($model->translateTable);
+ } elseif (empty($model->translateTable) && empty($model->translateModel)) {
+ $this->runtime[$model->alias]['model']->setSource('i18n');
+ }
+ return $this->runtime[$model->alias]['model'];
+ }
+
+/**
+ * Bind translation for fields, optionally with hasMany association for
+ * fake field.
+ *
+ * *Note* You should avoid binding translations that overlap existing model properties.
+ * This can cause un-expected and un-desirable behavior.
+ *
+ * @param Model $model instance of model
+ * @param string|array $fields string with field or array(field1, field2=>AssocName, field3)
+ * @param boolean $reset Leave true to have the fields only modified for the next operation.
+ * if false the field will be added for all future queries.
+ * @return boolean
+ * @throws CakeException when attempting to bind a translating called name. This is not allowed
+ * as it shadows Model::$name.
+ */
+ public function bindTranslation(Model $model, $fields, $reset = true) {
+ if (is_string($fields)) {
+ $fields = array($fields);
+ }
+ $associations = array();
+ $RuntimeModel = $this->translateModel($model);
+ $default = array('className' => $RuntimeModel->alias, 'foreignKey' => 'foreign_key');
+
+ foreach ($fields as $key => $value) {
+ if (is_numeric($key)) {
+ $field = $value;
+ $association = null;
+ } else {
+ $field = $key;
+ $association = $value;
+ }
+ if ($association === 'name') {
+ throw new CakeException(
+ __d('cake_dev', 'You cannot bind a translation named "name".')
+ );
+ }
+
+ $this->_removeField($model, $field);
+
+ if (is_null($association)) {
+ if ($reset) {
+ $this->runtime[$model->alias]['fields'][] = $field;
+ } else {
+ $this->settings[$model->alias][] = $field;
+ }
+ } else {
+ if ($reset) {
+ $this->runtime[$model->alias]['fields'][$field] = $association;
+ } else {
+ $this->settings[$model->alias][$field] = $association;
+ }
+
+ foreach (array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany') as $type) {
+ if (isset($model->{$type}[$association]) || isset($model->__backAssociation[$type][$association])) {
+ trigger_error(
+ __d('cake_dev', 'Association %s is already bound to model %s', $association, $model->alias),
+ E_USER_ERROR
+ );
+ return false;
+ }
+ }
+ $associations[$association] = array_merge($default, array('conditions' => array(
+ 'model' => $model->alias,
+ $RuntimeModel->displayField => $field
+ )));
+ }
+ }
+
+ if (!empty($associations)) {
+ $model->bindModel(array('hasMany' => $associations), $reset);
+ }
+ return true;
+ }
+
+/**
+ * Update runtime setting for a given field.
+ *
+ * @param string $field The field to update.
+ */
+ protected function _removeField(Model $model, $field) {
+ if (array_key_exists($field, $this->settings[$model->alias])) {
+ unset($this->settings[$model->alias][$field]);
+ } elseif (in_array($field, $this->settings[$model->alias])) {
+ $this->settings[$model->alias] = array_merge(array_diff($this->settings[$model->alias], array($field)));
+ }
+
+ if (array_key_exists($field, $this->runtime[$model->alias]['fields'])) {
+ unset($this->runtime[$model->alias]['fields'][$field]);
+ } elseif (in_array($field, $this->runtime[$model->alias]['fields'])) {
+ $this->runtime[$model->alias]['fields'] = array_merge(array_diff($this->runtime[$model->alias]['fields'], array($field)));
+ }
+ }
+
+/**
+ * Unbind translation for fields, optionally unbinds hasMany association for
+ * fake field
+ *
+ * @param Model $model instance of model
+ * @param string|array $fields string with field, or array(field1, field2=>AssocName, field3), or null for
+ * unbind all original translations
+ * @return boolean
+ */
+ public function unbindTranslation(Model $model, $fields = null) {
+ if (empty($fields) && empty($this->settings[$model->alias])) {
+ return false;
+ }
+ if (empty($fields)) {
+ return $this->unbindTranslation($model, $this->settings[$model->alias]);
+ }
+
+ if (is_string($fields)) {
+ $fields = array($fields);
+ }
+ $RuntimeModel = $this->translateModel($model);
+ $associations = array();
+
+ foreach ($fields as $key => $value) {
+ if (is_numeric($key)) {
+ $field = $value;
+ $association = null;
+ } else {
+ $field = $key;
+ $association = $value;
+ }
+
+ $this->_removeField($model, $field);
+
+ if (!is_null($association) && (isset($model->hasMany[$association]) || isset($model->__backAssociation['hasMany'][$association]))) {
+ $associations[] = $association;
+ }
+ }
+
+ if (!empty($associations)) {
+ $model->unbindModel(array('hasMany' => $associations), false);
+ }
+ return true;
+ }
+
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TreeBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TreeBehavior.php
new file mode 100644
index 0000000..a92c367
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Behavior/TreeBehavior.php
@@ -0,0 +1,1007 @@
+<?php
+/**
+ * Tree behavior class.
+ *
+ * Enables a model object to act as a node-based tree.
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Model.Behavior
+ * @since CakePHP v 1.2.0.4487
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Tree Behavior.
+ *
+ * Enables a model object to act as a node-based tree. Using Modified Preorder Tree Traversal
+ *
+ * @see http://en.wikipedia.org/wiki/Tree_traversal
+ * @package Cake.Model.Behavior
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html
+ */
+class TreeBehavior extends ModelBehavior {
+
+/**
+ * Errors
+ *
+ * @var array
+ */
+ public $errors = array();
+
+/**
+ * Defaults
+ *
+ * @var array
+ */
+ protected $_defaults = array(
+ 'parent' => 'parent_id', 'left' => 'lft', 'right' => 'rght',
+ 'scope' => '1 = 1', 'type' => 'nested', '__parentChange' => false, 'recursive' => -1
+ );
+
+/**
+ * Used to preserve state between delete callbacks.
+ *
+ * @var array
+ */
+ protected $_deletedRow = null;
+
+/**
+ * Initiate Tree behavior
+ *
+ * @param Model $Model instance of model
+ * @param array $config array of configuration settings.
+ * @return void
+ */
+ public function setup(Model $Model, $config = array()) {
+ if (isset($config[0])) {
+ $config['type'] = $config[0];
+ unset($config[0]);
+ }
+ $settings = array_merge($this->_defaults, $config);
+
+ if (in_array($settings['scope'], $Model->getAssociated('belongsTo'))) {
+ $data = $Model->getAssociated($settings['scope']);
+ $parent = $Model->{$settings['scope']};
+ $settings['scope'] = $Model->alias . '.' . $data['foreignKey'] . ' = ' . $parent->alias . '.' . $parent->primaryKey;
+ $settings['recursive'] = 0;
+ }
+ $this->settings[$Model->alias] = $settings;
+ }
+
+/**
+ * After save method. Called after all saves
+ *
+ * Overridden to transparently manage setting the lft and rght fields if and only if the parent field is included in the
+ * parameters to be saved.
+ *
+ * @param Model $Model Model instance.
+ * @param boolean $created indicates whether the node just saved was created or updated
+ * @return boolean true on success, false on failure
+ */
+ public function afterSave(Model $Model, $created) {
+ extract($this->settings[$Model->alias]);
+ if ($created) {
+ if ((isset($Model->data[$Model->alias][$parent])) && $Model->data[$Model->alias][$parent]) {
+ return $this->_setParent($Model, $Model->data[$Model->alias][$parent], $created);
+ }
+ } elseif ($this->settings[$Model->alias]['__parentChange']) {
+ $this->settings[$Model->alias]['__parentChange'] = false;
+ return $this->_setParent($Model, $Model->data[$Model->alias][$parent]);
+ }
+ }
+
+/**
+ * Runs before a find() operation
+ *
+ * @param Model $Model Model using the behavior
+ * @param array $query Query parameters as set by cake
+ * @return array
+ */
+ public function beforeFind(Model $Model, $query) {
+ if ($Model->findQueryType == 'threaded' && !isset($query['parent'])) {
+ $query['parent'] = $this->settings[$Model->alias]['parent'];
+ }
+ return $query;
+ }
+
+/**
+ * Stores the record about to be deleted.
+ *
+ * This is used to delete child nodes in the afterDelete.
+ *
+ * @param Model $Model Model instance
+ * @param boolean $cascade
+ * @return boolean
+ */
+ public function beforeDelete(Model $Model, $cascade = true) {
+ extract($this->settings[$Model->alias]);
+ $data = $Model->find('first', array(
+ 'conditions' => array($Model->alias . '.' . $Model->primaryKey => $Model->id),
+ 'fields' => array($Model->alias . '.' . $left, $Model->alias . '.' . $right),
+ 'recursive' => -1));
+ if ($data) {
+ $this->_deletedRow = current($data);
+ }
+ return true;
+ }
+
+/**
+ * After delete method.
+ *
+ * Will delete the current node and all children using the deleteAll method and sync the table
+ *
+ * @param Model $Model Model instance
+ * @return boolean true to continue, false to abort the delete
+ */
+ public function afterDelete(Model $Model) {
+ extract($this->settings[$Model->alias]);
+ $data = $this->_deletedRow;
+ $this->_deletedRow = null;
+
+ if (!$data[$right] || !$data[$left]) {
+ return true;
+ }
+ $diff = $data[$right] - $data[$left] + 1;
+
+ if ($diff > 2) {
+ if (is_string($scope)) {
+ $scope = array($scope);
+ }
+ $scope[]["{$Model->alias}.{$left} BETWEEN ? AND ?"] = array($data[$left] + 1, $data[$right] - 1);
+ $Model->deleteAll($scope);
+ }
+ $this->_sync($Model, $diff, '-', '> ' . $data[$right]);
+ return true;
+ }
+
+/**
+ * Before save method. Called before all saves
+ *
+ * Overridden to transparently manage setting the lft and rght fields if and only if the parent field is included in the
+ * parameters to be saved. For newly created nodes with NO parent the left and right field values are set directly by
+ * this method bypassing the setParent logic.
+ *
+ * @since 1.2
+ * @param Model $Model Model instance
+ * @return boolean true to continue, false to abort the save
+ */
+ public function beforeSave(Model $Model) {
+ extract($this->settings[$Model->alias]);
+
+ $this->_addToWhitelist($Model, array($left, $right));
+ if (!$Model->id) {
+ if (array_key_exists($parent, $Model->data[$Model->alias]) && $Model->data[$Model->alias][$parent]) {
+ $parentNode = $Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $Model->data[$Model->alias][$parent]),
+ 'fields' => array($Model->primaryKey, $right), 'recursive' => $recursive
+ ));
+ if (!$parentNode) {
+ return false;
+ }
+ list($parentNode) = array_values($parentNode);
+ $Model->data[$Model->alias][$left] = 0;
+ $Model->data[$Model->alias][$right] = 0;
+ } else {
+ $edge = $this->_getMax($Model, $scope, $right, $recursive);
+ $Model->data[$Model->alias][$left] = $edge + 1;
+ $Model->data[$Model->alias][$right] = $edge + 2;
+ }
+ } elseif (array_key_exists($parent, $Model->data[$Model->alias])) {
+ if ($Model->data[$Model->alias][$parent] != $Model->field($parent)) {
+ $this->settings[$Model->alias]['__parentChange'] = true;
+ }
+ if (!$Model->data[$Model->alias][$parent]) {
+ $Model->data[$Model->alias][$parent] = null;
+ $this->_addToWhitelist($Model, $parent);
+ } else {
+ $values = $Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $Model->id),
+ 'fields' => array($Model->primaryKey, $parent, $left, $right), 'recursive' => $recursive)
+ );
+
+ if ($values === false) {
+ return false;
+ }
+ list($node) = array_values($values);
+
+ $parentNode = $Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $Model->data[$Model->alias][$parent]),
+ 'fields' => array($Model->primaryKey, $left, $right), 'recursive' => $recursive
+ ));
+ if (!$parentNode) {
+ return false;
+ }
+ list($parentNode) = array_values($parentNode);
+
+ if (($node[$left] < $parentNode[$left]) && ($parentNode[$right] < $node[$right])) {
+ return false;
+ } elseif ($node[$Model->primaryKey] == $parentNode[$Model->primaryKey]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Get the number of child nodes
+ *
+ * If the direct parameter is set to true, only the direct children are counted (based upon the parent_id field)
+ * If false is passed for the id parameter, all top level nodes are counted, or all nodes are counted.
+ *
+ * @param Model $Model Model instance
+ * @param integer|string|boolean $id The ID of the record to read or false to read all top level nodes
+ * @param boolean $direct whether to count direct, or all, children
+ * @return integer number of child nodes
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::childCount
+ */
+ public function childCount(Model $Model, $id = null, $direct = false) {
+ if (is_array($id)) {
+ extract(array_merge(array('id' => null), $id));
+ }
+ if ($id === null && $Model->id) {
+ $id = $Model->id;
+ } elseif (!$id) {
+ $id = null;
+ }
+ extract($this->settings[$Model->alias]);
+
+ if ($direct) {
+ return $Model->find('count', array('conditions' => array($scope, $Model->escapeField($parent) => $id)));
+ }
+
+ if ($id === null) {
+ return $Model->find('count', array('conditions' => $scope));
+ } elseif ($Model->id === $id && isset($Model->data[$Model->alias][$left]) && isset($Model->data[$Model->alias][$right])) {
+ $data = $Model->data[$Model->alias];
+ } else {
+ $data = $Model->find('first', array('conditions' => array($scope, $Model->escapeField() => $id), 'recursive' => $recursive));
+ if (!$data) {
+ return 0;
+ }
+ $data = $data[$Model->alias];
+ }
+ return ($data[$right] - $data[$left] - 1) / 2;
+ }
+
+/**
+ * Get the child nodes of the current model
+ *
+ * If the direct parameter is set to true, only the direct children are returned (based upon the parent_id field)
+ * If false is passed for the id parameter, top level, or all (depending on direct parameter appropriate) are counted.
+ *
+ * @param Model $Model Model instance
+ * @param integer|string $id The ID of the record to read
+ * @param boolean $direct whether to return only the direct, or all, children
+ * @param string|array $fields Either a single string of a field name, or an array of field names
+ * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC") defaults to the tree order
+ * @param integer $limit SQL LIMIT clause, for calculating items per page.
+ * @param integer $page Page number, for accessing paged data
+ * @param integer $recursive The number of levels deep to fetch associated records
+ * @return array Array of child nodes
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::children
+ */
+ public function children(Model $Model, $id = null, $direct = false, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
+ if (is_array($id)) {
+ extract(array_merge(array('id' => null), $id));
+ }
+ $overrideRecursive = $recursive;
+
+ if ($id === null && $Model->id) {
+ $id = $Model->id;
+ } elseif (!$id) {
+ $id = null;
+ }
+
+ extract($this->settings[$Model->alias]);
+
+ if (!is_null($overrideRecursive)) {
+ $recursive = $overrideRecursive;
+ }
+ if (!$order) {
+ $order = $Model->alias . '.' . $left . ' asc';
+ }
+ if ($direct) {
+ $conditions = array($scope, $Model->escapeField($parent) => $id);
+ return $Model->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'));
+ }
+
+ if (!$id) {
+ $conditions = $scope;
+ } else {
+ $result = array_values((array)$Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $id),
+ 'fields' => array($left, $right),
+ 'recursive' => $recursive
+ )));
+
+ if (empty($result) || !isset($result[0])) {
+ return array();
+ }
+ $conditions = array($scope,
+ $Model->escapeField($right) . ' <' => $result[0][$right],
+ $Model->escapeField($left) . ' >' => $result[0][$left]
+ );
+ }
+ return $Model->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'));
+ }
+
+/**
+ * A convenience method for returning a hierarchical array used for HTML select boxes
+ *
+ * @param Model $Model Model instance
+ * @param string|array $conditions SQL conditions as a string or as an array('field' =>'value',...)
+ * @param string $keyPath A string path to the key, i.e. "{n}.Post.id"
+ * @param string $valuePath A string path to the value, i.e. "{n}.Post.title"
+ * @param string $spacer The character or characters which will be repeated
+ * @param integer $recursive The number of levels deep to fetch associated records
+ * @return array An associative array of records, where the id is the key, and the display field is the value
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::generateTreeList
+ */
+ public function generateTreeList(Model $Model, $conditions = null, $keyPath = null, $valuePath = null, $spacer = '_', $recursive = null) {
+ $overrideRecursive = $recursive;
+ extract($this->settings[$Model->alias]);
+ if (!is_null($overrideRecursive)) {
+ $recursive = $overrideRecursive;
+ }
+
+ if ($keyPath == null && $valuePath == null && $Model->hasField($Model->displayField)) {
+ $fields = array($Model->primaryKey, $Model->displayField, $left, $right);
+ } else {
+ $fields = null;
+ }
+
+ if ($keyPath == null) {
+ $keyPath = '{n}.' . $Model->alias . '.' . $Model->primaryKey;
+ }
+
+ if ($valuePath == null) {
+ $valuePath = array('%s%s', '{n}.tree_prefix', '{n}.' . $Model->alias . '.' . $Model->displayField);
+
+ } elseif (is_string($valuePath)) {
+ $valuePath = array('%s%s', '{n}.tree_prefix', $valuePath);
+
+ } else {
+ $valuePath[0] = '{' . (count($valuePath) - 1) . '}' . $valuePath[0];
+ $valuePath[] = '{n}.tree_prefix';
+ }
+ $order = $Model->alias . '.' . $left . ' asc';
+ $results = $Model->find('all', compact('conditions', 'fields', 'order', 'recursive'));
+ $stack = array();
+
+ foreach ($results as $i => $result) {
+ $count = count($stack);
+ while ($stack && ($stack[$count - 1] < $result[$Model->alias][$right])) {
+ array_pop($stack);
+ $count--;
+ }
+ $results[$i]['tree_prefix'] = str_repeat($spacer, $count);
+ $stack[] = $result[$Model->alias][$right];
+ }
+ if (empty($results)) {
+ return array();
+ }
+ return Hash::combine($results, $keyPath, $valuePath);
+ }
+
+/**
+ * Get the parent node
+ *
+ * reads the parent id and returns this node
+ *
+ * @param Model $Model Model instance
+ * @param integer|string $id The ID of the record to read
+ * @param string|array $fields
+ * @param integer $recursive The number of levels deep to fetch associated records
+ * @return array|boolean Array of data for the parent node
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::getParentNode
+ */
+ public function getParentNode(Model $Model, $id = null, $fields = null, $recursive = null) {
+ if (is_array($id)) {
+ extract(array_merge(array('id' => null), $id));
+ }
+ $overrideRecursive = $recursive;
+ if (empty ($id)) {
+ $id = $Model->id;
+ }
+ extract($this->settings[$Model->alias]);
+ if (!is_null($overrideRecursive)) {
+ $recursive = $overrideRecursive;
+ }
+ $parentId = $Model->find('first', array('conditions' => array($Model->primaryKey => $id), 'fields' => array($parent), 'recursive' => -1));
+
+ if ($parentId) {
+ $parentId = $parentId[$Model->alias][$parent];
+ $parent = $Model->find('first', array('conditions' => array($Model->escapeField() => $parentId), 'fields' => $fields, 'recursive' => $recursive));
+
+ return $parent;
+ }
+ return false;
+ }
+
+/**
+ * Get the path to the given node
+ *
+ * @param Model $Model Model instance
+ * @param integer|string $id The ID of the record to read
+ * @param string|array $fields Either a single string of a field name, or an array of field names
+ * @param integer $recursive The number of levels deep to fetch associated records
+ * @return array Array of nodes from top most parent to current node
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::getPath
+ */
+ public function getPath(Model $Model, $id = null, $fields = null, $recursive = null) {
+ if (is_array($id)) {
+ extract(array_merge(array('id' => null), $id));
+ }
+ $overrideRecursive = $recursive;
+ if (empty ($id)) {
+ $id = $Model->id;
+ }
+ extract($this->settings[$Model->alias]);
+ if (!is_null($overrideRecursive)) {
+ $recursive = $overrideRecursive;
+ }
+ $result = $Model->find('first', array('conditions' => array($Model->escapeField() => $id), 'fields' => array($left, $right), 'recursive' => $recursive));
+ if ($result) {
+ $result = array_values($result);
+ } else {
+ return null;
+ }
+ $item = $result[0];
+ $results = $Model->find('all', array(
+ 'conditions' => array($scope, $Model->escapeField($left) . ' <=' => $item[$left], $Model->escapeField($right) . ' >=' => $item[$right]),
+ 'fields' => $fields, 'order' => array($Model->escapeField($left) => 'asc'), 'recursive' => $recursive
+ ));
+ return $results;
+ }
+
+/**
+ * Reorder the node without changing the parent.
+ *
+ * If the node is the last child, or is a top level node with no subsequent node this method will return false
+ *
+ * @param Model $Model Model instance
+ * @param integer|string $id The ID of the record to move
+ * @param integer|boolean $number how many places to move the node or true to move to last position
+ * @return boolean true on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::moveDown
+ */
+ public function moveDown(Model $Model, $id = null, $number = 1) {
+ if (is_array($id)) {
+ extract(array_merge(array('id' => null), $id));
+ }
+ if (!$number) {
+ return false;
+ }
+ if (empty ($id)) {
+ $id = $Model->id;
+ }
+ extract($this->settings[$Model->alias]);
+ list($node) = array_values($Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $id),
+ 'fields' => array($Model->primaryKey, $left, $right, $parent), 'recursive' => $recursive
+ )));
+ if ($node[$parent]) {
+ list($parentNode) = array_values($Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $node[$parent]),
+ 'fields' => array($Model->primaryKey, $left, $right), 'recursive' => $recursive
+ )));
+ if (($node[$right] + 1) == $parentNode[$right]) {
+ return false;
+ }
+ }
+ $nextNode = $Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField($left) => ($node[$right] + 1)),
+ 'fields' => array($Model->primaryKey, $left, $right), 'recursive' => $recursive)
+ );
+ if ($nextNode) {
+ list($nextNode) = array_values($nextNode);
+ } else {
+ return false;
+ }
+ $edge = $this->_getMax($Model, $scope, $right, $recursive);
+ $this->_sync($Model, $edge - $node[$left] + 1, '+', 'BETWEEN ' . $node[$left] . ' AND ' . $node[$right]);
+ $this->_sync($Model, $nextNode[$left] - $node[$left], '-', 'BETWEEN ' . $nextNode[$left] . ' AND ' . $nextNode[$right]);
+ $this->_sync($Model, $edge - $node[$left] - ($nextNode[$right] - $nextNode[$left]), '-', '> ' . $edge);
+
+ if (is_int($number)) {
+ $number--;
+ }
+ if ($number) {
+ $this->moveDown($Model, $id, $number);
+ }
+ return true;
+ }
+
+/**
+ * Reorder the node without changing the parent.
+ *
+ * If the node is the first child, or is a top level node with no previous node this method will return false
+ *
+ * @param Model $Model Model instance
+ * @param integer|string $id The ID of the record to move
+ * @param integer|boolean $number how many places to move the node, or true to move to first position
+ * @return boolean true on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::moveUp
+ */
+ public function moveUp(Model $Model, $id = null, $number = 1) {
+ if (is_array($id)) {
+ extract(array_merge(array('id' => null), $id));
+ }
+ if (!$number) {
+ return false;
+ }
+ if (empty ($id)) {
+ $id = $Model->id;
+ }
+ extract($this->settings[$Model->alias]);
+ list($node) = array_values($Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $id),
+ 'fields' => array($Model->primaryKey, $left, $right, $parent), 'recursive' => $recursive
+ )));
+ if ($node[$parent]) {
+ list($parentNode) = array_values($Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $node[$parent]),
+ 'fields' => array($Model->primaryKey, $left, $right), 'recursive' => $recursive
+ )));
+ if (($node[$left] - 1) == $parentNode[$left]) {
+ return false;
+ }
+ }
+ $previousNode = $Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField($right) => ($node[$left] - 1)),
+ 'fields' => array($Model->primaryKey, $left, $right),
+ 'recursive' => $recursive
+ ));
+
+ if ($previousNode) {
+ list($previousNode) = array_values($previousNode);
+ } else {
+ return false;
+ }
+ $edge = $this->_getMax($Model, $scope, $right, $recursive);
+ $this->_sync($Model, $edge - $previousNode[$left] + 1, '+', 'BETWEEN ' . $previousNode[$left] . ' AND ' . $previousNode[$right]);
+ $this->_sync($Model, $node[$left] - $previousNode[$left], '-', 'BETWEEN ' . $node[$left] . ' AND ' . $node[$right]);
+ $this->_sync($Model, $edge - $previousNode[$left] - ($node[$right] - $node[$left]), '-', '> ' . $edge);
+ if (is_int($number)) {
+ $number--;
+ }
+ if ($number) {
+ $this->moveUp($Model, $id, $number);
+ }
+ return true;
+ }
+
+/**
+ * Recover a corrupted tree
+ *
+ * The mode parameter is used to specify the source of info that is valid/correct. The opposite source of data
+ * will be populated based upon that source of info. E.g. if the MPTT fields are corrupt or empty, with the $mode
+ * 'parent' the values of the parent_id field will be used to populate the left and right fields. The missingParentAction
+ * parameter only applies to "parent" mode and determines what to do if the parent field contains an id that is not present.
+ *
+ * @todo Could be written to be faster, *maybe*. Ideally using a subquery and putting all the logic burden on the DB.
+ * @param Model $Model Model instance
+ * @param string $mode parent or tree
+ * @param string|integer $missingParentAction 'return' to do nothing and return, 'delete' to
+ * delete, or the id of the parent to set as the parent_id
+ * @return boolean true on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::recover
+ */
+ public function recover(Model $Model, $mode = 'parent', $missingParentAction = null) {
+ if (is_array($mode)) {
+ extract(array_merge(array('mode' => 'parent'), $mode));
+ }
+ extract($this->settings[$Model->alias]);
+ $Model->recursive = $recursive;
+ if ($mode == 'parent') {
+ $Model->bindModel(array('belongsTo' => array('VerifyParent' => array(
+ 'className' => $Model->name,
+ 'foreignKey' => $parent,
+ 'fields' => array($Model->primaryKey, $left, $right, $parent),
+ ))));
+ $missingParents = $Model->find('list', array(
+ 'recursive' => 0,
+ 'conditions' => array($scope, array(
+ 'NOT' => array($Model->escapeField($parent) => null), $Model->VerifyParent->escapeField() => null
+ ))
+ ));
+ $Model->unbindModel(array('belongsTo' => array('VerifyParent')));
+ if ($missingParents) {
+ if ($missingParentAction == 'return') {
+ foreach ($missingParents as $id => $display) {
+ $this->errors[] = 'cannot find the parent for ' . $Model->alias . ' with id ' . $id . '(' . $display . ')';
+ }
+ return false;
+ } elseif ($missingParentAction == 'delete') {
+ $Model->deleteAll(array($Model->primaryKey => array_flip($missingParents)));
+ } else {
+ $Model->updateAll(array($parent => $missingParentAction), array($Model->escapeField($Model->primaryKey) => array_flip($missingParents)));
+ }
+ }
+ $count = 1;
+ foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey), 'order' => $left)) as $array) {
+ $lft = $count++;
+ $rght = $count++;
+ $Model->create(false);
+ $Model->id = $array[$Model->alias][$Model->primaryKey];
+ $Model->save(array($left => $lft, $right => $rght), array('callbacks' => false, 'validate' => false));
+ }
+ foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) {
+ $Model->create(false);
+ $Model->id = $array[$Model->alias][$Model->primaryKey];
+ $this->_setParent($Model, $array[$Model->alias][$parent]);
+ }
+ } else {
+ $db = ConnectionManager::getDataSource($Model->useDbConfig);
+ foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) {
+ $path = $this->getPath($Model, $array[$Model->alias][$Model->primaryKey]);
+ if ($path == null || count($path) < 2) {
+ $parentId = null;
+ } else {
+ $parentId = $path[count($path) - 2][$Model->alias][$Model->primaryKey];
+ }
+ $Model->updateAll(array($parent => $db->value($parentId, $parent)), array($Model->escapeField() => $array[$Model->alias][$Model->primaryKey]));
+ }
+ }
+ return true;
+ }
+
+/**
+ * Reorder method.
+ *
+ * Reorders the nodes (and child nodes) of the tree according to the field and direction specified in the parameters.
+ * This method does not change the parent of any node.
+ *
+ * Requires a valid tree, by default it verifies the tree before beginning.
+ *
+ * Options:
+ *
+ * - 'id' id of record to use as top node for reordering
+ * - 'field' Which field to use in reordering defaults to displayField
+ * - 'order' Direction to order either DESC or ASC (defaults to ASC)
+ * - 'verify' Whether or not to verify the tree before reorder. defaults to true.
+ *
+ * @param Model $Model Model instance
+ * @param array $options array of options to use in reordering.
+ * @return boolean true on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::reorder
+ */
+ public function reorder(Model $Model, $options = array()) {
+ $options = array_merge(array('id' => null, 'field' => $Model->displayField, 'order' => 'ASC', 'verify' => true), $options);
+ extract($options);
+ if ($verify && !$this->verify($Model)) {
+ return false;
+ }
+ $verify = false;
+ extract($this->settings[$Model->alias]);
+ $fields = array($Model->primaryKey, $field, $left, $right);
+ $sort = $field . ' ' . $order;
+ $nodes = $this->children($Model, $id, true, $fields, $sort, null, null, $recursive);
+
+ $cacheQueries = $Model->cacheQueries;
+ $Model->cacheQueries = false;
+ if ($nodes) {
+ foreach ($nodes as $node) {
+ $id = $node[$Model->alias][$Model->primaryKey];
+ $this->moveDown($Model, $id, true);
+ if ($node[$Model->alias][$left] != $node[$Model->alias][$right] - 1) {
+ $this->reorder($Model, compact('id', 'field', 'order', 'verify'));
+ }
+ }
+ }
+ $Model->cacheQueries = $cacheQueries;
+ return true;
+ }
+
+/**
+ * Remove the current node from the tree, and reparent all children up one level.
+ *
+ * If the parameter delete is false, the node will become a new top level node. Otherwise the node will be deleted
+ * after the children are reparented.
+ *
+ * @param Model $Model Model instance
+ * @param integer|string $id The ID of the record to remove
+ * @param boolean $delete whether to delete the node after reparenting children (if any)
+ * @return boolean true on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::removeFromTree
+ */
+ public function removeFromTree(Model $Model, $id = null, $delete = false) {
+ if (is_array($id)) {
+ extract(array_merge(array('id' => null), $id));
+ }
+ extract($this->settings[$Model->alias]);
+
+ list($node) = array_values($Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $id),
+ 'fields' => array($Model->primaryKey, $left, $right, $parent),
+ 'recursive' => $recursive
+ )));
+
+ if ($node[$right] == $node[$left] + 1) {
+ if ($delete) {
+ return $Model->delete($id);
+ } else {
+ $Model->id = $id;
+ return $Model->saveField($parent, null);
+ }
+ } elseif ($node[$parent]) {
+ list($parentNode) = array_values($Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $node[$parent]),
+ 'fields' => array($Model->primaryKey, $left, $right),
+ 'recursive' => $recursive
+ )));
+ } else {
+ $parentNode[$right] = $node[$right] + 1;
+ }
+
+ $db = ConnectionManager::getDataSource($Model->useDbConfig);
+ $Model->updateAll(
+ array($parent => $db->value($node[$parent], $parent)),
+ array($Model->escapeField($parent) => $node[$Model->primaryKey])
+ );
+ $this->_sync($Model, 1, '-', 'BETWEEN ' . ($node[$left] + 1) . ' AND ' . ($node[$right] - 1));
+ $this->_sync($Model, 2, '-', '> ' . ($node[$right]));
+ $Model->id = $id;
+
+ if ($delete) {
+ $Model->updateAll(
+ array(
+ $Model->escapeField($left) => 0,
+ $Model->escapeField($right) => 0,
+ $Model->escapeField($parent) => null
+ ),
+ array($Model->escapeField() => $id)
+ );
+ return $Model->delete($id);
+ } else {
+ $edge = $this->_getMax($Model, $scope, $right, $recursive);
+ if ($node[$right] == $edge) {
+ $edge = $edge - 2;
+ }
+ $Model->id = $id;
+ return $Model->save(
+ array($left => $edge + 1, $right => $edge + 2, $parent => null),
+ array('callbacks' => false, 'validate' => false)
+ );
+ }
+ }
+
+/**
+ * Check if the current tree is valid.
+ *
+ * Returns true if the tree is valid otherwise an array of (type, incorrect left/right index, message)
+ *
+ * @param Model $Model Model instance
+ * @return mixed true if the tree is valid or empty, otherwise an array of (error type [index, node],
+ * [incorrect left/right index,node id], message)
+ * @link http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html#TreeBehavior::verify
+ */
+ public function verify(Model $Model) {
+ extract($this->settings[$Model->alias]);
+ if (!$Model->find('count', array('conditions' => $scope))) {
+ return true;
+ }
+ $min = $this->_getMin($Model, $scope, $left, $recursive);
+ $edge = $this->_getMax($Model, $scope, $right, $recursive);
+ $errors = array();
+
+ for ($i = $min; $i <= $edge; $i++) {
+ $count = $Model->find('count', array('conditions' => array(
+ $scope, 'OR' => array($Model->escapeField($left) => $i, $Model->escapeField($right) => $i)
+ )));
+ if ($count != 1) {
+ if ($count == 0) {
+ $errors[] = array('index', $i, 'missing');
+ } else {
+ $errors[] = array('index', $i, 'duplicate');
+ }
+ }
+ }
+ $node = $Model->find('first', array('conditions' => array($scope, $Model->escapeField($right) . '< ' . $Model->escapeField($left)), 'recursive' => 0));
+ if ($node) {
+ $errors[] = array('node', $node[$Model->alias][$Model->primaryKey], 'left greater than right.');
+ }
+
+ $Model->bindModel(array('belongsTo' => array('VerifyParent' => array(
+ 'className' => $Model->name,
+ 'foreignKey' => $parent,
+ 'fields' => array($Model->primaryKey, $left, $right, $parent)
+ ))));
+
+ foreach ($Model->find('all', array('conditions' => $scope, 'recursive' => 0)) as $instance) {
+ if (is_null($instance[$Model->alias][$left]) || is_null($instance[$Model->alias][$right])) {
+ $errors[] = array('node', $instance[$Model->alias][$Model->primaryKey],
+ 'has invalid left or right values');
+ } elseif ($instance[$Model->alias][$left] == $instance[$Model->alias][$right]) {
+ $errors[] = array('node', $instance[$Model->alias][$Model->primaryKey],
+ 'left and right values identical');
+ } elseif ($instance[$Model->alias][$parent]) {
+ if (!$instance['VerifyParent'][$Model->primaryKey]) {
+ $errors[] = array('node', $instance[$Model->alias][$Model->primaryKey],
+ 'The parent node ' . $instance[$Model->alias][$parent] . ' doesn\'t exist');
+ } elseif ($instance[$Model->alias][$left] < $instance['VerifyParent'][$left]) {
+ $errors[] = array('node', $instance[$Model->alias][$Model->primaryKey],
+ 'left less than parent (node ' . $instance['VerifyParent'][$Model->primaryKey] . ').');
+ } elseif ($instance[$Model->alias][$right] > $instance['VerifyParent'][$right]) {
+ $errors[] = array('node', $instance[$Model->alias][$Model->primaryKey],
+ 'right greater than parent (node ' . $instance['VerifyParent'][$Model->primaryKey] . ').');
+ }
+ } elseif ($Model->find('count', array('conditions' => array($scope, $Model->escapeField($left) . ' <' => $instance[$Model->alias][$left], $Model->escapeField($right) . ' >' => $instance[$Model->alias][$right]), 'recursive' => 0))) {
+ $errors[] = array('node', $instance[$Model->alias][$Model->primaryKey], 'The parent field is blank, but has a parent');
+ }
+ }
+ if ($errors) {
+ return $errors;
+ }
+ return true;
+ }
+
+/**
+ * Sets the parent of the given node
+ *
+ * The force parameter is used to override the "don't change the parent to the current parent" logic in the event
+ * of recovering a corrupted table, or creating new nodes. Otherwise it should always be false. In reality this
+ * method could be private, since calling save with parent_id set also calls setParent
+ *
+ * @param Model $Model Model instance
+ * @param integer|string $parentId
+ * @param boolean $created
+ * @return boolean true on success, false on failure
+ */
+ protected function _setParent(Model $Model, $parentId = null, $created = false) {
+ extract($this->settings[$Model->alias]);
+ list($node) = array_values($Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $Model->id),
+ 'fields' => array($Model->primaryKey, $parent, $left, $right),
+ 'recursive' => $recursive
+ )));
+ $edge = $this->_getMax($Model, $scope, $right, $recursive, $created);
+
+ if (empty ($parentId)) {
+ $this->_sync($Model, $edge - $node[$left] + 1, '+', 'BETWEEN ' . $node[$left] . ' AND ' . $node[$right], $created);
+ $this->_sync($Model, $node[$right] - $node[$left] + 1, '-', '> ' . $node[$left], $created);
+ } else {
+ $values = $Model->find('first', array(
+ 'conditions' => array($scope, $Model->escapeField() => $parentId),
+ 'fields' => array($Model->primaryKey, $left, $right),
+ 'recursive' => $recursive
+ ));
+
+ if ($values === false) {
+ return false;
+ }
+ $parentNode = array_values($values);
+
+ if (empty($parentNode) || empty($parentNode[0])) {
+ return false;
+ }
+ $parentNode = $parentNode[0];
+
+ if (($Model->id == $parentId)) {
+ return false;
+ } elseif (($node[$left] < $parentNode[$left]) && ($parentNode[$right] < $node[$right])) {
+ return false;
+ }
+ if (empty($node[$left]) && empty($node[$right])) {
+ $this->_sync($Model, 2, '+', '>= ' . $parentNode[$right], $created);
+ $result = $Model->save(
+ array($left => $parentNode[$right], $right => $parentNode[$right] + 1, $parent => $parentId),
+ array('validate' => false, 'callbacks' => false)
+ );
+ $Model->data = $result;
+ } else {
+ $this->_sync($Model, $edge - $node[$left] + 1, '+', 'BETWEEN ' . $node[$left] . ' AND ' . $node[$right], $created);
+ $diff = $node[$right] - $node[$left] + 1;
+
+ if ($node[$left] > $parentNode[$left]) {
+ if ($node[$right] < $parentNode[$right]) {
+ $this->_sync($Model, $diff, '-', 'BETWEEN ' . $node[$right] . ' AND ' . ($parentNode[$right] - 1), $created);
+ $this->_sync($Model, $edge - $parentNode[$right] + $diff + 1, '-', '> ' . $edge, $created);
+ } else {
+ $this->_sync($Model, $diff, '+', 'BETWEEN ' . $parentNode[$right] . ' AND ' . $node[$right], $created);
+ $this->_sync($Model, $edge - $parentNode[$right] + 1, '-', '> ' . $edge, $created);
+ }
+ } else {
+ $this->_sync($Model, $diff, '-', 'BETWEEN ' . $node[$right] . ' AND ' . ($parentNode[$right] - 1), $created);
+ $this->_sync($Model, $edge - $parentNode[$right] + $diff + 1, '-', '> ' . $edge, $created);
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * get the maximum index value in the table.
+ *
+ * @param Model $Model
+ * @param string $scope
+ * @param string $right
+ * @param integer $recursive
+ * @param boolean $created
+ * @return integer
+ */
+ protected function _getMax(Model $Model, $scope, $right, $recursive = -1, $created = false) {
+ $db = ConnectionManager::getDataSource($Model->useDbConfig);
+ if ($created) {
+ if (is_string($scope)) {
+ $scope .= " AND {$Model->alias}.{$Model->primaryKey} <> ";
+ $scope .= $db->value($Model->id, $Model->getColumnType($Model->primaryKey));
+ } else {
+ $scope['NOT'][$Model->alias . '.' . $Model->primaryKey] = $Model->id;
+ }
+ }
+ $name = $Model->alias . '.' . $right;
+ list($edge) = array_values($Model->find('first', array(
+ 'conditions' => $scope,
+ 'fields' => $db->calculate($Model, 'max', array($name, $right)),
+ 'recursive' => $recursive
+ )));
+ return (empty($edge[$right])) ? 0 : $edge[$right];
+ }
+
+/**
+ * get the minimum index value in the table.
+ *
+ * @param Model $Model
+ * @param string $scope
+ * @param string $left
+ * @param integer $recursive
+ * @return integer
+ */
+ protected function _getMin(Model $Model, $scope, $left, $recursive = -1) {
+ $db = ConnectionManager::getDataSource($Model->useDbConfig);
+ $name = $Model->alias . '.' . $left;
+ list($edge) = array_values($Model->find('first', array(
+ 'conditions' => $scope,
+ 'fields' => $db->calculate($Model, 'min', array($name, $left)),
+ 'recursive' => $recursive
+ )));
+ return (empty($edge[$left])) ? 0 : $edge[$left];
+ }
+
+/**
+ * Table sync method.
+ *
+ * Handles table sync operations, Taking account of the behavior scope.
+ *
+ * @param Model $Model
+ * @param integer $shift
+ * @param string $dir
+ * @param array $conditions
+ * @param boolean $created
+ * @param string $field
+ * @return void
+ */
+ protected function _sync(Model $Model, $shift, $dir = '+', $conditions = array(), $created = false, $field = 'both') {
+ $ModelRecursive = $Model->recursive;
+ extract($this->settings[$Model->alias]);
+ $Model->recursive = $recursive;
+
+ if ($field == 'both') {
+ $this->_sync($Model, $shift, $dir, $conditions, $created, $left);
+ $field = $right;
+ }
+ if (is_string($conditions)) {
+ $conditions = array("{$Model->alias}.{$field} {$conditions}");
+ }
+ if (($scope != '1 = 1' && $scope !== true) && $scope) {
+ $conditions[] = $scope;
+ }
+ if ($created) {
+ $conditions['NOT'][$Model->alias . '.' . $Model->primaryKey] = $Model->id;
+ }
+ $Model->updateAll(array($Model->alias . '.' . $field => $Model->escapeField($field) . ' ' . $dir . ' ' . $shift), $conditions);
+ $Model->recursive = $ModelRecursive;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/BehaviorCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/BehaviorCollection.php
new file mode 100644
index 0000000..fff3e7d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/BehaviorCollection.php
@@ -0,0 +1,296 @@
+<?php
+/**
+ * BehaviorCollection
+ *
+ * Provides management and interface for interacting with collections of behaviors.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 1.2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * Model behavior collection class.
+ *
+ * Defines the Behavior interface, and contains common model interaction functionality.
+ *
+ * @package Cake.Model
+ */
+class BehaviorCollection extends ObjectCollection implements CakeEventListener {
+
+/**
+ * Stores a reference to the attached name
+ *
+ * @var string
+ */
+ public $modelName = null;
+
+/**
+ * Keeps a list of all methods of attached behaviors
+ *
+ * @var array
+ */
+ protected $_methods = array();
+
+/**
+ * Keeps a list of all methods which have been mapped with regular expressions
+ *
+ * @var array
+ */
+ protected $_mappedMethods = array();
+
+/**
+ * Attaches a model object and loads a list of behaviors
+ *
+ * @todo Make this method a constructor instead..
+ * @param string $modelName
+ * @param array $behaviors
+ * @return void
+ */
+ public function init($modelName, $behaviors = array()) {
+ $this->modelName = $modelName;
+
+ if (!empty($behaviors)) {
+ foreach (BehaviorCollection::normalizeObjectArray($behaviors) as $behavior => $config) {
+ $this->load($config['class'], $config['settings']);
+ }
+ }
+ }
+
+/**
+ * Backwards compatible alias for load()
+ *
+ * @param string $behavior
+ * @param array $config
+ * @return void
+ * @deprecated Replaced with load()
+ */
+ public function attach($behavior, $config = array()) {
+ return $this->load($behavior, $config);
+ }
+
+/**
+ * Loads a behavior into the collection. You can use use `$config['enabled'] = false`
+ * to load a behavior with callbacks disabled. By default callbacks are enabled. Disable behaviors
+ * can still be used as normal.
+ *
+ * You can alias your behavior as an existing behavior by setting the 'className' key, i.e.,
+ * {{{
+ * public $actsAs = array(
+ * 'Tree' => array(
+ * 'className' => 'AliasedTree'
+ * );
+ * );
+ * }}}
+ * All calls to the `Tree` behavior would use `AliasedTree` instead.
+ *
+ * @param string $behavior CamelCased name of the behavior to load
+ * @param array $config Behavior configuration parameters
+ * @return boolean True on success, false on failure
+ * @throws MissingBehaviorException when a behavior could not be found.
+ */
+ public function load($behavior, $config = array()) {
+ if (is_array($config) && isset($config['className'])) {
+ $alias = $behavior;
+ $behavior = $config['className'];
+ }
+ $configDisabled = isset($config['enabled']) && $config['enabled'] === false;
+ unset($config['enabled'], $config['className']);
+
+ list($plugin, $name) = pluginSplit($behavior, true);
+ if (!isset($alias)) {
+ $alias = $name;
+ }
+
+ $class = $name . 'Behavior';
+
+ App::uses($class, $plugin . 'Model/Behavior');
+ if (!class_exists($class)) {
+ throw new MissingBehaviorException(array(
+ 'class' => $class,
+ 'plugin' => substr($plugin, 0, -1)
+ ));
+ }
+
+ if (!isset($this->{$alias})) {
+ if (ClassRegistry::isKeySet($class)) {
+ $this->_loaded[$alias] = ClassRegistry::getObject($class);
+ } else {
+ $this->_loaded[$alias] = new $class();
+ ClassRegistry::addObject($class, $this->_loaded[$alias]);
+ if (!empty($plugin)) {
+ ClassRegistry::addObject($plugin . '.' . $class, $this->_loaded[$alias]);
+ }
+ }
+ } elseif (isset($this->_loaded[$alias]->settings) && isset($this->_loaded[$alias]->settings[$this->modelName])) {
+ if ($config !== null && $config !== false) {
+ $config = array_merge($this->_loaded[$alias]->settings[$this->modelName], $config);
+ } else {
+ $config = array();
+ }
+ }
+ if (empty($config)) {
+ $config = array();
+ }
+ $this->_loaded[$alias]->setup(ClassRegistry::getObject($this->modelName), $config);
+
+ foreach ($this->_loaded[$alias]->mapMethods as $method => $methodAlias) {
+ $this->_mappedMethods[$method] = array($alias, $methodAlias);
+ }
+ $methods = get_class_methods($this->_loaded[$alias]);
+ $parentMethods = array_flip(get_class_methods('ModelBehavior'));
+ $callbacks = array(
+ 'setup', 'cleanup', 'beforeFind', 'afterFind', 'beforeSave', 'afterSave',
+ 'beforeDelete', 'afterDelete', 'onError'
+ );
+
+ foreach ($methods as $m) {
+ if (!isset($parentMethods[$m])) {
+ $methodAllowed = (
+ $m[0] != '_' && !array_key_exists($m, $this->_methods) &&
+ !in_array($m, $callbacks)
+ );
+ if ($methodAllowed) {
+ $this->_methods[$m] = array($alias, $m);
+ }
+ }
+ }
+
+ if (!in_array($alias, $this->_enabled) && !$configDisabled) {
+ $this->enable($alias);
+ } else {
+ $this->disable($alias);
+ }
+ return true;
+ }
+
+/**
+ * Detaches a behavior from a model
+ *
+ * @param string $name CamelCased name of the behavior to unload
+ * @return void
+ */
+ public function unload($name) {
+ list($plugin, $name) = pluginSplit($name);
+ if (isset($this->_loaded[$name])) {
+ $this->_loaded[$name]->cleanup(ClassRegistry::getObject($this->modelName));
+ parent::unload($name);
+ }
+ foreach ($this->_methods as $m => $callback) {
+ if (is_array($callback) && $callback[0] == $name) {
+ unset($this->_methods[$m]);
+ }
+ }
+ }
+
+/**
+ * Backwards compatible alias for unload()
+ *
+ * @param string $name Name of behavior
+ * @return void
+ * @deprecated Use unload instead.
+ */
+ public function detach($name) {
+ return $this->unload($name);
+ }
+
+/**
+ * Dispatches a behavior method. Will call either normal methods or mapped methods.
+ *
+ * If a method is not handled by the BehaviorCollection, and $strict is false, a
+ * special return of `array('unhandled')` will be returned to signal the method was not found.
+ *
+ * @param Model $model The model the method was originally called on.
+ * @param string $method The method called.
+ * @param array $params Parameters for the called method.
+ * @param boolean $strict If methods are not found, trigger an error.
+ * @return array All methods for all behaviors attached to this object
+ */
+ public function dispatchMethod($model, $method, $params = array(), $strict = false) {
+ $method = $this->hasMethod($method, true);
+
+ if ($strict && empty($method)) {
+ trigger_error(__d('cake_dev', "BehaviorCollection::dispatchMethod() - Method %s not found in any attached behavior", $method), E_USER_WARNING);
+ return null;
+ }
+ if (empty($method)) {
+ return array('unhandled');
+ }
+ if (count($method) === 3) {
+ array_unshift($params, $method[2]);
+ unset($method[2]);
+ }
+ return call_user_func_array(
+ array($this->_loaded[$method[0]], $method[1]),
+ array_merge(array(&$model), $params)
+ );
+ }
+
+/**
+ * Gets the method list for attached behaviors, i.e. all public, non-callback methods.
+ * This does not include mappedMethods.
+ *
+ * @return array All public methods for all behaviors attached to this collection
+ */
+ public function methods() {
+ return $this->_methods;
+ }
+
+/**
+ * Check to see if a behavior in this collection implements the provided method. Will
+ * also check mappedMethods.
+ *
+ * @param string $method The method to find.
+ * @param boolean $callback Return the callback for the method.
+ * @return mixed If $callback is false, a boolean will be returned, if its true, an array
+ * containing callback information will be returned. For mapped methods the array will have 3 elements.
+ */
+ public function hasMethod($method, $callback = false) {
+ if (isset($this->_methods[$method])) {
+ return $callback ? $this->_methods[$method] : true;
+ }
+ foreach ($this->_mappedMethods as $pattern => $target) {
+ if (preg_match($pattern . 'i', $method)) {
+ if ($callback) {
+ $target[] = $method;
+ return $target;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns the implemented events that will get routed to the trigger function
+ * in order to dispatch them separately on each behavior
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'Model.beforeFind' => 'trigger',
+ 'Model.afterFind' => 'trigger',
+ 'Model.beforeValidate' => 'trigger',
+ 'Model.afterValidate' => 'trigger',
+ 'Model.beforeSave' => 'trigger',
+ 'Model.afterSave' => 'trigger',
+ 'Model.beforeDelete' => 'trigger',
+ 'Model.afterDelete' => 'trigger'
+ );
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/CakeSchema.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/CakeSchema.php
new file mode 100644
index 0000000..60c3b76
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/CakeSchema.php
@@ -0,0 +1,710 @@
+<?php
+/**
+ * Schema database management for CakePHP.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 1.2.0.5550
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('ConnectionManager', 'Model');
+App::uses('File', 'Utility');
+
+/**
+ * Base Class for Schema management
+ *
+ * @package Cake.Model
+ */
+class CakeSchema extends Object {
+
+/**
+ * Name of the schema
+ *
+ * @var string
+ */
+ public $name = null;
+
+/**
+ * Path to write location
+ *
+ * @var string
+ */
+ public $path = null;
+
+/**
+ * File to write
+ *
+ * @var string
+ */
+ public $file = 'schema.php';
+
+/**
+ * Connection used for read
+ *
+ * @var string
+ */
+ public $connection = 'default';
+
+/**
+ * plugin name.
+ *
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Set of tables
+ *
+ * @var array
+ */
+ public $tables = array();
+
+/**
+ * Constructor
+ *
+ * @param array $options optional load object properties
+ */
+ public function __construct($options = array()) {
+ parent::__construct();
+
+ if (empty($options['name'])) {
+ $this->name = preg_replace('/schema$/i', '', get_class($this));
+ }
+ if (!empty($options['plugin'])) {
+ $this->plugin = $options['plugin'];
+ }
+
+ if (strtolower($this->name) === 'cake') {
+ $this->name = Inflector::camelize(Inflector::slug(Configure::read('App.dir')));
+ }
+
+ if (empty($options['path'])) {
+ $this->path = APP . 'Config' . DS . 'Schema';
+ }
+
+ $options = array_merge(get_object_vars($this), $options);
+ $this->build($options);
+ }
+
+/**
+ * Builds schema object properties
+ *
+ * @param array $data loaded object properties
+ * @return void
+ */
+ public function build($data) {
+ $file = null;
+ foreach ($data as $key => $val) {
+ if (!empty($val)) {
+ if (!in_array($key, array('plugin', 'name', 'path', 'file', 'connection', 'tables', '_log'))) {
+ if ($key[0] === '_') {
+ continue;
+ }
+ $this->tables[$key] = $val;
+ unset($this->{$key});
+ } elseif ($key !== 'tables') {
+ if ($key === 'name' && $val !== $this->name && !isset($data['file'])) {
+ $file = Inflector::underscore($val) . '.php';
+ }
+ $this->{$key} = $val;
+ }
+ }
+ }
+ if (file_exists($this->path . DS . $file) && is_file($this->path . DS . $file)) {
+ $this->file = $file;
+ } elseif (!empty($this->plugin)) {
+ $this->path = CakePlugin::path($this->plugin) . 'Config' . DS . 'Schema';
+ }
+ }
+
+/**
+ * Before callback to be implemented in subclasses
+ *
+ * @param array $event schema object properties
+ * @return boolean Should process continue
+ */
+ public function before($event = array()) {
+ return true;
+ }
+
+/**
+ * After callback to be implemented in subclasses
+ *
+ * @param array $event schema object properties
+ * @return void
+ */
+ public function after($event = array()) {
+ }
+
+/**
+ * Reads database and creates schema tables
+ *
+ * @param array $options schema object properties
+ * @return array Set of name and tables
+ */
+ public function load($options = array()) {
+ if (is_string($options)) {
+ $options = array('path' => $options);
+ }
+
+ $this->build($options);
+ extract(get_object_vars($this));
+
+ $class = $name . 'Schema';
+
+ if (!class_exists($class)) {
+ if (file_exists($path . DS . $file) && is_file($path . DS . $file)) {
+ require_once $path . DS . $file;
+ } elseif (file_exists($path . DS . 'schema.php') && is_file($path . DS . 'schema.php')) {
+ require_once $path . DS . 'schema.php';
+ }
+ }
+
+ if (class_exists($class)) {
+ $Schema = new $class($options);
+ return $Schema;
+ }
+ return false;
+ }
+
+/**
+ * Reads database and creates schema tables
+ *
+ * Options
+ *
+ * - 'connection' - the db connection to use
+ * - 'name' - name of the schema
+ * - 'models' - a list of models to use, or false to ignore models
+ *
+ * @param array $options schema object properties
+ * @return array Array indexed by name and tables
+ */
+ public function read($options = array()) {
+ extract(array_merge(
+ array(
+ 'connection' => $this->connection,
+ 'name' => $this->name,
+ 'models' => true,
+ ),
+ $options
+ ));
+ $db = ConnectionManager::getDataSource($connection);
+
+ if (isset($this->plugin)) {
+ App::uses($this->plugin . 'AppModel', $this->plugin . '.Model');
+ }
+
+ $tables = array();
+ $currentTables = (array)$db->listSources();
+
+ $prefix = null;
+ if (isset($db->config['prefix'])) {
+ $prefix = $db->config['prefix'];
+ }
+
+ if (!is_array($models) && $models !== false) {
+ if (isset($this->plugin)) {
+ $models = App::objects($this->plugin . '.Model', null, false);
+ } else {
+ $models = App::objects('Model');
+ }
+ }
+
+ if (is_array($models)) {
+ foreach ($models as $model) {
+ $importModel = $model;
+ $plugin = null;
+ if ($model == 'AppModel') {
+ continue;
+ }
+
+ if (isset($this->plugin)) {
+ if ($model == $this->plugin . 'AppModel') {
+ continue;
+ }
+ $importModel = $model;
+ $plugin = $this->plugin . '.';
+ }
+
+ App::uses($importModel, $plugin . 'Model');
+ if (!class_exists($importModel)) {
+ continue;
+ }
+
+ $vars = get_class_vars($model);
+ if (empty($vars['useDbConfig']) || $vars['useDbConfig'] != $connection) {
+ continue;
+ }
+
+ try {
+ $Object = ClassRegistry::init(array('class' => $model, 'ds' => $connection));
+ } catch (CakeException $e) {
+ continue;
+ }
+
+ $db = $Object->getDataSource();
+ if (is_object($Object) && $Object->useTable !== false) {
+ $fulltable = $table = $db->fullTableName($Object, false, false);
+ if ($prefix && strpos($table, $prefix) !== 0) {
+ continue;
+ }
+ $table = $this->_noPrefixTable($prefix, $table);
+
+ if (in_array($fulltable, $currentTables)) {
+ $key = array_search($fulltable, $currentTables);
+ if (empty($tables[$table])) {
+ $tables[$table] = $this->_columns($Object);
+ $tables[$table]['indexes'] = $db->index($Object);
+ $tables[$table]['tableParameters'] = $db->readTableParameters($fulltable);
+ unset($currentTables[$key]);
+ }
+ if (!empty($Object->hasAndBelongsToMany)) {
+ foreach ($Object->hasAndBelongsToMany as $Assoc => $assocData) {
+ if (isset($assocData['with'])) {
+ $class = $assocData['with'];
+ }
+ if (is_object($Object->$class)) {
+ $withTable = $db->fullTableName($Object->$class, false, false);
+ if ($prefix && strpos($withTable, $prefix) !== 0) {
+ continue;
+ }
+ if (in_array($withTable, $currentTables)) {
+ $key = array_search($withTable, $currentTables);
+ $noPrefixWith = $this->_noPrefixTable($prefix, $withTable);
+
+ $tables[$noPrefixWith] = $this->_columns($Object->$class);
+ $tables[$noPrefixWith]['indexes'] = $db->index($Object->$class);
+ $tables[$noPrefixWith]['tableParameters'] = $db->readTableParameters($withTable);
+ unset($currentTables[$key]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!empty($currentTables)) {
+ foreach ($currentTables as $table) {
+ if ($prefix) {
+ if (strpos($table, $prefix) !== 0) {
+ continue;
+ }
+ $table = $this->_noPrefixTable($prefix, $table);
+ }
+ $Object = new AppModel(array(
+ 'name' => Inflector::classify($table), 'table' => $table, 'ds' => $connection
+ ));
+
+ $systemTables = array(
+ 'aros', 'acos', 'aros_acos', Configure::read('Session.table'), 'i18n'
+ );
+
+ $fulltable = $db->fullTableName($Object, false, false);
+
+ if (in_array($table, $systemTables)) {
+ $tables[$Object->table] = $this->_columns($Object);
+ $tables[$Object->table]['indexes'] = $db->index($Object);
+ $tables[$Object->table]['tableParameters'] = $db->readTableParameters($fulltable);
+ } elseif ($models === false) {
+ $tables[$table] = $this->_columns($Object);
+ $tables[$table]['indexes'] = $db->index($Object);
+ $tables[$table]['tableParameters'] = $db->readTableParameters($fulltable);
+ } else {
+ $tables['missing'][$table] = $this->_columns($Object);
+ $tables['missing'][$table]['indexes'] = $db->index($Object);
+ $tables['missing'][$table]['tableParameters'] = $db->readTableParameters($fulltable);
+ }
+ }
+ }
+
+ ksort($tables);
+ return compact('name', 'tables');
+ }
+
+/**
+ * Writes schema file from object or options
+ *
+ * @param array|object $object schema object or options array
+ * @param array $options schema object properties to override object
+ * @return mixed false or string written to file
+ */
+ public function write($object, $options = array()) {
+ if (is_object($object)) {
+ $object = get_object_vars($object);
+ $this->build($object);
+ }
+
+ if (is_array($object)) {
+ $options = $object;
+ unset($object);
+ }
+
+ extract(array_merge(
+ get_object_vars($this), $options
+ ));
+
+ $out = "class {$name}Schema extends CakeSchema {\n\n";
+
+ if ($path !== $this->path) {
+ $out .= "\tpublic \$path = '{$path}';\n\n";
+ }
+
+ if ($file !== $this->file) {
+ $out .= "\tpublic \$file = '{$file}';\n\n";
+ }
+
+ if ($connection !== 'default') {
+ $out .= "\tpublic \$connection = '{$connection}';\n\n";
+ }
+
+ $out .= "\tpublic function before(\$event = array()) {\n\t\treturn true;\n\t}\n\n\tpublic function after(\$event = array()) {\n\t}\n\n";
+
+ if (empty($tables)) {
+ $this->read();
+ }
+
+ foreach ($tables as $table => $fields) {
+ if (!is_numeric($table) && $table !== 'missing') {
+ $out .= $this->generateTable($table, $fields);
+ }
+ }
+ $out .= "}\n";
+
+ $file = new File($path . DS . $file, true);
+ $content = "<?php \n{$out}";
+ if ($file->write($content)) {
+ return $content;
+ }
+ return false;
+ }
+
+/**
+ * Generate the code for a table. Takes a table name and $fields array
+ * Returns a completed variable declaration to be used in schema classes
+ *
+ * @param string $table Table name you want returned.
+ * @param array $fields Array of field information to generate the table with.
+ * @return string Variable declaration for a schema class
+ */
+ public function generateTable($table, $fields) {
+ $out = "\tpublic \${$table} = array(\n";
+ if (is_array($fields)) {
+ $cols = array();
+ foreach ($fields as $field => $value) {
+ if ($field != 'indexes' && $field != 'tableParameters') {
+ if (is_string($value)) {
+ $type = $value;
+ $value = array('type' => $type);
+ }
+ $col = "\t\t'{$field}' => array('type' => '" . $value['type'] . "', ";
+ unset($value['type']);
+ $col .= join(', ', $this->_values($value));
+ } elseif ($field == 'indexes') {
+ $col = "\t\t'indexes' => array(\n\t\t\t";
+ $props = array();
+ foreach ((array)$value as $key => $index) {
+ $props[] = "'{$key}' => array(" . join(', ', $this->_values($index)) . ")";
+ }
+ $col .= join(",\n\t\t\t", $props) . "\n\t\t";
+ } elseif ($field == 'tableParameters') {
+ $col = "\t\t'tableParameters' => array(";
+ $props = array();
+ foreach ((array)$value as $key => $param) {
+ $props[] = "'{$key}' => '$param'";
+ }
+ $col .= join(', ', $props);
+ }
+ $col .= ")";
+ $cols[] = $col;
+ }
+ $out .= join(",\n", $cols);
+ }
+ $out .= "\n\t);\n";
+ return $out;
+ }
+
+/**
+ * Compares two sets of schemas
+ *
+ * @param array|object $old Schema object or array
+ * @param array|object $new Schema object or array
+ * @return array Tables (that are added, dropped, or changed)
+ */
+ public function compare($old, $new = null) {
+ if (empty($new)) {
+ $new = $this;
+ }
+ if (is_array($new)) {
+ if (isset($new['tables'])) {
+ $new = $new['tables'];
+ }
+ } else {
+ $new = $new->tables;
+ }
+
+ if (is_array($old)) {
+ if (isset($old['tables'])) {
+ $old = $old['tables'];
+ }
+ } else {
+ $old = $old->tables;
+ }
+ $tables = array();
+ foreach ($new as $table => $fields) {
+ if ($table == 'missing') {
+ continue;
+ }
+ if (!array_key_exists($table, $old)) {
+ $tables[$table]['add'] = $fields;
+ } else {
+ $diff = $this->_arrayDiffAssoc($fields, $old[$table]);
+ if (!empty($diff)) {
+ $tables[$table]['add'] = $diff;
+ }
+ $diff = $this->_arrayDiffAssoc($old[$table], $fields);
+ if (!empty($diff)) {
+ $tables[$table]['drop'] = $diff;
+ }
+ }
+
+ foreach ($fields as $field => $value) {
+ if (!empty($old[$table][$field])) {
+ $diff = $this->_arrayDiffAssoc($value, $old[$table][$field]);
+ if (!empty($diff) && $field !== 'indexes' && $field !== 'tableParameters') {
+ $tables[$table]['change'][$field] = $value;
+ }
+ }
+
+ if (isset($tables[$table]['add'][$field]) && $field !== 'indexes' && $field !== 'tableParameters') {
+ $wrapper = array_keys($fields);
+ if ($column = array_search($field, $wrapper)) {
+ if (isset($wrapper[$column - 1])) {
+ $tables[$table]['add'][$field]['after'] = $wrapper[$column - 1];
+ }
+ }
+ }
+ }
+
+ if (isset($old[$table]['indexes']) && isset($new[$table]['indexes'])) {
+ $diff = $this->_compareIndexes($new[$table]['indexes'], $old[$table]['indexes']);
+ if ($diff) {
+ if (!isset($tables[$table])) {
+ $tables[$table] = array();
+ }
+ if (isset($diff['drop'])) {
+ $tables[$table]['drop']['indexes'] = $diff['drop'];
+ }
+ if ($diff && isset($diff['add'])) {
+ $tables[$table]['add']['indexes'] = $diff['add'];
+ }
+ }
+ }
+ if (isset($old[$table]['tableParameters']) && isset($new[$table]['tableParameters'])) {
+ $diff = $this->_compareTableParameters($new[$table]['tableParameters'], $old[$table]['tableParameters']);
+ if ($diff) {
+ $tables[$table]['change']['tableParameters'] = $diff;
+ }
+ }
+ }
+ return $tables;
+ }
+
+/**
+ * Extended array_diff_assoc noticing change from/to NULL values
+ *
+ * It behaves almost the same way as array_diff_assoc except for NULL values: if
+ * one of the values is not NULL - change is detected. It is useful in situation
+ * where one value is strval('') ant other is strval(null) - in string comparing
+ * methods this results as EQUAL, while it is not.
+ *
+ * @param array $array1 Base array
+ * @param array $array2 Corresponding array checked for equality
+ * @return array Difference as array with array(keys => values) from input array
+ * where match was not found.
+ */
+ protected function _arrayDiffAssoc($array1, $array2) {
+ $difference = array();
+ foreach ($array1 as $key => $value) {
+ if (!array_key_exists($key, $array2)) {
+ $difference[$key] = $value;
+ continue;
+ }
+ $correspondingValue = $array2[$key];
+ if (is_null($value) !== is_null($correspondingValue)) {
+ $difference[$key] = $value;
+ continue;
+ }
+ if (is_bool($value) !== is_bool($correspondingValue)) {
+ $difference[$key] = $value;
+ continue;
+ }
+ if (is_array($value) && is_array($correspondingValue)) {
+ continue;
+ }
+ if ($value === $correspondingValue) {
+ continue;
+ }
+ $difference[$key] = $value;
+ }
+ return $difference;
+ }
+
+/**
+ * Formats Schema columns from Model Object
+ *
+ * @param array $values options keys(type, null, default, key, length, extra)
+ * @return array Formatted values
+ */
+ protected function _values($values) {
+ $vals = array();
+ if (is_array($values)) {
+ foreach ($values as $key => $val) {
+ if (is_array($val)) {
+ $vals[] = "'{$key}' => array('" . implode("', '", $val) . "')";
+ } elseif (!is_numeric($key)) {
+ $val = var_export($val, true);
+ if ($val === 'NULL') {
+ $val = 'null';
+ }
+ $vals[] = "'{$key}' => {$val}";
+ }
+ }
+ }
+ return $vals;
+ }
+
+/**
+ * Formats Schema columns from Model Object
+ *
+ * @param array $Obj model object
+ * @return array Formatted columns
+ */
+ protected function _columns(&$Obj) {
+ $db = $Obj->getDataSource();
+ $fields = $Obj->schema(true);
+
+ $columns = $props = array();
+ foreach ($fields as $name => $value) {
+ if ($Obj->primaryKey == $name) {
+ $value['key'] = 'primary';
+ }
+ if (!isset($db->columns[$value['type']])) {
+ trigger_error(__d('cake_dev', 'Schema generation error: invalid column type %s for %s.%s does not exist in DBO', $value['type'], $Obj->name, $name), E_USER_NOTICE);
+ continue;
+ } else {
+ $defaultCol = $db->columns[$value['type']];
+ if (isset($defaultCol['limit']) && $defaultCol['limit'] == $value['length']) {
+ unset($value['length']);
+ } elseif (isset($defaultCol['length']) && $defaultCol['length'] == $value['length']) {
+ unset($value['length']);
+ }
+ unset($value['limit']);
+ }
+
+ if (isset($value['default']) && ($value['default'] === '' || $value['default'] === false)) {
+ unset($value['default']);
+ }
+ if (empty($value['length'])) {
+ unset($value['length']);
+ }
+ if (empty($value['key'])) {
+ unset($value['key']);
+ }
+ $columns[$name] = $value;
+ }
+
+ return $columns;
+ }
+
+/**
+ * Compare two schema files table Parameters
+ *
+ * @param array $new New indexes
+ * @param array $old Old indexes
+ * @return mixed False on failure, or an array of parameters to add & drop.
+ */
+ protected function _compareTableParameters($new, $old) {
+ if (!is_array($new) || !is_array($old)) {
+ return false;
+ }
+ $change = $this->_arrayDiffAssoc($new, $old);
+ return $change;
+ }
+
+/**
+ * Compare two schema indexes
+ *
+ * @param array $new New indexes
+ * @param array $old Old indexes
+ * @return mixed false on failure or array of indexes to add and drop
+ */
+ protected function _compareIndexes($new, $old) {
+ if (!is_array($new) || !is_array($old)) {
+ return false;
+ }
+
+ $add = $drop = array();
+
+ $diff = $this->_arrayDiffAssoc($new, $old);
+ if (!empty($diff)) {
+ $add = $diff;
+ }
+
+ $diff = $this->_arrayDiffAssoc($old, $new);
+ if (!empty($diff)) {
+ $drop = $diff;
+ }
+
+ foreach ($new as $name => $value) {
+ if (isset($old[$name])) {
+ $newUnique = isset($value['unique']) ? $value['unique'] : 0;
+ $oldUnique = isset($old[$name]['unique']) ? $old[$name]['unique'] : 0;
+ $newColumn = $value['column'];
+ $oldColumn = $old[$name]['column'];
+
+ $diff = false;
+
+ if ($newUnique != $oldUnique) {
+ $diff = true;
+ } elseif (is_array($newColumn) && is_array($oldColumn)) {
+ $diff = ($newColumn !== $oldColumn);
+ } elseif (is_string($newColumn) && is_string($oldColumn)) {
+ $diff = ($newColumn != $oldColumn);
+ } else {
+ $diff = true;
+ }
+ if ($diff) {
+ $drop[$name] = null;
+ $add[$name] = $value;
+ }
+ }
+ }
+ return array_filter(compact('add', 'drop'));
+ }
+
+/**
+ * Trim the table prefix from the full table name, and return the prefix-less table
+ *
+ * @param string $prefix Table prefix
+ * @param string $table Full table name
+ * @return string Prefix-less table name
+ */
+ protected function _noPrefixTable($prefix, $table) {
+ return preg_replace('/^' . preg_quote($prefix) . '/', '', $table);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ConnectionManager.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ConnectionManager.php
new file mode 100644
index 0000000..edbcfa5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ConnectionManager.php
@@ -0,0 +1,266 @@
+<?php
+/**
+ * Datasource connection manager
+ *
+ * Provides an interface for loading and enumerating connections defined in app/Config/database.php
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.10.x.1402
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DataSource', 'Model/Datasource');
+
+/**
+ * Manages loaded instances of DataSource objects
+ *
+ * Provides an interface for loading and enumerating connections defined in
+ * app/Config/database.php
+ *
+ * @package Cake.Model
+ */
+class ConnectionManager {
+
+/**
+ * Holds a loaded instance of the Connections object
+ *
+ * @var DATABASE_CONFIG
+ */
+ public static $config = null;
+
+/**
+ * Holds instances DataSource objects
+ *
+ * @var array
+ */
+ protected static $_dataSources = array();
+
+/**
+ * Contains a list of all file and class names used in Connection settings
+ *
+ * @var array
+ */
+ protected static $_connectionsEnum = array();
+
+/**
+ * Indicates if the init code for this class has already been executed
+ *
+ * @var boolean
+ */
+ protected static $_init = false;
+
+/**
+ * Loads connections configuration.
+ *
+ * @return void
+ */
+ protected static function _init() {
+ include_once APP . 'Config' . DS . 'database.php';
+ if (class_exists('DATABASE_CONFIG')) {
+ self::$config = new DATABASE_CONFIG();
+ }
+ self::$_init = true;
+ }
+
+/**
+ * Gets a reference to a DataSource object
+ *
+ * @param string $name The name of the DataSource, as defined in app/Config/database.php
+ * @return DataSource Instance
+ * @throws MissingDatasourceConfigException
+ * @throws MissingDatasourceException
+ */
+ public static function getDataSource($name) {
+ if (empty(self::$_init)) {
+ self::_init();
+ }
+
+ if (!empty(self::$_dataSources[$name])) {
+ $return = self::$_dataSources[$name];
+ return $return;
+ }
+
+ if (empty(self::$_connectionsEnum[$name])) {
+ self::_getConnectionObject($name);
+ }
+
+ self::loadDataSource($name);
+ $conn = self::$_connectionsEnum[$name];
+ $class = $conn['classname'];
+
+ self::$_dataSources[$name] = new $class(self::$config->{$name});
+ self::$_dataSources[$name]->configKeyName = $name;
+
+ return self::$_dataSources[$name];
+ }
+
+/**
+ * Gets the list of available DataSource connections
+ * This will only return the datasources instantiated by this manager
+ * It differs from enumConnectionObjects, since the latter will return all configured connections
+ *
+ * @return array List of available connections
+ */
+ public static function sourceList() {
+ if (empty(self::$_init)) {
+ self::_init();
+ }
+ return array_keys(self::$_dataSources);
+ }
+
+/**
+ * Gets a DataSource name from an object reference.
+ *
+ * @param DataSource $source DataSource object
+ * @return string Datasource name, or null if source is not present
+ * in the ConnectionManager.
+ */
+ public static function getSourceName($source) {
+ if (empty(self::$_init)) {
+ self::_init();
+ }
+ foreach (self::$_dataSources as $name => $ds) {
+ if ($ds === $source) {
+ return $name;
+ }
+ }
+ return null;
+ }
+
+/**
+ * Loads the DataSource class for the given connection name
+ *
+ * @param string|array $connName A string name of the connection, as defined in app/Config/database.php,
+ * or an array containing the filename (without extension) and class name of the object,
+ * to be found in app/Model/Datasource/ or lib/Cake/Model/Datasource/.
+ * @return boolean True on success, null on failure or false if the class is already loaded
+ * @throws MissingDatasourceException
+ */
+ public static function loadDataSource($connName) {
+ if (empty(self::$_init)) {
+ self::_init();
+ }
+
+ if (is_array($connName)) {
+ $conn = $connName;
+ } else {
+ $conn = self::$_connectionsEnum[$connName];
+ }
+
+ if (class_exists($conn['classname'], false)) {
+ return false;
+ }
+
+ $plugin = $package = null;
+ if (!empty($conn['plugin'])) {
+ $plugin = $conn['plugin'] . '.';
+ }
+ if (!empty($conn['package'])) {
+ $package = '/' . $conn['package'];
+ }
+
+ App::uses($conn['classname'], $plugin . 'Model/Datasource' . $package);
+ if (!class_exists($conn['classname'])) {
+ throw new MissingDatasourceException(array(
+ 'class' => $conn['classname'],
+ 'plugin' => substr($plugin, 0, -1)
+ ));
+ }
+ return true;
+ }
+
+/**
+ * Return a list of connections
+ *
+ * @return array An associative array of elements where the key is the connection name
+ * (as defined in Connections), and the value is an array with keys 'filename' and 'classname'.
+ */
+ public static function enumConnectionObjects() {
+ if (empty(self::$_init)) {
+ self::_init();
+ }
+ return (array)self::$config;
+ }
+
+/**
+ * Dynamically creates a DataSource object at runtime, with the given name and settings
+ *
+ * @param string $name The DataSource name
+ * @param array $config The DataSource configuration settings
+ * @return DataSource A reference to the DataSource object, or null if creation failed
+ */
+ public static function create($name = '', $config = array()) {
+ if (empty(self::$_init)) {
+ self::_init();
+ }
+
+ if (empty($name) || empty($config) || array_key_exists($name, self::$_connectionsEnum)) {
+ return null;
+ }
+ self::$config->{$name} = $config;
+ self::$_connectionsEnum[$name] = self::_connectionData($config);
+ $return = self::getDataSource($name);
+ return $return;
+ }
+
+/**
+ * Removes a connection configuration at runtime given its name
+ *
+ * @param string $name the connection name as it was created
+ * @return boolean success if connection was removed, false if it does not exist
+ */
+ public static function drop($name) {
+ if (empty(self::$_init)) {
+ self::_init();
+ }
+
+ if (!isset(self::$config->{$name})) {
+ return false;
+ }
+ unset(self::$_connectionsEnum[$name], self::$_dataSources[$name], self::$config->{$name});
+ return true;
+ }
+
+/**
+ * Gets a list of class and file names associated with the user-defined DataSource connections
+ *
+ * @param string $name Connection name
+ * @return void
+ * @throws MissingDatasourceConfigException
+ */
+ protected static function _getConnectionObject($name) {
+ if (!empty(self::$config->{$name})) {
+ self::$_connectionsEnum[$name] = self::_connectionData(self::$config->{$name});
+ } else {
+ throw new MissingDatasourceConfigException(array('config' => $name));
+ }
+ }
+
+/**
+ * Returns the file, class name, and parent for the given driver.
+ *
+ * @param array $config Array with connection configuration. Key 'datasource' is required
+ * @return array An indexed array with: filename, classname, plugin and parent
+ */
+ protected static function _connectionData($config) {
+ $package = $classname = $plugin = null;
+
+ list($plugin, $classname) = pluginSplit($config['datasource']);
+ if (strpos($classname, '/') !== false) {
+ $package = dirname($classname);
+ $classname = basename($classname);
+ }
+ return compact('package', 'classname', 'plugin');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/CakeSession.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/CakeSession.php
new file mode 100644
index 0000000..6baab1d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/CakeSession.php
@@ -0,0 +1,688 @@
+<?php
+/**
+ * Session class for Cake.
+ *
+ * Cake abstracts the handling of sessions.
+ * There are several convenient methods to access session information.
+ * This class is the implementation of those methods.
+ * They are mostly used by the Session Component.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource
+ * @since CakePHP(tm) v .0.10.0.1222
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Hash', 'Utility');
+App::uses('Security', 'Utility');
+
+/**
+ * Session class for Cake.
+ *
+ * Cake abstracts the handling of sessions. There are several convenient methods to access session information.
+ * This class is the implementation of those methods. They are mostly used by the Session Component.
+ *
+ * @package Cake.Model.Datasource
+ */
+class CakeSession {
+
+/**
+ * True if the Session is still valid
+ *
+ * @var boolean
+ */
+ public static $valid = false;
+
+/**
+ * Error messages for this session
+ *
+ * @var array
+ */
+ public static $error = false;
+
+/**
+ * User agent string
+ *
+ * @var string
+ */
+ protected static $_userAgent = '';
+
+/**
+ * Path to where the session is active.
+ *
+ * @var string
+ */
+ public static $path = '/';
+
+/**
+ * Error number of last occurred error
+ *
+ * @var integer
+ */
+ public static $lastError = null;
+
+/**
+ * Start time for this session.
+ *
+ * @var integer
+ */
+ public static $time = false;
+
+/**
+ * Cookie lifetime
+ *
+ * @var integer
+ */
+ public static $cookieLifeTime;
+
+/**
+ * Time when this session becomes invalid.
+ *
+ * @var integer
+ */
+ public static $sessionTime = false;
+
+/**
+ * Current Session id
+ *
+ * @var string
+ */
+ public static $id = null;
+
+/**
+ * Hostname
+ *
+ * @var string
+ */
+ public static $host = null;
+
+/**
+ * Session timeout multiplier factor
+ *
+ * @var integer
+ */
+ public static $timeout = null;
+
+/**
+ * Number of requests that can occur during a session time without the session being renewed.
+ * This feature is only used when config value `Session.autoRegenerate` is set to true.
+ *
+ * @var integer
+ * @see CakeSession::_checkValid()
+ */
+ public static $requestCountdown = 10;
+
+/**
+ * Pseudo constructor.
+ *
+ * @param string $base The base path for the Session
+ * @return void
+ */
+ public static function init($base = null) {
+ self::$time = time();
+
+ $checkAgent = Configure::read('Session.checkAgent');
+ if (($checkAgent === true || $checkAgent === null) && env('HTTP_USER_AGENT') != null) {
+ self::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
+ }
+ self::_setPath($base);
+ self::_setHost(env('HTTP_HOST'));
+
+ register_shutdown_function('session_write_close');
+ }
+
+/**
+ * Setup the Path variable
+ *
+ * @param string $base base path
+ * @return void
+ */
+ protected static function _setPath($base = null) {
+ if (empty($base)) {
+ self::$path = '/';
+ return;
+ }
+ if (strpos($base, 'index.php') !== false) {
+ $base = str_replace('index.php', '', $base);
+ }
+ if (strpos($base, '?') !== false) {
+ $base = str_replace('?', '', $base);
+ }
+ self::$path = $base;
+ }
+
+/**
+ * Set the host name
+ *
+ * @param string $host Hostname
+ * @return void
+ */
+ protected static function _setHost($host) {
+ self::$host = $host;
+ if (strpos(self::$host, ':') !== false) {
+ self::$host = substr(self::$host, 0, strpos(self::$host, ':'));
+ }
+ }
+
+/**
+ * Starts the Session.
+ *
+ * @return boolean True if session was started
+ */
+ public static function start() {
+ if (self::started()) {
+ return true;
+ }
+ self::init();
+ $id = self::id();
+ session_write_close();
+ self::_configureSession();
+ self::_startSession();
+
+ if (!$id && self::started()) {
+ self::_checkValid();
+ }
+
+ self::$error = false;
+ return self::started();
+ }
+
+/**
+ * Determine if Session has been started.
+ *
+ * @return boolean True if session has been started.
+ */
+ public static function started() {
+ return isset($_SESSION) && session_id();
+ }
+
+/**
+ * Returns true if given variable is set in session.
+ *
+ * @param string $name Variable name to check for
+ * @return boolean True if variable is there
+ */
+ public static function check($name = null) {
+ if (!self::started() && !self::start()) {
+ return false;
+ }
+ if (empty($name)) {
+ return false;
+ }
+ $result = Hash::get($_SESSION, $name);
+ return isset($result);
+ }
+
+/**
+ * Returns the Session id
+ *
+ * @param string $id
+ * @return string Session id
+ */
+ public static function id($id = null) {
+ if ($id) {
+ self::$id = $id;
+ session_id(self::$id);
+ }
+ if (self::started()) {
+ return session_id();
+ }
+ return self::$id;
+ }
+
+/**
+ * Removes a variable from session.
+ *
+ * @param string $name Session variable to remove
+ * @return boolean Success
+ */
+ public static function delete($name) {
+ if (self::check($name)) {
+ self::_overwrite($_SESSION, Hash::remove($_SESSION, $name));
+ return (self::check($name) == false);
+ }
+ self::_setError(2, __d('cake_dev', "%s doesn't exist", $name));
+ return false;
+ }
+
+/**
+ * Used to write new data to _SESSION, since PHP doesn't like us setting the _SESSION var itself
+ *
+ * @param array $old Set of old variables => values
+ * @param array $new New set of variable => value
+ * @return void
+ */
+ protected static function _overwrite(&$old, $new) {
+ if (!empty($old)) {
+ foreach ($old as $key => $var) {
+ if (!isset($new[$key])) {
+ unset($old[$key]);
+ }
+ }
+ }
+ foreach ($new as $key => $var) {
+ $old[$key] = $var;
+ }
+ }
+
+/**
+ * Return error description for given error number.
+ *
+ * @param integer $errorNumber Error to set
+ * @return string Error as string
+ */
+ protected static function _error($errorNumber) {
+ if (!is_array(self::$error) || !array_key_exists($errorNumber, self::$error)) {
+ return false;
+ } else {
+ return self::$error[$errorNumber];
+ }
+ }
+
+/**
+ * Returns last occurred error as a string, if any.
+ *
+ * @return mixed Error description as a string, or false.
+ */
+ public static function error() {
+ if (self::$lastError) {
+ return self::_error(self::$lastError);
+ }
+ return false;
+ }
+
+/**
+ * Returns true if session is valid.
+ *
+ * @return boolean Success
+ */
+ public static function valid() {
+ if (self::read('Config')) {
+ if (self::_validAgentAndTime() && self::$error === false) {
+ self::$valid = true;
+ } else {
+ self::$valid = false;
+ self::_setError(1, 'Session Highjacking Attempted !!!');
+ }
+ }
+ return self::$valid;
+ }
+
+/**
+ * Tests that the user agent is valid and that the session hasn't 'timed out'.
+ * Since timeouts are implemented in CakeSession it checks the current self::$time
+ * against the time the session is set to expire. The User agent is only checked
+ * if Session.checkAgent == true.
+ *
+ * @return boolean
+ */
+ protected static function _validAgentAndTime() {
+ $config = self::read('Config');
+ $validAgent = (
+ Configure::read('Session.checkAgent') === false ||
+ self::$_userAgent == $config['userAgent']
+ );
+ return ($validAgent && self::$time <= $config['time']);
+ }
+
+/**
+ * Get / Set the userAgent
+ *
+ * @param string $userAgent Set the userAgent
+ * @return void
+ */
+ public static function userAgent($userAgent = null) {
+ if ($userAgent) {
+ self::$_userAgent = $userAgent;
+ }
+ if (empty(self::$_userAgent)) {
+ CakeSession::init(self::$path);
+ }
+ return self::$_userAgent;
+ }
+
+/**
+ * Returns given session variable, or all of them, if no parameters given.
+ *
+ * @param string|array $name The name of the session variable (or a path as sent to Set.extract)
+ * @return mixed The value of the session variable
+ */
+ public static function read($name = null) {
+ if (!self::started() && !self::start()) {
+ return false;
+ }
+ if (is_null($name)) {
+ return self::_returnSessionVars();
+ }
+ if (empty($name)) {
+ return false;
+ }
+ $result = Hash::get($_SESSION, $name);
+
+ if (isset($result)) {
+ return $result;
+ }
+ self::_setError(2, "$name doesn't exist");
+ return null;
+ }
+
+/**
+ * Returns all session variables.
+ *
+ * @return mixed Full $_SESSION array, or false on error.
+ */
+ protected static function _returnSessionVars() {
+ if (!empty($_SESSION)) {
+ return $_SESSION;
+ }
+ self::_setError(2, 'No Session vars set');
+ return false;
+ }
+
+/**
+ * Writes value to given session variable name.
+ *
+ * @param string|array $name Name of variable
+ * @param string $value Value to write
+ * @return boolean True if the write was successful, false if the write failed
+ */
+ public static function write($name, $value = null) {
+ if (!self::started() && !self::start()) {
+ return false;
+ }
+ if (empty($name)) {
+ return false;
+ }
+ $write = $name;
+ if (!is_array($name)) {
+ $write = array($name => $value);
+ }
+ foreach ($write as $key => $val) {
+ self::_overwrite($_SESSION, Hash::insert($_SESSION, $key, $val));
+ if (Hash::get($_SESSION, $key) !== $val) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+/**
+ * Helper method to destroy invalid sessions.
+ *
+ * @return void
+ */
+ public static function destroy() {
+ if (self::started()) {
+ session_destroy();
+ }
+ self::clear();
+ }
+
+/**
+ * Clears the session, the session id, and renew's the session.
+ *
+ * @return void
+ */
+ public static function clear() {
+ $_SESSION = null;
+ self::$id = null;
+ self::start();
+ self::renew();
+ }
+
+/**
+ * Helper method to initialize a session, based on Cake core settings.
+ *
+ * Sessions can be configured with a few shortcut names as well as have any number of ini settings declared.
+ *
+ * @return void
+ * @throws CakeSessionException Throws exceptions when ini_set() fails.
+ */
+ protected static function _configureSession() {
+ $sessionConfig = Configure::read('Session');
+ $iniSet = function_exists('ini_set');
+
+ if (isset($sessionConfig['defaults'])) {
+ $defaults = self::_defaultConfig($sessionConfig['defaults']);
+ if ($defaults) {
+ $sessionConfig = Hash::merge($defaults, $sessionConfig);
+ }
+ }
+ if (!isset($sessionConfig['ini']['session.cookie_secure']) && env('HTTPS')) {
+ $sessionConfig['ini']['session.cookie_secure'] = 1;
+ }
+ if (isset($sessionConfig['timeout']) && !isset($sessionConfig['cookieTimeout'])) {
+ $sessionConfig['cookieTimeout'] = $sessionConfig['timeout'];
+ }
+ if (!isset($sessionConfig['ini']['session.cookie_lifetime'])) {
+ $sessionConfig['ini']['session.cookie_lifetime'] = $sessionConfig['cookieTimeout'] * 60;
+ }
+ if (!isset($sessionConfig['ini']['session.name'])) {
+ $sessionConfig['ini']['session.name'] = $sessionConfig['cookie'];
+ }
+ if (!empty($sessionConfig['handler'])) {
+ $sessionConfig['ini']['session.save_handler'] = 'user';
+ }
+ if (!isset($sessionConfig['ini']['session.gc_maxlifetime'])) {
+ $sessionConfig['ini']['session.gc_maxlifetime'] = $sessionConfig['timeout'] * 60;
+ }
+ if (!isset($sessionConfig['ini']['session.cookie_httponly'])) {
+ $sessionConfig['ini']['session.cookie_httponly'] = 1;
+ }
+
+ if (empty($_SESSION)) {
+ if (!empty($sessionConfig['ini']) && is_array($sessionConfig['ini'])) {
+ foreach ($sessionConfig['ini'] as $setting => $value) {
+ if (ini_set($setting, $value) === false) {
+ throw new CakeSessionException(sprintf(
+ __d('cake_dev', 'Unable to configure the session, setting %s failed.'),
+ $setting
+ ));
+ }
+ }
+ }
+ }
+ if (!empty($sessionConfig['handler']) && !isset($sessionConfig['handler']['engine'])) {
+ call_user_func_array('session_set_save_handler', $sessionConfig['handler']);
+ }
+ if (!empty($sessionConfig['handler']['engine'])) {
+ $handler = self::_getHandler($sessionConfig['handler']['engine']);
+ session_set_save_handler(
+ array($handler, 'open'),
+ array($handler, 'close'),
+ array($handler, 'read'),
+ array($handler, 'write'),
+ array($handler, 'destroy'),
+ array($handler, 'gc')
+ );
+ }
+ Configure::write('Session', $sessionConfig);
+ self::$sessionTime = self::$time + ($sessionConfig['timeout'] * 60);
+ }
+
+/**
+ * Find the handler class and make sure it implements the correct interface.
+ *
+ * @param string $handler
+ * @return void
+ * @throws CakeSessionException
+ */
+ protected static function _getHandler($handler) {
+ list($plugin, $class) = pluginSplit($handler, true);
+ App::uses($class, $plugin . 'Model/Datasource/Session');
+ if (!class_exists($class)) {
+ throw new CakeSessionException(__d('cake_dev', 'Could not load %s to handle the session.', $class));
+ }
+ $handler = new $class();
+ if ($handler instanceof CakeSessionHandlerInterface) {
+ return $handler;
+ }
+ throw new CakeSessionException(__d('cake_dev', 'Chosen SessionHandler does not implement CakeSessionHandlerInterface it cannot be used with an engine key.'));
+ }
+
+/**
+ * Get one of the prebaked default session configurations.
+ *
+ * @param string $name
+ * @return boolean|array
+ */
+ protected static function _defaultConfig($name) {
+ $defaults = array(
+ 'php' => array(
+ 'cookie' => 'CAKEPHP',
+ 'timeout' => 240,
+ 'ini' => array(
+ 'session.use_trans_sid' => 0,
+ 'session.cookie_path' => self::$path
+ )
+ ),
+ 'cake' => array(
+ 'cookie' => 'CAKEPHP',
+ 'timeout' => 240,
+ 'ini' => array(
+ 'session.use_trans_sid' => 0,
+ 'url_rewriter.tags' => '',
+ 'session.serialize_handler' => 'php',
+ 'session.use_cookies' => 1,
+ 'session.cookie_path' => self::$path,
+ 'session.auto_start' => 0,
+ 'session.save_path' => TMP . 'sessions',
+ 'session.save_handler' => 'files'
+ )
+ ),
+ 'cache' => array(
+ 'cookie' => 'CAKEPHP',
+ 'timeout' => 240,
+ 'ini' => array(
+ 'session.use_trans_sid' => 0,
+ 'url_rewriter.tags' => '',
+ 'session.auto_start' => 0,
+ 'session.use_cookies' => 1,
+ 'session.cookie_path' => self::$path,
+ 'session.save_handler' => 'user',
+ ),
+ 'handler' => array(
+ 'engine' => 'CacheSession',
+ 'config' => 'default'
+ )
+ ),
+ 'database' => array(
+ 'cookie' => 'CAKEPHP',
+ 'timeout' => 240,
+ 'ini' => array(
+ 'session.use_trans_sid' => 0,
+ 'url_rewriter.tags' => '',
+ 'session.auto_start' => 0,
+ 'session.use_cookies' => 1,
+ 'session.cookie_path' => self::$path,
+ 'session.save_handler' => 'user',
+ 'session.serialize_handler' => 'php',
+ ),
+ 'handler' => array(
+ 'engine' => 'DatabaseSession',
+ 'model' => 'Session'
+ )
+ )
+ );
+ if (isset($defaults[$name])) {
+ return $defaults[$name];
+ }
+ return false;
+ }
+
+/**
+ * Helper method to start a session
+ *
+ * @return boolean Success
+ */
+ protected static function _startSession() {
+ if (headers_sent()) {
+ if (empty($_SESSION)) {
+ $_SESSION = array();
+ }
+ } else {
+ // For IE<=8
+ session_cache_limiter("must-revalidate");
+ session_start();
+ }
+ return true;
+ }
+
+/**
+ * Helper method to create a new session.
+ *
+ * @return void
+ */
+ protected static function _checkValid() {
+ if (!self::started() && !self::start()) {
+ self::$valid = false;
+ return false;
+ }
+ if ($config = self::read('Config')) {
+ $sessionConfig = Configure::read('Session');
+
+ if (self::_validAgentAndTime()) {
+ self::write('Config.time', self::$sessionTime);
+ if (isset($sessionConfig['autoRegenerate']) && $sessionConfig['autoRegenerate'] === true) {
+ $check = $config['countdown'];
+ $check -= 1;
+ self::write('Config.countdown', $check);
+
+ if ($check < 1) {
+ self::renew();
+ self::write('Config.countdown', self::$requestCountdown);
+ }
+ }
+ self::$valid = true;
+ } else {
+ self::destroy();
+ self::$valid = false;
+ self::_setError(1, 'Session Highjacking Attempted !!!');
+ }
+ } else {
+ self::write('Config.userAgent', self::$_userAgent);
+ self::write('Config.time', self::$sessionTime);
+ self::write('Config.countdown', self::$requestCountdown);
+ self::$valid = true;
+ }
+ }
+
+/**
+ * Restarts this session.
+ *
+ * @return void
+ */
+ public static function renew() {
+ if (session_id()) {
+ if (session_id() != '' || isset($_COOKIE[session_name()])) {
+ setcookie(Configure::read('Session.cookie'), '', time() - 42000, self::$path);
+ }
+ session_regenerate_id(true);
+ }
+ }
+
+/**
+ * Helper method to set an internal error message.
+ *
+ * @param integer $errorNumber Number of the error
+ * @param string $errorMessage Description of the error
+ * @return void
+ */
+ protected static function _setError($errorNumber, $errorMessage) {
+ if (self::$error === false) {
+ self::$error = array();
+ }
+ self::$error[$errorNumber] = $errorMessage;
+ self::$lastError = $errorNumber;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DataSource.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DataSource.php
new file mode 100644
index 0000000..e5e665f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DataSource.php
@@ -0,0 +1,442 @@
+<?php
+/**
+ * DataSource base class
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource
+ * @since CakePHP(tm) v 0.10.5.1790
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * DataSource base class
+ *
+ * @package Cake.Model.Datasource
+ */
+class DataSource extends Object {
+
+/**
+ * Are we connected to the DataSource?
+ *
+ * @var boolean
+ */
+ public $connected = false;
+
+/**
+ * The default configuration of a specific DataSource
+ *
+ * @var array
+ */
+ protected $_baseConfig = array();
+
+/**
+ * Holds references to descriptions loaded by the DataSource
+ *
+ * @var array
+ */
+ protected $_descriptions = array();
+
+/**
+ * Holds a list of sources (tables) contained in the DataSource
+ *
+ * @var array
+ */
+ protected $_sources = null;
+
+/**
+ * The DataSource configuration
+ *
+ * @var array
+ */
+ public $config = array();
+
+/**
+ * Whether or not this DataSource is in the middle of a transaction
+ *
+ * @var boolean
+ */
+ protected $_transactionStarted = false;
+
+/**
+ * Whether or not source data like available tables and schema descriptions
+ * should be cached
+ *
+ * @var boolean
+ */
+ public $cacheSources = true;
+
+/**
+ * Constructor.
+ *
+ * @param array $config Array of configuration information for the datasource.
+ */
+ public function __construct($config = array()) {
+ parent::__construct();
+ $this->setConfig($config);
+ }
+
+/**
+ * Caches/returns cached results for child instances
+ *
+ * @param mixed $data
+ * @return array Array of sources available in this datasource.
+ */
+ public function listSources($data = null) {
+ if ($this->cacheSources === false) {
+ return null;
+ }
+
+ if ($this->_sources !== null) {
+ return $this->_sources;
+ }
+
+ $key = ConnectionManager::getSourceName($this) . '_' . $this->config['database'] . '_list';
+ $key = preg_replace('/[^A-Za-z0-9_\-.+]/', '_', $key);
+ $sources = Cache::read($key, '_cake_model_');
+
+ if (empty($sources)) {
+ $sources = $data;
+ Cache::write($key, $data, '_cake_model_');
+ }
+
+ return $this->_sources = $sources;
+ }
+
+/**
+ * Returns a Model description (metadata) or null if none found.
+ *
+ * @param Model|string $model
+ * @return array Array of Metadata for the $model
+ */
+ public function describe($model) {
+ if ($this->cacheSources === false) {
+ return null;
+ }
+ if (is_string($model)) {
+ $table = $model;
+ } else {
+ $table = $model->tablePrefix . $model->table;
+ }
+
+ if (isset($this->_descriptions[$table])) {
+ return $this->_descriptions[$table];
+ }
+ $cache = $this->_cacheDescription($table);
+
+ if ($cache !== null) {
+ $this->_descriptions[$table] =& $cache;
+ return $cache;
+ }
+ return null;
+ }
+
+/**
+ * Begin a transaction
+ *
+ * @return boolean Returns true if a transaction is not in progress
+ */
+ public function begin() {
+ return !$this->_transactionStarted;
+ }
+
+/**
+ * Commit a transaction
+ *
+ * @return boolean Returns true if a transaction is in progress
+ */
+ public function commit() {
+ return $this->_transactionStarted;
+ }
+
+/**
+ * Rollback a transaction
+ *
+ * @return boolean Returns true if a transaction is in progress
+ */
+ public function rollback() {
+ return $this->_transactionStarted;
+ }
+
+/**
+ * Converts column types to basic types
+ *
+ * @param string $real Real column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ public function column($real) {
+ return false;
+ }
+
+/**
+ * Used to create new records. The "C" CRUD.
+ *
+ * To-be-overridden in subclasses.
+ *
+ * @param Model $model The Model to be created.
+ * @param array $fields An Array of fields to be saved.
+ * @param array $values An Array of values to save.
+ * @return boolean success
+ */
+ public function create(Model $model, $fields = null, $values = null) {
+ return false;
+ }
+
+/**
+ * Used to read records from the Datasource. The "R" in CRUD
+ *
+ * To-be-overridden in subclasses.
+ *
+ * @param Model $model The model being read.
+ * @param array $queryData An array of query data used to find the data you want
+ * @return mixed
+ */
+ public function read(Model $model, $queryData = array()) {
+ return false;
+ }
+
+/**
+ * Update a record(s) in the datasource.
+ *
+ * To-be-overridden in subclasses.
+ *
+ * @param Model $model Instance of the model class being updated
+ * @param array $fields Array of fields to be updated
+ * @param array $values Array of values to be update $fields to.
+ * @return boolean Success
+ */
+ public function update(Model $model, $fields = null, $values = null) {
+ return false;
+ }
+
+/**
+ * Delete a record(s) in the datasource.
+ *
+ * To-be-overridden in subclasses.
+ *
+ * @param Model $model The model class having record(s) deleted
+ * @param mixed $conditions The conditions to use for deleting.
+ * @return void
+ */
+ public function delete(Model $model, $id = null) {
+ return false;
+ }
+
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param mixed $source
+ * @return mixed Last ID key generated in previous INSERT
+ */
+ public function lastInsertId($source = null) {
+ return false;
+ }
+
+/**
+ * Returns the number of rows returned by last operation.
+ *
+ * @param mixed $source
+ * @return integer Number of rows returned by last operation
+ */
+ public function lastNumRows($source = null) {
+ return false;
+ }
+
+/**
+ * Returns the number of rows affected by last query.
+ *
+ * @param mixed $source
+ * @return integer Number of rows affected by last query.
+ */
+ public function lastAffected($source = null) {
+ return false;
+ }
+
+/**
+ * Check whether the conditions for the Datasource being available
+ * are satisfied. Often used from connect() to check for support
+ * before establishing a connection.
+ *
+ * @return boolean Whether or not the Datasources conditions for use are met.
+ */
+ public function enabled() {
+ return true;
+ }
+
+/**
+ * Sets the configuration for the DataSource.
+ * Merges the $config information with the _baseConfig and the existing $config property.
+ *
+ * @param array $config The configuration array
+ * @return void
+ */
+ public function setConfig($config = array()) {
+ $this->config = array_merge($this->_baseConfig, $this->config, $config);
+ }
+
+/**
+ * Cache the DataSource description
+ *
+ * @param string $object The name of the object (model) to cache
+ * @param mixed $data The description of the model, usually a string or array
+ * @return mixed
+ */
+ protected function _cacheDescription($object, $data = null) {
+ if ($this->cacheSources === false) {
+ return null;
+ }
+
+ if ($data !== null) {
+ $this->_descriptions[$object] =& $data;
+ }
+
+ $key = ConnectionManager::getSourceName($this) . '_' . $object;
+ $cache = Cache::read($key, '_cake_model_');
+
+ if (empty($cache)) {
+ $cache = $data;
+ Cache::write($key, $cache, '_cake_model_');
+ }
+
+ return $cache;
+ }
+
+/**
+ * Replaces `{$__cakeID__$}` and `{$__cakeForeignKey__$}` placeholders in query data.
+ *
+ * @param string $query Query string needing replacements done.
+ * @param array $data Array of data with values that will be inserted in placeholders.
+ * @param string $association Name of association model being replaced
+ * @param array $assocData
+ * @param Model $model Instance of the model to replace $__cakeID__$
+ * @param Model $linkModel Instance of model to replace $__cakeForeignKey__$
+ * @param array $stack
+ * @return string String of query data with placeholders replaced.
+ * @todo Remove and refactor $assocData, ensure uses of the method have the param removed too.
+ */
+ public function insertQueryData($query, $data, $association, $assocData, Model $model, Model $linkModel, $stack) {
+ $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}');
+
+ foreach ($keys as $key) {
+ $val = null;
+ $type = null;
+
+ if (strpos($query, $key) !== false) {
+ switch ($key) {
+ case '{$__cakeID__$}':
+ if (isset($data[$model->alias]) || isset($data[$association])) {
+ if (isset($data[$model->alias][$model->primaryKey])) {
+ $val = $data[$model->alias][$model->primaryKey];
+ } elseif (isset($data[$association][$model->primaryKey])) {
+ $val = $data[$association][$model->primaryKey];
+ }
+ } else {
+ $found = false;
+ foreach (array_reverse($stack) as $assoc) {
+ if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
+ $val = $data[$assoc][$model->primaryKey];
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ $val = '';
+ }
+ }
+ $type = $model->getColumnType($model->primaryKey);
+ break;
+ case '{$__cakeForeignKey__$}':
+ foreach ($model->associations() as $id => $name) {
+ foreach ($model->$name as $assocName => $assoc) {
+ if ($assocName === $association) {
+ if (isset($assoc['foreignKey'])) {
+ $foreignKey = $assoc['foreignKey'];
+ $assocModel = $model->$assocName;
+ $type = $assocModel->getColumnType($assocModel->primaryKey);
+
+ if (isset($data[$model->alias][$foreignKey])) {
+ $val = $data[$model->alias][$foreignKey];
+ } elseif (isset($data[$association][$foreignKey])) {
+ $val = $data[$association][$foreignKey];
+ } else {
+ $found = false;
+ foreach (array_reverse($stack) as $assoc) {
+ if (isset($data[$assoc]) && isset($data[$assoc][$foreignKey])) {
+ $val = $data[$assoc][$foreignKey];
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ $val = '';
+ }
+ }
+ }
+ break 3;
+ }
+ }
+ }
+ break;
+ }
+ if (empty($val) && $val !== '0') {
+ return false;
+ }
+ $query = str_replace($key, $this->value($val, $type), $query);
+ }
+ }
+ return $query;
+ }
+
+/**
+ * To-be-overridden in subclasses.
+ *
+ * @param Model $model Model instance
+ * @param string $key Key name to make
+ * @return string Key name for model.
+ */
+ public function resolveKey(Model $model, $key) {
+ return $model->alias . $key;
+ }
+
+/**
+ * Returns the schema name. Override this in subclasses.
+ *
+ * @return string schema name
+ * @access public
+ */
+ public function getSchemaName() {
+ return null;
+ }
+
+/**
+ * Closes a connection. Override in subclasses
+ *
+ * @return boolean
+ * @access public
+ */
+ public function close() {
+ return $this->connected = false;
+ }
+
+/**
+ * Closes the current datasource.
+ *
+ */
+ public function __destruct() {
+ if ($this->_transactionStarted) {
+ $this->rollback();
+ }
+ if ($this->connected) {
+ $this->close();
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Mysql.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Mysql.php
new file mode 100644
index 0000000..9506a8a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Mysql.php
@@ -0,0 +1,688 @@
+<?php
+/**
+ * MySQL layer for DBO
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource.Database
+ * @since CakePHP(tm) v 0.10.5.1790
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DboSource', 'Model/Datasource');
+
+/**
+ * MySQL DBO driver object
+ *
+ * Provides connection and SQL generation for MySQL RDMS
+ *
+ * @package Cake.Model.Datasource.Database
+ */
+class Mysql extends DboSource {
+
+/**
+ * Datasource description
+ *
+ * @var string
+ */
+ public $description = "MySQL DBO Driver";
+
+/**
+ * Base configuration settings for MySQL driver
+ *
+ * @var array
+ */
+ protected $_baseConfig = array(
+ 'persistent' => true,
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => '',
+ 'database' => 'cake',
+ 'port' => '3306'
+ );
+
+/**
+ * Reference to the PDO object connection
+ *
+ * @var PDO $_connection
+ */
+ protected $_connection = null;
+
+/**
+ * Start quote
+ *
+ * @var string
+ */
+ public $startQuote = "`";
+
+/**
+ * End quote
+ *
+ * @var string
+ */
+ public $endQuote = "`";
+
+/**
+ * use alias for update and delete. Set to true if version >= 4.1
+ *
+ * @var boolean
+ */
+ protected $_useAlias = true;
+
+/**
+ * List of engine specific additional field parameters used on table creating
+ *
+ * @var array
+ */
+ public $fieldParameters = array(
+ 'charset' => array('value' => 'CHARACTER SET', 'quote' => false, 'join' => ' ', 'column' => false, 'position' => 'beforeDefault'),
+ 'collate' => array('value' => 'COLLATE', 'quote' => false, 'join' => ' ', 'column' => 'Collation', 'position' => 'beforeDefault'),
+ 'comment' => array('value' => 'COMMENT', 'quote' => true, 'join' => ' ', 'column' => 'Comment', 'position' => 'afterDefault')
+ );
+
+/**
+ * List of table engine specific parameters used on table creating
+ *
+ * @var array
+ */
+ public $tableParameters = array(
+ 'charset' => array('value' => 'DEFAULT CHARSET', 'quote' => false, 'join' => '=', 'column' => 'charset'),
+ 'collate' => array('value' => 'COLLATE', 'quote' => false, 'join' => '=', 'column' => 'Collation'),
+ 'engine' => array('value' => 'ENGINE', 'quote' => false, 'join' => '=', 'column' => 'Engine')
+ );
+
+/**
+ * MySQL column definition
+ *
+ * @var array
+ */
+ public $columns = array(
+ 'primary_key' => array('name' => 'NOT NULL AUTO_INCREMENT'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'blob'),
+ 'boolean' => array('name' => 'tinyint', 'limit' => '1')
+ );
+
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return boolean True if the database could be connected, else false
+ * @throws MissingConnectionException
+ */
+ public function connect() {
+ $config = $this->config;
+ $this->connected = false;
+ try {
+ $flags = array(
+ PDO::ATTR_PERSISTENT => $config['persistent'],
+ PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
+ );
+ if (!empty($config['encoding'])) {
+ $flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding'];
+ }
+ if (empty($config['unix_socket'])) {
+ $dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}";
+ } else {
+ $dsn = "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}";
+ }
+ $this->_connection = new PDO(
+ $dsn,
+ $config['login'],
+ $config['password'],
+ $flags
+ );
+ $this->connected = true;
+ } catch (PDOException $e) {
+ throw new MissingConnectionException(array('class' => $e->getMessage()));
+ }
+
+ $this->_useAlias = (bool)version_compare($this->getVersion(), "4.1", ">=");
+
+ return $this->connected;
+ }
+
+/**
+ * Check whether the MySQL extension is installed/loaded
+ *
+ * @return boolean
+ */
+ public function enabled() {
+ return in_array('mysql', PDO::getAvailableDrivers());
+ }
+
+/**
+ * Returns an array of sources (tables) in the database.
+ *
+ * @param mixed $data
+ * @return array Array of table names in the database
+ */
+ public function listSources($data = null) {
+ $cache = parent::listSources();
+ if ($cache != null) {
+ return $cache;
+ }
+ $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']));
+
+ if (!$result) {
+ $result->closeCursor();
+ return array();
+ } else {
+ $tables = array();
+
+ while ($line = $result->fetch(PDO::FETCH_NUM)) {
+ $tables[] = $line[0];
+ }
+
+ $result->closeCursor();
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+
+/**
+ * Builds a map of the columns contained in a result
+ *
+ * @param PDOStatement $results
+ * @return void
+ */
+ public function resultSet($results) {
+ $this->map = array();
+ $numFields = $results->columnCount();
+ $index = 0;
+
+ while ($numFields-- > 0) {
+ $column = $results->getColumnMeta($index);
+ if (empty($column['native_type'])) {
+ $type = ($column['len'] == 1) ? 'boolean' : 'string';
+ } else {
+ $type = $column['native_type'];
+ }
+ if (!empty($column['table']) && strpos($column['name'], $this->virtualFieldSeparator) === false) {
+ $this->map[$index++] = array($column['table'], $column['name'], $type);
+ } else {
+ $this->map[$index++] = array(0, $column['name'], $type);
+ }
+ }
+ }
+
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return mixed array with results fetched and mapped to column names or false if there is no results left to fetch
+ */
+ public function fetchResult() {
+ if ($row = $this->_result->fetch(PDO::FETCH_NUM)) {
+ $resultRow = array();
+ foreach ($this->map as $col => $meta) {
+ list($table, $column, $type) = $meta;
+ $resultRow[$table][$column] = $row[$col];
+ if ($type === 'boolean' && $row[$col] !== null) {
+ $resultRow[$table][$column] = $this->boolean($resultRow[$table][$column]);
+ }
+ }
+ return $resultRow;
+ }
+ $this->_result->closeCursor();
+ return false;
+ }
+
+/**
+ * Gets the database encoding
+ *
+ * @return string The database encoding
+ */
+ public function getEncoding() {
+ return $this->_execute('SHOW VARIABLES LIKE ?', array('character_set_client'))->fetchObject()->Value;
+ }
+
+/**
+ * Query charset by collation
+ *
+ * @param string $name Collation name
+ * @return string Character set name
+ */
+ public function getCharsetName($name) {
+ if ((bool)version_compare($this->getVersion(), "5", ">=")) {
+ $r = $this->_execute('SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME = ?', array($name));
+ $cols = $r->fetch(PDO::FETCH_ASSOC);
+
+ if (isset($cols['CHARACTER_SET_NAME'])) {
+ return $cols['CHARACTER_SET_NAME'];
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param Model|string $model Name of database table to inspect or model instance
+ * @return array Fields in table. Keys are name and type
+ * @throws CakeException
+ */
+ public function describe($model) {
+ $key = $this->fullTableName($model, false);
+ $cache = parent::describe($key);
+ if ($cache != null) {
+ return $cache;
+ }
+ $table = $this->fullTableName($model);
+
+ $fields = false;
+ $cols = $this->_execute('SHOW FULL COLUMNS FROM ' . $table);
+ if (!$cols) {
+ throw new CakeException(__d('cake_dev', 'Could not describe table for %s', $table));
+ }
+
+ while ($column = $cols->fetch(PDO::FETCH_OBJ)) {
+ $fields[$column->Field] = array(
+ 'type' => $this->column($column->Type),
+ 'null' => ($column->Null === 'YES' ? true : false),
+ 'default' => $column->Default,
+ 'length' => $this->length($column->Type),
+ );
+ if (!empty($column->Key) && isset($this->index[$column->Key])) {
+ $fields[$column->Field]['key'] = $this->index[$column->Key];
+ }
+ foreach ($this->fieldParameters as $name => $value) {
+ if (!empty($column->{$value['column']})) {
+ $fields[$column->Field][$name] = $column->{$value['column']};
+ }
+ }
+ if (isset($fields[$column->Field]['collate'])) {
+ $charset = $this->getCharsetName($fields[$column->Field]['collate']);
+ if ($charset) {
+ $fields[$column->Field]['charset'] = $charset;
+ }
+ }
+ }
+ $this->_cacheDescription($key, $fields);
+ $cols->closeCursor();
+ return $fields;
+ }
+
+/**
+ * Generates and executes an SQL UPDATE statement for given model, fields, and values.
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @param mixed $conditions
+ * @return array
+ */
+ public function update(Model $model, $fields = array(), $values = null, $conditions = null) {
+ if (!$this->_useAlias) {
+ return parent::update($model, $fields, $values, $conditions);
+ }
+
+ if ($values == null) {
+ $combined = $fields;
+ } else {
+ $combined = array_combine($fields, $values);
+ }
+
+ $alias = $joins = false;
+ $fields = $this->_prepareUpdateFields($model, $combined, empty($conditions), !empty($conditions));
+ $fields = implode(', ', $fields);
+ $table = $this->fullTableName($model);
+
+ if (!empty($conditions)) {
+ $alias = $this->name($model->alias);
+ if ($model->name == $model->alias) {
+ $joins = implode(' ', $this->_getJoins($model));
+ }
+ }
+ $conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model);
+
+ if ($conditions === false) {
+ return false;
+ }
+
+ if (!$this->execute($this->renderStatement('update', compact('table', 'alias', 'joins', 'fields', 'conditions')))) {
+ $model->onError();
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Generates and executes an SQL DELETE statement for given id/conditions on given model.
+ *
+ * @param Model $model
+ * @param mixed $conditions
+ * @return boolean Success
+ */
+ public function delete(Model $model, $conditions = null) {
+ if (!$this->_useAlias) {
+ return parent::delete($model, $conditions);
+ }
+ $alias = $this->name($model->alias);
+ $table = $this->fullTableName($model);
+ $joins = implode(' ', $this->_getJoins($model));
+
+ if (empty($conditions)) {
+ $alias = $joins = false;
+ }
+ $complexConditions = false;
+ foreach ((array)$conditions as $key => $value) {
+ if (strpos($key, $model->alias) === false) {
+ $complexConditions = true;
+ break;
+ }
+ }
+ if (!$complexConditions) {
+ $joins = false;
+ }
+
+ $conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model);
+ if ($conditions === false) {
+ return false;
+ }
+ if ($this->execute($this->renderStatement('delete', compact('alias', 'table', 'joins', 'conditions'))) === false) {
+ $model->onError();
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Sets the database encoding
+ *
+ * @param string $enc Database encoding
+ * @return boolean
+ */
+ public function setEncoding($enc) {
+ return $this->_execute('SET NAMES ' . $enc) !== false;
+ }
+
+/**
+ * Returns an array of the indexes in given datasource name.
+ *
+ * @param string $model Name of model to inspect
+ * @return array Fields in table. Keys are column and unique
+ */
+ public function index($model) {
+ $index = array();
+ $table = $this->fullTableName($model);
+ $old = version_compare($this->getVersion(), '4.1', '<=');
+ if ($table) {
+ $indices = $this->_execute('SHOW INDEX FROM ' . $table);
+ // @codingStandardsIgnoreStart
+ // MySQL columns don't match the cakephp conventions.
+ while ($idx = $indices->fetch(PDO::FETCH_OBJ)) {
+ if ($old) {
+ $idx = (object)current((array)$idx);
+ }
+ if (!isset($index[$idx->Key_name]['column'])) {
+ $col = array();
+ $index[$idx->Key_name]['column'] = $idx->Column_name;
+ $index[$idx->Key_name]['unique'] = intval($idx->Non_unique == 0);
+ } else {
+ if (!empty($index[$idx->Key_name]['column']) && !is_array($index[$idx->Key_name]['column'])) {
+ $col[] = $index[$idx->Key_name]['column'];
+ }
+ $col[] = $idx->Column_name;
+ $index[$idx->Key_name]['column'] = $col;
+ }
+ }
+ // @codingStandardsIgnoreEnd
+ $indices->closeCursor();
+ }
+ return $index;
+ }
+
+/**
+ * Generate a MySQL Alter Table syntax for the given Schema comparison
+ *
+ * @param array $compare Result of a CakeSchema::compare()
+ * @param string $table
+ * @return array Array of alter statements to make.
+ */
+ public function alterSchema($compare, $table = null) {
+ if (!is_array($compare)) {
+ return false;
+ }
+ $out = '';
+ $colList = array();
+ foreach ($compare as $curTable => $types) {
+ $indexes = $tableParameters = $colList = array();
+ if (!$table || $table == $curTable) {
+ $out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n";
+ foreach ($types as $type => $column) {
+ if (isset($column['indexes'])) {
+ $indexes[$type] = $column['indexes'];
+ unset($column['indexes']);
+ }
+ if (isset($column['tableParameters'])) {
+ $tableParameters[$type] = $column['tableParameters'];
+ unset($column['tableParameters']);
+ }
+ switch ($type) {
+ case 'add':
+ foreach ($column as $field => $col) {
+ $col['name'] = $field;
+ $alter = 'ADD ' . $this->buildColumn($col);
+ if (isset($col['after'])) {
+ $alter .= ' AFTER ' . $this->name($col['after']);
+ }
+ $colList[] = $alter;
+ }
+ break;
+ case 'drop':
+ foreach ($column as $field => $col) {
+ $col['name'] = $field;
+ $colList[] = 'DROP ' . $this->name($field);
+ }
+ break;
+ case 'change':
+ foreach ($column as $field => $col) {
+ if (!isset($col['name'])) {
+ $col['name'] = $field;
+ }
+ $colList[] = 'CHANGE ' . $this->name($field) . ' ' . $this->buildColumn($col);
+ }
+ break;
+ }
+ }
+ $colList = array_merge($colList, $this->_alterIndexes($curTable, $indexes));
+ $colList = array_merge($colList, $this->_alterTableParameters($curTable, $tableParameters));
+ $out .= "\t" . implode(",\n\t", $colList) . ";\n\n";
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Generate a MySQL "drop table" statement for the given Schema object
+ *
+ * @param CakeSchema $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ public function dropSchema(CakeSchema $schema, $table = null) {
+ $out = '';
+ foreach ($schema->tables as $curTable => $columns) {
+ if (!$table || $table === $curTable) {
+ $out .= 'DROP TABLE IF EXISTS ' . $this->fullTableName($curTable) . ";\n";
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Generate MySQL table parameter alteration statements for a table.
+ *
+ * @param string $table Table to alter parameters for.
+ * @param array $parameters Parameters to add & drop.
+ * @return array Array of table property alteration statements.
+ * @todo Implement this method.
+ */
+ protected function _alterTableParameters($table, $parameters) {
+ if (isset($parameters['change'])) {
+ return $this->buildTableParameters($parameters['change']);
+ }
+ return array();
+ }
+
+/**
+ * Generate MySQL index alteration statements for a table.
+ *
+ * @param string $table Table to alter indexes for
+ * @param array $indexes Indexes to add and drop
+ * @return array Index alteration statements
+ */
+ protected function _alterIndexes($table, $indexes) {
+ $alter = array();
+ if (isset($indexes['drop'])) {
+ foreach ($indexes['drop'] as $name => $value) {
+ $out = 'DROP ';
+ if ($name == 'PRIMARY') {
+ $out .= 'PRIMARY KEY';
+ } else {
+ $out .= 'KEY ' . $name;
+ }
+ $alter[] = $out;
+ }
+ }
+ if (isset($indexes['add'])) {
+ foreach ($indexes['add'] as $name => $value) {
+ $out = 'ADD ';
+ if ($name == 'PRIMARY') {
+ $out .= 'PRIMARY ';
+ $name = null;
+ } else {
+ if (!empty($value['unique'])) {
+ $out .= 'UNIQUE ';
+ }
+ }
+ if (is_array($value['column'])) {
+ $out .= 'KEY ' . $name . ' (' . implode(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
+ } else {
+ $out .= 'KEY ' . $name . ' (' . $this->name($value['column']) . ')';
+ }
+ $alter[] = $out;
+ }
+ }
+ return $alter;
+ }
+
+/**
+ * Returns an detailed array of sources (tables) in the database.
+ *
+ * @param string $name Table name to get parameters
+ * @return array Array of table names in the database
+ */
+ public function listDetailedSources($name = null) {
+ $condition = '';
+ if (is_string($name)) {
+ $condition = ' WHERE name = ' . $this->value($name);
+ }
+ $result = $this->_connection->query('SHOW TABLE STATUS ' . $condition, PDO::FETCH_ASSOC);
+
+ if (!$result) {
+ $result->closeCursor();
+ return array();
+ } else {
+ $tables = array();
+ foreach ($result as $row) {
+ $tables[$row['Name']] = (array)$row;
+ unset($tables[$row['Name']]['queryString']);
+ if (!empty($row['Collation'])) {
+ $charset = $this->getCharsetName($row['Collation']);
+ if ($charset) {
+ $tables[$row['Name']]['charset'] = $charset;
+ }
+ }
+ }
+ $result->closeCursor();
+ if (is_string($name) && isset($tables[$name])) {
+ return $tables[$name];
+ }
+ return $tables;
+ }
+ }
+
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ public function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+ if (isset($real['limit'])) {
+ $col .= '(' . $real['limit'] . ')';
+ }
+ return $col;
+ }
+
+ $col = str_replace(')', '', $real);
+ $limit = $this->length($real);
+ if (strpos($col, '(') !== false) {
+ list($col, $vals) = explode('(', $col);
+ }
+
+ if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
+ return $col;
+ }
+ if (($col === 'tinyint' && $limit == 1) || $col === 'boolean') {
+ return 'boolean';
+ }
+ if (strpos($col, 'int') !== false) {
+ return 'integer';
+ }
+ if (strpos($col, 'char') !== false || $col === 'tinytext') {
+ return 'string';
+ }
+ if (strpos($col, 'text') !== false) {
+ return 'text';
+ }
+ if (strpos($col, 'blob') !== false || $col === 'binary') {
+ return 'binary';
+ }
+ if (strpos($col, 'float') !== false || strpos($col, 'double') !== false || strpos($col, 'decimal') !== false) {
+ return 'float';
+ }
+ if (strpos($col, 'enum') !== false) {
+ return "enum($vals)";
+ }
+ return 'text';
+ }
+
+/**
+ * Gets the schema name
+ *
+ * @return string The schema name
+ */
+ public function getSchemaName() {
+ return $this->config['database'];
+ }
+
+/**
+ * Check if the server support nested transactions
+ *
+ * @return boolean
+ */
+ public function nestedTransactionSupported() {
+ return $this->useNestedTransactions && version_compare($this->getVersion(), '4.1', '>=');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Postgres.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Postgres.php
new file mode 100644
index 0000000..74da346
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Postgres.php
@@ -0,0 +1,907 @@
+<?php
+/**
+ * PostgreSQL layer for DBO.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource.Database
+ * @since CakePHP(tm) v 0.9.1.114
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DboSource', 'Model/Datasource');
+
+/**
+ * PostgreSQL layer for DBO.
+ *
+ * @package Cake.Model.Datasource.Database
+ */
+class Postgres extends DboSource {
+
+/**
+ * Driver description
+ *
+ * @var string
+ */
+ public $description = "PostgreSQL DBO Driver";
+
+/**
+ * Base driver configuration settings. Merged with user settings.
+ *
+ * @var array
+ */
+ protected $_baseConfig = array(
+ 'persistent' => true,
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => '',
+ 'database' => 'cake',
+ 'schema' => 'public',
+ 'port' => 5432,
+ 'encoding' => ''
+ );
+
+/**
+ * Columns
+ *
+ * @var array
+ */
+ public $columns = array(
+ 'primary_key' => array('name' => 'serial NOT NULL'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'integer', 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'bytea'),
+ 'boolean' => array('name' => 'boolean'),
+ 'number' => array('name' => 'numeric'),
+ 'inet' => array('name' => 'inet')
+ );
+
+/**
+ * Starting Quote
+ *
+ * @var string
+ */
+ public $startQuote = '"';
+
+/**
+ * Ending Quote
+ *
+ * @var string
+ */
+ public $endQuote = '"';
+
+/**
+ * Contains mappings of custom auto-increment sequences, if a table uses a sequence name
+ * other than what is dictated by convention.
+ *
+ * @var array
+ */
+ protected $_sequenceMap = array();
+
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return boolean True if successfully connected.
+ * @throws MissingConnectionException
+ */
+ public function connect() {
+ $config = $this->config;
+ $this->connected = false;
+ try {
+ $flags = array(
+ PDO::ATTR_PERSISTENT => $config['persistent'],
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
+ );
+ $this->_connection = new PDO(
+ "pgsql:host={$config['host']};port={$config['port']};dbname={$config['database']}",
+ $config['login'],
+ $config['password'],
+ $flags
+ );
+
+ $this->connected = true;
+ if (!empty($config['encoding'])) {
+ $this->setEncoding($config['encoding']);
+ }
+ if (!empty($config['schema'])) {
+ $this->_execute('SET search_path TO ' . $config['schema']);
+ }
+ } catch (PDOException $e) {
+ throw new MissingConnectionException(array('class' => $e->getMessage()));
+ }
+
+ return $this->connected;
+ }
+
+/**
+ * Check if PostgreSQL is enabled/loaded
+ *
+ * @return boolean
+ */
+ public function enabled() {
+ return in_array('pgsql', PDO::getAvailableDrivers());
+ }
+
+/**
+ * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
+ *
+ * @param mixed $data
+ * @return array Array of table names in the database
+ */
+ public function listSources($data = null) {
+ $cache = parent::listSources();
+
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $schema = $this->config['schema'];
+ $sql = "SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = ?";
+ $result = $this->_execute($sql, array($schema));
+
+ if (!$result) {
+ return array();
+ } else {
+ $tables = array();
+
+ foreach ($result as $item) {
+ $tables[] = $item->name;
+ }
+
+ $result->closeCursor();
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param Model|string $model Name of database table to inspect
+ * @return array Fields in table. Keys are name and type
+ */
+ public function describe($model) {
+ $table = $this->fullTableName($model, false, false);
+ $fields = parent::describe($table);
+ $this->_sequenceMap[$table] = array();
+ $cols = null;
+
+ if ($fields === null) {
+ $cols = $this->_execute(
+ "SELECT DISTINCT table_schema AS schema, column_name AS name, data_type AS type, is_nullable AS null,
+ column_default AS default, ordinal_position AS position, character_maximum_length AS char_length,
+ character_octet_length AS oct_length FROM information_schema.columns
+ WHERE table_name = ? AND table_schema = ? ORDER BY position",
+ array($table, $this->config['schema'])
+ );
+
+ // @codingStandardsIgnoreStart
+ // Postgres columns don't match the coding standards.
+ foreach ($cols as $c) {
+ $type = $c->type;
+ if (!empty($c->oct_length) && $c->char_length === null) {
+ if ($c->type == 'character varying') {
+ $length = null;
+ $type = 'text';
+ } elseif ($c->type == 'uuid') {
+ $length = 36;
+ } else {
+ $length = intval($c->oct_length);
+ }
+ } elseif (!empty($c->char_length)) {
+ $length = intval($c->char_length);
+ } else {
+ $length = $this->length($c->type);
+ }
+ if (empty($length)) {
+ $length = null;
+ }
+ $fields[$c->name] = array(
+ 'type' => $this->column($type),
+ 'null' => ($c->null == 'NO' ? false : true),
+ 'default' => preg_replace(
+ "/^'(.*)'$/",
+ "$1",
+ preg_replace('/::.*/', '', $c->default)
+ ),
+ 'length' => $length
+ );
+ if ($model instanceof Model) {
+ if ($c->name == $model->primaryKey) {
+ $fields[$c->name]['key'] = 'primary';
+ if ($fields[$c->name]['type'] !== 'string') {
+ $fields[$c->name]['length'] = 11;
+ }
+ }
+ }
+ if (
+ $fields[$c->name]['default'] == 'NULL' ||
+ preg_match('/nextval\([\'"]?([\w.]+)/', $c->default, $seq)
+ ) {
+ $fields[$c->name]['default'] = null;
+ if (!empty($seq) && isset($seq[1])) {
+ if (strpos($seq[1], '.') === false) {
+ $sequenceName = $c->schema . '.' . $seq[1];
+ } else {
+ $sequenceName = $seq[1];
+ }
+ $this->_sequenceMap[$table][$c->name] = $sequenceName;
+ }
+ }
+ if ($fields[$c->name]['type'] == 'boolean' && !empty($fields[$c->name]['default'])) {
+ $fields[$c->name]['default'] = constant($fields[$c->name]['default']);
+ }
+ }
+ $this->_cacheDescription($table, $fields);
+ }
+ // @codingStandardsIgnoreEnd
+
+ if (isset($model->sequence)) {
+ $this->_sequenceMap[$table][$model->primaryKey] = $model->sequence;
+ }
+
+ if ($cols) {
+ $cols->closeCursor();
+ }
+ return $fields;
+ }
+
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param string $source Name of the database table
+ * @param string $field Name of the ID database field. Defaults to "id"
+ * @return integer
+ */
+ public function lastInsertId($source = null, $field = 'id') {
+ $seq = $this->getSequence($source, $field);
+ return $this->_connection->lastInsertId($seq);
+ }
+
+/**
+ * Gets the associated sequence for the given table/field
+ *
+ * @param string|Model $table Either a full table name (with prefix) as a string, or a model object
+ * @param string $field Name of the ID database field. Defaults to "id"
+ * @return string The associated sequence name from the sequence map, defaults to "{$table}_{$field}_seq"
+ */
+ public function getSequence($table, $field = 'id') {
+ if (is_object($table)) {
+ $table = $this->fullTableName($table, false, false);
+ }
+ if (isset($this->_sequenceMap[$table]) && isset($this->_sequenceMap[$table][$field])) {
+ return $this->_sequenceMap[$table][$field];
+ } else {
+ return "{$table}_{$field}_seq";
+ }
+ }
+
+/**
+ * Deletes all the records in a table and drops all associated auto-increment sequences
+ *
+ * @param string|Model $table A string or model class representing the table to be truncated
+ * @param boolean $reset true for resetting the sequence, false to leave it as is.
+ * and if 1, sequences are not modified
+ * @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
+ */
+ public function truncate($table, $reset = false) {
+ $table = $this->fullTableName($table, false, false);
+ if (!isset($this->_sequenceMap[$table])) {
+ $cache = $this->cacheSources;
+ $this->cacheSources = false;
+ $this->describe($table);
+ $this->cacheSources = $cache;
+ }
+ if ($this->execute('DELETE FROM ' . $this->fullTableName($table))) {
+ $schema = $this->config['schema'];
+ if (isset($this->_sequenceMap[$table]) && $reset != true) {
+ foreach ($this->_sequenceMap[$table] as $field => $sequence) {
+ list($schema, $sequence) = explode('.', $sequence);
+ $this->_execute("ALTER SEQUENCE \"{$schema}\".\"{$sequence}\" RESTART WITH 1");
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Prepares field names to be quoted by parent
+ *
+ * @param string $data
+ * @return string SQL field
+ */
+ public function name($data) {
+ if (is_string($data)) {
+ $data = str_replace('"__"', '__', $data);
+ }
+ return parent::name($data);
+ }
+
+/**
+ * Generates the fields list of an SQL query.
+ *
+ * @param Model $model
+ * @param string $alias Alias table name
+ * @param mixed $fields
+ * @param boolean $quote
+ * @return array
+ */
+ public function fields(Model $model, $alias = null, $fields = array(), $quote = true) {
+ if (empty($alias)) {
+ $alias = $model->alias;
+ }
+ $fields = parent::fields($model, $alias, $fields, false);
+
+ if (!$quote) {
+ return $fields;
+ }
+ $count = count($fields);
+
+ if ($count >= 1 && !preg_match('/^\s*COUNT\(\*/', $fields[0])) {
+ $result = array();
+ for ($i = 0; $i < $count; $i++) {
+ if (!preg_match('/^.+\\(.*\\)/', $fields[$i]) && !preg_match('/\s+AS\s+/', $fields[$i])) {
+ if (substr($fields[$i], -1) == '*') {
+ if (strpos($fields[$i], '.') !== false && $fields[$i] != $alias . '.*') {
+ $build = explode('.', $fields[$i]);
+ $AssociatedModel = $model->{$build[0]};
+ } else {
+ $AssociatedModel = $model;
+ }
+
+ $_fields = $this->fields($AssociatedModel, $AssociatedModel->alias, array_keys($AssociatedModel->schema()));
+ $result = array_merge($result, $_fields);
+ continue;
+ }
+
+ $prepend = '';
+ if (strpos($fields[$i], 'DISTINCT') !== false) {
+ $prepend = 'DISTINCT ';
+ $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
+ }
+
+ if (strrpos($fields[$i], '.') === false) {
+ $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fields[$i]);
+ } else {
+ $build = explode('.', $fields[$i]);
+ $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $build[1]);
+ }
+ } else {
+ $fields[$i] = preg_replace_callback('/\(([\s\.\w]+)\)/', array(&$this, '_quoteFunctionField'), $fields[$i]);
+ }
+ $result[] = $fields[$i];
+ }
+ return $result;
+ }
+ return $fields;
+ }
+
+/**
+ * Auxiliary function to quote matched `(Model.fields)` from a preg_replace_callback call
+ * Quotes the fields in a function call.
+ *
+ * @param string $match matched string
+ * @return string quoted string
+ */
+ protected function _quoteFunctionField($match) {
+ $prepend = '';
+ if (strpos($match[1], 'DISTINCT') !== false) {
+ $prepend = 'DISTINCT ';
+ $match[1] = trim(str_replace('DISTINCT', '', $match[1]));
+ }
+ $constant = preg_match('/^\d+|NULL|FALSE|TRUE$/i', $match[1]);
+
+ if (!$constant && strpos($match[1], '.') === false) {
+ $match[1] = $this->name($match[1]);
+ } elseif (!$constant) {
+ $parts = explode('.', $match[1]);
+ if (!Hash::numeric($parts)) {
+ $match[1] = $this->name($match[1]);
+ }
+ }
+ return '(' . $prepend . $match[1] . ')';
+ }
+
+/**
+ * Returns an array of the indexes in given datasource name.
+ *
+ * @param string $model Name of model to inspect
+ * @return array Fields in table. Keys are column and unique
+ */
+ public function index($model) {
+ $index = array();
+ $table = $this->fullTableName($model, false, false);
+ if ($table) {
+ $indexes = $this->query("SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) as statement, c2.reltablespace
+ FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
+ WHERE c.oid = (
+ SELECT c.oid
+ FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
+ WHERE c.relname ~ '^(" . $table . ")$'
+ AND pg_catalog.pg_table_is_visible(c.oid)
+ AND n.nspname ~ '^(" . $this->config['schema'] . ")$'
+ )
+ AND c.oid = i.indrelid AND i.indexrelid = c2.oid
+ ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname", false);
+ foreach ($indexes as $i => $info) {
+ $key = array_pop($info);
+ if ($key['indisprimary']) {
+ $key['relname'] = 'PRIMARY';
+ }
+ preg_match('/\(([^\)]+)\)/', $key['statement'], $indexColumns);
+ $parsedColumn = $indexColumns[1];
+ if (strpos($indexColumns[1], ',') !== false) {
+ $parsedColumn = explode(', ', $indexColumns[1]);
+ }
+ $index[$key['relname']]['unique'] = $key['indisunique'];
+ $index[$key['relname']]['column'] = $parsedColumn;
+ }
+ }
+ return $index;
+ }
+
+/**
+ * Alter the Schema of a table.
+ *
+ * @param array $compare Results of CakeSchema::compare()
+ * @param string $table name of the table
+ * @return array
+ */
+ public function alterSchema($compare, $table = null) {
+ if (!is_array($compare)) {
+ return false;
+ }
+ $out = '';
+ $colList = array();
+ foreach ($compare as $curTable => $types) {
+ $indexes = $colList = array();
+ if (!$table || $table == $curTable) {
+ $out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n";
+ foreach ($types as $type => $column) {
+ if (isset($column['indexes'])) {
+ $indexes[$type] = $column['indexes'];
+ unset($column['indexes']);
+ }
+ switch ($type) {
+ case 'add':
+ foreach ($column as $field => $col) {
+ $col['name'] = $field;
+ $colList[] = 'ADD COLUMN ' . $this->buildColumn($col);
+ }
+ break;
+ case 'drop':
+ foreach ($column as $field => $col) {
+ $col['name'] = $field;
+ $colList[] = 'DROP COLUMN ' . $this->name($field);
+ }
+ break;
+ case 'change':
+ foreach ($column as $field => $col) {
+ if (!isset($col['name'])) {
+ $col['name'] = $field;
+ }
+ $fieldName = $this->name($field);
+
+ $default = isset($col['default']) ? $col['default'] : null;
+ $nullable = isset($col['null']) ? $col['null'] : null;
+ unset($col['default'], $col['null']);
+ $colList[] = 'ALTER COLUMN ' . $fieldName . ' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col));
+ if (isset($nullable)) {
+ $nullable = ($nullable) ? 'DROP NOT NULL' : 'SET NOT NULL';
+ $colList[] = 'ALTER COLUMN ' . $fieldName . ' ' . $nullable;
+ }
+
+ if (isset($default)) {
+ $colList[] = 'ALTER COLUMN ' . $fieldName . ' SET DEFAULT ' . $this->value($default, $col['type']);
+ } else {
+ $colList[] = 'ALTER COLUMN ' . $fieldName . ' DROP DEFAULT';
+ }
+
+ }
+ break;
+ }
+ }
+ if (isset($indexes['drop']['PRIMARY'])) {
+ $colList[] = 'DROP CONSTRAINT ' . $curTable . '_pkey';
+ }
+ if (isset($indexes['add']['PRIMARY'])) {
+ $cols = $indexes['add']['PRIMARY']['column'];
+ if (is_array($cols)) {
+ $cols = implode(', ', $cols);
+ }
+ $colList[] = 'ADD PRIMARY KEY (' . $cols . ')';
+ }
+
+ if (!empty($colList)) {
+ $out .= "\t" . implode(",\n\t", $colList) . ";\n\n";
+ } else {
+ $out = '';
+ }
+ $out .= implode(";\n\t", $this->_alterIndexes($curTable, $indexes));
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Generate PostgreSQL index alteration statements for a table.
+ *
+ * @param string $table Table to alter indexes for
+ * @param array $indexes Indexes to add and drop
+ * @return array Index alteration statements
+ */
+ protected function _alterIndexes($table, $indexes) {
+ $alter = array();
+ if (isset($indexes['drop'])) {
+ foreach ($indexes['drop'] as $name => $value) {
+ $out = 'DROP ';
+ if ($name == 'PRIMARY') {
+ continue;
+ } else {
+ $out .= 'INDEX ' . $name;
+ }
+ $alter[] = $out;
+ }
+ }
+ if (isset($indexes['add'])) {
+ foreach ($indexes['add'] as $name => $value) {
+ $out = 'CREATE ';
+ if ($name == 'PRIMARY') {
+ continue;
+ } else {
+ if (!empty($value['unique'])) {
+ $out .= 'UNIQUE ';
+ }
+ $out .= 'INDEX ';
+ }
+ if (is_array($value['column'])) {
+ $out .= $name . ' ON ' . $table . ' (' . implode(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
+ } else {
+ $out .= $name . ' ON ' . $table . ' (' . $this->name($value['column']) . ')';
+ }
+ $alter[] = $out;
+ }
+ }
+ return $alter;
+ }
+
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param integer $limit Limit of results returned
+ * @param integer $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ public function limit($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
+ $rt = ' LIMIT';
+ }
+
+ $rt .= ' ' . $limit;
+ if ($offset) {
+ $rt .= ' OFFSET ' . $offset;
+ }
+
+ return $rt;
+ }
+ return null;
+ }
+
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ public function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+ if (isset($real['limit'])) {
+ $col .= '(' . $real['limit'] . ')';
+ }
+ return $col;
+ }
+
+ $col = str_replace(')', '', $real);
+ $limit = null;
+
+ if (strpos($col, '(') !== false) {
+ list($col, $limit) = explode('(', $col);
+ }
+
+ $floats = array(
+ 'float', 'float4', 'float8', 'double', 'double precision', 'decimal', 'real', 'numeric'
+ );
+
+ switch (true) {
+ case (in_array($col, array('date', 'time', 'inet', 'boolean'))):
+ return $col;
+ case (strpos($col, 'timestamp') !== false):
+ return 'datetime';
+ case (strpos($col, 'time') === 0):
+ return 'time';
+ case (strpos($col, 'int') !== false && $col != 'interval'):
+ return 'integer';
+ case (strpos($col, 'char') !== false || $col == 'uuid'):
+ return 'string';
+ case (strpos($col, 'text') !== false):
+ return 'text';
+ case (strpos($col, 'bytea') !== false):
+ return 'binary';
+ case (in_array($col, $floats)):
+ return 'float';
+ default:
+ return 'text';
+ break;
+ }
+ }
+
+/**
+ * Gets the length of a database-native column description, or null if no length
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return integer An integer representing the length of the column
+ */
+ public function length($real) {
+ $col = str_replace(array(')', 'unsigned'), '', $real);
+ $limit = null;
+
+ if (strpos($col, '(') !== false) {
+ list($col, $limit) = explode('(', $col);
+ }
+ if ($col == 'uuid') {
+ return 36;
+ }
+ if ($limit != null) {
+ return intval($limit);
+ }
+ return null;
+ }
+
+/**
+ * resultSet method
+ *
+ * @param array $results
+ * @return void
+ */
+ public function resultSet(&$results) {
+ $this->map = array();
+ $numFields = $results->columnCount();
+ $index = 0;
+ $j = 0;
+
+ while ($j < $numFields) {
+ $column = $results->getColumnMeta($j);
+ if (strpos($column['name'], '__')) {
+ list($table, $name) = explode('__', $column['name']);
+ $this->map[$index++] = array($table, $name, $column['native_type']);
+ } else {
+ $this->map[$index++] = array(0, $column['name'], $column['native_type']);
+ }
+ $j++;
+ }
+ }
+
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return array
+ */
+ public function fetchResult() {
+ if ($row = $this->_result->fetch(PDO::FETCH_NUM)) {
+ $resultRow = array();
+
+ foreach ($this->map as $index => $meta) {
+ list($table, $column, $type) = $meta;
+
+ switch ($type) {
+ case 'bool':
+ $resultRow[$table][$column] = is_null($row[$index]) ? null : $this->boolean($row[$index]);
+ break;
+ case 'binary':
+ case 'bytea':
+ $resultRow[$table][$column] = is_null($row[$index]) ? null : stream_get_contents($row[$index]);
+ break;
+ default:
+ $resultRow[$table][$column] = $row[$index];
+ break;
+ }
+ }
+ return $resultRow;
+ } else {
+ $this->_result->closeCursor();
+ return false;
+ }
+ }
+
+/**
+ * Translates between PHP boolean values and PostgreSQL boolean values
+ *
+ * @param mixed $data Value to be translated
+ * @param boolean $quote true to quote a boolean to be used in a query, false to return the boolean value
+ * @return boolean Converted boolean value
+ */
+ public function boolean($data, $quote = false) {
+ switch (true) {
+ case ($data === true || $data === false):
+ $result = $data;
+ break;
+ case ($data === 't' || $data === 'f'):
+ $result = ($data === 't');
+ break;
+ case ($data === 'true' || $data === 'false'):
+ $result = ($data === 'true');
+ break;
+ case ($data === 'TRUE' || $data === 'FALSE'):
+ $result = ($data === 'TRUE');
+ break;
+ default:
+ $result = (bool)$data;
+ break;
+ }
+
+ if ($quote) {
+ return ($result) ? 'TRUE' : 'FALSE';
+ }
+ return (bool)$result;
+ }
+
+/**
+ * Sets the database encoding
+ *
+ * @param mixed $enc Database encoding
+ * @return boolean True on success, false on failure
+ */
+ public function setEncoding($enc) {
+ return $this->_execute('SET NAMES ' . $this->value($enc)) !== false;
+ }
+
+/**
+ * Gets the database encoding
+ *
+ * @return string The database encoding
+ */
+ public function getEncoding() {
+ $result = $this->_execute('SHOW client_encoding')->fetch();
+ if ($result === false) {
+ return false;
+ }
+ return (isset($result['client_encoding'])) ? $result['client_encoding'] : false;
+ }
+
+/**
+ * Generate a Postgres-native column schema string
+ *
+ * @param array $column An array structured like the following:
+ * array('name'=>'value', 'type'=>'value'[, options]),
+ * where options can be 'default', 'length', or 'key'.
+ * @return string
+ */
+ public function buildColumn($column) {
+ $col = $this->columns[$column['type']];
+ if (!isset($col['length']) && !isset($col['limit'])) {
+ unset($column['length']);
+ }
+ $out = preg_replace('/integer\([0-9]+\)/', 'integer', parent::buildColumn($column));
+ $out = str_replace('integer serial', 'serial', $out);
+ if (strpos($out, 'timestamp DEFAULT')) {
+ if (isset($column['null']) && $column['null']) {
+ $out = str_replace('DEFAULT NULL', '', $out);
+ } else {
+ $out = str_replace('DEFAULT NOT NULL', '', $out);
+ }
+ }
+ if (strpos($out, 'DEFAULT DEFAULT')) {
+ if (isset($column['null']) && $column['null']) {
+ $out = str_replace('DEFAULT DEFAULT', 'DEFAULT NULL', $out);
+ } elseif (in_array($column['type'], array('integer', 'float'))) {
+ $out = str_replace('DEFAULT DEFAULT', 'DEFAULT 0', $out);
+ } elseif ($column['type'] == 'boolean') {
+ $out = str_replace('DEFAULT DEFAULT', 'DEFAULT FALSE', $out);
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Format indexes for create table
+ *
+ * @param array $indexes
+ * @param string $table
+ * @return string
+ */
+ public function buildIndex($indexes, $table = null) {
+ $join = array();
+ if (!is_array($indexes)) {
+ return array();
+ }
+ foreach ($indexes as $name => $value) {
+ if ($name == 'PRIMARY') {
+ $out = 'PRIMARY KEY (' . $this->name($value['column']) . ')';
+ } else {
+ $out = 'CREATE ';
+ if (!empty($value['unique'])) {
+ $out .= 'UNIQUE ';
+ }
+ if (is_array($value['column'])) {
+ $value['column'] = implode(', ', array_map(array(&$this, 'name'), $value['column']));
+ } else {
+ $value['column'] = $this->name($value['column']);
+ }
+ $out .= "INDEX {$name} ON {$table}({$value['column']});";
+ }
+ $join[] = $out;
+ }
+ return $join;
+ }
+
+/**
+ * Overrides DboSource::renderStatement to handle schema generation with Postgres-style indexes
+ *
+ * @param string $type
+ * @param array $data
+ * @return string
+ */
+ public function renderStatement($type, $data) {
+ switch (strtolower($type)) {
+ case 'schema':
+ extract($data);
+
+ foreach ($indexes as $i => $index) {
+ if (preg_match('/PRIMARY KEY/', $index)) {
+ unset($indexes[$i]);
+ $columns[] = $index;
+ break;
+ }
+ }
+ $join = array('columns' => ",\n\t", 'indexes' => "\n");
+
+ foreach (array('columns', 'indexes') as $var) {
+ if (is_array(${$var})) {
+ ${$var} = implode($join[$var], array_filter(${$var}));
+ }
+ }
+ return "CREATE TABLE {$table} (\n\t{$columns}\n);\n{$indexes}";
+ break;
+ default:
+ return parent::renderStatement($type, $data);
+ break;
+ }
+ }
+
+/**
+ * Gets the schema name
+ *
+ * @return string The schema name
+ */
+ public function getSchemaName() {
+ return $this->config['schema'];
+ }
+
+/**
+ * Check if the server support nested transactions
+ *
+ * @return boolean
+ */
+ public function nestedTransactionSupported() {
+ return $this->useNestedTransactions && version_compare($this->getVersion(), '8.0', '>=');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlite.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlite.php
new file mode 100644
index 0000000..63ed603
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlite.php
@@ -0,0 +1,571 @@
+<?php
+/**
+ * SQLite layer for DBO
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource.Database
+ * @since CakePHP(tm) v 0.9.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DboSource', 'Model/Datasource');
+App::uses('String', 'Utility');
+
+/**
+ * DBO implementation for the SQLite3 DBMS.
+ *
+ * A DboSource adapter for SQLite 3 using PDO
+ *
+ * @package Cake.Model.Datasource.Database
+ */
+class Sqlite extends DboSource {
+
+/**
+ * Datasource Description
+ *
+ * @var string
+ */
+ public $description = "SQLite DBO Driver";
+
+/**
+ * Quote Start
+ *
+ * @var string
+ */
+ public $startQuote = '"';
+
+/**
+ * Quote End
+ *
+ * @var string
+ */
+ public $endQuote = '"';
+
+/**
+ * Base configuration settings for SQLite3 driver
+ *
+ * @var array
+ */
+ protected $_baseConfig = array(
+ 'persistent' => false,
+ 'database' => null
+ );
+
+/**
+ * SQLite3 column definition
+ *
+ * @var array
+ */
+ public $columns = array(
+ 'primary_key' => array('name' => 'integer primary key autoincrement'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'integer', 'limit' => null, 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'blob'),
+ 'boolean' => array('name' => 'boolean')
+ );
+
+/**
+ * List of engine specific additional field parameters used on table creating
+ *
+ * @var array
+ */
+ public $fieldParameters = array(
+ 'collate' => array(
+ 'value' => 'COLLATE',
+ 'quote' => false,
+ 'join' => ' ',
+ 'column' => 'Collate',
+ 'position' => 'afterDefault',
+ 'options' => array(
+ 'BINARY', 'NOCASE', 'RTRIM'
+ )
+ ),
+ );
+
+/**
+ * Connects to the database using config['database'] as a filename.
+ *
+ * @return boolean
+ * @throws MissingConnectionException
+ */
+ public function connect() {
+ $config = $this->config;
+ $flags = array(
+ PDO::ATTR_PERSISTENT => $config['persistent'],
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
+ );
+ try {
+ $this->_connection = new PDO('sqlite:' . $config['database'], null, null, $flags);
+ $this->connected = true;
+ } catch(PDOException $e) {
+ throw new MissingConnectionException(array('class' => $e->getMessage()));
+ }
+ return $this->connected;
+ }
+
+/**
+ * Check whether the SQLite extension is installed/loaded
+ *
+ * @return boolean
+ */
+ public function enabled() {
+ return in_array('sqlite', PDO::getAvailableDrivers());
+ }
+
+/**
+ * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
+ *
+ * @param mixed $data
+ * @return array Array of table names in the database
+ */
+ public function listSources($data = null) {
+ $cache = parent::listSources();
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $result = $this->fetchAll("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;", false);
+
+ if (!$result || empty($result)) {
+ return array();
+ } else {
+ $tables = array();
+ foreach ($result as $table) {
+ $tables[] = $table[0]['name'];
+ }
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param Model|string $model Either the model or table name you want described.
+ * @return array Fields in table. Keys are name and type
+ */
+ public function describe($model) {
+ $table = $this->fullTableName($model, false, false);
+ $cache = parent::describe($table);
+ if ($cache != null) {
+ return $cache;
+ }
+ $fields = array();
+ $result = $this->_execute(
+ 'PRAGMA table_info(' . $this->value($table, 'string') . ')'
+ );
+
+ foreach ($result as $column) {
+ $column = (array)$column;
+ $default = ($column['dflt_value'] === 'NULL') ? null : trim($column['dflt_value'], "'");
+
+ $fields[$column['name']] = array(
+ 'type' => $this->column($column['type']),
+ 'null' => !$column['notnull'],
+ 'default' => $default,
+ 'length' => $this->length($column['type'])
+ );
+ if ($column['pk'] == 1) {
+ $fields[$column['name']]['key'] = $this->index['PRI'];
+ $fields[$column['name']]['null'] = false;
+ if (empty($fields[$column['name']]['length'])) {
+ $fields[$column['name']]['length'] = 11;
+ }
+ }
+ }
+
+ $result->closeCursor();
+ $this->_cacheDescription($table, $fields);
+ return $fields;
+ }
+
+/**
+ * Generates and executes an SQL UPDATE statement for given model, fields, and values.
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @param mixed $conditions
+ * @return array
+ */
+ public function update(Model $model, $fields = array(), $values = null, $conditions = null) {
+ if (empty($values) && !empty($fields)) {
+ foreach ($fields as $field => $value) {
+ if (strpos($field, $model->alias . '.') !== false) {
+ unset($fields[$field]);
+ $field = str_replace($model->alias . '.', "", $field);
+ $field = str_replace($model->alias . '.', "", $field);
+ $fields[$field] = $value;
+ }
+ }
+ }
+ return parent::update($model, $fields, $values, $conditions);
+ }
+
+/**
+ * Deletes all the records in a table and resets the count of the auto-incrementing
+ * primary key, where applicable.
+ *
+ * @param string|Model $table A string or model class representing the table to be truncated
+ * @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
+ */
+ public function truncate($table) {
+ $this->_execute('DELETE FROM sqlite_sequence where name=' . $this->startQuote . $this->fullTableName($table, false, false) . $this->endQuote);
+ return $this->execute('DELETE FROM ' . $this->fullTableName($table));
+ }
+
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ public function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+ if (isset($real['limit'])) {
+ $col .= '(' . $real['limit'] . ')';
+ }
+ return $col;
+ }
+
+ $col = strtolower(str_replace(')', '', $real));
+ $limit = null;
+ @list($col, $limit) = explode('(', $col);
+
+ if (in_array($col, array('text', 'integer', 'float', 'boolean', 'timestamp', 'date', 'datetime', 'time'))) {
+ return $col;
+ }
+ if (strpos($col, 'char') !== false) {
+ return 'string';
+ }
+ if (in_array($col, array('blob', 'clob'))) {
+ return 'binary';
+ }
+ if (strpos($col, 'numeric') !== false || strpos($col, 'decimal') !== false) {
+ return 'float';
+ }
+ return 'text';
+ }
+
+/**
+ * Generate ResultSet
+ *
+ * @param mixed $results
+ * @return void
+ */
+ public function resultSet($results) {
+ $this->results = $results;
+ $this->map = array();
+ $numFields = $results->columnCount();
+ $index = 0;
+ $j = 0;
+
+ //PDO::getColumnMeta is experimental and does not work with sqlite3,
+ // so try to figure it out based on the querystring
+ $querystring = $results->queryString;
+ if (stripos($querystring, 'SELECT') === 0) {
+ $last = strripos($querystring, 'FROM');
+ if ($last !== false) {
+ $selectpart = substr($querystring, 7, $last - 8);
+ $selects = String::tokenize($selectpart, ',', '(', ')');
+ }
+ } elseif (strpos($querystring, 'PRAGMA table_info') === 0) {
+ $selects = array('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk');
+ } elseif (strpos($querystring, 'PRAGMA index_list') === 0) {
+ $selects = array('seq', 'name', 'unique');
+ } elseif (strpos($querystring, 'PRAGMA index_info') === 0) {
+ $selects = array('seqno', 'cid', 'name');
+ }
+ while ($j < $numFields) {
+ if (!isset($selects[$j])) {
+ $j++;
+ continue;
+ }
+ if (preg_match('/\bAS\s+(.*)/i', $selects[$j], $matches)) {
+ $columnName = trim($matches[1], '"');
+ } else {
+ $columnName = trim(str_replace('"', '', $selects[$j]));
+ }
+
+ if (strpos($selects[$j], 'DISTINCT') === 0) {
+ $columnName = str_ireplace('DISTINCT', '', $columnName);
+ }
+
+ $metaType = false;
+ try {
+ $metaData = (array)$results->getColumnMeta($j);
+ if (!empty($metaData['sqlite:decl_type'])) {
+ $metaType = trim($metaData['sqlite:decl_type']);
+ }
+ } catch (Exception $e) {
+ }
+
+ if (strpos($columnName, '.')) {
+ $parts = explode('.', $columnName);
+ $this->map[$index++] = array(trim($parts[0]), trim($parts[1]), $metaType);
+ } else {
+ $this->map[$index++] = array(0, $columnName, $metaType);
+ }
+ $j++;
+ }
+ }
+
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return mixed array with results fetched and mapped to column names or false if there is no results left to fetch
+ */
+ public function fetchResult() {
+ if ($row = $this->_result->fetch(PDO::FETCH_NUM)) {
+ $resultRow = array();
+ foreach ($this->map as $col => $meta) {
+ list($table, $column, $type) = $meta;
+ $resultRow[$table][$column] = $row[$col];
+ if ($type == 'boolean' && !is_null($row[$col])) {
+ $resultRow[$table][$column] = $this->boolean($resultRow[$table][$column]);
+ }
+ }
+ return $resultRow;
+ } else {
+ $this->_result->closeCursor();
+ return false;
+ }
+ }
+
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param integer $limit Limit of results returned
+ * @param integer $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ public function limit($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
+ $rt = ' LIMIT';
+ }
+ $rt .= ' ' . $limit;
+ if ($offset) {
+ $rt .= ' OFFSET ' . $offset;
+ }
+ return $rt;
+ }
+ return null;
+ }
+
+/**
+ * Generate a database-native column schema string
+ *
+ * @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
+ * where options can be 'default', 'length', or 'key'.
+ * @return string
+ */
+ public function buildColumn($column) {
+ $name = $type = null;
+ $column = array_merge(array('null' => true), $column);
+ extract($column);
+
+ if (empty($name) || empty($type)) {
+ trigger_error(__d('cake_dev', 'Column name or type not defined in schema'), E_USER_WARNING);
+ return null;
+ }
+
+ if (!isset($this->columns[$type])) {
+ trigger_error(__d('cake_dev', 'Column type %s does not exist', $type), E_USER_WARNING);
+ return null;
+ }
+
+ if (isset($column['key']) && $column['key'] == 'primary' && $type == 'integer') {
+ return $this->name($name) . ' ' . $this->columns['primary_key']['name'];
+ }
+ return parent::buildColumn($column);
+ }
+
+/**
+ * Sets the database encoding
+ *
+ * @param string $enc Database encoding
+ * @return boolean
+ */
+ public function setEncoding($enc) {
+ if (!in_array($enc, array("UTF-8", "UTF-16", "UTF-16le", "UTF-16be"))) {
+ return false;
+ }
+ return $this->_execute("PRAGMA encoding = \"{$enc}\"") !== false;
+ }
+
+/**
+ * Gets the database encoding
+ *
+ * @return string The database encoding
+ */
+ public function getEncoding() {
+ return $this->fetchRow('PRAGMA encoding');
+ }
+
+/**
+ * Removes redundant primary key indexes, as they are handled in the column def of the key.
+ *
+ * @param array $indexes
+ * @param string $table
+ * @return string
+ */
+ public function buildIndex($indexes, $table = null) {
+ $join = array();
+
+ $table = str_replace('"', '', $table);
+ list($dbname, $table) = explode('.', $table);
+ $dbname = $this->name($dbname);
+
+ foreach ($indexes as $name => $value) {
+
+ if ($name == 'PRIMARY') {
+ continue;
+ }
+ $out = 'CREATE ';
+
+ if (!empty($value['unique'])) {
+ $out .= 'UNIQUE ';
+ }
+ if (is_array($value['column'])) {
+ $value['column'] = join(', ', array_map(array(&$this, 'name'), $value['column']));
+ } else {
+ $value['column'] = $this->name($value['column']);
+ }
+ $t = trim($table, '"');
+ $indexname = $this->name($t . '_' . $name);
+ $table = $this->name($table);
+ $out .= "INDEX {$dbname}.{$indexname} ON {$table}({$value['column']});";
+ $join[] = $out;
+ }
+ return $join;
+ }
+
+/**
+ * Overrides DboSource::index to handle SQLite index introspection
+ * Returns an array of the indexes in given table name.
+ *
+ * @param string $model Name of model to inspect
+ * @return array Fields in table. Keys are column and unique
+ */
+ public function index($model) {
+ $index = array();
+ $table = $this->fullTableName($model, false, false);
+ if ($table) {
+ $indexes = $this->query('PRAGMA index_list(' . $table . ')');
+
+ if (is_bool($indexes)) {
+ return array();
+ }
+ foreach ($indexes as $i => $info) {
+ $key = array_pop($info);
+ $keyInfo = $this->query('PRAGMA index_info("' . $key['name'] . '")');
+ foreach ($keyInfo as $keyCol) {
+ if (!isset($index[$key['name']])) {
+ $col = array();
+ if (preg_match('/autoindex/', $key['name'])) {
+ $key['name'] = 'PRIMARY';
+ }
+ $index[$key['name']]['column'] = $keyCol[0]['name'];
+ $index[$key['name']]['unique'] = intval($key['unique'] == 1);
+ } else {
+ if (!is_array($index[$key['name']]['column'])) {
+ $col[] = $index[$key['name']]['column'];
+ }
+ $col[] = $keyCol[0]['name'];
+ $index[$key['name']]['column'] = $col;
+ }
+ }
+ }
+ }
+ return $index;
+ }
+
+/**
+ * Overrides DboSource::renderStatement to handle schema generation with SQLite-style indexes
+ *
+ * @param string $type
+ * @param array $data
+ * @return string
+ */
+ public function renderStatement($type, $data) {
+ switch (strtolower($type)) {
+ case 'schema':
+ extract($data);
+ if (is_array($columns)) {
+ $columns = "\t" . join(",\n\t", array_filter($columns));
+ }
+ if (is_array($indexes)) {
+ $indexes = "\t" . join("\n\t", array_filter($indexes));
+ }
+ return "CREATE TABLE {$table} (\n{$columns});\n{$indexes}";
+ break;
+ default:
+ return parent::renderStatement($type, $data);
+ break;
+ }
+ }
+
+/**
+ * PDO deals in objects, not resources, so overload accordingly.
+ *
+ * @return boolean
+ */
+ public function hasResult() {
+ return is_object($this->_result);
+ }
+
+/**
+ * Generate a "drop table" statement for the given Schema object
+ *
+ * @param CakeSchema $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ public function dropSchema(CakeSchema $schema, $table = null) {
+ $out = '';
+ foreach ($schema->tables as $curTable => $columns) {
+ if (!$table || $table == $curTable) {
+ $out .= 'DROP TABLE IF EXISTS ' . $this->fullTableName($curTable) . ";\n";
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Gets the schema name
+ *
+ * @return string The schema name
+ */
+ public function getSchemaName() {
+ return "main"; // Sqlite Datasource does not support multidb
+ }
+
+/**
+ * Check if the server support nested transactions
+ *
+ * @return boolean
+ */
+ public function nestedTransactionSupported() {
+ return $this->useNestedTransactions && version_compare($this->getVersion(), '3.6.8', '>=');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlserver.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlserver.php
new file mode 100644
index 0000000..b23e59a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Database/Sqlserver.php
@@ -0,0 +1,783 @@
+<?php
+/**
+ * MS SQL Server layer for DBO
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource.Database
+ * @since CakePHP(tm) v 0.10.5.1790
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DboSource', 'Model/Datasource');
+
+/**
+ * Dbo driver for SQLServer
+ *
+ * A Dbo driver for SQLServer 2008 and higher. Requires the `sqlsrv`
+ * and `pdo_sqlsrv` extensions to be enabled.
+ *
+ * @package Cake.Model.Datasource.Database
+ */
+class Sqlserver extends DboSource {
+
+/**
+ * Driver description
+ *
+ * @var string
+ */
+ public $description = "SQL Server DBO Driver";
+
+/**
+ * Starting quote character for quoted identifiers
+ *
+ * @var string
+ */
+ public $startQuote = "[";
+
+/**
+ * Ending quote character for quoted identifiers
+ *
+ * @var string
+ */
+ public $endQuote = "]";
+
+/**
+ * Creates a map between field aliases and numeric indexes. Workaround for the
+ * SQL Server driver's 30-character column name limitation.
+ *
+ * @var array
+ */
+ protected $_fieldMappings = array();
+
+/**
+ * Storing the last affected value
+ *
+ * @var mixed
+ */
+ protected $_lastAffected = false;
+
+/**
+ * Base configuration settings for MS SQL driver
+ *
+ * @var array
+ */
+ protected $_baseConfig = array(
+ 'persistent' => true,
+ 'host' => 'localhost\SQLEXPRESS',
+ 'login' => '',
+ 'password' => '',
+ 'database' => 'cake',
+ 'schema' => '',
+ );
+
+/**
+ * MS SQL column definition
+ *
+ * @var array
+ */
+ public $columns = array(
+ 'primary_key' => array('name' => 'IDENTITY (1, 1) NOT NULL'),
+ 'string' => array('name' => 'nvarchar', 'limit' => '255'),
+ 'text' => array('name' => 'nvarchar', 'limit' => 'MAX'),
+ 'integer' => array('name' => 'int', 'formatter' => 'intval'),
+ 'float' => array('name' => 'numeric', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'datetime', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'datetime', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'varbinary'),
+ 'boolean' => array('name' => 'bit')
+ );
+
+/**
+ * Magic column name used to provide pagination support for SQLServer 2008
+ * which lacks proper limit/offset support.
+ */
+ const ROW_COUNTER = '_cake_page_rownum_';
+
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return boolean True if the database could be connected, else false
+ * @throws MissingConnectionException
+ */
+ public function connect() {
+ $config = $this->config;
+ $this->connected = false;
+ try {
+ $flags = array(
+ PDO::ATTR_PERSISTENT => $config['persistent'],
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
+ );
+ if (!empty($config['encoding'])) {
+ $flags[PDO::SQLSRV_ATTR_ENCODING] = $config['encoding'];
+ }
+ $this->_connection = new PDO(
+ "sqlsrv:server={$config['host']};Database={$config['database']}",
+ $config['login'],
+ $config['password'],
+ $flags
+ );
+ $this->connected = true;
+ } catch (PDOException $e) {
+ throw new MissingConnectionException(array('class' => $e->getMessage()));
+ }
+
+ return $this->connected;
+ }
+
+/**
+ * Check that PDO SQL Server is installed/loaded
+ *
+ * @return boolean
+ */
+ public function enabled() {
+ return in_array('sqlsrv', PDO::getAvailableDrivers());
+ }
+
+/**
+ * Returns an array of sources (tables) in the database.
+ *
+ * @param mixed $data
+ * @return array Array of table names in the database
+ */
+ public function listSources($data = null) {
+ $cache = parent::listSources();
+ if ($cache !== null) {
+ return $cache;
+ }
+ $result = $this->_execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES");
+
+ if (!$result) {
+ $result->closeCursor();
+ return array();
+ } else {
+ $tables = array();
+
+ while ($line = $result->fetch(PDO::FETCH_NUM)) {
+ $tables[] = $line[0];
+ }
+
+ $result->closeCursor();
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param Model|string $model Model object to describe, or a string table name.
+ * @return array Fields in table. Keys are name and type
+ * @throws CakeException
+ */
+ public function describe($model) {
+ $table = $this->fullTableName($model, false);
+ $cache = parent::describe($table);
+ if ($cache != null) {
+ return $cache;
+ }
+ $fields = array();
+ $table = $this->fullTableName($model, false);
+ $cols = $this->_execute(
+ "SELECT
+ COLUMN_NAME as Field,
+ DATA_TYPE as Type,
+ COL_LENGTH('" . $table . "', COLUMN_NAME) as Length,
+ IS_NULLABLE As [Null],
+ COLUMN_DEFAULT as [Default],
+ COLUMNPROPERTY(OBJECT_ID('" . $table . "'), COLUMN_NAME, 'IsIdentity') as [Key],
+ NUMERIC_SCALE as Size
+ FROM INFORMATION_SCHEMA.COLUMNS
+ WHERE TABLE_NAME = '" . $table . "'"
+ );
+ if (!$cols) {
+ throw new CakeException(__d('cake_dev', 'Could not describe table for %s', $table));
+ }
+
+ while ($column = $cols->fetch(PDO::FETCH_OBJ)) {
+ $field = $column->Field;
+ $fields[$field] = array(
+ 'type' => $this->column($column),
+ 'null' => ($column->Null === 'YES' ? true : false),
+ 'default' => preg_replace("/^[(]{1,2}'?([^')]*)?'?[)]{1,2}$/", "$1", $column->Default),
+ 'length' => $this->length($column),
+ 'key' => ($column->Key == '1') ? 'primary' : false
+ );
+
+ if ($fields[$field]['default'] === 'null') {
+ $fields[$field]['default'] = null;
+ } else {
+ $this->value($fields[$field]['default'], $fields[$field]['type']);
+ }
+
+ if ($fields[$field]['key'] !== false && $fields[$field]['type'] == 'integer') {
+ $fields[$field]['length'] = 11;
+ } elseif ($fields[$field]['key'] === false) {
+ unset($fields[$field]['key']);
+ }
+ if (in_array($fields[$field]['type'], array('date', 'time', 'datetime', 'timestamp'))) {
+ $fields[$field]['length'] = null;
+ }
+ if ($fields[$field]['type'] == 'float' && !empty($column->Size)) {
+ $fields[$field]['length'] = $fields[$field]['length'] . ',' . $column->Size;
+ }
+ }
+ $this->_cacheDescription($table, $fields);
+ $cols->closeCursor();
+ return $fields;
+ }
+
+/**
+ * Generates the fields list of an SQL query.
+ *
+ * @param Model $model
+ * @param string $alias Alias table name
+ * @param array $fields
+ * @param boolean $quote
+ * @return array
+ */
+ public function fields(Model $model, $alias = null, $fields = array(), $quote = true) {
+ if (empty($alias)) {
+ $alias = $model->alias;
+ }
+ $fields = parent::fields($model, $alias, $fields, false);
+ $count = count($fields);
+
+ if ($count >= 1 && strpos($fields[0], 'COUNT(*)') === false) {
+ $result = array();
+ for ($i = 0; $i < $count; $i++) {
+ $prepend = '';
+
+ if (strpos($fields[$i], 'DISTINCT') !== false) {
+ $prepend = 'DISTINCT ';
+ $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
+ }
+
+ if (!preg_match('/\s+AS\s+/i', $fields[$i])) {
+ if (substr($fields[$i], -1) == '*') {
+ if (strpos($fields[$i], '.') !== false && $fields[$i] != $alias . '.*') {
+ $build = explode('.', $fields[$i]);
+ $AssociatedModel = $model->{$build[0]};
+ } else {
+ $AssociatedModel = $model;
+ }
+
+ $_fields = $this->fields($AssociatedModel, $AssociatedModel->alias, array_keys($AssociatedModel->schema()));
+ $result = array_merge($result, $_fields);
+ continue;
+ }
+
+ if (strpos($fields[$i], '.') === false) {
+ $this->_fieldMappings[$alias . '__' . $fields[$i]] = $alias . '.' . $fields[$i];
+ $fieldName = $this->name($alias . '.' . $fields[$i]);
+ $fieldAlias = $this->name($alias . '__' . $fields[$i]);
+ } else {
+ $build = explode('.', $fields[$i]);
+ $this->_fieldMappings[$build[0] . '__' . $build[1]] = $fields[$i];
+ $fieldName = $this->name($build[0] . '.' . $build[1]);
+ $fieldAlias = $this->name(preg_replace("/^\[(.+)\]$/", "$1", $build[0]) . '__' . $build[1]);
+ }
+ if ($model->getColumnType($fields[$i]) == 'datetime') {
+ $fieldName = "CONVERT(VARCHAR(20), {$fieldName}, 20)";
+ }
+ $fields[$i] = "{$fieldName} AS {$fieldAlias}";
+ }
+ $result[] = $prepend . $fields[$i];
+ }
+ return $result;
+ } else {
+ return $fields;
+ }
+ }
+
+/**
+ * Generates and executes an SQL INSERT statement for given model, fields, and values.
+ * Removes Identity (primary key) column from update data before returning to parent, if
+ * value is empty.
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @return array
+ */
+ public function create(Model $model, $fields = null, $values = null) {
+ if (!empty($values)) {
+ $fields = array_combine($fields, $values);
+ }
+ $primaryKey = $this->_getPrimaryKey($model);
+
+ if (array_key_exists($primaryKey, $fields)) {
+ if (empty($fields[$primaryKey])) {
+ unset($fields[$primaryKey]);
+ } else {
+ $this->_execute('SET IDENTITY_INSERT ' . $this->fullTableName($model) . ' ON');
+ }
+ }
+ $result = parent::create($model, array_keys($fields), array_values($fields));
+ if (array_key_exists($primaryKey, $fields) && !empty($fields[$primaryKey])) {
+ $this->_execute('SET IDENTITY_INSERT ' . $this->fullTableName($model) . ' OFF');
+ }
+ return $result;
+ }
+
+/**
+ * Generates and executes an SQL UPDATE statement for given model, fields, and values.
+ * Removes Identity (primary key) column from update data before returning to parent.
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @param mixed $conditions
+ * @return array
+ */
+ public function update(Model $model, $fields = array(), $values = null, $conditions = null) {
+ if (!empty($values)) {
+ $fields = array_combine($fields, $values);
+ }
+ if (isset($fields[$model->primaryKey])) {
+ unset($fields[$model->primaryKey]);
+ }
+ if (empty($fields)) {
+ return true;
+ }
+ return parent::update($model, array_keys($fields), array_values($fields), $conditions);
+ }
+
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param integer $limit Limit of results returned
+ * @param integer $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ public function limit($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'top') || strpos(strtolower($limit), 'top') === 0) {
+ $rt = ' TOP';
+ }
+ $rt .= ' ' . $limit;
+ if (is_int($offset) && $offset > 0) {
+ $rt = ' OFFSET ' . intval($offset) . ' ROWS FETCH FIRST ' . intval($limit) . ' ROWS ONLY';
+ }
+ return $rt;
+ }
+ return null;
+ }
+
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param mixed $real Either the string value of the fields type.
+ * or the Result object from Sqlserver::describe()
+ * @return string Abstract column type (i.e. "string")
+ */
+ public function column($real) {
+ $limit = null;
+ $col = $real;
+ if (is_object($real) && isset($real->Field)) {
+ $limit = $real->Length;
+ $col = $real->Type;
+ }
+
+ if ($col == 'datetime2') {
+ return 'datetime';
+ }
+ if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
+ return $col;
+ }
+ if ($col == 'bit') {
+ return 'boolean';
+ }
+ if (strpos($col, 'int') !== false) {
+ return 'integer';
+ }
+ if (strpos($col, 'char') !== false && $limit == -1) {
+ return 'text';
+ }
+ if (strpos($col, 'char') !== false) {
+ return 'string';
+ }
+ if (strpos($col, 'text') !== false) {
+ return 'text';
+ }
+ if (strpos($col, 'binary') !== false || $col == 'image') {
+ return 'binary';
+ }
+ if (in_array($col, array('float', 'real', 'decimal', 'numeric'))) {
+ return 'float';
+ }
+ return 'text';
+ }
+
+/**
+ * Handle SQLServer specific length properties.
+ * SQLServer handles text types as nvarchar/varchar with a length of -1.
+ *
+ * @param mixed $length Either the length as a string, or a Column descriptor object.
+ * @return mixed null|integer with length of column.
+ */
+ public function length($length) {
+ if (is_object($length) && isset($length->Length)) {
+ if ($length->Length == -1 && strpos($length->Type, 'char') !== false) {
+ return null;
+ }
+ if (in_array($length->Type, array('nchar', 'nvarchar'))) {
+ return floor($length->Length / 2);
+ }
+ return $length->Length;
+ }
+ return parent::length($length);
+ }
+
+/**
+ * Builds a map of the columns contained in a result
+ *
+ * @param PDOStatement $results
+ * @return void
+ */
+ public function resultSet($results) {
+ $this->map = array();
+ $numFields = $results->columnCount();
+ $index = 0;
+
+ while ($numFields-- > 0) {
+ $column = $results->getColumnMeta($index);
+ $name = $column['name'];
+
+ if (strpos($name, '__')) {
+ if (isset($this->_fieldMappings[$name]) && strpos($this->_fieldMappings[$name], '.')) {
+ $map = explode('.', $this->_fieldMappings[$name]);
+ } elseif (isset($this->_fieldMappings[$name])) {
+ $map = array(0, $this->_fieldMappings[$name]);
+ } else {
+ $map = array(0, $name);
+ }
+ } else {
+ $map = array(0, $name);
+ }
+ $map[] = ($column['sqlsrv:decl_type'] == 'bit') ? 'boolean' : $column['native_type'];
+ $this->map[$index++] = $map;
+ }
+ }
+
+/**
+ * Builds final SQL statement
+ *
+ * @param string $type Query type
+ * @param array $data Query data
+ * @return string
+ */
+ public function renderStatement($type, $data) {
+ switch (strtolower($type)) {
+ case 'select':
+ extract($data);
+ $fields = trim($fields);
+
+ if (strpos($limit, 'TOP') !== false && strpos($fields, 'DISTINCT ') === 0) {
+ $limit = 'DISTINCT ' . trim($limit);
+ $fields = substr($fields, 9);
+ }
+
+ // hack order as SQLServer requires an order if there is a limit.
+ if ($limit && !$order) {
+ $order = 'ORDER BY (SELECT NULL)';
+ }
+
+ // For older versions use the subquery version of pagination.
+ if (version_compare($this->getVersion(), '11', '<') && preg_match('/FETCH\sFIRST\s+([0-9]+)/i', $limit, $offset)) {
+ preg_match('/OFFSET\s*(\d+)\s*.*?(\d+)\s*ROWS/', $limit, $limitOffset);
+
+ $limit = 'TOP ' . intval($limitOffset[2]);
+ $page = intval($limitOffset[1] / $limitOffset[2]);
+ $offset = intval($limitOffset[2] * $page);
+
+ $rowCounter = self::ROW_COUNTER;
+ return "
+ SELECT {$limit} * FROM (
+ SELECT {$fields}, ROW_NUMBER() OVER ({$order}) AS {$rowCounter}
+ FROM {$table} {$alias} {$joins} {$conditions} {$group}
+ ) AS _cake_paging_
+ WHERE _cake_paging_.{$rowCounter} > {$offset}
+ ORDER BY _cake_paging_.{$rowCounter}
+ ";
+ } elseif (strpos($limit, 'FETCH') !== false) {
+ return "SELECT {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$group} {$order} {$limit}";
+ } else {
+ return "SELECT {$limit} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$group} {$order}";
+ }
+ break;
+ case "schema":
+ extract($data);
+
+ foreach ($indexes as $i => $index) {
+ if (preg_match('/PRIMARY KEY/', $index)) {
+ unset($indexes[$i]);
+ break;
+ }
+ }
+
+ foreach (array('columns', 'indexes') as $var) {
+ if (is_array(${$var})) {
+ ${$var} = "\t" . implode(",\n\t", array_filter(${$var}));
+ }
+ }
+ return "CREATE TABLE {$table} (\n{$columns});\n{$indexes}";
+ break;
+ default:
+ return parent::renderStatement($type, $data);
+ break;
+ }
+ }
+
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column The column into which this data will be inserted
+ * @return string Quoted and escaped data
+ */
+ public function value($data, $column = null) {
+ if (is_array($data) || is_object($data)) {
+ return parent::value($data, $column);
+ } elseif (in_array($data, array('{$__cakeID__$}', '{$__cakeForeignKey__$}'), true)) {
+ return $data;
+ }
+
+ if (empty($column)) {
+ $column = $this->introspectType($data);
+ }
+
+ switch ($column) {
+ case 'string':
+ case 'text':
+ return 'N' . $this->_connection->quote($data, PDO::PARAM_STR);
+ default:
+ return parent::value($data, $column);
+ }
+ }
+
+/**
+ * Returns an array of all result rows for a given SQL query.
+ * Returns false if no rows matched.
+ *
+ * @param Model $model
+ * @param array $queryData
+ * @param integer $recursive
+ * @return array Array of resultset rows, or false if no rows matched
+ */
+ public function read(Model $model, $queryData = array(), $recursive = null) {
+ $results = parent::read($model, $queryData, $recursive);
+ $this->_fieldMappings = array();
+ return $results;
+ }
+
+/**
+ * Fetches the next row from the current result set.
+ * Eats the magic ROW_COUNTER variable.
+ *
+ * @return mixed
+ */
+ public function fetchResult() {
+ if ($row = $this->_result->fetch(PDO::FETCH_NUM)) {
+ $resultRow = array();
+ foreach ($this->map as $col => $meta) {
+ list($table, $column, $type) = $meta;
+ if ($table === 0 && $column === self::ROW_COUNTER) {
+ continue;
+ }
+ $resultRow[$table][$column] = $row[$col];
+ if ($type === 'boolean' && !is_null($row[$col])) {
+ $resultRow[$table][$column] = $this->boolean($resultRow[$table][$column]);
+ }
+ }
+ return $resultRow;
+ }
+ $this->_result->closeCursor();
+ return false;
+ }
+
+/**
+ * Inserts multiple values into a table
+ *
+ * @param string $table
+ * @param string $fields
+ * @param array $values
+ * @return void
+ */
+ public function insertMulti($table, $fields, $values) {
+ $primaryKey = $this->_getPrimaryKey($table);
+ $hasPrimaryKey = $primaryKey != null && (
+ (is_array($fields) && in_array($primaryKey, $fields)
+ || (is_string($fields) && strpos($fields, $this->startQuote . $primaryKey . $this->endQuote) !== false))
+ );
+
+ if ($hasPrimaryKey) {
+ $this->_execute('SET IDENTITY_INSERT ' . $this->fullTableName($table) . ' ON');
+ }
+
+ parent::insertMulti($table, $fields, $values);
+
+ if ($hasPrimaryKey) {
+ $this->_execute('SET IDENTITY_INSERT ' . $this->fullTableName($table) . ' OFF');
+ }
+ }
+
+/**
+ * Generate a database-native column schema string
+ *
+ * @param array $column An array structured like the
+ * following: array('name'=>'value', 'type'=>'value'[, options]),
+ * where options can be 'default', 'length', or 'key'.
+ * @return string
+ */
+ public function buildColumn($column) {
+ $result = parent::buildColumn($column);
+ $result = preg_replace('/(int|integer)\([0-9]+\)/i', '$1', $result);
+ $result = preg_replace('/(bit)\([0-9]+\)/i', '$1', $result);
+ if (strpos($result, 'DEFAULT NULL') !== false) {
+ if (isset($column['default']) && $column['default'] === '') {
+ $result = str_replace('DEFAULT NULL', "DEFAULT ''", $result);
+ } else {
+ $result = str_replace('DEFAULT NULL', 'NULL', $result);
+ }
+ } elseif (array_keys($column) == array('type', 'name')) {
+ $result .= ' NULL';
+ } elseif (strpos($result, "DEFAULT N'")) {
+ $result = str_replace("DEFAULT N'", "DEFAULT '", $result);
+ }
+ return $result;
+ }
+
+/**
+ * Format indexes for create table
+ *
+ * @param array $indexes
+ * @param string $table
+ * @return string
+ */
+ public function buildIndex($indexes, $table = null) {
+ $join = array();
+
+ foreach ($indexes as $name => $value) {
+ if ($name == 'PRIMARY') {
+ $join[] = 'PRIMARY KEY (' . $this->name($value['column']) . ')';
+ } elseif (isset($value['unique']) && $value['unique']) {
+ $out = "ALTER TABLE {$table} ADD CONSTRAINT {$name} UNIQUE";
+
+ if (is_array($value['column'])) {
+ $value['column'] = implode(', ', array_map(array(&$this, 'name'), $value['column']));
+ } else {
+ $value['column'] = $this->name($value['column']);
+ }
+ $out .= "({$value['column']});";
+ $join[] = $out;
+ }
+ }
+ return $join;
+ }
+
+/**
+ * Makes sure it will return the primary key
+ *
+ * @param Model|string $model Model instance of table name
+ * @return string
+ */
+ protected function _getPrimaryKey($model) {
+ $schema = $this->describe($model);
+ foreach ($schema as $field => $props) {
+ if (isset($props['key']) && $props['key'] == 'primary') {
+ return $field;
+ }
+ }
+ return null;
+ }
+
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists,
+ * this returns false.
+ *
+ * @param mixed $source
+ * @return integer Number of affected rows
+ */
+ public function lastAffected($source = null) {
+ $affected = parent::lastAffected();
+ if ($affected === null && $this->_lastAffected !== false) {
+ return $this->_lastAffected;
+ }
+ return $affected;
+ }
+
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @param array $params list of params to be bound to query (supported only in select)
+ * @param array $prepareOptions Options to be used in the prepare statement
+ * @return mixed PDOStatement if query executes with no problem, true as the result of a successful, false on error
+ * query returning no rows, such as a CREATE statement, false otherwise
+ * @throws PDOException
+ */
+ protected function _execute($sql, $params = array(), $prepareOptions = array()) {
+ $this->_lastAffected = false;
+ if (strncasecmp($sql, 'SELECT', 6) == 0 || preg_match('/^EXEC(?:UTE)?\s/mi', $sql) > 0) {
+ $prepareOptions += array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL);
+ return parent::_execute($sql, $params, $prepareOptions);
+ }
+ try {
+ $this->_lastAffected = $this->_connection->exec($sql);
+ if ($this->_lastAffected === false) {
+ $this->_results = null;
+ $error = $this->_connection->errorInfo();
+ $this->error = $error[2];
+ return false;
+ }
+ return true;
+ } catch (PDOException $e) {
+ if (isset($query->queryString)) {
+ $e->queryString = $query->queryString;
+ } else {
+ $e->queryString = $sql;
+ }
+ throw $e;
+ }
+ }
+
+/**
+ * Generate a "drop table" statement for the given Schema object
+ *
+ * @param CakeSchema $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ public function dropSchema(CakeSchema $schema, $table = null) {
+ $out = '';
+ foreach ($schema->tables as $curTable => $columns) {
+ if (!$table || $table == $curTable) {
+ $out .= "IF OBJECT_ID('" . $this->fullTableName($curTable, false) . "', 'U') IS NOT NULL DROP TABLE " . $this->fullTableName($curTable) . ";\n";
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Gets the schema name
+ *
+ * @return string The schema name
+ */
+ public function getSchemaName() {
+ return $this->config['schema'];
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DboSource.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DboSource.php
new file mode 100644
index 0000000..ce19daa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/DboSource.php
@@ -0,0 +1,3268 @@
+<?php
+/**
+ * Dbo Source
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DataSource', 'Model/Datasource');
+App::uses('String', 'Utility');
+App::uses('View', 'View');
+
+/**
+ * DboSource
+ *
+ * Creates DBO-descendant objects from a given db connection configuration
+ *
+ * @package Cake.Model.Datasource
+ */
+class DboSource extends DataSource {
+
+/**
+ * Description string for this Database Data Source.
+ *
+ * @var string
+ */
+ public $description = "Database Data Source";
+
+/**
+ * index definition, standard cake, primary, index, unique
+ *
+ * @var array
+ */
+ public $index = array('PRI' => 'primary', 'MUL' => 'index', 'UNI' => 'unique');
+
+/**
+ * Database keyword used to assign aliases to identifiers.
+ *
+ * @var string
+ */
+ public $alias = 'AS ';
+
+/**
+ * Caches result from query parsing operations. Cached results for both DboSource::name() and
+ * DboSource::conditions() will be stored here. Method caching uses `md5()`. If you have
+ * problems with collisions, set DboSource::$cacheMethods to false.
+ *
+ * @var array
+ */
+ public static $methodCache = array();
+
+/**
+ * Whether or not to cache the results of DboSource::name() and DboSource::conditions()
+ * into the memory cache. Set to false to disable the use of the memory cache.
+ *
+ * @var boolean.
+ */
+ public $cacheMethods = true;
+
+/**
+ * Flag to support nested transactions. If it is set to false, you will be able to use
+ * the transaction methods (begin/commit/rollback), but just the global transaction will
+ * be executed.
+ *
+ * @var boolean
+ */
+ public $useNestedTransactions = false;
+
+/**
+ * Print full query debug info?
+ *
+ * @var boolean
+ */
+ public $fullDebug = false;
+
+/**
+ * String to hold how many rows were affected by the last SQL operation.
+ *
+ * @var string
+ */
+ public $affected = null;
+
+/**
+ * Number of rows in current resultset
+ *
+ * @var integer
+ */
+ public $numRows = null;
+
+/**
+ * Time the last query took
+ *
+ * @var integer
+ */
+ public $took = null;
+
+/**
+ * Result
+ *
+ * @var array
+ */
+ protected $_result = null;
+
+/**
+ * Queries count.
+ *
+ * @var integer
+ */
+ protected $_queriesCnt = 0;
+
+/**
+ * Total duration of all queries.
+ *
+ * @var integer
+ */
+ protected $_queriesTime = null;
+
+/**
+ * Log of queries executed by this DataSource
+ *
+ * @var array
+ */
+ protected $_queriesLog = array();
+
+/**
+ * Maximum number of items in query log
+ *
+ * This is to prevent query log taking over too much memory.
+ *
+ * @var integer Maximum number of queries in the queries log.
+ */
+ protected $_queriesLogMax = 200;
+
+/**
+ * Caches serialized results of executed queries
+ *
+ * @var array Cache of results from executed sql queries.
+ */
+ protected $_queryCache = array();
+
+/**
+ * A reference to the physical connection of this DataSource
+ *
+ * @var array
+ */
+ protected $_connection = null;
+
+/**
+ * The DataSource configuration key name
+ *
+ * @var string
+ */
+ public $configKeyName = null;
+
+/**
+ * The starting character that this DataSource uses for quoted identifiers.
+ *
+ * @var string
+ */
+ public $startQuote = null;
+
+/**
+ * The ending character that this DataSource uses for quoted identifiers.
+ *
+ * @var string
+ */
+ public $endQuote = null;
+
+/**
+ * The set of valid SQL operations usable in a WHERE statement
+ *
+ * @var array
+ */
+ protected $_sqlOps = array('like', 'ilike', 'or', 'not', 'in', 'between', 'regexp', 'similar to');
+
+/**
+ * Indicates the level of nested transactions
+ *
+ * @var integer
+ */
+ protected $_transactionNesting = 0;
+
+/**
+ * Default fields that are used by the DBO
+ *
+ * @var array
+ */
+ protected $_queryDefaults = array(
+ 'conditions' => array(),
+ 'fields' => null,
+ 'table' => null,
+ 'alias' => null,
+ 'order' => null,
+ 'limit' => null,
+ 'joins' => array(),
+ 'group' => null,
+ 'offset' => null
+ );
+
+/**
+ * Separator string for virtualField composition
+ *
+ * @var string
+ */
+ public $virtualFieldSeparator = '__';
+
+/**
+ * List of table engine specific parameters used on table creating
+ *
+ * @var array
+ */
+ public $tableParameters = array();
+
+/**
+ * List of engine specific additional field parameters used on table creating
+ *
+ * @var array
+ */
+ public $fieldParameters = array();
+
+/**
+ * Indicates whether there was a change on the cached results on the methods of this class
+ * This will be used for storing in a more persistent cache
+ *
+ * @var boolean
+ */
+ protected $_methodCacheChange = false;
+
+/**
+ * Constructor
+ *
+ * @param array $config Array of configuration information for the Datasource.
+ * @param boolean $autoConnect Whether or not the datasource should automatically connect.
+ * @throws MissingConnectionException when a connection cannot be made.
+ */
+ public function __construct($config = null, $autoConnect = true) {
+ if (!isset($config['prefix'])) {
+ $config['prefix'] = '';
+ }
+ parent::__construct($config);
+ $this->fullDebug = Configure::read('debug') > 1;
+ if (!$this->enabled()) {
+ throw new MissingConnectionException(array(
+ 'class' => get_class($this),
+ 'enabled' => false
+ ));
+ }
+ if ($autoConnect) {
+ $this->connect();
+ }
+ }
+
+/**
+ * Reconnects to database server with optional new settings
+ *
+ * @param array $config An array defining the new configuration settings
+ * @return boolean True on success, false on failure
+ */
+ public function reconnect($config = array()) {
+ $this->disconnect();
+ $this->setConfig($config);
+ $this->_sources = null;
+
+ return $this->connect();
+ }
+
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ public function disconnect() {
+ if ($this->_result instanceof PDOStatement) {
+ $this->_result->closeCursor();
+ }
+ unset($this->_connection);
+ $this->connected = false;
+ return true;
+ }
+
+/**
+ * Get the underlying connection object.
+ *
+ * @return PDO
+ */
+ public function getConnection() {
+ return $this->_connection;
+ }
+
+/**
+ * Gets the version string of the database server
+ *
+ * @return string The database version
+ */
+ public function getVersion() {
+ return $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION);
+ }
+
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column The column into which this data will be inserted
+ * @return string Quoted and escaped data
+ */
+ public function value($data, $column = null) {
+ if (is_array($data) && !empty($data)) {
+ return array_map(
+ array(&$this, 'value'),
+ $data, array_fill(0, count($data), $column)
+ );
+ } elseif (is_object($data) && isset($data->type, $data->value)) {
+ if ($data->type == 'identifier') {
+ return $this->name($data->value);
+ } elseif ($data->type == 'expression') {
+ return $data->value;
+ }
+ } elseif (in_array($data, array('{$__cakeID__$}', '{$__cakeForeignKey__$}'), true)) {
+ return $data;
+ }
+
+ if ($data === null || (is_array($data) && empty($data))) {
+ return 'NULL';
+ }
+
+ if (empty($column)) {
+ $column = $this->introspectType($data);
+ }
+
+ switch ($column) {
+ case 'binary':
+ return $this->_connection->quote($data, PDO::PARAM_LOB);
+ break;
+ case 'boolean':
+ return $this->_connection->quote($this->boolean($data, true), PDO::PARAM_BOOL);
+ break;
+ case 'string':
+ case 'text':
+ return $this->_connection->quote($data, PDO::PARAM_STR);
+ default:
+ if ($data === '') {
+ return 'NULL';
+ }
+ if (is_float($data)) {
+ return str_replace(',', '.', strval($data));
+ }
+ if ((is_int($data) || $data === '0') || (
+ is_numeric($data) && strpos($data, ',') === false &&
+ $data[0] != '0' && strpos($data, 'e') === false)
+ ) {
+ return $data;
+ }
+ return $this->_connection->quote($data);
+ break;
+ }
+ }
+
+/**
+ * Returns an object to represent a database identifier in a query. Expression objects
+ * are not sanitized or escaped.
+ *
+ * @param string $identifier A SQL expression to be used as an identifier
+ * @return stdClass An object representing a database identifier to be used in a query
+ */
+ public function identifier($identifier) {
+ $obj = new stdClass();
+ $obj->type = 'identifier';
+ $obj->value = $identifier;
+ return $obj;
+ }
+
+/**
+ * Returns an object to represent a database expression in a query. Expression objects
+ * are not sanitized or escaped.
+ *
+ * @param string $expression An arbitrary SQL expression to be inserted into a query.
+ * @return stdClass An object representing a database expression to be used in a query
+ */
+ public function expression($expression) {
+ $obj = new stdClass();
+ $obj->type = 'expression';
+ $obj->value = $expression;
+ return $obj;
+ }
+
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @param array $params Additional options for the query.
+ * @return boolean
+ */
+ public function rawQuery($sql, $params = array()) {
+ $this->took = $this->numRows = false;
+ return $this->execute($sql, $params);
+ }
+
+/**
+ * Queries the database with given SQL statement, and obtains some metadata about the result
+ * (rows affected, timing, any errors, number of rows in resultset). The query is also logged.
+ * If Configure::read('debug') is set, the log is shown all the time, else it is only shown on errors.
+ *
+ * ### Options
+ *
+ * - log - Whether or not the query should be logged to the memory log.
+ *
+ * @param string $sql SQL statement
+ * @param array $options
+ * @param array $params values to be bound to the query
+ * @return mixed Resource or object representing the result set, or false on failure
+ */
+ public function execute($sql, $options = array(), $params = array()) {
+ $options += array('log' => $this->fullDebug);
+
+ $t = microtime(true);
+ $this->_result = $this->_execute($sql, $params);
+
+ if ($options['log']) {
+ $this->took = round((microtime(true) - $t) * 1000, 0);
+ $this->numRows = $this->affected = $this->lastAffected();
+ $this->logQuery($sql, $params);
+ }
+
+ return $this->_result;
+ }
+
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @param array $params list of params to be bound to query
+ * @param array $prepareOptions Options to be used in the prepare statement
+ * @return mixed PDOStatement if query executes with no problem, true as the result of a successful, false on error
+ * query returning no rows, such as a CREATE statement, false otherwise
+ * @throws PDOException
+ */
+ protected function _execute($sql, $params = array(), $prepareOptions = array()) {
+ $sql = trim($sql);
+ if (preg_match('/^(?:CREATE|ALTER|DROP)/i', $sql)) {
+ $statements = array_filter(explode(';', $sql));
+ if (count($statements) > 1) {
+ $result = array_map(array($this, '_execute'), $statements);
+ return array_search(false, $result) === false;
+ }
+ }
+
+ try {
+ $query = $this->_connection->prepare($sql, $prepareOptions);
+ $query->setFetchMode(PDO::FETCH_LAZY);
+ if (!$query->execute($params)) {
+ $this->_results = $query;
+ $query->closeCursor();
+ return false;
+ }
+ if (!$query->columnCount()) {
+ $query->closeCursor();
+ if (!$query->rowCount()) {
+ return true;
+ }
+ }
+ return $query;
+ } catch (PDOException $e) {
+ if (isset($query->queryString)) {
+ $e->queryString = $query->queryString;
+ } else {
+ $e->queryString = $sql;
+ }
+ throw $e;
+ }
+ }
+
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @param PDOStatement $query the query to extract the error from if any
+ * @return string Error message with error number
+ */
+ public function lastError(PDOStatement $query = null) {
+ if ($query) {
+ $error = $query->errorInfo();
+ } else {
+ $error = $this->_connection->errorInfo();
+ }
+ if (empty($error[2])) {
+ return null;
+ }
+ return $error[1] . ': ' . $error[2];
+ }
+
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists,
+ * this returns false.
+ *
+ * @param mixed $source
+ * @return integer Number of affected rows
+ */
+ public function lastAffected($source = null) {
+ if ($this->hasResult()) {
+ return $this->_result->rowCount();
+ }
+ return 0;
+ }
+
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @param mixed $source Not used
+ * @return integer Number of rows in resultset
+ */
+ public function lastNumRows($source = null) {
+ return $this->lastAffected();
+ }
+
+/**
+ * DataSource Query abstraction
+ *
+ * @return resource Result resource identifier.
+ */
+ public function query() {
+ $args = func_get_args();
+ $fields = null;
+ $order = null;
+ $limit = null;
+ $page = null;
+ $recursive = null;
+
+ if (count($args) === 1) {
+ return $this->fetchAll($args[0]);
+ } elseif (count($args) > 1 && (strpos($args[0], 'findBy') === 0 || strpos($args[0], 'findAllBy') === 0)) {
+ $params = $args[1];
+
+ if (substr($args[0], 0, 6) === 'findBy') {
+ $all = false;
+ $field = Inflector::underscore(substr($args[0], 6));
+ } else {
+ $all = true;
+ $field = Inflector::underscore(substr($args[0], 9));
+ }
+
+ $or = (strpos($field, '_or_') !== false);
+ if ($or) {
+ $field = explode('_or_', $field);
+ } else {
+ $field = explode('_and_', $field);
+ }
+ $off = count($field) - 1;
+
+ if (isset($params[1 + $off])) {
+ $fields = $params[1 + $off];
+ }
+
+ if (isset($params[2 + $off])) {
+ $order = $params[2 + $off];
+ }
+
+ if (!array_key_exists(0, $params)) {
+ return false;
+ }
+
+ $c = 0;
+ $conditions = array();
+
+ foreach ($field as $f) {
+ $conditions[$args[2]->alias . '.' . $f] = $params[$c++];
+ }
+
+ if ($or) {
+ $conditions = array('OR' => $conditions);
+ }
+
+ if ($all) {
+ if (isset($params[3 + $off])) {
+ $limit = $params[3 + $off];
+ }
+
+ if (isset($params[4 + $off])) {
+ $page = $params[4 + $off];
+ }
+
+ if (isset($params[5 + $off])) {
+ $recursive = $params[5 + $off];
+ }
+ return $args[2]->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'));
+ } else {
+ if (isset($params[3 + $off])) {
+ $recursive = $params[3 + $off];
+ }
+ return $args[2]->find('first', compact('conditions', 'fields', 'order', 'recursive'));
+ }
+ } else {
+ if (isset($args[1]) && $args[1] === true) {
+ return $this->fetchAll($args[0], true);
+ } elseif (isset($args[1]) && !is_array($args[1]) ) {
+ return $this->fetchAll($args[0], false);
+ } elseif (isset($args[1]) && is_array($args[1])) {
+ if (isset($args[2])) {
+ $cache = $args[2];
+ } else {
+ $cache = true;
+ }
+ return $this->fetchAll($args[0], $args[1], array('cache' => $cache));
+ }
+ }
+ }
+
+/**
+ * Returns a row from current resultset as an array
+ *
+ * @param string $sql Some SQL to be executed.
+ * @return array The fetched row as an array
+ */
+ public function fetchRow($sql = null) {
+ if (is_string($sql) && strlen($sql) > 5 && !$this->execute($sql)) {
+ return null;
+ }
+
+ if ($this->hasResult()) {
+ $this->resultSet($this->_result);
+ $resultRow = $this->fetchResult();
+ if (isset($resultRow[0])) {
+ $this->fetchVirtualField($resultRow);
+ }
+ return $resultRow;
+ } else {
+ return null;
+ }
+ }
+
+/**
+ * Returns an array of all result rows for a given SQL query.
+ * Returns false if no rows matched.
+ *
+ *
+ * ### Options
+ *
+ * - `cache` - Returns the cached version of the query, if exists and stores the result in cache.
+ * This is a non-persistent cache, and only lasts for a single request. This option
+ * defaults to true. If you are directly calling this method, you can disable caching
+ * by setting $options to `false`
+ *
+ * @param string $sql SQL statement
+ * @param array $params parameters to be bound as values for the SQL statement
+ * @param array $options additional options for the query.
+ * @return array Array of resultset rows, or false if no rows matched
+ */
+ public function fetchAll($sql, $params = array(), $options = array()) {
+ if (is_string($options)) {
+ $options = array('modelName' => $options);
+ }
+ if (is_bool($params)) {
+ $options['cache'] = $params;
+ $params = array();
+ }
+ $options += array('cache' => true);
+ $cache = $options['cache'];
+ if ($cache && ($cached = $this->getQueryCache($sql, $params)) !== false) {
+ return $cached;
+ }
+ if ($result = $this->execute($sql, array(), $params)) {
+ $out = array();
+
+ if ($this->hasResult()) {
+ $first = $this->fetchRow();
+ if ($first != null) {
+ $out[] = $first;
+ }
+ while ($item = $this->fetchResult()) {
+ if (isset($item[0])) {
+ $this->fetchVirtualField($item);
+ }
+ $out[] = $item;
+ }
+ }
+
+ if (!is_bool($result) && $cache) {
+ $this->_writeQueryCache($sql, $out, $params);
+ }
+
+ if (empty($out) && is_bool($this->_result)) {
+ return $this->_result;
+ }
+ return $out;
+ }
+ return false;
+ }
+
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return boolean
+ */
+ public function fetchResult() {
+ return false;
+ }
+
+/**
+ * Modifies $result array to place virtual fields in model entry where they belongs to
+ *
+ * @param array $result Reference to the fetched row
+ * @return void
+ */
+ public function fetchVirtualField(&$result) {
+ if (isset($result[0]) && is_array($result[0])) {
+ foreach ($result[0] as $field => $value) {
+ if (strpos($field, $this->virtualFieldSeparator) === false) {
+ continue;
+ }
+ list($alias, $virtual) = explode($this->virtualFieldSeparator, $field);
+
+ if (!ClassRegistry::isKeySet($alias)) {
+ return;
+ }
+ $model = ClassRegistry::getObject($alias);
+ if ($model->isVirtualField($virtual)) {
+ $result[$alias][$virtual] = $value;
+ unset($result[0][$field]);
+ }
+ }
+ if (empty($result[0])) {
+ unset($result[0]);
+ }
+ }
+ }
+
+/**
+ * Returns a single field of the first of query results for a given SQL query, or false if empty.
+ *
+ * @param string $name Name of the field
+ * @param string $sql SQL query
+ * @return mixed Value of field read.
+ */
+ public function field($name, $sql) {
+ $data = $this->fetchRow($sql);
+ if (empty($data[$name])) {
+ return false;
+ }
+ return $data[$name];
+ }
+
+/**
+ * Empties the method caches.
+ * These caches are used by DboSource::name() and DboSource::conditions()
+ *
+ * @return void
+ */
+ public function flushMethodCache() {
+ $this->_methodCacheChange = true;
+ self::$methodCache = array();
+ }
+
+/**
+ * Cache a value into the methodCaches. Will respect the value of DboSource::$cacheMethods.
+ * Will retrieve a value from the cache if $value is null.
+ *
+ * If caching is disabled and a write is attempted, the $value will be returned.
+ * A read will either return the value or null.
+ *
+ * @param string $method Name of the method being cached.
+ * @param string $key The key name for the cache operation.
+ * @param mixed $value The value to cache into memory.
+ * @return mixed Either null on failure, or the value if its set.
+ */
+ public function cacheMethod($method, $key, $value = null) {
+ if ($this->cacheMethods === false) {
+ return $value;
+ }
+ if (empty(self::$methodCache)) {
+ self::$methodCache = Cache::read('method_cache', '_cake_core_');
+ }
+ if ($value === null) {
+ return (isset(self::$methodCache[$method][$key])) ? self::$methodCache[$method][$key] : null;
+ }
+ $this->_methodCacheChange = true;
+ return self::$methodCache[$method][$key] = $value;
+ }
+
+/**
+ * Returns a quoted name of $data for use in an SQL statement.
+ * Strips fields out of SQL functions before quoting.
+ *
+ * Results of this method are stored in a memory cache. This improves performance, but
+ * because the method uses a hashing algorithm it can have collisions.
+ * Setting DboSource::$cacheMethods to false will disable the memory cache.
+ *
+ * @param mixed $data Either a string with a column to quote. An array of columns to quote or an
+ * object from DboSource::expression() or DboSource::identifier()
+ * @return string SQL field
+ */
+ public function name($data) {
+ if (is_object($data) && isset($data->type)) {
+ return $data->value;
+ }
+ if ($data === '*') {
+ return '*';
+ }
+ if (is_array($data)) {
+ foreach ($data as $i => $dataItem) {
+ $data[$i] = $this->name($dataItem);
+ }
+ return $data;
+ }
+ $cacheKey = md5($this->startQuote . $data . $this->endQuote);
+ if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
+ return $return;
+ }
+ $data = trim($data);
+ if (preg_match('/^[\w-]+(?:\.[^ \*]*)*$/', $data)) { // string, string.string
+ if (strpos($data, '.') === false) { // string
+ return $this->cacheMethod(__FUNCTION__, $cacheKey, $this->startQuote . $data . $this->endQuote);
+ }
+ $items = explode('.', $data);
+ return $this->cacheMethod(__FUNCTION__, $cacheKey,
+ $this->startQuote . implode($this->endQuote . '.' . $this->startQuote, $items) . $this->endQuote
+ );
+ }
+ if (preg_match('/^[\w-]+\.\*$/', $data)) { // string.*
+ return $this->cacheMethod(__FUNCTION__, $cacheKey,
+ $this->startQuote . str_replace('.*', $this->endQuote . '.*', $data)
+ );
+ }
+ if (preg_match('/^([\w-]+)\((.*)\)$/', $data, $matches)) { // Functions
+ return $this->cacheMethod(__FUNCTION__, $cacheKey,
+ $matches[1] . '(' . $this->name($matches[2]) . ')'
+ );
+ }
+ if (
+ preg_match('/^([\w-]+(\.[\w-]+|\(.*\))*)\s+' . preg_quote($this->alias) . '\s*([\w-]+)$/i', $data, $matches
+ )) {
+ return $this->cacheMethod(
+ __FUNCTION__, $cacheKey,
+ preg_replace(
+ '/\s{2,}/', ' ', $this->name($matches[1]) . ' ' . $this->alias . ' ' . $this->name($matches[3])
+ )
+ );
+ }
+ if (preg_match('/^[\w-_\s]*[\w-_]+/', $data)) {
+ return $this->cacheMethod(__FUNCTION__, $cacheKey, $this->startQuote . $data . $this->endQuote);
+ }
+ return $this->cacheMethod(__FUNCTION__, $cacheKey, $data);
+ }
+
+/**
+ * Checks if the source is connected to the database.
+ *
+ * @return boolean True if the database is connected, else false
+ */
+ public function isConnected() {
+ return $this->connected;
+ }
+
+/**
+ * Checks if the result is valid
+ *
+ * @return boolean True if the result is valid else false
+ */
+ public function hasResult() {
+ return is_a($this->_result, 'PDOStatement');
+ }
+
+/**
+ * Get the query log as an array.
+ *
+ * @param boolean $sorted Get the queries sorted by time taken, defaults to false.
+ * @param boolean $clear If True the existing log will cleared.
+ * @return array Array of queries run as an array
+ */
+ public function getLog($sorted = false, $clear = true) {
+ if ($sorted) {
+ $log = sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC);
+ } else {
+ $log = $this->_queriesLog;
+ }
+ if ($clear) {
+ $this->_queriesLog = array();
+ }
+ return array('log' => $log, 'count' => $this->_queriesCnt, 'time' => $this->_queriesTime);
+ }
+
+/**
+ * Outputs the contents of the queries log. If in a non-CLI environment the sql_log element
+ * will be rendered and output. If in a CLI environment, a plain text log is generated.
+ *
+ * @param boolean $sorted Get the queries sorted by time taken, defaults to false.
+ * @return void
+ */
+ public function showLog($sorted = false) {
+ $log = $this->getLog($sorted, false);
+ if (empty($log['log'])) {
+ return;
+ }
+ if (PHP_SAPI != 'cli') {
+ $controller = null;
+ $View = new View($controller, false);
+ $View->set('logs', array($this->configKeyName => $log));
+ echo $View->element('sql_dump', array('_forced_from_dbo_' => true));
+ } else {
+ foreach ($log['log'] as $k => $i) {
+ print (($k + 1) . ". {$i['query']}\n");
+ }
+ }
+ }
+
+/**
+ * Log given SQL query.
+ *
+ * @param string $sql SQL statement
+ * @param array $params Values binded to the query (prepared statements)
+ * @return void
+ */
+ public function logQuery($sql, $params = array()) {
+ $this->_queriesCnt++;
+ $this->_queriesTime += $this->took;
+ $this->_queriesLog[] = array(
+ 'query' => $sql,
+ 'params' => $params,
+ 'affected' => $this->affected,
+ 'numRows' => $this->numRows,
+ 'took' => $this->took
+ );
+ if (count($this->_queriesLog) > $this->_queriesLogMax) {
+ array_pop($this->_queriesLog);
+ }
+ }
+
+/**
+ * Gets full table name including prefix
+ *
+ * @param Model|string $model Either a Model object or a string table name.
+ * @param boolean $quote Whether you want the table name quoted.
+ * @param boolean $schema Whether you want the schema name included.
+ * @return string Full quoted table name
+ */
+ public function fullTableName($model, $quote = true, $schema = true) {
+ if (is_object($model)) {
+ $schemaName = $model->schemaName;
+ $table = $model->tablePrefix . $model->table;
+ } elseif (!empty($this->config['prefix']) && strpos($model, $this->config['prefix']) !== 0) {
+ $table = $this->config['prefix'] . strval($model);
+ } else {
+ $table = strval($model);
+ }
+ if ($schema && !isset($schemaName)) {
+ $schemaName = $this->getSchemaName();
+ }
+
+ if ($quote) {
+ if ($schema && !empty($schemaName)) {
+ if (false == strstr($table, '.')) {
+ return $this->name($schemaName) . '.' . $this->name($table);
+ }
+ }
+ return $this->name($table);
+ }
+ if ($schema && !empty($schemaName)) {
+ if (false == strstr($table, '.')) {
+ return $schemaName . '.' . $table;
+ }
+ }
+ return $table;
+ }
+
+/**
+ * The "C" in CRUD
+ *
+ * Creates new records in the database.
+ *
+ * @param Model $model Model object that the record is for.
+ * @param array $fields An array of field names to insert. If null, $model->data will be
+ * used to generate field names.
+ * @param array $values An array of values with keys matching the fields. If null, $model->data will
+ * be used to generate values.
+ * @return boolean Success
+ */
+ public function create(Model $model, $fields = null, $values = null) {
+ $id = null;
+
+ if ($fields == null) {
+ unset($fields, $values);
+ $fields = array_keys($model->data);
+ $values = array_values($model->data);
+ }
+ $count = count($fields);
+
+ for ($i = 0; $i < $count; $i++) {
+ $valueInsert[] = $this->value($values[$i], $model->getColumnType($fields[$i]));
+ $fieldInsert[] = $this->name($fields[$i]);
+ if ($fields[$i] == $model->primaryKey) {
+ $id = $values[$i];
+ }
+ }
+ $query = array(
+ 'table' => $this->fullTableName($model),
+ 'fields' => implode(', ', $fieldInsert),
+ 'values' => implode(', ', $valueInsert)
+ );
+
+ if ($this->execute($this->renderStatement('create', $query))) {
+ if (empty($id)) {
+ $id = $this->lastInsertId($this->fullTableName($model, false, false), $model->primaryKey);
+ }
+ $model->setInsertID($id);
+ $model->id = $id;
+ return true;
+ }
+ $model->onError();
+ return false;
+ }
+
+/**
+ * The "R" in CRUD
+ *
+ * Reads record(s) from the database.
+ *
+ * @param Model $model A Model object that the query is for.
+ * @param array $queryData An array of queryData information containing keys similar to Model::find()
+ * @param integer $recursive Number of levels of association
+ * @return mixed boolean false on error/failure. An array of results on success.
+ */
+ public function read(Model $model, $queryData = array(), $recursive = null) {
+ $queryData = $this->_scrubQueryData($queryData);
+
+ $null = null;
+ $array = array('callbacks' => $queryData['callbacks']);
+ $linkedModels = array();
+ $bypass = false;
+
+ if ($recursive === null && isset($queryData['recursive'])) {
+ $recursive = $queryData['recursive'];
+ }
+
+ if (!is_null($recursive)) {
+ $_recursive = $model->recursive;
+ $model->recursive = $recursive;
+ }
+
+ if (!empty($queryData['fields'])) {
+ $bypass = true;
+ $queryData['fields'] = $this->fields($model, null, $queryData['fields']);
+ } else {
+ $queryData['fields'] = $this->fields($model);
+ }
+
+ $_associations = $model->associations();
+
+ if ($model->recursive == -1) {
+ $_associations = array();
+ } elseif ($model->recursive == 0) {
+ unset($_associations[2], $_associations[3]);
+ }
+
+ foreach ($_associations as $type) {
+ foreach ($model->{$type} as $assoc => $assocData) {
+ $linkModel = $model->{$assoc};
+ $external = isset($assocData['external']);
+
+ $linkModel->getDataSource();
+ if ($model->useDbConfig === $linkModel->useDbConfig) {
+ if ($bypass) {
+ $assocData['fields'] = false;
+ }
+ if (true === $this->generateAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
+ $linkedModels[$type . '/' . $assoc] = true;
+ }
+ }
+ }
+ }
+
+ $query = trim($this->generateAssociationQuery($model, null, null, null, null, $queryData, false, $null));
+
+ $resultSet = $this->fetchAll($query, $model->cacheQueries);
+
+ if ($resultSet === false) {
+ $model->onError();
+ return false;
+ }
+
+ $filtered = array();
+
+ if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
+ $filtered = $this->_filterResults($resultSet, $model);
+ }
+
+ if ($model->recursive > -1) {
+ $joined = array();
+ if (isset($queryData['joins'][0]['alias'])) {
+ $joined[$model->alias] = (array)Hash::extract($queryData['joins'], '{n}.alias');
+ }
+ foreach ($_associations as $type) {
+ foreach ($model->{$type} as $assoc => $assocData) {
+ $linkModel = $model->{$assoc};
+
+ if (!isset($linkedModels[$type . '/' . $assoc])) {
+ if ($model->useDbConfig === $linkModel->useDbConfig) {
+ $db = $this;
+ } else {
+ $db = ConnectionManager::getDataSource($linkModel->useDbConfig);
+ }
+ } elseif ($model->recursive > 1 && ($type === 'belongsTo' || $type === 'hasOne')) {
+ $db = $this;
+ }
+
+ if (isset($db) && method_exists($db, 'queryAssociation')) {
+ $stack = array($assoc);
+ $stack['_joined'] = $joined;
+ $db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1, $stack);
+ unset($db);
+
+ if ($type === 'hasMany') {
+ $filtered[] = $assoc;
+ }
+ }
+ }
+ }
+ if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
+ $this->_filterResults($resultSet, $model, $filtered);
+ }
+ }
+
+ if (!is_null($recursive)) {
+ $model->recursive = $_recursive;
+ }
+ return $resultSet;
+ }
+
+/**
+ * Passes association results thru afterFind filters of corresponding model
+ *
+ * @param array $results Reference of resultset to be filtered
+ * @param Model $model Instance of model to operate against
+ * @param array $filtered List of classes already filtered, to be skipped
+ * @return array Array of results that have been filtered through $model->afterFind
+ */
+ protected function _filterResults(&$results, Model $model, $filtered = array()) {
+ $current = reset($results);
+ if (!is_array($current)) {
+ return array();
+ }
+ $keys = array_diff(array_keys($current), $filtered, array($model->alias));
+ $filtering = array();
+ foreach ($keys as $className) {
+ if (!isset($model->{$className}) || !is_object($model->{$className})) {
+ continue;
+ }
+ $linkedModel = $model->{$className};
+ $filtering[] = $className;
+ foreach ($results as &$result) {
+ $data = $linkedModel->afterFind(array(array($className => $result[$className])), false);
+ if (isset($data[0][$className])) {
+ $result[$className] = $data[0][$className];
+ }
+ }
+ }
+ return $filtering;
+ }
+
+/**
+ * Queries associations. Used to fetch results on recursive models.
+ *
+ * @param Model $model Primary Model object
+ * @param Model $linkModel Linked model that
+ * @param string $type Association type, one of the model association types ie. hasMany
+ * @param string $association
+ * @param array $assocData
+ * @param array $queryData
+ * @param boolean $external Whether or not the association query is on an external datasource.
+ * @param array $resultSet Existing results
+ * @param integer $recursive Number of levels of association
+ * @param array $stack
+ * @return mixed
+ * @throws CakeException when results cannot be created.
+ */
+ public function queryAssociation(Model $model, &$linkModel, $type, $association, $assocData, &$queryData, $external, &$resultSet, $recursive, $stack) {
+ if (isset($stack['_joined'])) {
+ $joined = $stack['_joined'];
+ unset($stack['_joined']);
+ }
+
+ if ($query = $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet)) {
+ if (!is_array($resultSet)) {
+ throw new CakeException(__d('cake_dev', 'Error in Model %s', get_class($model)));
+ }
+ if ($type === 'hasMany' && empty($assocData['limit']) && !empty($assocData['foreignKey'])) {
+ $ins = $fetch = array();
+ foreach ($resultSet as &$result) {
+ if ($in = $this->insertQueryData('{$__cakeID__$}', $result, $association, $assocData, $model, $linkModel, $stack)) {
+ $ins[] = $in;
+ }
+ }
+
+ if (!empty($ins)) {
+ $ins = array_unique($ins);
+ $fetch = $this->fetchAssociated($model, $query, $ins);
+ }
+
+ if (!empty($fetch) && is_array($fetch)) {
+ if ($recursive > 0) {
+ foreach ($linkModel->associations() as $type1) {
+ foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
+ $deepModel = $linkModel->{$assoc1};
+ $tmpStack = $stack;
+ $tmpStack[] = $assoc1;
+
+ if ($linkModel->useDbConfig === $deepModel->useDbConfig) {
+ $db = $this;
+ } else {
+ $db = ConnectionManager::getDataSource($deepModel->useDbConfig);
+ }
+ $db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
+ }
+ }
+ }
+ }
+ if ($queryData['callbacks'] === true || $queryData['callbacks'] === 'after') {
+ $this->_filterResults($fetch, $model);
+ }
+ return $this->_mergeHasMany($resultSet, $fetch, $association, $model, $linkModel);
+ } elseif ($type === 'hasAndBelongsToMany') {
+ $ins = $fetch = array();
+ foreach ($resultSet as &$result) {
+ if ($in = $this->insertQueryData('{$__cakeID__$}', $result, $association, $assocData, $model, $linkModel, $stack)) {
+ $ins[] = $in;
+ }
+ }
+ if (!empty($ins)) {
+ $ins = array_unique($ins);
+ if (count($ins) > 1) {
+ $query = str_replace('{$__cakeID__$}', '(' . implode(', ', $ins) . ')', $query);
+ $query = str_replace('= (', 'IN (', $query);
+ } else {
+ $query = str_replace('{$__cakeID__$}', $ins[0], $query);
+ }
+ $query = str_replace(' WHERE 1 = 1', '', $query);
+ }
+
+ $foreignKey = $model->hasAndBelongsToMany[$association]['foreignKey'];
+ $joinKeys = array($foreignKey, $model->hasAndBelongsToMany[$association]['associationForeignKey']);
+ list($with, $habtmFields) = $model->joinModel($model->hasAndBelongsToMany[$association]['with'], $joinKeys);
+ $habtmFieldsCount = count($habtmFields);
+ $q = $this->insertQueryData($query, null, $association, $assocData, $model, $linkModel, $stack);
+
+ if ($q !== false) {
+ $fetch = $this->fetchAll($q, $model->cacheQueries);
+ } else {
+ $fetch = null;
+ }
+ }
+
+ $modelAlias = $model->alias;
+ $modelPK = $model->primaryKey;
+ foreach ($resultSet as &$row) {
+ if ($type !== 'hasAndBelongsToMany') {
+ $q = $this->insertQueryData($query, $row, $association, $assocData, $model, $linkModel, $stack);
+ $fetch = null;
+ if ($q !== false) {
+ $joinedData = array();
+ if (($type === 'belongsTo' || $type === 'hasOne') && isset($row[$linkModel->alias], $joined[$model->alias]) && in_array($linkModel->alias, $joined[$model->alias])) {
+ $joinedData = Hash::filter($row[$linkModel->alias]);
+ if (!empty($joinedData)) {
+ $fetch[0] = array($linkModel->alias => $row[$linkModel->alias]);
+ }
+ } else {
+ $fetch = $this->fetchAll($q, $model->cacheQueries);
+ }
+ }
+ }
+ $selfJoin = $linkModel->name === $model->name;
+
+ if (!empty($fetch) && is_array($fetch)) {
+ if ($recursive > 0) {
+ foreach ($linkModel->associations() as $type1) {
+ foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
+ $deepModel = $linkModel->{$assoc1};
+
+ if ($type1 === 'belongsTo' || ($deepModel->alias === $modelAlias && $type === 'belongsTo') || ($deepModel->alias !== $modelAlias)) {
+ $tmpStack = $stack;
+ $tmpStack[] = $assoc1;
+ if ($linkModel->useDbConfig == $deepModel->useDbConfig) {
+ $db = $this;
+ } else {
+ $db = ConnectionManager::getDataSource($deepModel->useDbConfig);
+ }
+ $db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
+ }
+ }
+ }
+ }
+ if ($type === 'hasAndBelongsToMany') {
+ $uniqueIds = $merge = array();
+
+ foreach ($fetch as $j => $data) {
+ if (isset($data[$with]) && $data[$with][$foreignKey] === $row[$modelAlias][$modelPK]) {
+ if ($habtmFieldsCount <= 2) {
+ unset($data[$with]);
+ }
+ $merge[] = $data;
+ }
+ }
+ if (empty($merge) && !isset($row[$association])) {
+ $row[$association] = $merge;
+ } else {
+ $this->_mergeAssociation($row, $merge, $association, $type);
+ }
+ } else {
+ $this->_mergeAssociation($row, $fetch, $association, $type, $selfJoin);
+ }
+ if (isset($row[$association])) {
+ $row[$association] = $linkModel->afterFind($row[$association], false);
+ }
+ } else {
+ $tempArray[0][$association] = false;
+ $this->_mergeAssociation($row, $tempArray, $association, $type, $selfJoin);
+ }
+ }
+ }
+ }
+
+/**
+ * A more efficient way to fetch associations. Woohoo!
+ *
+ * @param Model $model Primary model object
+ * @param string $query Association query
+ * @param array $ids Array of IDs of associated records
+ * @return array Association results
+ */
+ public function fetchAssociated(Model $model, $query, $ids) {
+ $query = str_replace('{$__cakeID__$}', implode(', ', $ids), $query);
+ if (count($ids) > 1) {
+ $query = str_replace('= (', 'IN (', $query);
+ }
+ return $this->fetchAll($query, $model->cacheQueries);
+ }
+
+/**
+ * mergeHasMany - Merge the results of hasMany relations.
+ *
+ *
+ * @param array $resultSet Data to merge into
+ * @param array $merge Data to merge
+ * @param string $association Name of Model being Merged
+ * @param Model $model Model being merged onto
+ * @param Model $linkModel Model being merged
+ * @return void
+ */
+ protected function _mergeHasMany(&$resultSet, $merge, $association, $model, $linkModel) {
+ $modelAlias = $model->alias;
+ $modelPK = $model->primaryKey;
+ $modelFK = $model->hasMany[$association]['foreignKey'];
+ foreach ($resultSet as &$result) {
+ if (!isset($result[$modelAlias])) {
+ continue;
+ }
+ $merged = array();
+ foreach ($merge as $data) {
+ if ($result[$modelAlias][$modelPK] === $data[$association][$modelFK]) {
+ if (count($data) > 1) {
+ $data = array_merge($data[$association], $data);
+ unset($data[$association]);
+ foreach ($data as $key => $name) {
+ if (is_numeric($key)) {
+ $data[$association][] = $name;
+ unset($data[$key]);
+ }
+ }
+ $merged[] = $data;
+ } else {
+ $merged[] = $data[$association];
+ }
+ }
+ }
+ $result = Hash::mergeDiff($result, array($association => $merged));
+ }
+ }
+
+/**
+ * Merge association of merge into data
+ *
+ * @param array $data
+ * @param array $merge
+ * @param string $association
+ * @param string $type
+ * @param boolean $selfJoin
+ * @return void
+ */
+ protected function _mergeAssociation(&$data, &$merge, $association, $type, $selfJoin = false) {
+ if (isset($merge[0]) && !isset($merge[0][$association])) {
+ $association = Inflector::pluralize($association);
+ }
+
+ if ($type === 'belongsTo' || $type === 'hasOne') {
+ if (isset($merge[$association])) {
+ $data[$association] = $merge[$association][0];
+ } else {
+ if (count($merge[0][$association]) > 1) {
+ foreach ($merge[0] as $assoc => $data2) {
+ if ($assoc !== $association) {
+ $merge[0][$association][$assoc] = $data2;
+ }
+ }
+ }
+ if (!isset($data[$association])) {
+ if ($merge[0][$association] != null) {
+ $data[$association] = $merge[0][$association];
+ } else {
+ $data[$association] = array();
+ }
+ } else {
+ if (is_array($merge[0][$association])) {
+ foreach ($data[$association] as $k => $v) {
+ if (!is_array($v)) {
+ $dataAssocTmp[$k] = $v;
+ }
+ }
+
+ foreach ($merge[0][$association] as $k => $v) {
+ if (!is_array($v)) {
+ $mergeAssocTmp[$k] = $v;
+ }
+ }
+ $dataKeys = array_keys($data);
+ $mergeKeys = array_keys($merge[0]);
+
+ if ($mergeKeys[0] === $dataKeys[0] || $mergeKeys === $dataKeys) {
+ $data[$association][$association] = $merge[0][$association];
+ } else {
+ $diff = Hash::diff($dataAssocTmp, $mergeAssocTmp);
+ $data[$association] = array_merge($merge[0][$association], $diff);
+ }
+ } elseif ($selfJoin && array_key_exists($association, $merge[0])) {
+ $data[$association] = array_merge($data[$association], array($association => array()));
+ }
+ }
+ }
+ } else {
+ if (isset($merge[0][$association]) && $merge[0][$association] === false) {
+ if (!isset($data[$association])) {
+ $data[$association] = array();
+ }
+ } else {
+ foreach ($merge as $i => $row) {
+ $insert = array();
+ if (count($row) === 1) {
+ $insert = $row[$association];
+ } elseif (isset($row[$association])) {
+ $insert = array_merge($row[$association], $row);
+ unset($insert[$association]);
+ }
+
+ if (empty($data[$association]) || (isset($data[$association]) && !in_array($insert, $data[$association], true))) {
+ $data[$association][] = $insert;
+ }
+ }
+ }
+ }
+ }
+
+/**
+ * Generates an array representing a query or part of a query from a single model or two associated models
+ *
+ * @param Model $model
+ * @param Model $linkModel
+ * @param string $type
+ * @param string $association
+ * @param array $assocData
+ * @param array $queryData
+ * @param boolean $external
+ * @param array $resultSet
+ * @return mixed
+ */
+ public function generateAssociationQuery(Model $model, $linkModel, $type, $association, $assocData, &$queryData, $external, &$resultSet) {
+ $queryData = $this->_scrubQueryData($queryData);
+ $assocData = $this->_scrubQueryData($assocData);
+ $modelAlias = $model->alias;
+
+ if (empty($queryData['fields'])) {
+ $queryData['fields'] = $this->fields($model, $modelAlias);
+ } elseif (!empty($model->hasMany) && $model->recursive > -1) {
+ $assocFields = $this->fields($model, $modelAlias, array("{$modelAlias}.{$model->primaryKey}"));
+ $passedFields = $queryData['fields'];
+ if (count($passedFields) === 1) {
+ if (strpos($passedFields[0], $assocFields[0]) === false && !preg_match('/^[a-z]+\(/i', $passedFields[0])) {
+ $queryData['fields'] = array_merge($passedFields, $assocFields);
+ } else {
+ $queryData['fields'] = $passedFields;
+ }
+ } else {
+ $queryData['fields'] = array_merge($passedFields, $assocFields);
+ }
+ unset($assocFields, $passedFields);
+ }
+
+ if ($linkModel === null) {
+ return $this->buildStatement(
+ array(
+ 'fields' => array_unique($queryData['fields']),
+ 'table' => $this->fullTableName($model),
+ 'alias' => $modelAlias,
+ 'limit' => $queryData['limit'],
+ 'offset' => $queryData['offset'],
+ 'joins' => $queryData['joins'],
+ 'conditions' => $queryData['conditions'],
+ 'order' => $queryData['order'],
+ 'group' => $queryData['group']
+ ),
+ $model
+ );
+ }
+ if ($external && !empty($assocData['finderQuery'])) {
+ return $assocData['finderQuery'];
+ }
+
+ $self = $model->name === $linkModel->name;
+ $fields = array();
+
+ if ($external || (in_array($type, array('hasOne', 'belongsTo')) && $assocData['fields'] !== false)) {
+ $fields = $this->fields($linkModel, $association, $assocData['fields']);
+ }
+ if (empty($assocData['offset']) && !empty($assocData['page'])) {
+ $assocData['offset'] = ($assocData['page'] - 1) * $assocData['limit'];
+ }
+ $assocData['limit'] = $this->limit($assocData['limit'], $assocData['offset']);
+
+ switch ($type) {
+ case 'hasOne':
+ case 'belongsTo':
+ $conditions = $this->_mergeConditions(
+ $assocData['conditions'],
+ $this->getConstraint($type, $model, $linkModel, $association, array_merge($assocData, compact('external', 'self')))
+ );
+
+ if (!$self && $external) {
+ foreach ($conditions as $key => $condition) {
+ if (is_numeric($key) && strpos($condition, $modelAlias . '.') !== false) {
+ unset($conditions[$key]);
+ }
+ }
+ }
+
+ if ($external) {
+ $query = array_merge($assocData, array(
+ 'conditions' => $conditions,
+ 'table' => $this->fullTableName($linkModel),
+ 'fields' => $fields,
+ 'alias' => $association,
+ 'group' => null
+ ));
+ $query += array('order' => $assocData['order'], 'limit' => $assocData['limit']);
+ } else {
+ $join = array(
+ 'table' => $linkModel,
+ 'alias' => $association,
+ 'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT',
+ 'conditions' => trim($this->conditions($conditions, true, false, $model))
+ );
+ $queryData['fields'] = array_merge($queryData['fields'], $fields);
+
+ if (!empty($assocData['order'])) {
+ $queryData['order'][] = $assocData['order'];
+ }
+ if (!in_array($join, $queryData['joins'])) {
+ $queryData['joins'][] = $join;
+ }
+ return true;
+ }
+ break;
+ case 'hasMany':
+ $assocData['fields'] = $this->fields($linkModel, $association, $assocData['fields']);
+ if (!empty($assocData['foreignKey'])) {
+ $assocData['fields'] = array_merge($assocData['fields'], $this->fields($linkModel, $association, array("{$association}.{$assocData['foreignKey']}")));
+ }
+ $query = array(
+ 'conditions' => $this->_mergeConditions($this->getConstraint('hasMany', $model, $linkModel, $association, $assocData), $assocData['conditions']),
+ 'fields' => array_unique($assocData['fields']),
+ 'table' => $this->fullTableName($linkModel),
+ 'alias' => $association,
+ 'order' => $assocData['order'],
+ 'limit' => $assocData['limit'],
+ 'group' => null
+ );
+ break;
+ case 'hasAndBelongsToMany':
+ $joinFields = array();
+ $joinAssoc = null;
+
+ if (isset($assocData['with']) && !empty($assocData['with'])) {
+ $joinKeys = array($assocData['foreignKey'], $assocData['associationForeignKey']);
+ list($with, $joinFields) = $model->joinModel($assocData['with'], $joinKeys);
+
+ $joinTbl = $model->{$with};
+ $joinAlias = $joinTbl;
+
+ if (is_array($joinFields) && !empty($joinFields)) {
+ $joinAssoc = $joinAlias = $model->{$with}->alias;
+ $joinFields = $this->fields($model->{$with}, $joinAlias, $joinFields);
+ } else {
+ $joinFields = array();
+ }
+ } else {
+ $joinTbl = $assocData['joinTable'];
+ $joinAlias = $this->fullTableName($assocData['joinTable']);
+ }
+ $query = array(
+ 'conditions' => $assocData['conditions'],
+ 'limit' => $assocData['limit'],
+ 'table' => $this->fullTableName($linkModel),
+ 'alias' => $association,
+ 'fields' => array_merge($this->fields($linkModel, $association, $assocData['fields']), $joinFields),
+ 'order' => $assocData['order'],
+ 'group' => null,
+ 'joins' => array(array(
+ 'table' => $joinTbl,
+ 'alias' => $joinAssoc,
+ 'conditions' => $this->getConstraint('hasAndBelongsToMany', $model, $linkModel, $joinAlias, $assocData, $association)
+ ))
+ );
+ break;
+ }
+ if (isset($query)) {
+ return $this->buildStatement($query, $model);
+ }
+ return null;
+ }
+
+/**
+ * Returns a conditions array for the constraint between two models
+ *
+ * @param string $type Association type
+ * @param Model $model Model object
+ * @param string $linkModel
+ * @param string $alias
+ * @param array $assoc
+ * @param string $alias2
+ * @return array Conditions array defining the constraint between $model and $association
+ */
+ public function getConstraint($type, $model, $linkModel, $alias, $assoc, $alias2 = null) {
+ $assoc += array('external' => false, 'self' => false);
+
+ if (empty($assoc['foreignKey'])) {
+ return array();
+ }
+
+ switch (true) {
+ case ($assoc['external'] && $type === 'hasOne'):
+ return array("{$alias}.{$assoc['foreignKey']}" => '{$__cakeID__$}');
+ case ($assoc['external'] && $type === 'belongsTo'):
+ return array("{$alias}.{$linkModel->primaryKey}" => '{$__cakeForeignKey__$}');
+ case (!$assoc['external'] && $type === 'hasOne'):
+ return array("{$alias}.{$assoc['foreignKey']}" => $this->identifier("{$model->alias}.{$model->primaryKey}"));
+ case (!$assoc['external'] && $type === 'belongsTo'):
+ return array("{$model->alias}.{$assoc['foreignKey']}" => $this->identifier("{$alias}.{$linkModel->primaryKey}"));
+ case ($type === 'hasMany'):
+ return array("{$alias}.{$assoc['foreignKey']}" => array('{$__cakeID__$}'));
+ case ($type === 'hasAndBelongsToMany'):
+ return array(
+ array("{$alias}.{$assoc['foreignKey']}" => '{$__cakeID__$}'),
+ array("{$alias}.{$assoc['associationForeignKey']}" => $this->identifier("{$alias2}.{$linkModel->primaryKey}"))
+ );
+ }
+ return array();
+ }
+
+/**
+ * Builds and generates a JOIN statement from an array. Handles final clean-up before conversion.
+ *
+ * @param array $join An array defining a JOIN statement in a query
+ * @return string An SQL JOIN statement to be used in a query
+ * @see DboSource::renderJoinStatement()
+ * @see DboSource::buildStatement()
+ */
+ public function buildJoinStatement($join) {
+ $data = array_merge(array(
+ 'type' => null,
+ 'alias' => null,
+ 'table' => 'join_table',
+ 'conditions' => array()
+ ), $join);
+
+ if (!empty($data['alias'])) {
+ $data['alias'] = $this->alias . $this->name($data['alias']);
+ }
+ if (!empty($data['conditions'])) {
+ $data['conditions'] = trim($this->conditions($data['conditions'], true, false));
+ }
+ if (!empty($data['table'])) {
+ $schema = !(is_string($data['table']) && strpos($data['table'], '(') === 0);
+ $data['table'] = $this->fullTableName($data['table'], true, $schema);
+ }
+ return $this->renderJoinStatement($data);
+ }
+
+/**
+ * Builds and generates an SQL statement from an array. Handles final clean-up before conversion.
+ *
+ * @param array $query An array defining an SQL query
+ * @param Model $model The model object which initiated the query
+ * @return string An executable SQL statement
+ * @see DboSource::renderStatement()
+ */
+ public function buildStatement($query, $model) {
+ $query = array_merge($this->_queryDefaults, $query);
+ if (!empty($query['joins'])) {
+ $count = count($query['joins']);
+ for ($i = 0; $i < $count; $i++) {
+ if (is_array($query['joins'][$i])) {
+ $query['joins'][$i] = $this->buildJoinStatement($query['joins'][$i]);
+ }
+ }
+ }
+ return $this->renderStatement('select', array(
+ 'conditions' => $this->conditions($query['conditions'], true, true, $model),
+ 'fields' => implode(', ', $query['fields']),
+ 'table' => $query['table'],
+ 'alias' => $this->alias . $this->name($query['alias']),
+ 'order' => $this->order($query['order'], 'ASC', $model),
+ 'limit' => $this->limit($query['limit'], $query['offset']),
+ 'joins' => implode(' ', $query['joins']),
+ 'group' => $this->group($query['group'], $model)
+ ));
+ }
+
+/**
+ * Renders a final SQL JOIN statement
+ *
+ * @param array $data
+ * @return string
+ */
+ public function renderJoinStatement($data) {
+ extract($data);
+ return trim("{$type} JOIN {$table} {$alias} ON ({$conditions})");
+ }
+
+/**
+ * Renders a final SQL statement by putting together the component parts in the correct order
+ *
+ * @param string $type type of query being run. e.g select, create, update, delete, schema, alter.
+ * @param array $data Array of data to insert into the query.
+ * @return string Rendered SQL expression to be run.
+ */
+ public function renderStatement($type, $data) {
+ extract($data);
+ $aliases = null;
+
+ switch (strtolower($type)) {
+ case 'select':
+ return "SELECT {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$group} {$order} {$limit}";
+ case 'create':
+ return "INSERT INTO {$table} ({$fields}) VALUES ({$values})";
+ case 'update':
+ if (!empty($alias)) {
+ $aliases = "{$this->alias}{$alias} {$joins} ";
+ }
+ return "UPDATE {$table} {$aliases}SET {$fields} {$conditions}";
+ case 'delete':
+ if (!empty($alias)) {
+ $aliases = "{$this->alias}{$alias} {$joins} ";
+ }
+ return "DELETE {$alias} FROM {$table} {$aliases}{$conditions}";
+ case 'schema':
+ foreach (array('columns', 'indexes', 'tableParameters') as $var) {
+ if (is_array(${$var})) {
+ ${$var} = "\t" . join(",\n\t", array_filter(${$var}));
+ } else {
+ ${$var} = '';
+ }
+ }
+ if (trim($indexes) !== '') {
+ $columns .= ',';
+ }
+ return "CREATE TABLE {$table} (\n{$columns}{$indexes}) {$tableParameters};";
+ case 'alter':
+ return;
+ }
+ }
+
+/**
+ * Merges a mixed set of string/array conditions
+ *
+ * @param mixed $query
+ * @param mixed $assoc
+ * @return array
+ */
+ protected function _mergeConditions($query, $assoc) {
+ if (empty($assoc)) {
+ return $query;
+ }
+
+ if (is_array($query)) {
+ return array_merge((array)$assoc, $query);
+ }
+
+ if (!empty($query)) {
+ $query = array($query);
+ if (is_array($assoc)) {
+ $query = array_merge($query, $assoc);
+ } else {
+ $query[] = $assoc;
+ }
+ return $query;
+ }
+
+ return $assoc;
+ }
+
+/**
+ * Generates and executes an SQL UPDATE statement for given model, fields, and values.
+ * For databases that do not support aliases in UPDATE queries.
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @param mixed $conditions
+ * @return boolean Success
+ */
+ public function update(Model $model, $fields = array(), $values = null, $conditions = null) {
+ if ($values == null) {
+ $combined = $fields;
+ } else {
+ $combined = array_combine($fields, $values);
+ }
+
+ $fields = implode(', ', $this->_prepareUpdateFields($model, $combined, empty($conditions)));
+
+ $alias = $joins = null;
+ $table = $this->fullTableName($model);
+ $conditions = $this->_matchRecords($model, $conditions);
+
+ if ($conditions === false) {
+ return false;
+ }
+ $query = compact('table', 'alias', 'joins', 'fields', 'conditions');
+
+ if (!$this->execute($this->renderStatement('update', $query))) {
+ $model->onError();
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Quotes and prepares fields and values for an SQL UPDATE statement
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param boolean $quoteValues If values should be quoted, or treated as SQL snippets
+ * @param boolean $alias Include the model alias in the field name
+ * @return array Fields and values, quoted and prepared
+ */
+ protected function _prepareUpdateFields(Model $model, $fields, $quoteValues = true, $alias = false) {
+ $quotedAlias = $this->startQuote . $model->alias . $this->endQuote;
+
+ $updates = array();
+ foreach ($fields as $field => $value) {
+ if ($alias && strpos($field, '.') === false) {
+ $quoted = $model->escapeField($field);
+ } elseif (!$alias && strpos($field, '.') !== false) {
+ $quoted = $this->name(str_replace($quotedAlias . '.', '', str_replace(
+ $model->alias . '.', '', $field
+ )));
+ } else {
+ $quoted = $this->name($field);
+ }
+
+ if ($value === null) {
+ $updates[] = $quoted . ' = NULL';
+ continue;
+ }
+ $update = $quoted . ' = ';
+
+ if ($quoteValues) {
+ $update .= $this->value($value, $model->getColumnType($field));
+ } elseif ($model->getColumnType($field) == 'boolean' && (is_int($value) || is_bool($value))) {
+ $update .= $this->boolean($value, true);
+ } elseif (!$alias) {
+ $update .= str_replace($quotedAlias . '.', '', str_replace(
+ $model->alias . '.', '', $value
+ ));
+ } else {
+ $update .= $value;
+ }
+ $updates[] = $update;
+ }
+ return $updates;
+ }
+
+/**
+ * Generates and executes an SQL DELETE statement.
+ * For databases that do not support aliases in UPDATE queries.
+ *
+ * @param Model $model
+ * @param mixed $conditions
+ * @return boolean Success
+ */
+ public function delete(Model $model, $conditions = null) {
+ $alias = $joins = null;
+ $table = $this->fullTableName($model);
+ $conditions = $this->_matchRecords($model, $conditions);
+
+ if ($conditions === false) {
+ return false;
+ }
+
+ if ($this->execute($this->renderStatement('delete', compact('alias', 'table', 'joins', 'conditions'))) === false) {
+ $model->onError();
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Gets a list of record IDs for the given conditions. Used for multi-record updates and deletes
+ * in databases that do not support aliases in UPDATE/DELETE queries.
+ *
+ * @param Model $model
+ * @param mixed $conditions
+ * @return array List of record IDs
+ */
+ protected function _matchRecords(Model $model, $conditions = null) {
+ if ($conditions === true) {
+ $conditions = $this->conditions(true);
+ } elseif ($conditions === null) {
+ $conditions = $this->conditions($this->defaultConditions($model, $conditions, false), true, true, $model);
+ } else {
+ $noJoin = true;
+ foreach ($conditions as $field => $value) {
+ $originalField = $field;
+ if (strpos($field, '.') !== false) {
+ list($alias, $field) = explode('.', $field);
+ $field = ltrim($field, $this->startQuote);
+ $field = rtrim($field, $this->endQuote);
+ }
+ if (!$model->hasField($field)) {
+ $noJoin = false;
+ break;
+ }
+ if ($field !== $originalField) {
+ $conditions[$field] = $value;
+ unset($conditions[$originalField]);
+ }
+ }
+ if ($noJoin === true) {
+ return $this->conditions($conditions);
+ }
+ $idList = $model->find('all', array(
+ 'fields' => "{$model->alias}.{$model->primaryKey}",
+ 'conditions' => $conditions
+ ));
+
+ if (empty($idList)) {
+ return false;
+ }
+ $conditions = $this->conditions(array(
+ $model->primaryKey => Hash::extract($idList, "{n}.{$model->alias}.{$model->primaryKey}")
+ ));
+ }
+ return $conditions;
+ }
+
+/**
+ * Returns an array of SQL JOIN fragments from a model's associations
+ *
+ * @param Model $model
+ * @return array
+ */
+ protected function _getJoins(Model $model) {
+ $join = array();
+ $joins = array_merge($model->getAssociated('hasOne'), $model->getAssociated('belongsTo'));
+
+ foreach ($joins as $assoc) {
+ if (isset($model->{$assoc}) && $model->useDbConfig == $model->{$assoc}->useDbConfig && $model->{$assoc}->getDataSource()) {
+ $assocData = $model->getAssociated($assoc);
+ $join[] = $this->buildJoinStatement(array(
+ 'table' => $model->{$assoc},
+ 'alias' => $assoc,
+ 'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT',
+ 'conditions' => trim($this->conditions(
+ $this->_mergeConditions($assocData['conditions'], $this->getConstraint($assocData['association'], $model, $model->{$assoc}, $assoc, $assocData)),
+ true, false, $model
+ ))
+ ));
+ }
+ }
+ return $join;
+ }
+
+/**
+ * Returns an SQL calculation, i.e. COUNT() or MAX()
+ *
+ * @param Model $model
+ * @param string $func Lowercase name of SQL function, i.e. 'count' or 'max'
+ * @param array $params Function parameters (any values must be quoted manually)
+ * @return string An SQL calculation function
+ */
+ public function calculate(Model $model, $func, $params = array()) {
+ $params = (array)$params;
+
+ switch (strtolower($func)) {
+ case 'count':
+ if (!isset($params[0])) {
+ $params[0] = '*';
+ }
+ if (!isset($params[1])) {
+ $params[1] = 'count';
+ }
+ if (is_object($model) && $model->isVirtualField($params[0])) {
+ $arg = $this->_quoteFields($model->getVirtualField($params[0]));
+ } else {
+ $arg = $this->name($params[0]);
+ }
+ return 'COUNT(' . $arg . ') AS ' . $this->name($params[1]);
+ case 'max':
+ case 'min':
+ if (!isset($params[1])) {
+ $params[1] = $params[0];
+ }
+ if (is_object($model) && $model->isVirtualField($params[0])) {
+ $arg = $this->_quoteFields($model->getVirtualField($params[0]));
+ } else {
+ $arg = $this->name($params[0]);
+ }
+ return strtoupper($func) . '(' . $arg . ') AS ' . $this->name($params[1]);
+ break;
+ }
+ }
+
+/**
+ * Deletes all the records in a table and resets the count of the auto-incrementing
+ * primary key, where applicable.
+ *
+ * @param Model|string $table A string or model class representing the table to be truncated
+ * @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
+ */
+ public function truncate($table) {
+ return $this->execute('TRUNCATE TABLE ' . $this->fullTableName($table));
+ }
+
+/**
+ * Check if the server support nested transactions
+ *
+ * @return boolean
+ */
+ public function nestedTransactionSupported() {
+ return false;
+ }
+
+/**
+ * Begin a transaction
+ *
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ public function begin() {
+ if ($this->_transactionStarted) {
+ if ($this->nestedTransactionSupported()) {
+ return $this->_beginNested();
+ }
+ $this->_transactionNesting++;
+ return $this->_transactionStarted;
+ }
+
+ $this->_transactionNesting = 0;
+ if ($this->fullDebug) {
+ $this->logQuery('BEGIN');
+ }
+ return $this->_transactionStarted = $this->_connection->beginTransaction();
+ }
+
+/**
+ * Begin a nested transaction
+ *
+ * @return boolean
+ */
+ protected function _beginNested() {
+ $query = 'SAVEPOINT LEVEL' . ++$this->_transactionNesting;
+ if ($this->fullDebug) {
+ $this->logQuery($query);
+ }
+ $this->_connection->exec($query);
+ return true;
+ }
+
+/**
+ * Commit a transaction
+ *
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ public function commit() {
+ if (!$this->_transactionStarted) {
+ return false;
+ }
+
+ if ($this->_transactionNesting === 0) {
+ if ($this->fullDebug) {
+ $this->logQuery('COMMIT');
+ }
+ $this->_transactionStarted = false;
+ return $this->_connection->commit();
+ }
+
+ if ($this->nestedTransactionSupported()) {
+ return $this->_commitNested();
+ }
+
+ $this->_transactionNesting--;
+ return true;
+ }
+
+/**
+ * Commit a nested transaction
+ *
+ * @return boolean
+ */
+ protected function _commitNested() {
+ $query = 'RELEASE SAVEPOINT LEVEL' . $this->_transactionNesting--;
+ if ($this->fullDebug) {
+ $this->logQuery($query);
+ }
+ $this->_connection->exec($query);
+ return true;
+ }
+
+/**
+ * Rollback a transaction
+ *
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ public function rollback() {
+ if (!$this->_transactionStarted) {
+ return false;
+ }
+
+ if ($this->_transactionNesting === 0) {
+ if ($this->fullDebug) {
+ $this->logQuery('ROLLBACK');
+ }
+ $this->_transactionStarted = false;
+ return $this->_connection->rollBack();
+ }
+
+ if ($this->nestedTransactionSupported()) {
+ return $this->_rollbackNested();
+ }
+
+ $this->_transactionNesting--;
+ return true;
+ }
+
+/**
+ * Rollback a nested transaction
+ *
+ * @return boolean
+ */
+ protected function _rollbackNested() {
+ $query = 'ROLLBACK TO SAVEPOINT LEVEL' . $this->_transactionNesting--;
+ if ($this->fullDebug) {
+ $this->logQuery($query);
+ }
+ $this->_connection->exec($query);
+ return true;
+ }
+
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param mixed $source
+ * @return mixed
+ */
+ public function lastInsertId($source = null) {
+ return $this->_connection->lastInsertId();
+ }
+
+/**
+ * Creates a default set of conditions from the model if $conditions is null/empty.
+ * If conditions are supplied then they will be returned. If a model doesn't exist and no conditions
+ * were provided either null or false will be returned based on what was input.
+ *
+ * @param Model $model
+ * @param string|array|boolean $conditions Array of conditions, conditions string, null or false. If an array of conditions,
+ * or string conditions those conditions will be returned. With other values the model's existence will be checked.
+ * If the model doesn't exist a null or false will be returned depending on the input value.
+ * @param boolean $useAlias Use model aliases rather than table names when generating conditions
+ * @return mixed Either null, false, $conditions or an array of default conditions to use.
+ * @see DboSource::update()
+ * @see DboSource::conditions()
+ */
+ public function defaultConditions(Model $model, $conditions, $useAlias = true) {
+ if (!empty($conditions)) {
+ return $conditions;
+ }
+ $exists = $model->exists();
+ if (!$exists && $conditions !== null) {
+ return false;
+ } elseif (!$exists) {
+ return null;
+ }
+ $alias = $model->alias;
+
+ if (!$useAlias) {
+ $alias = $this->fullTableName($model, false);
+ }
+ return array("{$alias}.{$model->primaryKey}" => $model->getID());
+ }
+
+/**
+ * Returns a key formatted like a string Model.fieldname(i.e. Post.title, or Country.name)
+ *
+ * @param Model $model
+ * @param string $key
+ * @param string $assoc
+ * @return string
+ */
+ public function resolveKey(Model $model, $key, $assoc = null) {
+ if (strpos('.', $key) !== false) {
+ return $this->name($model->alias) . '.' . $this->name($key);
+ }
+ return $key;
+ }
+
+/**
+ * Private helper method to remove query metadata in given data array.
+ *
+ * @param array $data
+ * @return array
+ */
+ protected function _scrubQueryData($data) {
+ static $base = null;
+ if ($base === null) {
+ $base = array_fill_keys(array('conditions', 'fields', 'joins', 'order', 'limit', 'offset', 'group'), array());
+ $base['callbacks'] = null;
+ }
+ return (array)$data + $base;
+ }
+
+/**
+ * Converts model virtual fields into sql expressions to be fetched later
+ *
+ * @param Model $model
+ * @param string $alias Alias table name
+ * @param array $fields virtual fields to be used on query
+ * @return array
+ */
+ protected function _constructVirtualFields(Model $model, $alias, $fields) {
+ $virtual = array();
+ foreach ($fields as $field) {
+ $virtualField = $this->name($alias . $this->virtualFieldSeparator . $field);
+ $expression = $this->_quoteFields($model->getVirtualField($field));
+ $virtual[] = '(' . $expression . ") {$this->alias} {$virtualField}";
+ }
+ return $virtual;
+ }
+
+/**
+ * Generates the fields list of an SQL query.
+ *
+ * @param Model $model
+ * @param string $alias Alias table name
+ * @param mixed $fields
+ * @param boolean $quote If false, returns fields array unquoted
+ * @return array
+ */
+ public function fields(Model $model, $alias = null, $fields = array(), $quote = true) {
+ if (empty($alias)) {
+ $alias = $model->alias;
+ }
+ $virtualFields = $model->getVirtualField();
+ $cacheKey = array(
+ $alias,
+ get_class($model),
+ $model->alias,
+ $virtualFields,
+ $fields,
+ $quote,
+ ConnectionManager::getSourceName($this)
+ );
+ $cacheKey = md5(serialize($cacheKey));
+ if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
+ return $return;
+ }
+ $allFields = empty($fields);
+ if ($allFields) {
+ $fields = array_keys($model->schema());
+ } elseif (!is_array($fields)) {
+ $fields = String::tokenize($fields);
+ }
+ $fields = array_values(array_filter($fields));
+ $allFields = $allFields || in_array('*', $fields) || in_array($model->alias . '.*', $fields);
+
+ $virtual = array();
+ if (!empty($virtualFields)) {
+ $virtualKeys = array_keys($virtualFields);
+ foreach ($virtualKeys as $field) {
+ $virtualKeys[] = $model->alias . '.' . $field;
+ }
+ $virtual = ($allFields) ? $virtualKeys : array_intersect($virtualKeys, $fields);
+ foreach ($virtual as $i => $field) {
+ if (strpos($field, '.') !== false) {
+ $virtual[$i] = str_replace($model->alias . '.', '', $field);
+ }
+ $fields = array_diff($fields, array($field));
+ }
+ $fields = array_values($fields);
+ }
+
+ if (!$quote) {
+ if (!empty($virtual)) {
+ $fields = array_merge($fields, $this->_constructVirtualFields($model, $alias, $virtual));
+ }
+ return $fields;
+ }
+ $count = count($fields);
+
+ if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) {
+ for ($i = 0; $i < $count; $i++) {
+ if (is_string($fields[$i]) && in_array($fields[$i], $virtual)) {
+ unset($fields[$i]);
+ continue;
+ }
+ if (is_object($fields[$i]) && isset($fields[$i]->type) && $fields[$i]->type === 'expression') {
+ $fields[$i] = $fields[$i]->value;
+ } elseif (preg_match('/^\(.*\)\s' . $this->alias . '.*/i', $fields[$i])) {
+ continue;
+ } elseif (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
+ $prepend = '';
+
+ if (strpos($fields[$i], 'DISTINCT') !== false) {
+ $prepend = 'DISTINCT ';
+ $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
+ }
+ $dot = strpos($fields[$i], '.');
+
+ if ($dot === false) {
+ $prefix = !(
+ strpos($fields[$i], ' ') !== false ||
+ strpos($fields[$i], '(') !== false
+ );
+ $fields[$i] = $this->name(($prefix ? $alias . '.' : '') . $fields[$i]);
+ } else {
+ if (strpos($fields[$i], ',') === false) {
+ $build = explode('.', $fields[$i]);
+ if (!Hash::numeric($build)) {
+ $fields[$i] = $this->name(implode('.', $build));
+ }
+ }
+ }
+ $fields[$i] = $prepend . $fields[$i];
+ } elseif (preg_match('/\(([\.\w]+)\)/', $fields[$i], $field)) {
+ if (isset($field[1])) {
+ if (strpos($field[1], '.') === false) {
+ $field[1] = $this->name($alias . '.' . $field[1]);
+ } else {
+ $field[0] = explode('.', $field[1]);
+ if (!Hash::numeric($field[0])) {
+ $field[0] = implode('.', array_map(array(&$this, 'name'), $field[0]));
+ $fields[$i] = preg_replace('/\(' . $field[1] . '\)/', '(' . $field[0] . ')', $fields[$i], 1);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!empty($virtual)) {
+ $fields = array_merge($fields, $this->_constructVirtualFields($model, $alias, $virtual));
+ }
+ return $this->cacheMethod(__FUNCTION__, $cacheKey, array_unique($fields));
+ }
+
+/**
+ * Creates a WHERE clause by parsing given conditions data. If an array or string
+ * conditions are provided those conditions will be parsed and quoted. If a boolean
+ * is given it will be integer cast as condition. Null will return 1 = 1.
+ *
+ * Results of this method are stored in a memory cache. This improves performance, but
+ * because the method uses a hashing algorithm it can have collisions.
+ * Setting DboSource::$cacheMethods to false will disable the memory cache.
+ *
+ * @param mixed $conditions Array or string of conditions, or any value.
+ * @param boolean $quoteValues If true, values should be quoted
+ * @param boolean $where If true, "WHERE " will be prepended to the return value
+ * @param Model $model A reference to the Model instance making the query
+ * @return string SQL fragment
+ */
+ public function conditions($conditions, $quoteValues = true, $where = true, $model = null) {
+ $clause = $out = '';
+
+ if ($where) {
+ $clause = ' WHERE ';
+ }
+
+ if (is_array($conditions) && !empty($conditions)) {
+ $out = $this->conditionKeysToString($conditions, $quoteValues, $model);
+
+ if (empty($out)) {
+ return $clause . ' 1 = 1';
+ }
+ return $clause . implode(' AND ', $out);
+ }
+ if (is_bool($conditions)) {
+ return $clause . (int)$conditions . ' = 1';
+ }
+
+ if (empty($conditions) || trim($conditions) === '') {
+ return $clause . '1 = 1';
+ }
+ $clauses = '/^WHERE\\x20|^GROUP\\x20BY\\x20|^HAVING\\x20|^ORDER\\x20BY\\x20/i';
+
+ if (preg_match($clauses, $conditions, $match)) {
+ $clause = '';
+ }
+ $conditions = $this->_quoteFields($conditions);
+ return $clause . $conditions;
+ }
+
+/**
+ * Creates a WHERE clause by parsing given conditions array. Used by DboSource::conditions().
+ *
+ * @param array $conditions Array or string of conditions
+ * @param boolean $quoteValues If true, values should be quoted
+ * @param Model $model A reference to the Model instance making the query
+ * @return string SQL fragment
+ */
+ public function conditionKeysToString($conditions, $quoteValues = true, $model = null) {
+ $out = array();
+ $data = $columnType = null;
+ $bool = array('and', 'or', 'not', 'and not', 'or not', 'xor', '||', '&&');
+
+ foreach ($conditions as $key => $value) {
+ $join = ' AND ';
+ $not = null;
+
+ if (is_array($value)) {
+ $valueInsert = (
+ !empty($value) &&
+ (substr_count($key, '?') === count($value) || substr_count($key, ':') === count($value))
+ );
+ }
+
+ if (is_numeric($key) && empty($value)) {
+ continue;
+ } elseif (is_numeric($key) && is_string($value)) {
+ $out[] = $not . $this->_quoteFields($value);
+ } elseif ((is_numeric($key) && is_array($value)) || in_array(strtolower(trim($key)), $bool)) {
+ if (in_array(strtolower(trim($key)), $bool)) {
+ $join = ' ' . strtoupper($key) . ' ';
+ } else {
+ $key = $join;
+ }
+ $value = $this->conditionKeysToString($value, $quoteValues, $model);
+
+ if (strpos($join, 'NOT') !== false) {
+ if (strtoupper(trim($key)) === 'NOT') {
+ $key = 'AND ' . trim($key);
+ }
+ $not = 'NOT ';
+ }
+
+ if (empty($value[1])) {
+ if ($not) {
+ $out[] = $not . '(' . $value[0] . ')';
+ } else {
+ $out[] = $value[0];
+ }
+ } else {
+ $out[] = '(' . $not . '(' . implode(') ' . strtoupper($key) . ' (', $value) . '))';
+ }
+ } else {
+ if (is_object($value) && isset($value->type)) {
+ if ($value->type === 'identifier') {
+ $data .= $this->name($key) . ' = ' . $this->name($value->value);
+ } elseif ($value->type === 'expression') {
+ if (is_numeric($key)) {
+ $data .= $value->value;
+ } else {
+ $data .= $this->name($key) . ' = ' . $value->value;
+ }
+ }
+ } elseif (is_array($value) && !empty($value) && !$valueInsert) {
+ $keys = array_keys($value);
+ if ($keys === array_values($keys)) {
+ $count = count($value);
+ if ($count === 1 && !preg_match("/\s+NOT$/", $key)) {
+ $data = $this->_quoteFields($key) . ' = (';
+ } else {
+ $data = $this->_quoteFields($key) . ' IN (';
+ }
+ if ($quoteValues) {
+ if (is_object($model)) {
+ $columnType = $model->getColumnType($key);
+ }
+ $data .= implode(', ', $this->value($value, $columnType));
+ }
+ $data .= ')';
+ } else {
+ $ret = $this->conditionKeysToString($value, $quoteValues, $model);
+ if (count($ret) > 1) {
+ $data = '(' . implode(') AND (', $ret) . ')';
+ } elseif (isset($ret[0])) {
+ $data = $ret[0];
+ }
+ }
+ } elseif (is_numeric($key) && !empty($value)) {
+ $data = $this->_quoteFields($value);
+ } else {
+ $data = $this->_parseKey($model, trim($key), $value);
+ }
+
+ if ($data != null) {
+ $out[] = $data;
+ $data = null;
+ }
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Extracts a Model.field identifier and an SQL condition operator from a string, formats
+ * and inserts values, and composes them into an SQL snippet.
+ *
+ * @param Model $model Model object initiating the query
+ * @param string $key An SQL key snippet containing a field and optional SQL operator
+ * @param mixed $value The value(s) to be inserted in the string
+ * @return string
+ */
+ protected function _parseKey($model, $key, $value) {
+ $operatorMatch = '/^(((' . implode(')|(', $this->_sqlOps);
+ $operatorMatch .= ')\\x20?)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is';
+ $bound = (strpos($key, '?') !== false || (is_array($value) && strpos($key, ':') !== false));
+
+ if (strpos($key, ' ') === false) {
+ $operator = '=';
+ } else {
+ list($key, $operator) = explode(' ', trim($key), 2);
+
+ if (!preg_match($operatorMatch, trim($operator)) && strpos($operator, ' ') !== false) {
+ $key = $key . ' ' . $operator;
+ $split = strrpos($key, ' ');
+ $operator = substr($key, $split);
+ $key = substr($key, 0, $split);
+ }
+ }
+
+ $virtual = false;
+ if (is_object($model) && $model->isVirtualField($key)) {
+ $key = $this->_quoteFields($model->getVirtualField($key));
+ $virtual = true;
+ }
+
+ $type = is_object($model) ? $model->getColumnType($key) : null;
+ $null = $value === null || (is_array($value) && empty($value));
+
+ if (strtolower($operator) === 'not') {
+ $data = $this->conditionKeysToString(
+ array($operator => array($key => $value)), true, $model
+ );
+ return $data[0];
+ }
+
+ $value = $this->value($value, $type);
+
+ if (!$virtual && $key !== '?') {
+ $isKey = (strpos($key, '(') !== false || strpos($key, ')') !== false);
+ $key = $isKey ? $this->_quoteFields($key) : $this->name($key);
+ }
+
+ if ($bound) {
+ return String::insert($key . ' ' . trim($operator), $value);
+ }
+
+ if (!preg_match($operatorMatch, trim($operator))) {
+ $operator .= ' =';
+ }
+ $operator = trim($operator);
+
+ if (is_array($value)) {
+ $value = implode(', ', $value);
+
+ switch ($operator) {
+ case '=':
+ $operator = 'IN';
+ break;
+ case '!=':
+ case '<>':
+ $operator = 'NOT IN';
+ break;
+ }
+ $value = "({$value})";
+ } elseif ($null || $value === 'NULL') {
+ switch ($operator) {
+ case '=':
+ $operator = 'IS';
+ break;
+ case '!=':
+ case '<>':
+ $operator = 'IS NOT';
+ break;
+ }
+ }
+ if ($virtual) {
+ return "({$key}) {$operator} {$value}";
+ }
+ return "{$key} {$operator} {$value}";
+ }
+
+/**
+ * Quotes Model.fields
+ *
+ * @param string $conditions
+ * @return string or false if no match
+ */
+ protected function _quoteFields($conditions) {
+ $start = $end = null;
+ $original = $conditions;
+
+ if (!empty($this->startQuote)) {
+ $start = preg_quote($this->startQuote);
+ }
+ if (!empty($this->endQuote)) {
+ $end = preg_quote($this->endQuote);
+ }
+ $conditions = str_replace(array($start, $end), '', $conditions);
+ $conditions = preg_replace_callback('/(?:[\'\"][^\'\"\\\]*(?:\\\.[^\'\"\\\]*)*[\'\"])|([a-z0-9_' . $start . $end . ']*\\.[a-z0-9_' . $start . $end . ']*)/i', array(&$this, '_quoteMatchedField'), $conditions);
+
+ if ($conditions !== null) {
+ return $conditions;
+ }
+ return $original;
+ }
+
+/**
+ * Auxiliary function to quote matches `Model.fields` from a preg_replace_callback call
+ *
+ * @param string $match matched string
+ * @return string quoted string
+ */
+ protected function _quoteMatchedField($match) {
+ if (is_numeric($match[0])) {
+ return $match[0];
+ }
+ return $this->name($match[0]);
+ }
+
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param integer $limit Limit of results returned
+ * @param integer $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ public function limit($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'limit')) {
+ $rt = ' LIMIT';
+ }
+
+ if ($offset) {
+ $rt .= ' ' . $offset . ',';
+ }
+
+ $rt .= ' ' . $limit;
+ return $rt;
+ }
+ return null;
+ }
+
+/**
+ * Returns an ORDER BY clause as a string.
+ *
+ * @param array|string $keys Field reference, as a key (i.e. Post.title)
+ * @param string $direction Direction (ASC or DESC)
+ * @param Model $model model reference (used to look for virtual field)
+ * @return string ORDER BY clause
+ */
+ public function order($keys, $direction = 'ASC', $model = null) {
+ if (!is_array($keys)) {
+ $keys = array($keys);
+ }
+ $keys = array_filter($keys);
+ $result = array();
+ while (!empty($keys)) {
+ list($key, $dir) = each($keys);
+ array_shift($keys);
+
+ if (is_numeric($key)) {
+ $key = $dir;
+ $dir = $direction;
+ }
+
+ if (is_string($key) && strpos($key, ',') !== false && !preg_match('/\(.+\,.+\)/', $key)) {
+ $key = array_map('trim', explode(',', $key));
+ }
+ if (is_array($key)) {
+ //Flatten the array
+ $key = array_reverse($key, true);
+ foreach ($key as $k => $v) {
+ if (is_numeric($k)) {
+ array_unshift($keys, $v);
+ } else {
+ $keys = array($k => $v) + $keys;
+ }
+ }
+ continue;
+ } elseif (is_object($key) && isset($key->type) && $key->type === 'expression') {
+ $result[] = $key->value;
+ continue;
+ }
+
+ if (preg_match('/\\x20(ASC|DESC).*/i', $key, $_dir)) {
+ $dir = $_dir[0];
+ $key = preg_replace('/\\x20(ASC|DESC).*/i', '', $key);
+ }
+
+ $key = trim($key);
+
+ if (is_object($model) && $model->isVirtualField($key)) {
+ $key = '(' . $this->_quoteFields($model->getVirtualField($key)) . ')';
+ }
+ list($alias, $field) = pluginSplit($key);
+ if (is_object($model) && $alias !== $model->alias && is_object($model->{$alias}) && $model->{$alias}->isVirtualField($key)) {
+ $key = '(' . $this->_quoteFields($model->{$alias}->getVirtualField($key)) . ')';
+ }
+
+ if (strpos($key, '.')) {
+ $key = preg_replace_callback('/([a-zA-Z0-9_-]{1,})\\.([a-zA-Z0-9_-]{1,})/', array(&$this, '_quoteMatchedField'), $key);
+ }
+ if (!preg_match('/\s/', $key) && strpos($key, '.') === false) {
+ $key = $this->name($key);
+ }
+ $key .= ' ' . trim($dir);
+ $result[] = $key;
+ }
+ if (!empty($result)) {
+ return ' ORDER BY ' . implode(', ', $result);
+ }
+ return '';
+ }
+
+/**
+ * Create a GROUP BY SQL clause
+ *
+ * @param string $group Group By Condition
+ * @param Model $model
+ * @return string string condition or null
+ */
+ public function group($group, $model = null) {
+ if ($group) {
+ if (!is_array($group)) {
+ $group = array($group);
+ }
+ foreach ($group as $index => $key) {
+ if (is_object($model) && $model->isVirtualField($key)) {
+ $group[$index] = '(' . $model->getVirtualField($key) . ')';
+ }
+ }
+ $group = implode(', ', $group);
+ return ' GROUP BY ' . $this->_quoteFields($group);
+ }
+ return null;
+ }
+
+/**
+ * Disconnects database, kills the connection and says the connection is closed.
+ *
+ * @return void
+ */
+ public function close() {
+ $this->disconnect();
+ }
+
+/**
+ * Checks if the specified table contains any record matching specified SQL
+ *
+ * @param Model $Model Model to search
+ * @param string $sql SQL WHERE clause (condition only, not the "WHERE" part)
+ * @return boolean True if the table has a matching record, else false
+ */
+ public function hasAny(Model $Model, $sql) {
+ $sql = $this->conditions($sql);
+ $table = $this->fullTableName($Model);
+ $alias = $this->alias . $this->name($Model->alias);
+ $where = $sql ? "{$sql}" : ' WHERE 1 = 1';
+ $id = $Model->escapeField();
+
+ $out = $this->fetchRow("SELECT COUNT({$id}) {$this->alias}count FROM {$table} {$alias}{$where}");
+
+ if (is_array($out)) {
+ return $out[0]['count'];
+ }
+ return false;
+ }
+
+/**
+ * Gets the length of a database-native column description, or null if no length
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return mixed An integer or string representing the length of the column, or null for unknown length.
+ */
+ public function length($real) {
+ if (!preg_match_all('/([\w\s]+)(?:\((\d+)(?:,(\d+))?\))?(\sunsigned)?(\szerofill)?/', $real, $result)) {
+ $col = str_replace(array(')', 'unsigned'), '', $real);
+ $limit = null;
+
+ if (strpos($col, '(') !== false) {
+ list($col, $limit) = explode('(', $col);
+ }
+ if ($limit !== null) {
+ return intval($limit);
+ }
+ return null;
+ }
+
+ $types = array(
+ 'int' => 1, 'tinyint' => 1, 'smallint' => 1, 'mediumint' => 1, 'integer' => 1, 'bigint' => 1
+ );
+
+ list($real, $type, $length, $offset, $sign, $zerofill) = $result;
+ $typeArr = $type;
+ $type = $type[0];
+ $length = $length[0];
+ $offset = $offset[0];
+
+ $isFloat = in_array($type, array('dec', 'decimal', 'float', 'numeric', 'double'));
+ if ($isFloat && $offset) {
+ return $length . ',' . $offset;
+ }
+
+ if (($real[0] == $type) && (count($real) === 1)) {
+ return null;
+ }
+
+ if (isset($types[$type])) {
+ $length += $types[$type];
+ if (!empty($sign)) {
+ $length--;
+ }
+ } elseif (in_array($type, array('enum', 'set'))) {
+ $length = 0;
+ foreach ($typeArr as $key => $enumValue) {
+ if ($key === 0) {
+ continue;
+ }
+ $tmpLength = strlen($enumValue);
+ if ($tmpLength > $length) {
+ $length = $tmpLength;
+ }
+ }
+ }
+ return intval($length);
+ }
+
+/**
+ * Translates between PHP boolean values and Database (faked) boolean values
+ *
+ * @param mixed $data Value to be translated
+ * @param boolean $quote
+ * @return string|boolean Converted boolean value
+ */
+ public function boolean($data, $quote = false) {
+ if ($quote) {
+ return !empty($data) ? '1' : '0';
+ }
+ return !empty($data);
+ }
+
+/**
+ * Inserts multiple values into a table
+ *
+ * @param string $table The table being inserted into.
+ * @param array $fields The array of field/column names being inserted.
+ * @param array $values The array of values to insert. The values should
+ * be an array of rows. Each row should have values keyed by the column name.
+ * Each row must have the values in the same order as $fields.
+ * @return boolean
+ */
+ public function insertMulti($table, $fields, $values) {
+ $table = $this->fullTableName($table);
+ $holder = implode(',', array_fill(0, count($fields), '?'));
+ $fields = implode(', ', array_map(array(&$this, 'name'), $fields));
+
+ $pdoMap = array(
+ 'integer' => PDO::PARAM_INT,
+ 'float' => PDO::PARAM_STR,
+ 'boolean' => PDO::PARAM_BOOL,
+ 'string' => PDO::PARAM_STR,
+ 'text' => PDO::PARAM_STR
+ );
+ $columnMap = array();
+
+ $sql = "INSERT INTO {$table} ({$fields}) VALUES ({$holder})";
+ $statement = $this->_connection->prepare($sql);
+ $this->begin();
+
+ foreach ($values[key($values)] as $key => $val) {
+ $type = $this->introspectType($val);
+ $columnMap[$key] = $pdoMap[$type];
+ }
+
+ foreach ($values as $row => $value) {
+ $i = 1;
+ foreach ($value as $col => $val) {
+ $statement->bindValue($i, $val, $columnMap[$col]);
+ $i += 1;
+ }
+ $statement->execute();
+ $statement->closeCursor();
+ }
+ return $this->commit();
+ }
+
+/**
+ * Returns an array of the indexes in given datasource name.
+ *
+ * @param string $model Name of model to inspect
+ * @return array Fields in table. Keys are column and unique
+ */
+ public function index($model) {
+ return false;
+ }
+
+/**
+ * Generate a database-native schema for the given Schema object
+ *
+ * @param Model $schema An instance of a subclass of CakeSchema
+ * @param string $tableName Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ public function createSchema($schema, $tableName = null) {
+ if (!is_a($schema, 'CakeSchema')) {
+ trigger_error(__d('cake_dev', 'Invalid schema object'), E_USER_WARNING);
+ return null;
+ }
+ $out = '';
+
+ foreach ($schema->tables as $curTable => $columns) {
+ if (!$tableName || $tableName == $curTable) {
+ $cols = $colList = $indexes = $tableParameters = array();
+ $primary = null;
+ $table = $this->fullTableName($curTable);
+
+ foreach ($columns as $name => $col) {
+ if (is_string($col)) {
+ $col = array('type' => $col);
+ }
+ if (isset($col['key']) && $col['key'] === 'primary') {
+ $primary = $name;
+ }
+ if ($name !== 'indexes' && $name !== 'tableParameters') {
+ $col['name'] = $name;
+ if (!isset($col['type'])) {
+ $col['type'] = 'string';
+ }
+ $cols[] = $this->buildColumn($col);
+ } elseif ($name === 'indexes') {
+ $indexes = array_merge($indexes, $this->buildIndex($col, $table));
+ } elseif ($name === 'tableParameters') {
+ $tableParameters = array_merge($tableParameters, $this->buildTableParameters($col, $table));
+ }
+ }
+ if (empty($indexes) && !empty($primary)) {
+ $col = array('PRIMARY' => array('column' => $primary, 'unique' => 1));
+ $indexes = array_merge($indexes, $this->buildIndex($col, $table));
+ }
+ $columns = $cols;
+ $out .= $this->renderStatement('schema', compact('table', 'columns', 'indexes', 'tableParameters')) . "\n\n";
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Generate a alter syntax from CakeSchema::compare()
+ *
+ * @param mixed $compare
+ * @param string $table
+ * @return boolean
+ */
+ public function alterSchema($compare, $table = null) {
+ return false;
+ }
+
+/**
+ * Generate a "drop table" statement for the given Schema object
+ *
+ * @param CakeSchema $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ public function dropSchema(CakeSchema $schema, $table = null) {
+ $out = '';
+
+ foreach ($schema->tables as $curTable => $columns) {
+ if (!$table || $table == $curTable) {
+ $out .= 'DROP TABLE ' . $this->fullTableName($curTable) . ";\n";
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Generate a database-native column schema string
+ *
+ * @param array $column An array structured like the following: array('name' => 'value', 'type' => 'value'[, options]),
+ * where options can be 'default', 'length', or 'key'.
+ * @return string
+ */
+ public function buildColumn($column) {
+ $name = $type = null;
+ extract(array_merge(array('null' => true), $column));
+
+ if (empty($name) || empty($type)) {
+ trigger_error(__d('cake_dev', 'Column name or type not defined in schema'), E_USER_WARNING);
+ return null;
+ }
+
+ if (!isset($this->columns[$type])) {
+ trigger_error(__d('cake_dev', 'Column type %s does not exist', $type), E_USER_WARNING);
+ return null;
+ }
+
+ $real = $this->columns[$type];
+ $out = $this->name($name) . ' ' . $real['name'];
+
+ if (isset($column['length'])) {
+ $length = $column['length'];
+ } elseif (isset($column['limit'])) {
+ $length = $column['limit'];
+ } elseif (isset($real['length'])) {
+ $length = $real['length'];
+ } elseif (isset($real['limit'])) {
+ $length = $real['limit'];
+ }
+ if (isset($length)) {
+ $out .= '(' . $length . ')';
+ }
+
+ if (($column['type'] === 'integer' || $column['type'] === 'float') && isset($column['default']) && $column['default'] === '') {
+ $column['default'] = null;
+ }
+ $out = $this->_buildFieldParameters($out, $column, 'beforeDefault');
+
+ if (isset($column['key']) && $column['key'] === 'primary' && $type === 'integer') {
+ $out .= ' ' . $this->columns['primary_key']['name'];
+ } elseif (isset($column['key']) && $column['key'] === 'primary') {
+ $out .= ' NOT NULL';
+ } elseif (isset($column['default']) && isset($column['null']) && $column['null'] === false) {
+ $out .= ' DEFAULT ' . $this->value($column['default'], $type) . ' NOT NULL';
+ } elseif (isset($column['default'])) {
+ $out .= ' DEFAULT ' . $this->value($column['default'], $type);
+ } elseif ($type !== 'timestamp' && !empty($column['null'])) {
+ $out .= ' DEFAULT NULL';
+ } elseif ($type === 'timestamp' && !empty($column['null'])) {
+ $out .= ' NULL';
+ } elseif (isset($column['null']) && $column['null'] === false) {
+ $out .= ' NOT NULL';
+ }
+ if ($type === 'timestamp' && isset($column['default']) && strtolower($column['default']) === 'current_timestamp') {
+ $out = str_replace(array("'CURRENT_TIMESTAMP'", "'current_timestamp'"), 'CURRENT_TIMESTAMP', $out);
+ }
+ return $this->_buildFieldParameters($out, $column, 'afterDefault');
+ }
+
+/**
+ * Build the field parameters, in a position
+ *
+ * @param string $columnString The partially built column string
+ * @param array $columnData The array of column data.
+ * @param string $position The position type to use. 'beforeDefault' or 'afterDefault' are common
+ * @return string a built column with the field parameters added.
+ */
+ protected function _buildFieldParameters($columnString, $columnData, $position) {
+ foreach ($this->fieldParameters as $paramName => $value) {
+ if (isset($columnData[$paramName]) && $value['position'] == $position) {
+ if (isset($value['options']) && !in_array($columnData[$paramName], $value['options'])) {
+ continue;
+ }
+ $val = $columnData[$paramName];
+ if ($value['quote']) {
+ $val = $this->value($val);
+ }
+ $columnString .= ' ' . $value['value'] . $value['join'] . $val;
+ }
+ }
+ return $columnString;
+ }
+
+/**
+ * Format indexes for create table
+ *
+ * @param array $indexes
+ * @param string $table
+ * @return array
+ */
+ public function buildIndex($indexes, $table = null) {
+ $join = array();
+ foreach ($indexes as $name => $value) {
+ $out = '';
+ if ($name === 'PRIMARY') {
+ $out .= 'PRIMARY ';
+ $name = null;
+ } else {
+ if (!empty($value['unique'])) {
+ $out .= 'UNIQUE ';
+ }
+ $name = $this->startQuote . $name . $this->endQuote;
+ }
+ if (is_array($value['column'])) {
+ $out .= 'KEY ' . $name . ' (' . implode(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
+ } else {
+ $out .= 'KEY ' . $name . ' (' . $this->name($value['column']) . ')';
+ }
+ $join[] = $out;
+ }
+ return $join;
+ }
+
+/**
+ * Read additional table parameters
+ *
+ * @param string $name
+ * @return array
+ */
+ public function readTableParameters($name) {
+ $parameters = array();
+ if (method_exists($this, 'listDetailedSources')) {
+ $currentTableDetails = $this->listDetailedSources($name);
+ foreach ($this->tableParameters as $paramName => $parameter) {
+ if (!empty($parameter['column']) && !empty($currentTableDetails[$parameter['column']])) {
+ $parameters[$paramName] = $currentTableDetails[$parameter['column']];
+ }
+ }
+ }
+ return $parameters;
+ }
+
+/**
+ * Format parameters for create table
+ *
+ * @param array $parameters
+ * @param string $table
+ * @return array
+ */
+ public function buildTableParameters($parameters, $table = null) {
+ $result = array();
+ foreach ($parameters as $name => $value) {
+ if (isset($this->tableParameters[$name])) {
+ if ($this->tableParameters[$name]['quote']) {
+ $value = $this->value($value);
+ }
+ $result[] = $this->tableParameters[$name]['value'] . $this->tableParameters[$name]['join'] . $value;
+ }
+ }
+ return $result;
+ }
+
+/**
+ * Guesses the data type of an array
+ *
+ * @param string $value
+ * @return void
+ */
+ public function introspectType($value) {
+ if (!is_array($value)) {
+ if (is_bool($value)) {
+ return 'boolean';
+ }
+ if (is_float($value) && floatval($value) === $value) {
+ return 'float';
+ }
+ if (is_int($value) && intval($value) === $value) {
+ return 'integer';
+ }
+ if (is_string($value) && strlen($value) > 255) {
+ return 'text';
+ }
+ return 'string';
+ }
+
+ $isAllFloat = $isAllInt = true;
+ $containsFloat = $containsInt = $containsString = false;
+ foreach ($value as $key => $valElement) {
+ $valElement = trim($valElement);
+ if (!is_float($valElement) && !preg_match('/^[\d]+\.[\d]+$/', $valElement)) {
+ $isAllFloat = false;
+ } else {
+ $containsFloat = true;
+ continue;
+ }
+ if (!is_int($valElement) && !preg_match('/^[\d]+$/', $valElement)) {
+ $isAllInt = false;
+ } else {
+ $containsInt = true;
+ continue;
+ }
+ $containsString = true;
+ }
+
+ if ($isAllFloat) {
+ return 'float';
+ }
+ if ($isAllInt) {
+ return 'integer';
+ }
+
+ if ($containsInt && !$containsString) {
+ return 'integer';
+ }
+ return 'string';
+ }
+
+/**
+ * Writes a new key for the in memory sql query cache
+ *
+ * @param string $sql SQL query
+ * @param mixed $data result of $sql query
+ * @param array $params query params bound as values
+ * @return void
+ */
+ protected function _writeQueryCache($sql, $data, $params = array()) {
+ if (preg_match('/^\s*select/i', $sql)) {
+ $this->_queryCache[$sql][serialize($params)] = $data;
+ }
+ }
+
+/**
+ * Returns the result for a sql query if it is already cached
+ *
+ * @param string $sql SQL query
+ * @param array $params query params bound as values
+ * @return mixed results for query if it is cached, false otherwise
+ */
+ public function getQueryCache($sql, $params = array()) {
+ if (isset($this->_queryCache[$sql]) && preg_match('/^\s*select/i', $sql)) {
+ $serialized = serialize($params);
+ if (isset($this->_queryCache[$sql][$serialized])) {
+ return $this->_queryCache[$sql][$serialized];
+ }
+ }
+ return false;
+ }
+
+/**
+ * Used for storing in cache the results of the in-memory methodCache
+ *
+ */
+ public function __destruct() {
+ if ($this->_methodCacheChange) {
+ Cache::write('method_cache', self::$methodCache, '_cake_core_');
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CacheSession.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CacheSession.php
new file mode 100644
index 0000000..c9f14e4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CacheSession.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Cache Session save handler. Allows saving session information into Cache.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource.Session
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+App::uses('CakeSessionHandlerInterface', 'Model/Datasource/Session');
+
+/**
+ * CacheSession provides method for saving sessions into a Cache engine. Used with CakeSession
+ *
+ * @package Cake.Model.Datasource.Session
+ * @see CakeSession for configuration information.
+ */
+class CacheSession implements CakeSessionHandlerInterface {
+
+/**
+ * Method called on open of a database session.
+ *
+ * @return boolean Success
+ */
+ public function open() {
+ return true;
+ }
+
+/**
+ * Method called on close of a database session.
+ *
+ * @return boolean Success
+ */
+ public function close() {
+ return true;
+ }
+
+/**
+ * Method used to read from a database session.
+ *
+ * @param string $id The key of the value to read
+ * @return mixed The value of the key or false if it does not exist
+ */
+ public function read($id) {
+ return Cache::read($id, Configure::read('Session.handler.config'));
+ }
+
+/**
+ * Helper function called on write for database sessions.
+ *
+ * @param integer $id ID that uniquely identifies session in database
+ * @param mixed $data The value of the data to be saved.
+ * @return boolean True for successful write, false otherwise.
+ */
+ public function write($id, $data) {
+ return Cache::write($id, $data, Configure::read('Session.handler.config'));
+ }
+
+/**
+ * Method called on the destruction of a database session.
+ *
+ * @param integer $id ID that uniquely identifies session in cache
+ * @return boolean True for successful delete, false otherwise.
+ */
+ public function destroy($id) {
+ return Cache::delete($id, Configure::read('Session.handler.config'));
+ }
+
+/**
+ * Helper function called on gc for cache sessions.
+ *
+ * @param integer $expires Timestamp (defaults to current time)
+ * @return boolean Success
+ */
+ public function gc($expires = null) {
+ return Cache::gc(Configure::read('Session.handler.config'), $expires);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CakeSessionHandlerInterface.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CakeSessionHandlerInterface.php
new file mode 100644
index 0000000..26c9cad
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/CakeSessionHandlerInterface.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Interface for Session handlers. Custom session handler classes should implement
+ * this interface as it allows CakeSession know how to map methods to session_set_save_handler()
+ *
+ * @package Cake.Model.Datasource.Session
+ */
+interface CakeSessionHandlerInterface {
+
+/**
+ * Method called on open of a session.
+ *
+ * @return boolean Success
+ */
+ public function open();
+
+/**
+ * Method called on close of a session.
+ *
+ * @return boolean Success
+ */
+ public function close();
+
+/**
+ * Method used to read from a session.
+ *
+ * @param string $id The key of the value to read
+ * @return mixed The value of the key or false if it does not exist
+ */
+ public function read($id);
+
+/**
+ * Helper function called on write for sessions.
+ *
+ * @param integer $id ID that uniquely identifies session in database
+ * @param mixed $data The value of the data to be saved.
+ * @return boolean True for successful write, false otherwise.
+ */
+ public function write($id, $data);
+
+/**
+ * Method called on the destruction of a session.
+ *
+ * @param integer $id ID that uniquely identifies session in database
+ * @return boolean True for successful delete, false otherwise.
+ */
+ public function destroy($id);
+
+/**
+ * Run the Garbage collection on the session storage. This method should vacuum all
+ * expired or dead sessions.
+ *
+ * @param integer $expires Timestamp (defaults to current time)
+ * @return boolean Success
+ */
+ public function gc($expires = null);
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/DatabaseSession.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/DatabaseSession.php
new file mode 100644
index 0000000..17207f9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Datasource/Session/DatabaseSession.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Database Session save handler. Allows saving session information into a model.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Datasource.Session
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeSessionHandlerInterface', 'Model/Datasource/Session');
+App::uses('ClassRegistry', 'Utility');
+
+/**
+ * DatabaseSession provides methods to be used with CakeSession.
+ *
+ * @package Cake.Model.Datasource.Session
+ */
+class DatabaseSession implements CakeSessionHandlerInterface {
+
+/**
+ * Reference to the model handling the session data
+ *
+ * @var Model
+ */
+ protected $_model;
+
+/**
+ * Number of seconds to mark the session as expired
+ *
+ * @var int
+ */
+ protected $_timeout;
+
+/**
+ * Constructor. Looks at Session configuration information and
+ * sets up the session model.
+ *
+ */
+ public function __construct() {
+ $modelName = Configure::read('Session.handler.model');
+
+ if (empty($modelName)) {
+ $settings = array(
+ 'class' => 'Session',
+ 'alias' => 'Session',
+ 'table' => 'cake_sessions',
+ );
+ } else {
+ $settings = array(
+ 'class' => $modelName,
+ 'alias' => 'Session',
+ );
+ }
+ $this->_model = ClassRegistry::init($settings);
+ $this->_timeout = Configure::read('Session.timeout') * 60;
+ }
+
+/**
+ * Method called on open of a database session.
+ *
+ * @return boolean Success
+ */
+ public function open() {
+ return true;
+ }
+
+/**
+ * Method called on close of a database session.
+ *
+ * @return boolean Success
+ */
+ public function close() {
+ return true;
+ }
+
+/**
+ * Method used to read from a database session.
+ *
+ * @param integer|string $id The key of the value to read
+ * @return mixed The value of the key or false if it does not exist
+ */
+ public function read($id) {
+ $row = $this->_model->find('first', array(
+ 'conditions' => array($this->_model->primaryKey => $id)
+ ));
+
+ if (empty($row[$this->_model->alias]['data'])) {
+ return false;
+ }
+
+ return $row[$this->_model->alias]['data'];
+ }
+
+/**
+ * Helper function called on write for database sessions.
+ *
+ * @param integer $id ID that uniquely identifies session in database
+ * @param mixed $data The value of the data to be saved.
+ * @return boolean True for successful write, false otherwise.
+ */
+ public function write($id, $data) {
+ if (!$id) {
+ return false;
+ }
+ $expires = time() + $this->_timeout;
+ $record = compact('id', 'data', 'expires');
+ $record[$this->_model->primaryKey] = $id;
+ return $this->_model->save($record);
+ }
+
+/**
+ * Method called on the destruction of a database session.
+ *
+ * @param integer $id ID that uniquely identifies session in database
+ * @return boolean True for successful delete, false otherwise.
+ */
+ public function destroy($id) {
+ return $this->_model->delete($id);
+ }
+
+/**
+ * Helper function called on gc for database sessions.
+ *
+ * @param integer $expires Timestamp (defaults to current time)
+ * @return boolean Success
+ */
+ public function gc($expires = null) {
+ if (!$expires) {
+ $expires = time();
+ }
+ return $this->_model->deleteAll(array($this->_model->alias . ".expires <" => $expires), false, false);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/I18nModel.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/I18nModel.php
new file mode 100644
index 0000000..9b18506
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/I18nModel.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.4525
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * A model used by TranslateBehavior to access the translation tables.
+ *
+ * @package Cake.Model
+ */
+class I18nModel extends AppModel {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'I18nModel';
+
+/**
+ * Table name
+ *
+ * @var string
+ */
+ public $useTable = 'i18n';
+
+/**
+ * Display field
+ *
+ * @var string
+ */
+ public $displayField = 'field';
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Model.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Model.php
new file mode 100644
index 0000000..8909483
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Model.php
@@ -0,0 +1,3402 @@
+<?php
+/**
+ * Object-relational mapper.
+ *
+ * DBO-backed object data model, for mapping database tables to Cake objects.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.10.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ClassRegistry', 'Utility');
+App::uses('Validation', 'Utility');
+App::uses('String', 'Utility');
+App::uses('Hash', 'Utility');
+App::uses('BehaviorCollection', 'Model');
+App::uses('ModelBehavior', 'Model');
+App::uses('ModelValidator', 'Model');
+App::uses('ConnectionManager', 'Model');
+App::uses('Xml', 'Utility');
+App::uses('CakeEvent', 'Event');
+App::uses('CakeEventListener', 'Event');
+App::uses('CakeEventManager', 'Event');
+
+/**
+ * Object-relational mapper.
+ *
+ * DBO-backed object data model.
+ * Automatically selects a database table name based on a pluralized lowercase object class name
+ * (i.e. class 'User' => table 'users'; class 'Man' => table 'men')
+ * The table is required to have at least 'id auto_increment' primary key.
+ *
+ * @package Cake.Model
+ * @link http://book.cakephp.org/2.0/en/models.html
+ */
+class Model extends Object implements CakeEventListener {
+
+/**
+ * The name of the DataSource connection that this Model uses
+ *
+ * The value must be an attribute name that you defined in `app/Config/database.php`
+ * or created using `ConnectionManager::create()`.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#usedbconfig
+ */
+ public $useDbConfig = 'default';
+
+/**
+ * Custom database table name, or null/false if no table association is desired.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#usetable
+ */
+ public $useTable = null;
+
+/**
+ * Custom display field name. Display fields are used by Scaffold, in SELECT boxes' OPTION elements.
+ *
+ * This field is also used in `find('list')` when called with no extra parameters in the fields list
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#displayfield
+ */
+ public $displayField = null;
+
+/**
+ * Value of the primary key ID of the record that this model is currently pointing to.
+ * Automatically set after database insertions.
+ *
+ * @var mixed
+ */
+ public $id = false;
+
+/**
+ * Container for the data that this model gets from persistent storage (usually, a database).
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#data
+ */
+ public $data = array();
+
+/**
+ * Holds physical schema/database name for this model. Automatically set during Model creation.
+ *
+ * @var string
+ * @access public
+ */
+ public $schemaName = null;
+
+/**
+ * Table name for this Model.
+ *
+ * @var string
+ */
+ public $table = false;
+
+/**
+ * The name of the primary key field for this model.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#primaryKey
+ */
+ public $primaryKey = null;
+
+/**
+ * Field-by-field table metadata.
+ *
+ * @var array
+ */
+ protected $_schema = null;
+
+/**
+ * List of validation rules. It must be an array with the field name as key and using
+ * as value one of the following possibilities
+ *
+ * ### Validating using regular expressions
+ *
+ * {{{
+ * public $validate = array(
+ * 'name' => '/^[a-z].+$/i'
+ * );
+ * }}}
+ *
+ * ### Validating using methods (no parameters)
+ *
+ * {{{
+ * public $validate = array(
+ * 'name' => 'notEmpty'
+ * );
+ * }}}
+ *
+ * ### Validating using methods (with parameters)
+ *
+ * {{{
+ * public $validate = array(
+ * 'age' => array(
+ * 'rule' => array('between', 5, 25)
+ * )
+ * );
+ * }}}
+ *
+ * ### Validating using custom method
+ *
+ * {{{
+ * public $validate = array(
+ * 'password' => array(
+ * 'rule' => array('customValidation')
+ * )
+ * );
+ * public function customValidation($data) {
+ * // $data will contain array('password' => 'value')
+ * if (isset($this->data[$this->alias]['password2'])) {
+ * return $this->data[$this->alias]['password2'] === current($data);
+ * }
+ * return true;
+ * }
+ * }}}
+ *
+ * ### Validations with messages
+ *
+ * The messages will be used in Model::$validationErrors and can be used in the FormHelper
+ *
+ * {{{
+ * public $validate = array(
+ * 'age' => array(
+ * 'rule' => array('between', 5, 25),
+ * 'message' => array('The age must be between %d and %d.')
+ * )
+ * );
+ * }}}
+ *
+ * ### Multiple validations to the same field
+ *
+ * {{{
+ * public $validate = array(
+ * 'login' => array(
+ * array(
+ * 'rule' => 'alphaNumeric',
+ * 'message' => 'Only alphabets and numbers allowed',
+ * 'last' => true
+ * ),
+ * array(
+ * 'rule' => array('minLength', 8),
+ * 'message' => array('Minimum length of %d characters')
+ * )
+ * )
+ * );
+ * }}}
+ *
+ * ### Valid keys in validations
+ *
+ * - `rule`: String with method name, regular expression (started by slash) or array with method and parameters
+ * - `message`: String with the message or array if have multiple parameters. See http://php.net/sprintf
+ * - `last`: Boolean value to indicate if continue validating the others rules if the current fail [Default: true]
+ * - `required`: Boolean value to indicate if the field must be present on save
+ * - `allowEmpty`: Boolean value to indicate if the field can be empty
+ * - `on`: Possible values: `update`, `create`. Indicate to apply this rule only on update or create
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#validate
+ * @link http://book.cakephp.org/2.0/en/models/data-validation.html
+ */
+ public $validate = array();
+
+/**
+ * List of validation errors.
+ *
+ * @var array
+ */
+ public $validationErrors = array();
+
+/**
+ * Name of the validation string domain to use when translating validation errors.
+ *
+ * @var string
+ */
+ public $validationDomain = null;
+
+/**
+ * Database table prefix for tables in model.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#tableprefix
+ */
+ public $tablePrefix = null;
+
+/**
+ * Name of the model.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#name
+ */
+ public $name = null;
+
+/**
+ * Alias name for model.
+ *
+ * @var string
+ */
+ public $alias = null;
+
+/**
+ * List of table names included in the model description. Used for associations.
+ *
+ * @var array
+ */
+ public $tableToModel = array();
+
+/**
+ * Whether or not to cache queries for this model. This enables in-memory
+ * caching only, the results are not stored beyond the current request.
+ *
+ * @var boolean
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#cachequeries
+ */
+ public $cacheQueries = false;
+
+/**
+ * Detailed list of belongsTo associations.
+ *
+ * ### Basic usage
+ *
+ * `public $belongsTo = array('Group', 'Department');`
+ *
+ * ### Detailed configuration
+ *
+ * {{{
+ * public $belongsTo = array(
+ * 'Group',
+ * 'Department' => array(
+ * 'className' => 'Department',
+ * 'foreignKey' => 'department_id'
+ * )
+ * );
+ * }}}
+ *
+ * ### Possible keys in association
+ *
+ * - `className`: the classname of the model being associated to the current model.
+ * If you're defining a 'Profile belongsTo User' relationship, the className key should equal 'User.'
+ * - `foreignKey`: the name of the foreign key found in the current model. This is
+ * especially handy if you need to define multiple belongsTo relationships. The default
+ * value for this key is the underscored, singular name of the other model, suffixed with '_id'.
+ * - `conditions`: An SQL fragment used to filter related model records. It's good
+ * practice to use model names in SQL fragments: 'User.active = 1' is always
+ * better than just 'active = 1.'
+ * - `type`: the type of the join to use in the SQL query, default is LEFT which
+ * may not fit your needs in all situations, INNER may be helpful when you want
+ * everything from your main and associated models or nothing at all!(effective
+ * when used with some conditions of course). (NB: type value is in lower case - i.e. left, inner)
+ * - `fields`: A list of fields to be retrieved when the associated model data is
+ * fetched. Returns all fields by default.
+ * - `order`: An SQL fragment that defines the sorting order for the returned associated rows.
+ * - `counterCache`: If set to true the associated Model will automatically increase or
+ * decrease the "[singular_model_name]_count" field in the foreign table whenever you do
+ * a save() or delete(). If its a string then its the field name to use. The value in the
+ * counter field represents the number of related rows.
+ * - `counterScope`: Optional conditions array to use for updating counter cache field.
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#belongsto
+ */
+ public $belongsTo = array();
+
+/**
+ * Detailed list of hasOne associations.
+ *
+ * ### Basic usage
+ *
+ * `public $hasOne = array('Profile', 'Address');`
+ *
+ * ### Detailed configuration
+ *
+ * {{{
+ * public $hasOne = array(
+ * 'Profile',
+ * 'Address' => array(
+ * 'className' => 'Address',
+ * 'foreignKey' => 'user_id'
+ * )
+ * );
+ * }}}
+ *
+ * ### Possible keys in association
+ *
+ * - `className`: the classname of the model being associated to the current model.
+ * If you're defining a 'User hasOne Profile' relationship, the className key should equal 'Profile.'
+ * - `foreignKey`: the name of the foreign key found in the other model. This is
+ * especially handy if you need to define multiple hasOne relationships.
+ * The default value for this key is the underscored, singular name of the
+ * current model, suffixed with '_id'. In the example above it would default to 'user_id'.
+ * - `conditions`: An SQL fragment used to filter related model records. It's good
+ * practice to use model names in SQL fragments: "Profile.approved = 1" is
+ * always better than just "approved = 1."
+ * - `fields`: A list of fields to be retrieved when the associated model data is
+ * fetched. Returns all fields by default.
+ * - `order`: An SQL fragment that defines the sorting order for the returned associated rows.
+ * - `dependent`: When the dependent key is set to true, and the model's delete()
+ * method is called with the cascade parameter set to true, associated model
+ * records are also deleted. In this case we set it true so that deleting a
+ * User will also delete her associated Profile.
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasone
+ */
+ public $hasOne = array();
+
+/**
+ * Detailed list of hasMany associations.
+ *
+ * ### Basic usage
+ *
+ * `public $hasMany = array('Comment', 'Task');`
+ *
+ * ### Detailed configuration
+ *
+ * {{{
+ * public $hasMany = array(
+ * 'Comment',
+ * 'Task' => array(
+ * 'className' => 'Task',
+ * 'foreignKey' => 'user_id'
+ * )
+ * );
+ * }}}
+ *
+ * ### Possible keys in association
+ *
+ * - `className`: the classname of the model being associated to the current model.
+ * If you're defining a 'User hasMany Comment' relationship, the className key should equal 'Comment.'
+ * - `foreignKey`: the name of the foreign key found in the other model. This is
+ * especially handy if you need to define multiple hasMany relationships. The default
+ * value for this key is the underscored, singular name of the actual model, suffixed with '_id'.
+ * - `conditions`: An SQL fragment used to filter related model records. It's good
+ * practice to use model names in SQL fragments: "Comment.status = 1" is always
+ * better than just "status = 1."
+ * - `fields`: A list of fields to be retrieved when the associated model data is
+ * fetched. Returns all fields by default.
+ * - `order`: An SQL fragment that defines the sorting order for the returned associated rows.
+ * - `limit`: The maximum number of associated rows you want returned.
+ * - `offset`: The number of associated rows to skip over (given the current
+ * conditions and order) before fetching and associating.
+ * - `dependent`: When dependent is set to true, recursive model deletion is
+ * possible. In this example, Comment records will be deleted when their
+ * associated User record has been deleted.
+ * - `exclusive`: When exclusive is set to true, recursive model deletion does
+ * the delete with a deleteAll() call, instead of deleting each entity separately.
+ * This greatly improves performance, but may not be ideal for all circumstances.
+ * - `finderQuery`: A complete SQL query CakePHP can use to fetch associated model
+ * records. This should be used in situations that require very custom results.
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasmany
+ */
+ public $hasMany = array();
+
+/**
+ * Detailed list of hasAndBelongsToMany associations.
+ *
+ * ### Basic usage
+ *
+ * `public $hasAndBelongsToMany = array('Role', 'Address');`
+ *
+ * ### Detailed configuration
+ *
+ * {{{
+ * public $hasAndBelongsToMany = array(
+ * 'Role',
+ * 'Address' => array(
+ * 'className' => 'Address',
+ * 'foreignKey' => 'user_id',
+ * 'associationForeignKey' => 'address_id',
+ * 'joinTable' => 'addresses_users'
+ * )
+ * );
+ * }}}
+ *
+ * ### Possible keys in association
+ *
+ * - `className`: the classname of the model being associated to the current model.
+ * If you're defining a 'Recipe HABTM Tag' relationship, the className key should equal 'Tag.'
+ * - `joinTable`: The name of the join table used in this association (if the
+ * current table doesn't adhere to the naming convention for HABTM join tables).
+ * - `with`: Defines the name of the model for the join table. By default CakePHP
+ * will auto-create a model for you. Using the example above it would be called
+ * RecipesTag. By using this key you can override this default name. The join
+ * table model can be used just like any "regular" model to access the join table directly.
+ * - `foreignKey`: the name of the foreign key found in the current model.
+ * This is especially handy if you need to define multiple HABTM relationships.
+ * The default value for this key is the underscored, singular name of the
+ * current model, suffixed with '_id'.
+ * - `associationForeignKey`: the name of the foreign key found in the other model.
+ * This is especially handy if you need to define multiple HABTM relationships.
+ * The default value for this key is the underscored, singular name of the other
+ * model, suffixed with '_id'.
+ * - `unique`: If true (default value) cake will first delete existing relationship
+ * records in the foreign keys table before inserting new ones, when updating a
+ * record. So existing associations need to be passed again when updating.
+ * To prevent deletion of existing relationship records, set this key to a string 'keepExisting'.
+ * - `conditions`: An SQL fragment used to filter related model records. It's good
+ * practice to use model names in SQL fragments: "Comment.status = 1" is always
+ * better than just "status = 1."
+ * - `fields`: A list of fields to be retrieved when the associated model data is
+ * fetched. Returns all fields by default.
+ * - `order`: An SQL fragment that defines the sorting order for the returned associated rows.
+ * - `limit`: The maximum number of associated rows you want returned.
+ * - `offset`: The number of associated rows to skip over (given the current
+ * conditions and order) before fetching and associating.
+ * - `finderQuery`, `deleteQuery`, `insertQuery`: A complete SQL query CakePHP
+ * can use to fetch, delete, or create new associated model records. This should
+ * be used in situations that require very custom results.
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm
+ */
+ public $hasAndBelongsToMany = array();
+
+/**
+ * List of behaviors to load when the model object is initialized. Settings can be
+ * passed to behaviors by using the behavior name as index. Eg:
+ *
+ * public $actsAs = array('Translate', 'MyBehavior' => array('setting1' => 'value1'))
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/behaviors.html#using-behaviors
+ */
+ public $actsAs = null;
+
+/**
+ * Holds the Behavior objects currently bound to this model.
+ *
+ * @var BehaviorCollection
+ */
+ public $Behaviors = null;
+
+/**
+ * Whitelist of fields allowed to be saved.
+ *
+ * @var array
+ */
+ public $whitelist = array();
+
+/**
+ * Whether or not to cache sources for this model.
+ *
+ * @var boolean
+ */
+ public $cacheSources = true;
+
+/**
+ * Type of find query currently executing.
+ *
+ * @var string
+ */
+ public $findQueryType = null;
+
+/**
+ * Number of associations to recurse through during find calls. Fetches only
+ * the first level by default.
+ *
+ * @var integer
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive
+ */
+ public $recursive = 1;
+
+/**
+ * The column name(s) and direction(s) to order find results by default.
+ *
+ * public $order = "Post.created DESC";
+ * public $order = array("Post.view_count DESC", "Post.rating DESC");
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#order
+ */
+ public $order = null;
+
+/**
+ * Array of virtual fields this model has. Virtual fields are aliased
+ * SQL expressions. Fields added to this property will be read as other fields in a model
+ * but will not be saveable.
+ *
+ * `public $virtualFields = array('two' => '1 + 1');`
+ *
+ * Is a simplistic example of how to set virtualFields
+ *
+ * @var array
+ * @link http://book.cakephp.org/2.0/en/models/model-attributes.html#virtualfields
+ */
+ public $virtualFields = array();
+
+/**
+ * Default list of association keys.
+ *
+ * @var array
+ */
+ protected $_associationKeys = array(
+ 'belongsTo' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'counterCache'),
+ 'hasOne' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'dependent'),
+ 'hasMany' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'),
+ 'hasAndBelongsToMany' => array('className', 'joinTable', 'with', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery')
+ );
+
+/**
+ * Holds provided/generated association key names and other data for all associations.
+ *
+ * @var array
+ */
+ protected $_associations = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+
+/**
+ * Holds model associations temporarily to allow for dynamic (un)binding.
+ *
+ * @var array
+ */
+ public $__backAssociation = array();
+
+/**
+ * Back inner association
+ *
+ * @var array
+ */
+ public $__backInnerAssociation = array();
+
+/**
+ * Back original association
+ *
+ * @var array
+ */
+ public $__backOriginalAssociation = array();
+
+/**
+ * Back containable association
+ *
+ * @var array
+ */
+ public $__backContainableAssociation = array();
+
+/**
+ * The ID of the model record that was last inserted.
+ *
+ * @var integer
+ */
+ protected $_insertID = null;
+
+/**
+ * Has the datasource been configured.
+ *
+ * @var boolean
+ * @see Model::getDataSource
+ */
+ protected $_sourceConfigured = false;
+
+/**
+ * List of valid finder method options, supplied as the first parameter to find().
+ *
+ * @var array
+ */
+ public $findMethods = array(
+ 'all' => true, 'first' => true, 'count' => true,
+ 'neighbors' => true, 'list' => true, 'threaded' => true
+ );
+
+/**
+ * Instance of the CakeEventManager this model is using
+ * to dispatch inner events.
+ *
+ * @var CakeEventManager
+ */
+ protected $_eventManager = null;
+
+/**
+ * Instance of the ModelValidator
+ *
+ * @var ModelValidator
+ */
+ protected $_validator = null;
+
+/**
+ * Constructor. Binds the model's database table to the object.
+ *
+ * If `$id` is an array it can be used to pass several options into the model.
+ *
+ * - id - The id to start the model on.
+ * - table - The table to use for this model.
+ * - ds - The connection name this model is connected to.
+ * - name - The name of the model eg. Post.
+ * - alias - The alias of the model, this is used for registering the instance in the `ClassRegistry`.
+ * eg. `ParentThread`
+ *
+ * ### Overriding Model's __construct method.
+ *
+ * When overriding Model::__construct() be careful to include and pass in all 3 of the
+ * arguments to `parent::__construct($id, $table, $ds);`
+ *
+ * ### Dynamically creating models
+ *
+ * You can dynamically create model instances using the $id array syntax.
+ *
+ * {{{
+ * $Post = new Model(array('table' => 'posts', 'name' => 'Post', 'ds' => 'connection2'));
+ * }}}
+ *
+ * Would create a model attached to the posts table on connection2. Dynamic model creation is useful
+ * when you want a model object that contains no associations or attached behaviors.
+ *
+ * @param integer|string|array $id Set this ID for this model on startup, can also be an array of options, see above.
+ * @param string $table Name of database table to use.
+ * @param string $ds DataSource connection name.
+ */
+ public function __construct($id = false, $table = null, $ds = null) {
+ parent::__construct();
+
+ if (is_array($id)) {
+ extract(array_merge(
+ array(
+ 'id' => $this->id, 'table' => $this->useTable, 'ds' => $this->useDbConfig,
+ 'name' => $this->name, 'alias' => $this->alias
+ ),
+ $id
+ ));
+ }
+
+ if ($this->name === null) {
+ $this->name = (isset($name) ? $name : get_class($this));
+ }
+
+ if ($this->alias === null) {
+ $this->alias = (isset($alias) ? $alias : $this->name);
+ }
+
+ if ($this->primaryKey === null) {
+ $this->primaryKey = 'id';
+ }
+
+ ClassRegistry::addObject($this->alias, $this);
+
+ $this->id = $id;
+ unset($id);
+
+ if ($table === false) {
+ $this->useTable = false;
+ } elseif ($table) {
+ $this->useTable = $table;
+ }
+
+ if ($ds !== null) {
+ $this->useDbConfig = $ds;
+ }
+
+ if (is_subclass_of($this, 'AppModel')) {
+ $merge = array('actsAs', 'findMethods');
+ $parentClass = get_parent_class($this);
+ if ($parentClass !== 'AppModel') {
+ $this->_mergeVars($merge, $parentClass);
+ }
+ $this->_mergeVars($merge, 'AppModel');
+ }
+ $this->_mergeVars(array('findMethods'), 'Model');
+
+ $this->Behaviors = new BehaviorCollection();
+
+ if ($this->useTable !== false) {
+
+ if ($this->useTable === null) {
+ $this->useTable = Inflector::tableize($this->name);
+ }
+
+ if ($this->displayField == null) {
+ unset($this->displayField);
+ }
+ $this->table = $this->useTable;
+ $this->tableToModel[$this->table] = $this->alias;
+ } elseif ($this->table === false) {
+ $this->table = Inflector::tableize($this->name);
+ }
+
+ if ($this->tablePrefix === null) {
+ unset($this->tablePrefix);
+ }
+
+ $this->_createLinks();
+ $this->Behaviors->init($this->alias, $this->actsAs);
+ }
+
+/**
+ * Returns a list of all events that will fire in the model during it's lifecycle.
+ * You can override this function to add you own listener callbacks
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'Model.beforeFind' => array('callable' => 'beforeFind', 'passParams' => true),
+ 'Model.afterFind' => array('callable' => 'afterFind', 'passParams' => true),
+ 'Model.beforeValidate' => array('callable' => 'beforeValidate', 'passParams' => true),
+ 'Model.afterValidate' => array('callable' => 'afterValidate'),
+ 'Model.beforeSave' => array('callable' => 'beforeSave', 'passParams' => true),
+ 'Model.afterSave' => array('callable' => 'afterSave', 'passParams' => true),
+ 'Model.beforeDelete' => array('callable' => 'beforeDelete', 'passParams' => true),
+ 'Model.afterDelete' => array('callable' => 'afterDelete'),
+ );
+ }
+
+/**
+ * Returns the CakeEventManager manager instance that is handling any callbacks.
+ * You can use this instance to register any new listeners or callbacks to the
+ * model events, or create your own events and trigger them at will.
+ *
+ * @return CakeEventManager
+ */
+ public function getEventManager() {
+ if (empty($this->_eventManager)) {
+ $this->_eventManager = new CakeEventManager();
+ $this->_eventManager->attach($this->Behaviors);
+ $this->_eventManager->attach($this);
+ }
+ return $this->_eventManager;
+ }
+
+/**
+ * Handles custom method calls, like findBy<field> for DB models,
+ * and custom RPC calls for remote data sources.
+ *
+ * @param string $method Name of method to call.
+ * @param array $params Parameters for the method.
+ * @return mixed Whatever is returned by called method
+ */
+ public function __call($method, $params) {
+ $result = $this->Behaviors->dispatchMethod($this, $method, $params);
+ if ($result !== array('unhandled')) {
+ return $result;
+ }
+ $return = $this->getDataSource()->query($method, $params, $this);
+ return $return;
+ }
+
+/**
+ * Handles the lazy loading of model associations by looking in the association arrays for the requested variable
+ *
+ * @param string $name variable tested for existence in class
+ * @return boolean true if the variable exists (if is a not loaded model association it will be created), false otherwise
+ */
+ public function __isset($name) {
+ $className = false;
+
+ foreach ($this->_associations as $type) {
+ if (isset($name, $this->{$type}[$name])) {
+ $className = empty($this->{$type}[$name]['className']) ? $name : $this->{$type}[$name]['className'];
+ break;
+ } elseif (isset($name, $this->__backAssociation[$type][$name])) {
+ $className = empty($this->__backAssociation[$type][$name]['className']) ?
+ $name : $this->__backAssociation[$type][$name]['className'];
+ break;
+ } elseif ($type == 'hasAndBelongsToMany') {
+ foreach ($this->{$type} as $k => $relation) {
+ if (empty($relation['with'])) {
+ continue;
+ }
+ if (is_array($relation['with'])) {
+ if (key($relation['with']) === $name) {
+ $className = $name;
+ }
+ } else {
+ list($plugin, $class) = pluginSplit($relation['with']);
+ if ($class === $name) {
+ $className = $relation['with'];
+ }
+ }
+ if ($className) {
+ $assocKey = $k;
+ $dynamic = !empty($relation['dynamicWith']);
+ break(2);
+ }
+ }
+ }
+ }
+
+ if (!$className) {
+ return false;
+ }
+
+ list($plugin, $className) = pluginSplit($className);
+
+ if (!ClassRegistry::isKeySet($className) && !empty($dynamic)) {
+ $this->{$className} = new AppModel(array(
+ 'name' => $className,
+ 'table' => $this->hasAndBelongsToMany[$assocKey]['joinTable'],
+ 'ds' => $this->useDbConfig
+ ));
+ } else {
+ $this->_constructLinkedModel($name, $className, $plugin);
+ }
+
+ if (!empty($assocKey)) {
+ $this->hasAndBelongsToMany[$assocKey]['joinTable'] = $this->{$name}->table;
+ if (count($this->{$name}->schema()) <= 2 && $this->{$name}->primaryKey !== false) {
+ $this->{$name}->primaryKey = $this->hasAndBelongsToMany[$assocKey]['foreignKey'];
+ }
+ }
+
+ return true;
+ }
+
+/**
+ * Returns the value of the requested variable if it can be set by __isset()
+ *
+ * @param string $name variable requested for it's value or reference
+ * @return mixed value of requested variable if it is set
+ */
+ public function __get($name) {
+ if ($name === 'displayField') {
+ return $this->displayField = $this->hasField(array('title', 'name', $this->primaryKey));
+ }
+ if ($name === 'tablePrefix') {
+ $this->setDataSource();
+ if (property_exists($this, 'tablePrefix') && !empty($this->tablePrefix)) {
+ return $this->tablePrefix;
+ }
+ return $this->tablePrefix = null;
+ }
+ if (isset($this->{$name})) {
+ return $this->{$name};
+ }
+ }
+
+/**
+ * Bind model associations on the fly.
+ *
+ * If `$reset` is false, association will not be reset
+ * to the originals defined in the model
+ *
+ * Example: Add a new hasOne binding to the Profile model not
+ * defined in the model source code:
+ *
+ * `$this->User->bindModel( array('hasOne' => array('Profile')) );`
+ *
+ * Bindings that are not made permanent will be reset by the next Model::find() call on this
+ * model.
+ *
+ * @param array $params Set of bindings (indexed by binding type)
+ * @param boolean $reset Set to false to make the binding permanent
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#creating-and-destroying-associations-on-the-fly
+ */
+ public function bindModel($params, $reset = true) {
+ foreach ($params as $assoc => $model) {
+ if ($reset === true && !isset($this->__backAssociation[$assoc])) {
+ $this->__backAssociation[$assoc] = $this->{$assoc};
+ }
+ foreach ($model as $key => $value) {
+ $assocName = $key;
+
+ if (is_numeric($key)) {
+ $assocName = $value;
+ $value = array();
+ }
+ $this->{$assoc}[$assocName] = $value;
+ if (property_exists($this, $assocName)) {
+ unset($this->{$assocName});
+ }
+ if ($reset === false && isset($this->__backAssociation[$assoc])) {
+ $this->__backAssociation[$assoc][$assocName] = $value;
+ }
+ }
+ }
+ $this->_createLinks();
+ return true;
+ }
+
+/**
+ * Turn off associations on the fly.
+ *
+ * If $reset is false, association will not be reset
+ * to the originals defined in the model
+ *
+ * Example: Turn off the associated Model Support request,
+ * to temporarily lighten the User model:
+ *
+ * `$this->User->unbindModel( array('hasMany' => array('Supportrequest')) );`
+ *
+ * unbound models that are not made permanent will reset with the next call to Model::find()
+ *
+ * @param array $params Set of bindings to unbind (indexed by binding type)
+ * @param boolean $reset Set to false to make the unbinding permanent
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#creating-and-destroying-associations-on-the-fly
+ */
+ public function unbindModel($params, $reset = true) {
+ foreach ($params as $assoc => $models) {
+ if ($reset === true && !isset($this->__backAssociation[$assoc])) {
+ $this->__backAssociation[$assoc] = $this->{$assoc};
+ }
+ foreach ($models as $model) {
+ if ($reset === false && isset($this->__backAssociation[$assoc][$model])) {
+ unset($this->__backAssociation[$assoc][$model]);
+ }
+ unset($this->{$assoc}[$model]);
+ }
+ }
+ return true;
+ }
+
+/**
+ * Create a set of associations.
+ *
+ * @return void
+ */
+ protected function _createLinks() {
+ foreach ($this->_associations as $type) {
+ if (!is_array($this->{$type})) {
+ $this->{$type} = explode(',', $this->{$type});
+
+ foreach ($this->{$type} as $i => $className) {
+ $className = trim($className);
+ unset ($this->{$type}[$i]);
+ $this->{$type}[$className] = array();
+ }
+ }
+
+ if (!empty($this->{$type})) {
+ foreach ($this->{$type} as $assoc => $value) {
+ $plugin = null;
+
+ if (is_numeric($assoc)) {
+ unset ($this->{$type}[$assoc]);
+ $assoc = $value;
+ $value = array();
+
+ if (strpos($assoc, '.') !== false) {
+ list($plugin, $assoc) = pluginSplit($assoc, true);
+ $this->{$type}[$assoc] = array('className' => $plugin . $assoc);
+ } else {
+ $this->{$type}[$assoc] = $value;
+ }
+ }
+ $this->_generateAssociation($type, $assoc);
+ }
+ }
+ }
+ }
+
+/**
+ * Protected helper method to create associated models of a given class.
+ *
+ * @param string $assoc Association name
+ * @param string $className Class name
+ * @param string $plugin name of the plugin where $className is located
+ * examples: public $hasMany = array('Assoc' => array('className' => 'ModelName'));
+ * usage: $this->Assoc->modelMethods();
+ *
+ * public $hasMany = array('ModelName');
+ * usage: $this->ModelName->modelMethods();
+ * @return void
+ */
+ protected function _constructLinkedModel($assoc, $className = null, $plugin = null) {
+ if (empty($className)) {
+ $className = $assoc;
+ }
+
+ if (!isset($this->{$assoc}) || $this->{$assoc}->name !== $className) {
+ if ($plugin) {
+ $plugin .= '.';
+ }
+ $model = array('class' => $plugin . $className, 'alias' => $assoc);
+ $this->{$assoc} = ClassRegistry::init($model);
+ if ($plugin) {
+ ClassRegistry::addObject($plugin . $className, $this->{$assoc});
+ }
+ if ($assoc) {
+ $this->tableToModel[$this->{$assoc}->table] = $assoc;
+ }
+ }
+ }
+
+/**
+ * Build an array-based association from string.
+ *
+ * @param string $type 'belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'
+ * @param string $assocKey
+ * @return void
+ */
+ protected function _generateAssociation($type, $assocKey) {
+ $class = $assocKey;
+ $dynamicWith = false;
+
+ foreach ($this->_associationKeys[$type] as $key) {
+
+ if (!isset($this->{$type}[$assocKey][$key]) || $this->{$type}[$assocKey][$key] === null) {
+ $data = '';
+
+ switch ($key) {
+ case 'fields':
+ $data = '';
+ break;
+
+ case 'foreignKey':
+ $data = (($type == 'belongsTo') ? Inflector::underscore($assocKey) : Inflector::singularize($this->table)) . '_id';
+ break;
+
+ case 'associationForeignKey':
+ $data = Inflector::singularize($this->{$class}->table) . '_id';
+ break;
+
+ case 'with':
+ $data = Inflector::camelize(Inflector::singularize($this->{$type}[$assocKey]['joinTable']));
+ $dynamicWith = true;
+ break;
+
+ case 'joinTable':
+ $tables = array($this->table, $this->{$class}->table);
+ sort ($tables);
+ $data = $tables[0] . '_' . $tables[1];
+ break;
+
+ case 'className':
+ $data = $class;
+ break;
+
+ case 'unique':
+ $data = true;
+ break;
+ }
+ $this->{$type}[$assocKey][$key] = $data;
+ }
+
+ if ($dynamicWith) {
+ $this->{$type}[$assocKey]['dynamicWith'] = true;
+ }
+
+ }
+ }
+
+/**
+ * Sets a custom table for your controller class. Used by your controller to select a database table.
+ *
+ * @param string $tableName Name of the custom table
+ * @throws MissingTableException when database table $tableName is not found on data source
+ * @return void
+ */
+ public function setSource($tableName) {
+ $this->setDataSource($this->useDbConfig);
+ $db = ConnectionManager::getDataSource($this->useDbConfig);
+ $db->cacheSources = ($this->cacheSources && $db->cacheSources);
+
+ if (method_exists($db, 'listSources')) {
+ $sources = $db->listSources();
+ if (is_array($sources) && !in_array(strtolower($this->tablePrefix . $tableName), array_map('strtolower', $sources))) {
+ throw new MissingTableException(array(
+ 'table' => $this->tablePrefix . $tableName,
+ 'class' => $this->alias,
+ 'ds' => $this->useDbConfig,
+ ));
+ }
+ $this->_schema = null;
+ }
+ $this->table = $this->useTable = $tableName;
+ $this->tableToModel[$this->table] = $this->alias;
+ }
+
+/**
+ * This function does two things:
+ *
+ * 1. it scans the array $one for the primary key,
+ * and if that's found, it sets the current id to the value of $one[id].
+ * For all other keys than 'id' the keys and values of $one are copied to the 'data' property of this object.
+ * 2. Returns an array with all of $one's keys and values.
+ * (Alternative indata: two strings, which are mangled to
+ * a one-item, two-dimensional array using $one for a key and $two as its value.)
+ *
+ * @param string|array|SimpleXmlElement|DomNode $one Array or string of data
+ * @param string $two Value string for the alternative indata method
+ * @return array Data with all of $one's keys and values
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html
+ */
+ public function set($one, $two = null) {
+ if (!$one) {
+ return;
+ }
+ if (is_object($one)) {
+ if ($one instanceof SimpleXMLElement || $one instanceof DOMNode) {
+ $one = $this->_normalizeXmlData(Xml::toArray($one));
+ } else {
+ $one = Set::reverse($one);
+ }
+ }
+
+ if (is_array($one)) {
+ $data = $one;
+ if (empty($one[$this->alias])) {
+ $data = $this->_setAliasData($one);
+ }
+ } else {
+ $data = array($this->alias => array($one => $two));
+ }
+
+ foreach ($data as $modelName => $fieldSet) {
+ if (is_array($fieldSet)) {
+
+ foreach ($fieldSet as $fieldName => $fieldValue) {
+ if (isset($this->validationErrors[$fieldName])) {
+ unset ($this->validationErrors[$fieldName]);
+ }
+
+ if ($modelName === $this->alias) {
+ if ($fieldName === $this->primaryKey) {
+ $this->id = $fieldValue;
+ }
+ }
+ if (is_array($fieldValue) || is_object($fieldValue)) {
+ $fieldValue = $this->deconstruct($fieldName, $fieldValue);
+ }
+ $this->data[$modelName][$fieldName] = $fieldValue;
+ }
+ }
+ }
+ return $data;
+ }
+
+/**
+ * Move values to alias
+ *
+ * @param array $data
+ * @return array
+ */
+ protected function _setAliasData($data) {
+ $models = array_keys($this->getAssociated());
+ $schema = array_keys((array)$this->schema());
+ foreach ($data as $field => $value) {
+ if (in_array($field, $schema) || !in_array($field, $models)) {
+ $data[$this->alias][$field] = $value;
+ unset($data[$field]);
+ }
+ }
+ return $data;
+ }
+
+/**
+ * Normalize Xml::toArray() to use in Model::save()
+ *
+ * @param array $xml XML as array
+ * @return array
+ */
+ protected function _normalizeXmlData(array $xml) {
+ $return = array();
+ foreach ($xml as $key => $value) {
+ if (is_array($value)) {
+ $return[Inflector::camelize($key)] = $this->_normalizeXmlData($value);
+ } elseif ($key[0] === '@') {
+ $return[substr($key, 1)] = $value;
+ } else {
+ $return[$key] = $value;
+ }
+ }
+ return $return;
+ }
+
+/**
+ * Deconstructs a complex data type (array or object) into a single field value.
+ *
+ * @param string $field The name of the field to be deconstructed
+ * @param array|object $data An array or object to be deconstructed into a field
+ * @return mixed The resulting data that should be assigned to a field
+ */
+ public function deconstruct($field, $data) {
+ if (!is_array($data)) {
+ return $data;
+ }
+
+ $type = $this->getColumnType($field);
+
+ if (in_array($type, array('datetime', 'timestamp', 'date', 'time'))) {
+ $useNewDate = (isset($data['year']) || isset($data['month']) ||
+ isset($data['day']) || isset($data['hour']) || isset($data['minute']));
+
+ $dateFields = array('Y' => 'year', 'm' => 'month', 'd' => 'day', 'H' => 'hour', 'i' => 'min', 's' => 'sec');
+ $timeFields = array('H' => 'hour', 'i' => 'min', 's' => 'sec');
+ $date = array();
+
+ if (isset($data['meridian']) && empty($data['meridian'])) {
+ return null;
+ }
+
+ if (
+ isset($data['hour']) &&
+ isset($data['meridian']) &&
+ !empty($data['hour']) &&
+ $data['hour'] != 12 &&
+ 'pm' == $data['meridian']
+ ) {
+ $data['hour'] = $data['hour'] + 12;
+ }
+ if (isset($data['hour']) && isset($data['meridian']) && $data['hour'] == 12 && 'am' == $data['meridian']) {
+ $data['hour'] = '00';
+ }
+ if ($type == 'time') {
+ foreach ($timeFields as $key => $val) {
+ if (!isset($data[$val]) || $data[$val] === '0' || $data[$val] === '00') {
+ $data[$val] = '00';
+ } elseif ($data[$val] !== '') {
+ $data[$val] = sprintf('%02d', $data[$val]);
+ }
+ if (!empty($data[$val])) {
+ $date[$key] = $data[$val];
+ } else {
+ return null;
+ }
+ }
+ }
+
+ if ($type == 'datetime' || $type == 'timestamp' || $type == 'date') {
+ foreach ($dateFields as $key => $val) {
+ if ($val == 'hour' || $val == 'min' || $val == 'sec') {
+ if (!isset($data[$val]) || $data[$val] === '0' || $data[$val] === '00') {
+ $data[$val] = '00';
+ } else {
+ $data[$val] = sprintf('%02d', $data[$val]);
+ }
+ }
+ if (!isset($data[$val]) || isset($data[$val]) && (empty($data[$val]) || $data[$val][0] === '-')) {
+ return null;
+ }
+ if (isset($data[$val]) && !empty($data[$val])) {
+ $date[$key] = $data[$val];
+ }
+ }
+ }
+
+ if ($useNewDate && !empty($date)) {
+ $format = $this->getDataSource()->columns[$type]['format'];
+ foreach (array('m', 'd', 'H', 'i', 's') as $index) {
+ if (isset($date[$index])) {
+ $date[$index] = sprintf('%02d', $date[$index]);
+ }
+ }
+ return str_replace(array_keys($date), array_values($date), $format);
+ }
+ }
+ return $data;
+ }
+
+/**
+ * Returns an array of table metadata (column names and types) from the database.
+ * $field => keys(type, null, default, key, length, extra)
+ *
+ * @param boolean|string $field Set to true to reload schema, or a string to return a specific field
+ * @return array Array of table metadata
+ */
+ public function schema($field = false) {
+ if ($this->useTable !== false && (!is_array($this->_schema) || $field === true)) {
+ $db = $this->getDataSource();
+ $db->cacheSources = ($this->cacheSources && $db->cacheSources);
+ if (method_exists($db, 'describe') && $this->useTable !== false) {
+ $this->_schema = $db->describe($this);
+ } elseif ($this->useTable === false) {
+ $this->_schema = array();
+ }
+ }
+ if (is_string($field)) {
+ if (isset($this->_schema[$field])) {
+ return $this->_schema[$field];
+ } else {
+ return null;
+ }
+ }
+ return $this->_schema;
+ }
+
+/**
+ * Returns an associative array of field names and column types.
+ *
+ * @return array Field types indexed by field name
+ */
+ public function getColumnTypes() {
+ $columns = $this->schema();
+ if (empty($columns)) {
+ trigger_error(__d('cake_dev', '(Model::getColumnTypes) Unable to build model field data. If you are using a model without a database table, try implementing schema()'), E_USER_WARNING);
+ }
+ $cols = array();
+ foreach ($columns as $field => $values) {
+ $cols[$field] = $values['type'];
+ }
+ return $cols;
+ }
+
+/**
+ * Returns the column type of a column in the model.
+ *
+ * @param string $column The name of the model column
+ * @return string Column type
+ */
+ public function getColumnType($column) {
+ $db = $this->getDataSource();
+ $cols = $this->schema();
+ $model = null;
+
+ $startQuote = isset($db->startQuote) ? $db->startQuote : null;
+ $endQuote = isset($db->endQuote) ? $db->endQuote : null;
+ $column = str_replace(array($startQuote, $endQuote), '', $column);
+
+ if (strpos($column, '.')) {
+ list($model, $column) = explode('.', $column);
+ }
+ if ($model != $this->alias && isset($this->{$model})) {
+ return $this->{$model}->getColumnType($column);
+ }
+ if (isset($cols[$column]) && isset($cols[$column]['type'])) {
+ return $cols[$column]['type'];
+ }
+ return null;
+ }
+
+/**
+ * Returns true if the supplied field exists in the model's database table.
+ *
+ * @param string|array $name Name of field to look for, or an array of names
+ * @param boolean $checkVirtual checks if the field is declared as virtual
+ * @return mixed If $name is a string, returns a boolean indicating whether the field exists.
+ * If $name is an array of field names, returns the first field that exists,
+ * or false if none exist.
+ */
+ public function hasField($name, $checkVirtual = false) {
+ if (is_array($name)) {
+ foreach ($name as $n) {
+ if ($this->hasField($n, $checkVirtual)) {
+ return $n;
+ }
+ }
+ return false;
+ }
+
+ if ($checkVirtual && !empty($this->virtualFields)) {
+ if ($this->isVirtualField($name)) {
+ return true;
+ }
+ }
+
+ if (empty($this->_schema)) {
+ $this->schema();
+ }
+
+ if ($this->_schema != null) {
+ return isset($this->_schema[$name]);
+ }
+ return false;
+ }
+
+/**
+ * Check that a method is callable on a model. This will check both the model's own methods, its
+ * inherited methods and methods that could be callable through behaviors.
+ *
+ * @param string $method The method to be called.
+ * @return boolean True on method being callable.
+ */
+ public function hasMethod($method) {
+ if (method_exists($this, $method)) {
+ return true;
+ }
+ if ($this->Behaviors->hasMethod($method)) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Returns true if the supplied field is a model Virtual Field
+ *
+ * @param string $field Name of field to look for
+ * @return boolean indicating whether the field exists as a model virtual field.
+ */
+ public function isVirtualField($field) {
+ if (empty($this->virtualFields) || !is_string($field)) {
+ return false;
+ }
+ if (isset($this->virtualFields[$field])) {
+ return true;
+ }
+ if (strpos($field, '.') !== false) {
+ list($model, $field) = explode('.', $field);
+ if ($model == $this->alias && isset($this->virtualFields[$field])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns the expression for a model virtual field
+ *
+ * @param string $field Name of field to look for
+ * @return mixed If $field is string expression bound to virtual field $field
+ * If $field is null, returns an array of all model virtual fields
+ * or false if none $field exist.
+ */
+ public function getVirtualField($field = null) {
+ if ($field == null) {
+ return empty($this->virtualFields) ? false : $this->virtualFields;
+ }
+ if ($this->isVirtualField($field)) {
+ if (strpos($field, '.') !== false) {
+ list($model, $field) = explode('.', $field);
+ }
+ return $this->virtualFields[$field];
+ }
+ return false;
+ }
+
+/**
+ * Initializes the model for writing a new record, loading the default values
+ * for those fields that are not defined in $data, and clearing previous validation errors.
+ * Especially helpful for saving data in loops.
+ *
+ * @param boolean|array $data Optional data array to assign to the model after it is created. If null or false,
+ * schema data defaults are not merged.
+ * @param boolean $filterKey If true, overwrites any primary key input with an empty value
+ * @return array The current Model::data; after merging $data and/or defaults from database
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-create-array-data-array
+ */
+ public function create($data = array(), $filterKey = false) {
+ $defaults = array();
+ $this->id = false;
+ $this->data = array();
+ $this->validationErrors = array();
+
+ if ($data !== null && $data !== false) {
+ foreach ($this->schema() as $field => $properties) {
+ if ($this->primaryKey !== $field && isset($properties['default']) && $properties['default'] !== '') {
+ $defaults[$field] = $properties['default'];
+ }
+ }
+ $this->set($defaults);
+ $this->set($data);
+ }
+ if ($filterKey) {
+ $this->set($this->primaryKey, false);
+ }
+ return $this->data;
+ }
+
+/**
+ * Returns a list of fields from the database, and sets the current model
+ * data (Model::$data) with the record found.
+ *
+ * @param string|array $fields String of single field name, or an array of field names.
+ * @param integer|string $id The ID of the record to read
+ * @return array Array of database fields, or false if not found
+ * @link http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-read
+ */
+ public function read($fields = null, $id = null) {
+ $this->validationErrors = array();
+
+ if ($id != null) {
+ $this->id = $id;
+ }
+
+ $id = $this->id;
+
+ if (is_array($this->id)) {
+ $id = $this->id[0];
+ }
+
+ if ($id !== null && $id !== false) {
+ $this->data = $this->find('first', array(
+ 'conditions' => array($this->alias . '.' . $this->primaryKey => $id),
+ 'fields' => $fields
+ ));
+ return $this->data;
+ } else {
+ return false;
+ }
+ }
+
+/**
+ * Returns the contents of a single field given the supplied conditions, in the
+ * supplied order.
+ *
+ * @param string $name Name of field to get
+ * @param array $conditions SQL conditions (defaults to NULL)
+ * @param string $order SQL ORDER BY fragment
+ * @return string field contents, or false if not found
+ * @link http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-field
+ */
+ public function field($name, $conditions = null, $order = null) {
+ if ($conditions === null && $this->id !== false) {
+ $conditions = array($this->alias . '.' . $this->primaryKey => $this->id);
+ }
+ if ($this->recursive >= 1) {
+ $recursive = -1;
+ } else {
+ $recursive = $this->recursive;
+ }
+ $fields = $name;
+ if ($data = $this->find('first', compact('conditions', 'fields', 'order', 'recursive'))) {
+ if (strpos($name, '.') === false) {
+ if (isset($data[$this->alias][$name])) {
+ return $data[$this->alias][$name];
+ }
+ } else {
+ $name = explode('.', $name);
+ if (isset($data[$name[0]][$name[1]])) {
+ return $data[$name[0]][$name[1]];
+ }
+ }
+ if (isset($data[0]) && count($data[0]) > 0) {
+ return array_shift($data[0]);
+ }
+ } else {
+ return false;
+ }
+ }
+
+/**
+ * Saves the value of a single field to the database, based on the current
+ * model ID.
+ *
+ * @param string $name Name of the table field
+ * @param mixed $value Value of the field
+ * @param array $validate See $options param in Model::save(). Does not respect 'fieldList' key if passed
+ * @return boolean See Model::save()
+ * @see Model::save()
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savefield-string-fieldname-string-fieldvalue-validate-false
+ */
+ public function saveField($name, $value, $validate = false) {
+ $id = $this->id;
+ $this->create(false);
+
+ if (is_array($validate)) {
+ $options = array_merge(array('validate' => false, 'fieldList' => array($name)), $validate);
+ } else {
+ $options = array('validate' => $validate, 'fieldList' => array($name));
+ }
+ return $this->save(array($this->alias => array($this->primaryKey => $id, $name => $value)), $options);
+ }
+
+/**
+ * Saves model data (based on white-list, if supplied) to the database. By
+ * default, validation occurs before save.
+ *
+ * @param array $data Data to save.
+ * @param boolean|array $validate Either a boolean, or an array.
+ * If a boolean, indicates whether or not to validate before saving.
+ * If an array, allows control of validate, callbacks, and fieldList
+ * @param array $fieldList List of fields to allow to be written
+ * @return mixed On success Model::$data if its not empty or true, false on failure
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html
+ */
+ public function save($data = null, $validate = true, $fieldList = array()) {
+ $defaults = array('validate' => true, 'fieldList' => array(), 'callbacks' => true);
+ $_whitelist = $this->whitelist;
+ $fields = array();
+
+ if (!is_array($validate)) {
+ $options = array_merge($defaults, compact('validate', 'fieldList', 'callbacks'));
+ } else {
+ $options = array_merge($defaults, $validate);
+ }
+
+ if (!empty($options['fieldList'])) {
+ if (!empty($options['fieldList'][$this->alias]) && is_array($options['fieldList'][$this->alias])) {
+ $this->whitelist = $options['fieldList'][$this->alias];
+ } else {
+ $this->whitelist = $options['fieldList'];
+ }
+ } elseif ($options['fieldList'] === null) {
+ $this->whitelist = array();
+ }
+ $this->set($data);
+
+ if (empty($this->data) && !$this->hasField(array('created', 'updated', 'modified'))) {
+ return false;
+ }
+
+ foreach (array('created', 'updated', 'modified') as $field) {
+ $keyPresentAndEmpty = (
+ isset($this->data[$this->alias]) &&
+ array_key_exists($field, $this->data[$this->alias]) &&
+ $this->data[$this->alias][$field] === null
+ );
+ if ($keyPresentAndEmpty) {
+ unset($this->data[$this->alias][$field]);
+ }
+ }
+
+ $exists = $this->exists();
+ $dateFields = array('modified', 'updated');
+
+ if (!$exists) {
+ $dateFields[] = 'created';
+ }
+ if (isset($this->data[$this->alias])) {
+ $fields = array_keys($this->data[$this->alias]);
+ }
+ if ($options['validate'] && !$this->validates($options)) {
+ $this->whitelist = $_whitelist;
+ return false;
+ }
+
+ $db = $this->getDataSource();
+
+ foreach ($dateFields as $updateCol) {
+ if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) {
+ $default = array('formatter' => 'date');
+ $colType = array_merge($default, $db->columns[$this->getColumnType($updateCol)]);
+ if (!array_key_exists('format', $colType)) {
+ $time = strtotime('now');
+ } else {
+ $time = call_user_func($colType['formatter'], $colType['format']);
+ }
+ if (!empty($this->whitelist)) {
+ $this->whitelist[] = $updateCol;
+ }
+ $this->set($updateCol, $time);
+ }
+ }
+
+ if ($options['callbacks'] === true || $options['callbacks'] === 'before') {
+ $event = new CakeEvent('Model.beforeSave', $this, array($options));
+ list($event->break, $event->breakOn) = array(true, array(false, null));
+ $this->getEventManager()->dispatch($event);
+ if (!$event->result) {
+ $this->whitelist = $_whitelist;
+ return false;
+ }
+ }
+
+ if (empty($this->data[$this->alias][$this->primaryKey])) {
+ unset($this->data[$this->alias][$this->primaryKey]);
+ }
+ $fields = $values = array();
+
+ foreach ($this->data as $n => $v) {
+ if (isset($this->hasAndBelongsToMany[$n])) {
+ if (isset($v[$n])) {
+ $v = $v[$n];
+ }
+ $joined[$n] = $v;
+ } else {
+ if ($n === $this->alias) {
+ foreach (array('created', 'updated', 'modified') as $field) {
+ if (array_key_exists($field, $v) && empty($v[$field])) {
+ unset($v[$field]);
+ }
+ }
+
+ foreach ($v as $x => $y) {
+ if ($this->hasField($x) && (empty($this->whitelist) || in_array($x, $this->whitelist))) {
+ list($fields[], $values[]) = array($x, $y);
+ }
+ }
+ }
+ }
+ }
+ $count = count($fields);
+
+ if (!$exists && $count > 0) {
+ $this->id = false;
+ }
+ $success = true;
+ $created = false;
+
+ if ($count > 0) {
+ $cache = $this->_prepareUpdateFields(array_combine($fields, $values));
+
+ if (!empty($this->id)) {
+ $success = (bool)$db->update($this, $fields, $values);
+ } else {
+ $fInfo = $this->schema($this->primaryKey);
+ $isUUID = ($fInfo['length'] == 36 &&
+ ($fInfo['type'] === 'string' || $fInfo['type'] === 'binary')
+ );
+ if (empty($this->data[$this->alias][$this->primaryKey]) && $isUUID) {
+ if (array_key_exists($this->primaryKey, $this->data[$this->alias])) {
+ $j = array_search($this->primaryKey, $fields);
+ $values[$j] = String::uuid();
+ } else {
+ list($fields[], $values[]) = array($this->primaryKey, String::uuid());
+ }
+ }
+
+ if (!$db->create($this, $fields, $values)) {
+ $success = $created = false;
+ } else {
+ $created = true;
+ }
+ }
+
+ if ($success && !empty($this->belongsTo)) {
+ $this->updateCounterCache($cache, $created);
+ }
+ }
+
+ if (!empty($joined) && $success === true) {
+ $this->_saveMulti($joined, $this->id, $db);
+ }
+
+ if ($success && $count > 0) {
+ if (!empty($this->data)) {
+ $success = $this->data;
+ if ($created) {
+ $this->data[$this->alias][$this->primaryKey] = $this->id;
+ }
+ }
+ if ($options['callbacks'] === true || $options['callbacks'] === 'after') {
+ $event = new CakeEvent('Model.afterSave', $this, array($created, $options));
+ $this->getEventManager()->dispatch($event);
+ }
+ if (!empty($this->data)) {
+ $success = Hash::merge($success, $this->data);
+ }
+ $this->data = false;
+ $this->_clearCache();
+ $this->validationErrors = array();
+ }
+ $this->whitelist = $_whitelist;
+ return $success;
+ }
+
+/**
+ * Saves model hasAndBelongsToMany data to the database.
+ *
+ * @param array $joined Data to save
+ * @param integer|string $id ID of record in this model
+ * @param DataSource $db
+ * @return void
+ */
+ protected function _saveMulti($joined, $id, $db) {
+ foreach ($joined as $assoc => $data) {
+
+ if (isset($this->hasAndBelongsToMany[$assoc])) {
+ list($join) = $this->joinModel($this->hasAndBelongsToMany[$assoc]['with']);
+
+ $keyInfo = $this->{$join}->schema($this->{$join}->primaryKey);
+ if ($with = $this->hasAndBelongsToMany[$assoc]['with']) {
+ $withModel = is_array($with) ? key($with) : $with;
+ list($pluginName, $withModel) = pluginSplit($withModel);
+ $dbMulti = $this->{$withModel}->getDataSource();
+ } else {
+ $dbMulti = $db;
+ }
+
+ $isUUID = !empty($this->{$join}->primaryKey) && (
+ $keyInfo['length'] == 36 && (
+ $keyInfo['type'] === 'string' ||
+ $keyInfo['type'] === 'binary'
+ )
+ );
+
+ $newData = $newValues = $newJoins = array();
+ $primaryAdded = false;
+
+ $fields = array(
+ $dbMulti->name($this->hasAndBelongsToMany[$assoc]['foreignKey']),
+ $dbMulti->name($this->hasAndBelongsToMany[$assoc]['associationForeignKey'])
+ );
+
+ $idField = $db->name($this->{$join}->primaryKey);
+ if ($isUUID && !in_array($idField, $fields)) {
+ $fields[] = $idField;
+ $primaryAdded = true;
+ }
+
+ foreach ((array)$data as $row) {
+ if ((is_string($row) && (strlen($row) == 36 || strlen($row) == 16)) || is_numeric($row)) {
+ $newJoins[] = $row;
+ $values = array($id, $row);
+ if ($isUUID && $primaryAdded) {
+ $values[] = String::uuid();
+ }
+ $newValues[$row] = $values;
+ unset($values);
+ } elseif (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
+ if (!empty($row[$this->{$join}->primaryKey])) {
+ $newJoins[] = $row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
+ }
+ $newData[] = $row;
+ } elseif (isset($row[$join]) && isset($row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
+ if (!empty($row[$join][$this->{$join}->primaryKey])) {
+ $newJoins[] = $row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
+ }
+ $newData[] = $row[$join];
+ }
+ }
+
+ $keepExisting = $this->hasAndBelongsToMany[$assoc]['unique'] === 'keepExisting';
+ if ($this->hasAndBelongsToMany[$assoc]['unique']) {
+ $conditions = array(
+ $join . '.' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] => $id
+ );
+ if (!empty($this->hasAndBelongsToMany[$assoc]['conditions'])) {
+ $conditions = array_merge($conditions, (array)$this->hasAndBelongsToMany[$assoc]['conditions']);
+ }
+ $associationForeignKey = $this->{$join}->alias . '.' . $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
+ $links = $this->{$join}->find('all', array(
+ 'conditions' => $conditions,
+ 'recursive' => empty($this->hasAndBelongsToMany[$assoc]['conditions']) ? -1 : 0,
+ 'fields' => $associationForeignKey,
+ ));
+
+ $oldLinks = Hash::extract($links, "{n}.{$associationForeignKey}");
+ if (!empty($oldLinks)) {
+ if ($keepExisting && !empty($newJoins)) {
+ $conditions[$associationForeignKey] = array_diff($oldLinks, $newJoins);
+ } else {
+ $conditions[$associationForeignKey] = $oldLinks;
+ }
+ $dbMulti->delete($this->{$join}, $conditions);
+ }
+ }
+
+ if (!empty($newData)) {
+ foreach ($newData as $data) {
+ $data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;
+ if (empty($data[$this->{$join}->primaryKey])) {
+ $this->{$join}->create();
+ }
+ $this->{$join}->save($data);
+ }
+ }
+
+ if (!empty($newValues)) {
+ if ($keepExisting && !empty($links)) {
+ foreach ($links as $link) {
+ $oldJoin = $link[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
+ if (! in_array($oldJoin, $newJoins) ) {
+ $conditions[$associationForeignKey] = $oldJoin;
+ $db->delete($this->{$join}, $conditions);
+ } else {
+ unset($newValues[$oldJoin]);
+ }
+ }
+ $newValues = array_values($newValues);
+ }
+ if (!empty($newValues)) {
+ $dbMulti->insertMulti($this->{$join}, $fields, $newValues);
+ }
+ }
+ }
+ }
+ }
+
+/**
+ * Updates the counter cache of belongsTo associations after a save or delete operation
+ *
+ * @param array $keys Optional foreign key data, defaults to the information $this->data
+ * @param boolean $created True if a new record was created, otherwise only associations with
+ * 'counterScope' defined get updated
+ * @return void
+ */
+ public function updateCounterCache($keys = array(), $created = false) {
+ $keys = empty($keys) ? $this->data[$this->alias] : $keys;
+ $keys['old'] = isset($keys['old']) ? $keys['old'] : array();
+
+ foreach ($this->belongsTo as $parent => $assoc) {
+ if (!empty($assoc['counterCache'])) {
+ if (!is_array($assoc['counterCache'])) {
+ if (isset($assoc['counterScope'])) {
+ $assoc['counterCache'] = array($assoc['counterCache'] => $assoc['counterScope']);
+ } else {
+ $assoc['counterCache'] = array($assoc['counterCache'] => array());
+ }
+ }
+
+ $foreignKey = $assoc['foreignKey'];
+ $fkQuoted = $this->escapeField($assoc['foreignKey']);
+
+ foreach ($assoc['counterCache'] as $field => $conditions) {
+ if (!is_string($field)) {
+ $field = Inflector::underscore($this->alias) . '_count';
+ }
+ if (!$this->{$parent}->hasField($field)) {
+ continue;
+ }
+ if ($conditions === true) {
+ $conditions = array();
+ } else {
+ $conditions = (array)$conditions;
+ }
+
+ if (!array_key_exists($foreignKey, $keys)) {
+ $keys[$foreignKey] = $this->field($foreignKey);
+ }
+ $recursive = (empty($conditions) ? -1 : 0);
+
+ if (isset($keys['old'][$foreignKey])) {
+ if ($keys['old'][$foreignKey] != $keys[$foreignKey]) {
+ $conditions[$fkQuoted] = $keys['old'][$foreignKey];
+ $count = intval($this->find('count', compact('conditions', 'recursive')));
+
+ $this->{$parent}->updateAll(
+ array($field => $count),
+ array($this->{$parent}->escapeField() => $keys['old'][$foreignKey])
+ );
+ }
+ }
+ $conditions[$fkQuoted] = $keys[$foreignKey];
+
+ if ($recursive === 0) {
+ $conditions = array_merge($conditions, (array)$conditions);
+ }
+ $count = intval($this->find('count', compact('conditions', 'recursive')));
+
+ $this->{$parent}->updateAll(
+ array($field => $count),
+ array($this->{$parent}->escapeField() => $keys[$foreignKey])
+ );
+ }
+ }
+ }
+ }
+
+/**
+ * Helper method for Model::updateCounterCache(). Checks the fields to be updated for
+ *
+ * @param array $data The fields of the record that will be updated
+ * @return array Returns updated foreign key values, along with an 'old' key containing the old
+ * values, or empty if no foreign keys are updated.
+ */
+ protected function _prepareUpdateFields($data) {
+ $foreignKeys = array();
+ foreach ($this->belongsTo as $assoc => $info) {
+ if ($info['counterCache']) {
+ $foreignKeys[$assoc] = $info['foreignKey'];
+ }
+ }
+ $included = array_intersect($foreignKeys, array_keys($data));
+
+ if (empty($included) || empty($this->id)) {
+ return array();
+ }
+ $old = $this->find('first', array(
+ 'conditions' => array($this->alias . '.' . $this->primaryKey => $this->id),
+ 'fields' => array_values($included),
+ 'recursive' => -1
+ ));
+ return array_merge($data, array('old' => $old[$this->alias]));
+ }
+
+/**
+ * Backwards compatible passthrough method for:
+ * saveMany(), validateMany(), saveAssociated() and validateAssociated()
+ *
+ * Saves multiple individual records for a single model; Also works with a single record, as well as
+ * all its associated records.
+ *
+ * #### Options
+ *
+ * - validate: Set to false to disable validation, true to validate each record before saving,
+ * 'first' to validate *all* records before any are saved (default),
+ * or 'only' to only validate the records, but not save them.
+ * - atomic: If true (default), will attempt to save all records in a single transaction.
+ * Should be set to false if database/table does not support transactions.
+ * - fieldList: Equivalent to the $fieldList parameter in Model::save().
+ * It should be an associate array with model name as key and array of fields as value. Eg.
+ * {{{
+ * array(
+ * 'SomeModel' => array('field'),
+ * 'AssociatedModel' => array('field', 'otherfield')
+ * )
+ * }}}
+ * - deep: see saveMany/saveAssociated
+ *
+ * @param array $data Record data to save. This can be either a numerically-indexed array (for saving multiple
+ * records of the same type), or an array indexed by association name.
+ * @param array $options Options to use when saving record data, See $options above.
+ * @return mixed If atomic: True on success, or false on failure.
+ * Otherwise: array similar to the $data array passed, but values are set to true/false
+ * depending on whether each record saved successfully.
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveall-array-data-null-array-options-array
+ */
+ public function saveAll($data, $options = array()) {
+ $options = array_merge(array('validate' => 'first'), $options);
+ if (Hash::numeric(array_keys($data))) {
+ if ($options['validate'] === 'only') {
+ return $this->validateMany($data, $options);
+ }
+ return $this->saveMany($data, $options);
+ }
+ if ($options['validate'] === 'only') {
+ return $this->validateAssociated($data, $options);
+ }
+ return $this->saveAssociated($data, $options);
+ }
+
+/**
+ * Saves multiple individual records for a single model
+ *
+ * #### Options
+ *
+ * - validate: Set to false to disable validation, true to validate each record before saving,
+ * 'first' to validate *all* records before any are saved (default),
+ * - atomic: If true (default), will attempt to save all records in a single transaction.
+ * Should be set to false if database/table does not support transactions.
+ * - fieldList: Equivalent to the $fieldList parameter in Model::save()
+ * - deep: If set to true, all associated data will be saved as well.
+ *
+ * @param array $data Record data to save. This should be a numerically-indexed array
+ * @param array $options Options to use when saving record data, See $options above.
+ * @return mixed If atomic: True on success, or false on failure.
+ * Otherwise: array similar to the $data array passed, but values are set to true/false
+ * depending on whether each record saved successfully.
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savemany-array-data-null-array-options-array
+ */
+ public function saveMany($data = null, $options = array()) {
+ if (empty($data)) {
+ $data = $this->data;
+ }
+
+ $options = array_merge(array('validate' => 'first', 'atomic' => true, 'deep' => false), $options);
+ $this->validationErrors = $validationErrors = array();
+
+ if (empty($data) && $options['validate'] !== false) {
+ $result = $this->save($data, $options);
+ if (!$options['atomic']) {
+ return array(!empty($result));
+ }
+ return !empty($result);
+ }
+
+ if ($options['validate'] === 'first') {
+ $validates = $this->validateMany($data, $options);
+ if ((!$validates && $options['atomic']) || (!$options['atomic'] && in_array(false, $validates, true))) {
+ return $validates;
+ }
+ $options['validate'] = false;
+ }
+
+ if ($options['atomic']) {
+ $db = $this->getDataSource();
+ $transactionBegun = $db->begin();
+ }
+ $return = array();
+ foreach ($data as $key => $record) {
+ $validates = $this->create(null) !== null;
+ $saved = false;
+ if ($validates) {
+ if ($options['deep']) {
+ $saved = $this->saveAssociated($record, array_merge($options, array('atomic' => false)));
+ } else {
+ $saved = $this->save($record, $options);
+ }
+ }
+ $validates = ($validates && ($saved === true || (is_array($saved) && !in_array(false, $saved, true))));
+ if (!$validates) {
+ $validationErrors[$key] = $this->validationErrors;
+ }
+ if (!$options['atomic']) {
+ $return[$key] = $validates;
+ } elseif (!$validates) {
+ break;
+ }
+ }
+ $this->validationErrors = $validationErrors;
+
+ if (!$options['atomic']) {
+ return $return;
+ }
+ if ($validates) {
+ if ($transactionBegun) {
+ return $db->commit() !== false;
+ } else {
+ return true;
+ }
+ }
+ $db->rollback();
+ return false;
+ }
+
+/**
+ * Validates multiple individual records for a single model
+ *
+ * #### Options
+ *
+ * - atomic: If true (default), returns boolean. If false returns array.
+ * - fieldList: Equivalent to the $fieldList parameter in Model::save()
+ * - deep: If set to true, all associated data will be validated as well.
+ *
+ * Warning: This method could potentially change the passed argument `$data`,
+ * If you do not want this to happen, make a copy of `$data` before passing it
+ * to this method
+ *
+ * @param array $data Record data to validate. This should be a numerically-indexed array
+ * @param array $options Options to use when validating record data (see above), See also $options of validates().
+ * @return boolean True on success, or false on failure.
+ * @return mixed If atomic: True on success, or false on failure.
+ * Otherwise: array similar to the $data array passed, but values are set to true/false
+ * depending on whether each record validated successfully.
+ */
+ public function validateMany(&$data, $options = array()) {
+ return $this->validator()->validateMany($data, $options);
+ }
+
+/**
+ * Saves a single record, as well as all its directly associated records.
+ *
+ * #### Options
+ *
+ * - `validate` Set to `false` to disable validation, `true` to validate each record before saving,
+ * 'first' to validate *all* records before any are saved(default),
+ * - `atomic` If true (default), will attempt to save all records in a single transaction.
+ * Should be set to false if database/table does not support transactions.
+ * - fieldList: Equivalent to the $fieldList parameter in Model::save().
+ * It should be an associate array with model name as key and array of fields as value. Eg.
+ * {{{
+ * array(
+ * 'SomeModel' => array('field'),
+ * 'AssociatedModel' => array('field', 'otherfield')
+ * )
+ * }}}
+ * - deep: If set to true, not only directly associated data is saved, but deeper nested associated data as well.
+ *
+ * @param array $data Record data to save. This should be an array indexed by association name.
+ * @param array $options Options to use when saving record data, See $options above.
+ * @return mixed If atomic: True on success, or false on failure.
+ * Otherwise: array similar to the $data array passed, but values are set to true/false
+ * depending on whether each record saved successfully.
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array
+ */
+ public function saveAssociated($data = null, $options = array()) {
+ if (empty($data)) {
+ $data = $this->data;
+ }
+
+ $options = array_merge(array('validate' => 'first', 'atomic' => true, 'deep' => false), $options);
+ $this->validationErrors = $validationErrors = array();
+
+ if (empty($data) && $options['validate'] !== false) {
+ $result = $this->save($data, $options);
+ if (!$options['atomic']) {
+ return array(!empty($result));
+ }
+ return !empty($result);
+ }
+
+ if ($options['validate'] === 'first') {
+ $validates = $this->validateAssociated($data, $options);
+ if ((!$validates && $options['atomic']) || (!$options['atomic'] && in_array(false, $validates, true))) {
+ return $validates;
+ }
+ $options['validate'] = false;
+ }
+ if ($options['atomic']) {
+ $db = $this->getDataSource();
+ $transactionBegun = $db->begin();
+ }
+
+ $associations = $this->getAssociated();
+ $return = array();
+ $validates = true;
+ foreach ($data as $association => $values) {
+ $notEmpty = !empty($values[$association]) || (!isset($values[$association]) && !empty($values));
+ if (isset($associations[$association]) && $associations[$association] === 'belongsTo' && $notEmpty) {
+ $validates = $this->{$association}->create(null) !== null;
+ $saved = false;
+ if ($validates) {
+ if ($options['deep']) {
+ $saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
+ } else {
+ $saved = $this->{$association}->save($values, array_merge($options, array('atomic' => false)));
+ }
+ $validates = ($saved === true || (is_array($saved) && !in_array(false, $saved, true)));
+ }
+ if ($validates) {
+ $key = $this->belongsTo[$association]['foreignKey'];
+ if (isset($data[$this->alias])) {
+ $data[$this->alias][$key] = $this->{$association}->id;
+ } else {
+ $data = array_merge(array($key => $this->{$association}->id), $data, array($key => $this->{$association}->id));
+ }
+ } else {
+ $validationErrors[$association] = $this->{$association}->validationErrors;
+ }
+ $return[$association] = $validates;
+ }
+ }
+ if ($validates && !($this->create(null) !== null && $this->save($data, $options))) {
+ $validationErrors[$this->alias] = $this->validationErrors;
+ $validates = false;
+ }
+ $return[$this->alias] = $validates;
+
+ foreach ($data as $association => $values) {
+ if (!$validates) {
+ break;
+ }
+ $notEmpty = !empty($values[$association]) || (!isset($values[$association]) && !empty($values));
+ if (isset($associations[$association]) && $notEmpty) {
+ $type = $associations[$association];
+ $key = $this->{$type}[$association]['foreignKey'];
+ switch ($type) {
+ case 'hasOne':
+ if (isset($values[$association])) {
+ $values[$association][$key] = $this->id;
+ } else {
+ $values = array_merge(array($key => $this->id), $values, array($key => $this->id));
+ }
+ $validates = $this->{$association}->create(null) !== null;
+ $saved = false;
+ if ($validates) {
+ if ($options['deep']) {
+ $saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
+ } else {
+ $saved = $this->{$association}->save($values, $options);
+ }
+ }
+ $validates = ($validates && ($saved === true || (is_array($saved) && !in_array(false, $saved, true))));
+ if (!$validates) {
+ $validationErrors[$association] = $this->{$association}->validationErrors;
+ }
+ $return[$association] = $validates;
+ break;
+ case 'hasMany':
+ foreach ($values as $i => $value) {
+ if (isset($values[$i][$association])) {
+ $values[$i][$association][$key] = $this->id;
+ } else {
+ $values[$i] = array_merge(array($key => $this->id), $value, array($key => $this->id));
+ }
+ }
+ $_return = $this->{$association}->saveMany($values, array_merge($options, array('atomic' => false)));
+ if (in_array(false, $_return, true)) {
+ $validationErrors[$association] = $this->{$association}->validationErrors;
+ $validates = false;
+ }
+ $return[$association] = $_return;
+ break;
+ }
+ }
+ }
+ $this->validationErrors = $validationErrors;
+
+ if (isset($validationErrors[$this->alias])) {
+ $this->validationErrors = $validationErrors[$this->alias];
+ unset($validationErrors[$this->alias]);
+ $this->validationErrors = array_merge($this->validationErrors, $validationErrors);
+ }
+
+ if (!$options['atomic']) {
+ return $return;
+ }
+ if ($validates) {
+ if ($transactionBegun) {
+ return $db->commit() !== false;
+ } else {
+ return true;
+ }
+ }
+ $db->rollback();
+ return false;
+ }
+
+/**
+ * Validates a single record, as well as all its directly associated records.
+ *
+ * #### Options
+ *
+ * - atomic: If true (default), returns boolean. If false returns array.
+ * - fieldList: Equivalent to the $fieldList parameter in Model::save()
+ * - deep: If set to true, not only directly associated data , but deeper nested associated data is validated as well.
+ *
+ * Warning: This method could potentially change the passed argument `$data`,
+ * If you do not want this to happen, make a copy of `$data` before passing it
+ * to this method
+ *
+ * @param array $data Record data to validate. This should be an array indexed by association name.
+ * @param array $options Options to use when validating record data (see above), See also $options of validates().
+ * @return array|boolean If atomic: True on success, or false on failure.
+ * Otherwise: array similar to the $data array passed, but values are set to true/false
+ * depending on whether each record validated successfully.
+ */
+ public function validateAssociated(&$data, $options = array()) {
+ return $this->validator()->validateAssociated($data, $options);
+ }
+
+/**
+ * Updates multiple model records based on a set of conditions.
+ *
+ * @param array $fields Set of fields and values, indexed by fields.
+ * Fields are treated as SQL snippets, to insert literal values manually escape your data.
+ * @param mixed $conditions Conditions to match, true for all records
+ * @return boolean True on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-updateall-array-fields-array-conditions
+ */
+ public function updateAll($fields, $conditions = true) {
+ return $this->getDataSource()->update($this, $fields, null, $conditions);
+ }
+
+/**
+ * Removes record for given ID. If no ID is given, the current ID is used. Returns true on success.
+ *
+ * @param integer|string $id ID of record to delete
+ * @param boolean $cascade Set to true to delete records that depend on this record
+ * @return boolean True on success
+ * @link http://book.cakephp.org/2.0/en/models/deleting-data.html
+ */
+ public function delete($id = null, $cascade = true) {
+ if (!empty($id)) {
+ $this->id = $id;
+ }
+ $id = $this->id;
+
+ $event = new CakeEvent('Model.beforeDelete', $this, array($cascade));
+ list($event->break, $event->breakOn) = array(true, array(false, null));
+ $this->getEventManager()->dispatch($event);
+ if (!$event->isStopped()) {
+ if (!$this->exists()) {
+ return false;
+ }
+ $db = $this->getDataSource();
+
+ $this->_deleteDependent($id, $cascade);
+ $this->_deleteLinks($id);
+ $this->id = $id;
+
+ $updateCounterCache = false;
+ if (!empty($this->belongsTo)) {
+ foreach ($this->belongsTo as $parent => $assoc) {
+ if (!empty($assoc['counterCache'])) {
+ $updateCounterCache = true;
+ break;
+ }
+ }
+ if ($updateCounterCache) {
+ $keys = $this->find('first', array(
+ 'fields' => $this->_collectForeignKeys(),
+ 'conditions' => array($this->alias . '.' . $this->primaryKey => $id),
+ 'recursive' => -1,
+ 'callbacks' => false
+ ));
+ }
+ }
+
+ if ($db->delete($this, array($this->alias . '.' . $this->primaryKey => $id))) {
+ if ($updateCounterCache) {
+ $this->updateCounterCache($keys[$this->alias]);
+ }
+ $this->getEventManager()->dispatch(new CakeEvent('Model.afterDelete', $this));
+ $this->_clearCache();
+ $this->id = false;
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Cascades model deletes through associated hasMany and hasOne child records.
+ *
+ * @param string $id ID of record that was deleted
+ * @param boolean $cascade Set to true to delete records that depend on this record
+ * @return void
+ */
+ protected function _deleteDependent($id, $cascade) {
+ if (!empty($this->__backAssociation)) {
+ $savedAssociatons = $this->__backAssociation;
+ $this->__backAssociation = array();
+ }
+ if ($cascade === true) {
+ foreach (array_merge($this->hasMany, $this->hasOne) as $assoc => $data) {
+ if ($data['dependent'] === true) {
+
+ $model = $this->{$assoc};
+
+ if ($data['foreignKey'] === false && $data['conditions'] && in_array($this->name, $model->getAssociated('belongsTo'))) {
+ $model->recursive = 0;
+ $conditions = array($this->escapeField(null, $this->name) => $id);
+ } else {
+ $model->recursive = -1;
+ $conditions = array($model->escapeField($data['foreignKey']) => $id);
+ if ($data['conditions']) {
+ $conditions = array_merge((array)$data['conditions'], $conditions);
+ }
+ }
+
+ if (isset($data['exclusive']) && $data['exclusive']) {
+ $model->deleteAll($conditions);
+ } else {
+ $records = $model->find('all', array(
+ 'conditions' => $conditions, 'fields' => $model->primaryKey
+ ));
+
+ if (!empty($records)) {
+ foreach ($records as $record) {
+ $model->delete($record[$model->alias][$model->primaryKey]);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (isset($savedAssociatons)) {
+ $this->__backAssociation = $savedAssociatons;
+ }
+ }
+
+/**
+ * Cascades model deletes through HABTM join keys.
+ *
+ * @param string $id ID of record that was deleted
+ * @return void
+ */
+ protected function _deleteLinks($id) {
+ foreach ($this->hasAndBelongsToMany as $assoc => $data) {
+ list($plugin, $joinModel) = pluginSplit($data['with']);
+ $records = $this->{$joinModel}->find('all', array(
+ 'conditions' => array($this->{$joinModel}->escapeField($data['foreignKey']) => $id),
+ 'fields' => $this->{$joinModel}->primaryKey,
+ 'recursive' => -1,
+ 'callbacks' => false
+ ));
+ if (!empty($records)) {
+ foreach ($records as $record) {
+ $this->{$joinModel}->delete($record[$this->{$joinModel}->alias][$this->{$joinModel}->primaryKey]);
+ }
+ }
+ }
+ }
+
+/**
+ * Deletes multiple model records based on a set of conditions.
+ *
+ * @param mixed $conditions Conditions to match
+ * @param boolean $cascade Set to true to delete records that depend on this record
+ * @param boolean $callbacks Run callbacks
+ * @return boolean True on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/models/deleting-data.html#deleteall
+ */
+ public function deleteAll($conditions, $cascade = true, $callbacks = false) {
+ if (empty($conditions)) {
+ return false;
+ }
+ $db = $this->getDataSource();
+
+ if (!$cascade && !$callbacks) {
+ return $db->delete($this, $conditions);
+ } else {
+ $ids = $this->find('all', array_merge(array(
+ 'fields' => "{$this->alias}.{$this->primaryKey}",
+ 'recursive' => 0), compact('conditions'))
+ );
+ if ($ids === false) {
+ return false;
+ }
+
+ $ids = Hash::extract($ids, "{n}.{$this->alias}.{$this->primaryKey}");
+ if (empty($ids)) {
+ return true;
+ }
+
+ if ($callbacks) {
+ $_id = $this->id;
+ $result = true;
+ foreach ($ids as $id) {
+ $result = ($result && $this->delete($id, $cascade));
+ }
+ $this->id = $_id;
+ return $result;
+ } else {
+ foreach ($ids as $id) {
+ $this->_deleteLinks($id);
+ if ($cascade) {
+ $this->_deleteDependent($id, $cascade);
+ }
+ }
+ return $db->delete($this, array($this->alias . '.' . $this->primaryKey => $ids));
+ }
+ }
+ }
+
+/**
+ * Collects foreign keys from associations.
+ *
+ * @param string $type
+ * @return array
+ */
+ protected function _collectForeignKeys($type = 'belongsTo') {
+ $result = array();
+
+ foreach ($this->{$type} as $assoc => $data) {
+ if (isset($data['foreignKey']) && is_string($data['foreignKey'])) {
+ $result[$assoc] = $data['foreignKey'];
+ }
+ }
+ return $result;
+ }
+
+/**
+ * Returns true if a record with particular ID exists.
+ *
+ * If $id is not passed it calls Model::getID() to obtain the current record ID,
+ * and then performs a Model::find('count') on the currently configured datasource
+ * to ascertain the existence of the record in persistent storage.
+ *
+ * @param integer|string $id ID of record to check for existence
+ * @return boolean True if such a record exists
+ */
+ public function exists($id = null) {
+ if ($id === null) {
+ $id = $this->getID();
+ }
+ if ($id === false) {
+ return false;
+ }
+ $conditions = array($this->alias . '.' . $this->primaryKey => $id);
+ $query = array('conditions' => $conditions, 'recursive' => -1, 'callbacks' => false);
+ return ($this->find('count', $query) > 0);
+ }
+
+/**
+ * Returns true if a record that meets given conditions exists.
+ *
+ * @param array $conditions SQL conditions array
+ * @return boolean True if such a record exists
+ */
+ public function hasAny($conditions = null) {
+ return ($this->find('count', array('conditions' => $conditions, 'recursive' => -1)) != false);
+ }
+
+/**
+ * Queries the datasource and returns a result set array.
+ *
+ * Also used to perform notation finds, where the first argument is type of find operation to perform
+ * (all / first / count / neighbors / list / threaded),
+ * second parameter options for finding ( indexed array, including: 'conditions', 'limit',
+ * 'recursive', 'page', 'fields', 'offset', 'order')
+ *
+ * Eg:
+ * {{{
+ * find('all', array(
+ * 'conditions' => array('name' => 'Thomas Anderson'),
+ * 'fields' => array('name', 'email'),
+ * 'order' => 'field3 DESC',
+ * 'recursive' => 2,
+ * 'group' => 'type'
+ * ));
+ * }}}
+ *
+ * In addition to the standard query keys above, you can provide Datasource, and behavior specific
+ * keys. For example, when using a SQL based datasource you can use the joins key to specify additional
+ * joins that should be part of the query.
+ *
+ * {{{
+ * find('all', array(
+ * 'conditions' => array('name' => 'Thomas Anderson'),
+ * 'joins' => array(
+ * array(
+ * 'alias' => 'Thought',
+ * 'table' => 'thoughts',
+ * 'type' => 'LEFT',
+ * 'conditions' => '`Thought`.`person_id` = `Person`.`id`'
+ * )
+ * )
+ * ));
+ * }}}
+ *
+ * Behaviors and find types can also define custom finder keys which are passed into find().
+ *
+ * Specifying 'fields' for notation 'list':
+ *
+ * - If no fields are specified, then 'id' is used for key and 'model->displayField' is used for value.
+ * - If a single field is specified, 'id' is used for key and specified field is used for value.
+ * - If three fields are specified, they are used (in order) for key, value and group.
+ * - Otherwise, first and second fields are used for key and value.
+ *
+ * Note: find(list) + database views have issues with MySQL 5.0. Try upgrading to MySQL 5.1 if you
+ * have issues with database views.
+ * @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
+ * @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)
+ * @return array Array of records
+ * @link http://book.cakephp.org/2.0/en/models/deleting-data.html#deleteall
+ */
+ public function find($type = 'first', $query = array()) {
+ $this->findQueryType = $type;
+ $this->id = $this->getID();
+
+ $query = $this->buildQuery($type, $query);
+ if (is_null($query)) {
+ return null;
+ }
+
+ $results = $this->getDataSource()->read($this, $query);
+ $this->resetAssociations();
+
+ if ($query['callbacks'] === true || $query['callbacks'] === 'after') {
+ $results = $this->_filterResults($results);
+ }
+
+ $this->findQueryType = null;
+
+ if ($type === 'all') {
+ return $results;
+ } else {
+ if ($this->findMethods[$type] === true) {
+ return $this->{'_find' . ucfirst($type)}('after', $query, $results);
+ }
+ }
+ }
+
+/**
+ * Builds the query array that is used by the data source to generate the query to fetch the data.
+ *
+ * @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
+ * @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)
+ * @return array Query array or null if it could not be build for some reasons
+ * @see Model::find()
+ */
+ public function buildQuery($type = 'first', $query = array()) {
+ $query = array_merge(
+ array(
+ 'conditions' => null, 'fields' => null, 'joins' => array(), 'limit' => null,
+ 'offset' => null, 'order' => null, 'page' => 1, 'group' => null, 'callbacks' => true,
+ ),
+ (array)$query
+ );
+
+ if ($type !== 'all') {
+ if ($this->findMethods[$type] === true) {
+ $query = $this->{'_find' . ucfirst($type)}('before', $query);
+ }
+ }
+
+ if (!is_numeric($query['page']) || intval($query['page']) < 1) {
+ $query['page'] = 1;
+ }
+ if ($query['page'] > 1 && !empty($query['limit'])) {
+ $query['offset'] = ($query['page'] - 1) * $query['limit'];
+ }
+ if ($query['order'] === null && $this->order !== null) {
+ $query['order'] = $this->order;
+ }
+ $query['order'] = array($query['order']);
+
+ if ($query['callbacks'] === true || $query['callbacks'] === 'before') {
+ $event = new CakeEvent('Model.beforeFind', $this, array($query));
+ list($event->break, $event->breakOn, $event->modParams) = array(true, array(false, null), 0);
+ $this->getEventManager()->dispatch($event);
+ if ($event->isStopped()) {
+ return null;
+ }
+ $query = $event->result === true ? $event->data[0] : $event->result;
+ }
+
+ return $query;
+ }
+
+/**
+ * Handles the before/after filter logic for find('first') operations. Only called by Model::find().
+ *
+ * @param string $state Either "before" or "after"
+ * @param array $query
+ * @param array $results
+ * @return array
+ * @see Model::find()
+ */
+ protected function _findFirst($state, $query, $results = array()) {
+ if ($state === 'before') {
+ $query['limit'] = 1;
+ return $query;
+ } elseif ($state === 'after') {
+ if (empty($results[0])) {
+ return false;
+ }
+ return $results[0];
+ }
+ }
+
+/**
+ * Handles the before/after filter logic for find('count') operations. Only called by Model::find().
+ *
+ * @param string $state Either "before" or "after"
+ * @param array $query
+ * @param array $results
+ * @return integer The number of records found, or false
+ * @see Model::find()
+ */
+ protected function _findCount($state, $query, $results = array()) {
+ if ($state === 'before') {
+ if (!empty($query['type']) && isset($this->findMethods[$query['type']]) && $query['type'] !== 'count' ) {
+ $query['operation'] = 'count';
+ $query = $this->{'_find' . ucfirst($query['type'])}('before', $query);
+ }
+ $db = $this->getDataSource();
+ $query['order'] = false;
+ if (!method_exists($db, 'calculate')) {
+ return $query;
+ }
+ if (!empty($query['fields']) && is_array($query['fields'])) {
+ if (!preg_match('/^count/i', current($query['fields']))) {
+ unset($query['fields']);
+ }
+ }
+ if (empty($query['fields'])) {
+ $query['fields'] = $db->calculate($this, 'count');
+ } elseif (method_exists($db, 'expression') && is_string($query['fields']) && !preg_match('/count/i', $query['fields'])) {
+ $query['fields'] = $db->calculate($this, 'count', array(
+ $db->expression($query['fields']), 'count'
+ ));
+ }
+ return $query;
+ } elseif ($state === 'after') {
+ foreach (array(0, $this->alias) as $key) {
+ if (isset($results[0][$key]['count'])) {
+ if (($count = count($results)) > 1) {
+ return $count;
+ } else {
+ return intval($results[0][$key]['count']);
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+/**
+ * Handles the before/after filter logic for find('list') operations. Only called by Model::find().
+ *
+ * @param string $state Either "before" or "after"
+ * @param array $query
+ * @param array $results
+ * @return array Key/value pairs of primary keys/display field values of all records found
+ * @see Model::find()
+ */
+ protected function _findList($state, $query, $results = array()) {
+ if ($state === 'before') {
+ if (empty($query['fields'])) {
+ $query['fields'] = array("{$this->alias}.{$this->primaryKey}", "{$this->alias}.{$this->displayField}");
+ $list = array("{n}.{$this->alias}.{$this->primaryKey}", "{n}.{$this->alias}.{$this->displayField}", null);
+ } else {
+ if (!is_array($query['fields'])) {
+ $query['fields'] = String::tokenize($query['fields']);
+ }
+
+ if (count($query['fields']) === 1) {
+ if (strpos($query['fields'][0], '.') === false) {
+ $query['fields'][0] = $this->alias . '.' . $query['fields'][0];
+ }
+
+ $list = array("{n}.{$this->alias}.{$this->primaryKey}", '{n}.' . $query['fields'][0], null);
+ $query['fields'] = array("{$this->alias}.{$this->primaryKey}", $query['fields'][0]);
+ } elseif (count($query['fields']) === 3) {
+ for ($i = 0; $i < 3; $i++) {
+ if (strpos($query['fields'][$i], '.') === false) {
+ $query['fields'][$i] = $this->alias . '.' . $query['fields'][$i];
+ }
+ }
+
+ $list = array('{n}.' . $query['fields'][0], '{n}.' . $query['fields'][1], '{n}.' . $query['fields'][2]);
+ } else {
+ for ($i = 0; $i < 2; $i++) {
+ if (strpos($query['fields'][$i], '.') === false) {
+ $query['fields'][$i] = $this->alias . '.' . $query['fields'][$i];
+ }
+ }
+
+ $list = array('{n}.' . $query['fields'][0], '{n}.' . $query['fields'][1], null);
+ }
+ }
+ if (!isset($query['recursive']) || $query['recursive'] === null) {
+ $query['recursive'] = -1;
+ }
+ list($query['list']['keyPath'], $query['list']['valuePath'], $query['list']['groupPath']) = $list;
+ return $query;
+ } elseif ($state === 'after') {
+ if (empty($results)) {
+ return array();
+ }
+ $lst = $query['list'];
+ return Hash::combine($results, $lst['keyPath'], $lst['valuePath'], $lst['groupPath']);
+ }
+ }
+
+/**
+ * Detects the previous field's value, then uses logic to find the 'wrapping'
+ * rows and return them.
+ *
+ * @param string $state Either "before" or "after"
+ * @param array $query
+ * @param array $results
+ * @return array
+ */
+ protected function _findNeighbors($state, $query, $results = array()) {
+ if ($state === 'before') {
+ extract($query);
+ $conditions = (array)$conditions;
+ if (isset($field) && isset($value)) {
+ if (strpos($field, '.') === false) {
+ $field = $this->alias . '.' . $field;
+ }
+ } else {
+ $field = $this->alias . '.' . $this->primaryKey;
+ $value = $this->id;
+ }
+ $query['conditions'] = array_merge($conditions, array($field . ' <' => $value));
+ $query['order'] = $field . ' DESC';
+ $query['limit'] = 1;
+ $query['field'] = $field;
+ $query['value'] = $value;
+ return $query;
+ } elseif ($state === 'after') {
+ extract($query);
+ unset($query['conditions'][$field . ' <']);
+ $return = array();
+ if (isset($results[0])) {
+ $prevVal = Hash::get($results[0], $field);
+ $query['conditions'][$field . ' >='] = $prevVal;
+ $query['conditions'][$field . ' !='] = $value;
+ $query['limit'] = 2;
+ } else {
+ $return['prev'] = null;
+ $query['conditions'][$field . ' >'] = $value;
+ $query['limit'] = 1;
+ }
+ $query['order'] = $field . ' ASC';
+ $neighbors = $this->find('all', $query);
+ if (!array_key_exists('prev', $return)) {
+ $return['prev'] = $neighbors[0];
+ }
+ if (count($neighbors) === 2) {
+ $return['next'] = $neighbors[1];
+ } elseif (count($neighbors) === 1 && !$return['prev']) {
+ $return['next'] = $neighbors[0];
+ } else {
+ $return['next'] = null;
+ }
+ return $return;
+ }
+ }
+
+/**
+ * In the event of ambiguous results returned (multiple top level results, with different parent_ids)
+ * top level results with different parent_ids to the first result will be dropped
+ *
+ * @param string $state
+ * @param mixed $query
+ * @param array $results
+ * @return array Threaded results
+ */
+ protected function _findThreaded($state, $query, $results = array()) {
+ if ($state === 'before') {
+ return $query;
+ } elseif ($state === 'after') {
+ $parent = 'parent_id';
+ if (isset($query['parent'])) {
+ $parent = $query['parent'];
+ }
+ return Hash::nest($results, array(
+ 'idPath' => '{n}.' . $this->alias . '.' . $this->primaryKey,
+ 'parentPath' => '{n}.' . $this->alias . '.' . $parent
+ ));
+ }
+ }
+
+/**
+ * Passes query results through model and behavior afterFilter() methods.
+ *
+ * @param array $results Results to filter
+ * @param boolean $primary If this is the primary model results (results from model where the find operation was performed)
+ * @return array Set of filtered results
+ */
+ protected function _filterResults($results, $primary = true) {
+ $event = new CakeEvent('Model.afterFind', $this, array($results, $primary));
+ $event->modParams = 0;
+ $this->getEventManager()->dispatch($event);
+ return $event->result;
+ }
+
+/**
+ * This resets the association arrays for the model back
+ * to those originally defined in the model. Normally called at the end
+ * of each call to Model::find()
+ *
+ * @return boolean Success
+ */
+ public function resetAssociations() {
+ if (!empty($this->__backAssociation)) {
+ foreach ($this->_associations as $type) {
+ if (isset($this->__backAssociation[$type])) {
+ $this->{$type} = $this->__backAssociation[$type];
+ }
+ }
+ $this->__backAssociation = array();
+ }
+
+ foreach ($this->_associations as $type) {
+ foreach ($this->{$type} as $key => $name) {
+ if (property_exists($this, $key) && !empty($this->{$key}->__backAssociation)) {
+ $this->{$key}->resetAssociations();
+ }
+ }
+ }
+ $this->__backAssociation = array();
+ return true;
+ }
+
+/**
+ * Returns false if any fields passed match any (by default, all if $or = false) of their matching values.
+ *
+ * @param array $fields Field/value pairs to search (if no values specified, they are pulled from $this->data)
+ * @param boolean $or If false, all fields specified must match in order for a false return value
+ * @return boolean False if any records matching any fields are found
+ */
+ public function isUnique($fields, $or = true) {
+ if (!is_array($fields)) {
+ $fields = func_get_args();
+ if (is_bool($fields[count($fields) - 1])) {
+ $or = $fields[count($fields) - 1];
+ unset($fields[count($fields) - 1]);
+ }
+ }
+
+ foreach ($fields as $field => $value) {
+ if (is_numeric($field)) {
+ unset($fields[$field]);
+
+ $field = $value;
+ if (isset($this->data[$this->alias][$field])) {
+ $value = $this->data[$this->alias][$field];
+ } else {
+ $value = null;
+ }
+ }
+
+ if (strpos($field, '.') === false) {
+ unset($fields[$field]);
+ $fields[$this->alias . '.' . $field] = $value;
+ }
+ }
+ if ($or) {
+ $fields = array('or' => $fields);
+ }
+ if (!empty($this->id)) {
+ $fields[$this->alias . '.' . $this->primaryKey . ' !='] = $this->id;
+ }
+ return ($this->find('count', array('conditions' => $fields, 'recursive' => -1)) == 0);
+ }
+
+/**
+ * Returns a resultset for a given SQL statement. Custom SQL queries should be performed with this method.
+ *
+ * @param string $sql,... SQL statement
+ * @return mixed Resultset array or boolean indicating success / failure depending on the query executed
+ * @link http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-query
+ */
+ public function query($sql) {
+ $params = func_get_args();
+ $db = $this->getDataSource();
+ return call_user_func_array(array(&$db, 'query'), $params);
+ }
+
+/**
+ * Returns true if all fields pass validation. Will validate hasAndBelongsToMany associations
+ * that use the 'with' key as well. Since _saveMulti is incapable of exiting a save operation.
+ *
+ * Will validate the currently set data. Use Model::set() or Model::create() to set the active data.
+ *
+ * @param array $options An optional array of custom options to be made available in the beforeValidate callback
+ * @return boolean True if there are no errors
+ */
+ public function validates($options = array()) {
+ return $this->validator()->validates($options);
+ }
+
+/**
+ * Returns an array of fields that have failed validation. On the current model.
+ *
+ * @param string $options An optional array of custom options to be made available in the beforeValidate callback
+ * @return array Array of invalid fields
+ * @see Model::validates()
+ */
+ public function invalidFields($options = array()) {
+ return $this->validator()->errors($options);
+ }
+
+/**
+ * Marks a field as invalid, optionally setting the name of validation
+ * rule (in case of multiple validation for field) that was broken.
+ *
+ * @param string $field The name of the field to invalidate
+ * @param mixed $value Name of validation rule that was not failed, or validation message to
+ * be returned. If no validation key is provided, defaults to true.
+ * @return void
+ */
+ public function invalidate($field, $value = true) {
+ $this->validator()->invalidate($field, $value);
+ }
+
+/**
+ * Returns true if given field name is a foreign key in this model.
+ *
+ * @param string $field Returns true if the input string ends in "_id"
+ * @return boolean True if the field is a foreign key listed in the belongsTo array.
+ */
+ public function isForeignKey($field) {
+ $foreignKeys = array();
+ if (!empty($this->belongsTo)) {
+ foreach ($this->belongsTo as $assoc => $data) {
+ $foreignKeys[] = $data['foreignKey'];
+ }
+ }
+ return in_array($field, $foreignKeys);
+ }
+
+/**
+ * Escapes the field name and prepends the model name. Escaping is done according to the
+ * current database driver's rules.
+ *
+ * @param string $field Field to escape (e.g: id)
+ * @param string $alias Alias for the model (e.g: Post)
+ * @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`).
+ */
+ public function escapeField($field = null, $alias = null) {
+ if (empty($alias)) {
+ $alias = $this->alias;
+ }
+ if (empty($field)) {
+ $field = $this->primaryKey;
+ }
+ $db = $this->getDataSource();
+ if (strpos($field, $db->name($alias) . '.') === 0) {
+ return $field;
+ }
+ return $db->name($alias . '.' . $field);
+ }
+
+/**
+ * Returns the current record's ID
+ *
+ * @param integer $list Index on which the composed ID is located
+ * @return mixed The ID of the current record, false if no ID
+ */
+ public function getID($list = 0) {
+ if (empty($this->id) || (is_array($this->id) && isset($this->id[0]) && empty($this->id[0]))) {
+ return false;
+ }
+
+ if (!is_array($this->id)) {
+ return $this->id;
+ }
+
+ if (isset($this->id[$list]) && !empty($this->id[$list])) {
+ return $this->id[$list];
+ } elseif (isset($this->id[$list])) {
+ return false;
+ }
+
+ return current($this->id);
+ }
+
+/**
+ * Returns the ID of the last record this model inserted.
+ *
+ * @return mixed Last inserted ID
+ */
+ public function getLastInsertID() {
+ return $this->getInsertID();
+ }
+
+/**
+ * Returns the ID of the last record this model inserted.
+ *
+ * @return mixed Last inserted ID
+ */
+ public function getInsertID() {
+ return $this->_insertID;
+ }
+
+/**
+ * Sets the ID of the last record this model inserted
+ *
+ * @param integer|string $id Last inserted ID
+ * @return void
+ */
+ public function setInsertID($id) {
+ $this->_insertID = $id;
+ }
+
+/**
+ * Returns the number of rows returned from the last query.
+ *
+ * @return integer Number of rows
+ */
+ public function getNumRows() {
+ return $this->getDataSource()->lastNumRows();
+ }
+
+/**
+ * Returns the number of rows affected by the last query.
+ *
+ * @return integer Number of rows
+ */
+ public function getAffectedRows() {
+ return $this->getDataSource()->lastAffected();
+ }
+
+/**
+ * Sets the DataSource to which this model is bound.
+ *
+ * @param string $dataSource The name of the DataSource, as defined in app/Config/database.php
+ * @return void
+ * @throws MissingConnectionException
+ */
+ public function setDataSource($dataSource = null) {
+ $oldConfig = $this->useDbConfig;
+
+ if ($dataSource != null) {
+ $this->useDbConfig = $dataSource;
+ }
+ $db = ConnectionManager::getDataSource($this->useDbConfig);
+ if (!empty($oldConfig) && isset($db->config['prefix'])) {
+ $oldDb = ConnectionManager::getDataSource($oldConfig);
+
+ if (!isset($this->tablePrefix) || (!isset($oldDb->config['prefix']) || $this->tablePrefix == $oldDb->config['prefix'])) {
+ $this->tablePrefix = $db->config['prefix'];
+ }
+ } elseif (isset($db->config['prefix'])) {
+ $this->tablePrefix = $db->config['prefix'];
+ }
+
+ $this->schemaName = $db->getSchemaName();
+ }
+
+/**
+ * Gets the DataSource to which this model is bound.
+ *
+ * @return DataSource A DataSource object
+ */
+ public function getDataSource() {
+ if (!$this->_sourceConfigured && $this->useTable !== false) {
+ $this->_sourceConfigured = true;
+ $this->setSource($this->useTable);
+ }
+ return ConnectionManager::getDataSource($this->useDbConfig);
+ }
+
+/**
+ * Get associations
+ *
+ * @return array
+ */
+ public function associations() {
+ return $this->_associations;
+ }
+
+/**
+ * Gets all the models with which this model is associated.
+ *
+ * @param string $type Only result associations of this type
+ * @return array Associations
+ */
+ public function getAssociated($type = null) {
+ if ($type == null) {
+ $associated = array();
+ foreach ($this->_associations as $assoc) {
+ if (!empty($this->{$assoc})) {
+ $models = array_keys($this->{$assoc});
+ foreach ($models as $m) {
+ $associated[$m] = $assoc;
+ }
+ }
+ }
+ return $associated;
+ } elseif (in_array($type, $this->_associations)) {
+ if (empty($this->{$type})) {
+ return array();
+ }
+ return array_keys($this->{$type});
+ } else {
+ $assoc = array_merge(
+ $this->hasOne,
+ $this->hasMany,
+ $this->belongsTo,
+ $this->hasAndBelongsToMany
+ );
+ if (array_key_exists($type, $assoc)) {
+ foreach ($this->_associations as $a) {
+ if (isset($this->{$a}[$type])) {
+ $assoc[$type]['association'] = $a;
+ break;
+ }
+ }
+ return $assoc[$type];
+ }
+ return null;
+ }
+ }
+
+/**
+ * Gets the name and fields to be used by a join model. This allows specifying join fields
+ * in the association definition.
+ *
+ * @param string|array $assoc The model to be joined
+ * @param array $keys Any join keys which must be merged with the keys queried
+ * @return array
+ */
+ public function joinModel($assoc, $keys = array()) {
+ if (is_string($assoc)) {
+ list(, $assoc) = pluginSplit($assoc);
+ return array($assoc, array_keys($this->{$assoc}->schema()));
+ } elseif (is_array($assoc)) {
+ $with = key($assoc);
+ return array($with, array_unique(array_merge($assoc[$with], $keys)));
+ }
+ trigger_error(
+ __d('cake_dev', 'Invalid join model settings in %s', $model->alias),
+ E_USER_WARNING
+ );
+ }
+
+/**
+ * Called before each find operation. Return false if you want to halt the find
+ * call, otherwise return the (modified) query data.
+ *
+ * @param array $queryData Data used to execute this query, i.e. conditions, order, etc.
+ * @return mixed true if the operation should continue, false if it should abort; or, modified
+ * $queryData to continue with new $queryData
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#beforefind
+ */
+ public function beforeFind($queryData) {
+ return true;
+ }
+
+/**
+ * Called after each find operation. Can be used to modify any results returned by find().
+ * Return value should be the (modified) results.
+ *
+ * @param mixed $results The results of the find operation
+ * @param boolean $primary Whether this model is being queried directly (vs. being queried as an association)
+ * @return mixed Result of the find operation
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#afterfind
+ */
+ public function afterFind($results, $primary = false) {
+ return $results;
+ }
+
+/**
+ * Called before each save operation, after validation. Return a non-true result
+ * to halt the save.
+ *
+ * @param array $options
+ * @return boolean True if the operation should continue, false if it should abort
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#beforesave
+ */
+ public function beforeSave($options = array()) {
+ return true;
+ }
+
+/**
+ * Called after each successful save operation.
+ *
+ * @param boolean $created True if this save created a new record
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#aftersave
+ */
+ public function afterSave($created) {
+ }
+
+/**
+ * Called before every deletion operation.
+ *
+ * @param boolean $cascade If true records that depend on this record will also be deleted
+ * @return boolean True if the operation should continue, false if it should abort
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#beforedelete
+ */
+ public function beforeDelete($cascade = true) {
+ return true;
+ }
+
+/**
+ * Called after every deletion operation.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#afterdelete
+ */
+ public function afterDelete() {
+ }
+
+/**
+ * Called during validation operations, before validation. Please note that custom
+ * validation rules can be defined in $validate.
+ *
+ * @param array $options Options passed from model::save(), see $options of model::save().
+ * @return boolean True if validate operation should continue, false to abort
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#beforevalidate
+ */
+ public function beforeValidate($options = array()) {
+ return true;
+ }
+
+/**
+ * Called after data has been checked for errors
+ *
+ * @return void
+ */
+ public function afterValidate() {
+ }
+
+/**
+ * Called when a DataSource-level error occurs.
+ *
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#onerror
+ */
+ public function onError() {
+ }
+
+/**
+ * Clears cache for this model.
+ *
+ * @param string $type If null this deletes cached views if Cache.check is true
+ * Will be used to allow deleting query cache also
+ * @return boolean true on delete
+ */
+ protected function _clearCache($type = null) {
+ if ($type === null) {
+ if (Configure::read('Cache.check') === true) {
+ $assoc[] = strtolower(Inflector::pluralize($this->alias));
+ $assoc[] = strtolower(Inflector::underscore(Inflector::pluralize($this->alias)));
+ foreach ($this->_associations as $key => $association) {
+ foreach ($this->$association as $key => $className) {
+ $check = strtolower(Inflector::pluralize($className['className']));
+ if (!in_array($check, $assoc)) {
+ $assoc[] = strtolower(Inflector::pluralize($className['className']));
+ $assoc[] = strtolower(Inflector::underscore(Inflector::pluralize($className['className'])));
+ }
+ }
+ }
+ clearCache($assoc);
+ return true;
+ }
+ } else {
+ //Will use for query cache deleting
+ }
+ }
+
+/**
+ * Retunrs an instance of a model validator for this class
+ *
+ * @return ModelValidator
+ */
+ public function validator($instance = null) {
+ if ($instance instanceof ModelValidator) {
+ return $this->_validator = $instance;
+ }
+
+ if (empty($this->_validator) && is_null($instance)) {
+ $this->_validator = new ModelValidator($this);
+ }
+
+ return $this->_validator;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelBehavior.php
new file mode 100644
index 0000000..141b9d5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelBehavior.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * Model behaviors base class.
+ *
+ * Adds methods and automagic functionality to Cake Models.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 1.2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Model behavior base class.
+ *
+ * Defines the Behavior interface, and contains common model interaction functionality. Behaviors
+ * allow you to simulate mixins, and create reusable blocks of application logic, that can be reused across
+ * several models. Behaviors also provide a way to hook into model callbacks and augment their behavior.
+ *
+ * ### Mixin methods
+ *
+ * Behaviors can provide mixin like features by declaring public methods. These methods should expect
+ * the model instance to be shifted onto the parameter list.
+ *
+ * {{{
+ * function doSomething(Model $model, $arg1, $arg2) {
+ * //do something
+ * }
+ * }}}
+ *
+ * Would be called like `$this->Model->doSomething($arg1, $arg2);`.
+ *
+ * ### Mapped methods
+ *
+ * Behaviors can also define mapped methods. Mapped methods use pattern matching for method invocation. This
+ * allows you to create methods similar to Model::findAllByXXX methods on your behaviors. Mapped methods need to
+ * be declared in your behaviors `$mapMethods` array. The method signature for a mapped method is slightly different
+ * than a normal behavior mixin method.
+ *
+ * {{{
+ * public $mapMethods = array('/do(\w+)/' => 'doSomething');
+ *
+ * function doSomething(Model $model, $method, $arg1, $arg2) {
+ * //do something
+ * }
+ * }}}
+ *
+ * The above will map every doXXX() method call to the behavior. As you can see, the model is
+ * still the first parameter, but the called method name will be the 2nd parameter. This allows
+ * you to munge the method name for additional information, much like Model::findAllByXX.
+ *
+ * @package Cake.Model
+ * @see Model::$actsAs
+ * @see BehaviorCollection::load()
+ */
+class ModelBehavior extends Object {
+
+/**
+ * Contains configuration settings for use with individual model objects. This
+ * is used because if multiple models use this Behavior, each will use the same
+ * object instance. Individual model settings should be stored as an
+ * associative array, keyed off of the model name.
+ *
+ * @var array
+ * @see Model::$alias
+ */
+ public $settings = array();
+
+/**
+ * Allows the mapping of preg-compatible regular expressions to public or
+ * private methods in this class, where the array key is a /-delimited regular
+ * expression, and the value is a class method. Similar to the functionality of
+ * the findBy* / findAllBy* magic methods.
+ *
+ * @var array
+ */
+ public $mapMethods = array();
+
+/**
+ * Setup this behavior with the specified configuration settings.
+ *
+ * @param Model $model Model using this behavior
+ * @param array $config Configuration settings for $model
+ * @return void
+ */
+ public function setup(Model $model, $config = array()) {
+ }
+
+/**
+ * Clean up any initialization this behavior has done on a model. Called when a behavior is dynamically
+ * detached from a model using Model::detach().
+ *
+ * @param Model $model Model using this behavior
+ * @return void
+ * @see BehaviorCollection::detach()
+ */
+ public function cleanup(Model $model) {
+ if (isset($this->settings[$model->alias])) {
+ unset($this->settings[$model->alias]);
+ }
+ }
+
+/**
+ * beforeFind can be used to cancel find operations, or modify the query that will be executed.
+ * By returning null/false you can abort a find. By returning an array you can modify/replace the query
+ * that is going to be run.
+ *
+ * @param Model $model Model using this behavior
+ * @param array $query Data used to execute this query, i.e. conditions, order, etc.
+ * @return boolean|array False or null will abort the operation. You can return an array to replace the
+ * $query that will be eventually run.
+ */
+ public function beforeFind(Model $model, $query) {
+ return true;
+ }
+
+/**
+ * After find callback. Can be used to modify any results returned by find.
+ *
+ * @param Model $model Model using this behavior
+ * @param mixed $results The results of the find operation
+ * @param boolean $primary Whether this model is being queried directly (vs. being queried as an association)
+ * @return mixed An array value will replace the value of $results - any other value will be ignored.
+ */
+ public function afterFind(Model $model, $results, $primary) {
+ }
+
+/**
+ * beforeValidate is called before a model is validated, you can use this callback to
+ * add behavior validation rules into a models validate array. Returning false
+ * will allow you to make the validation fail.
+ *
+ * @param Model $model Model using this behavior
+ * @return mixed False or null will abort the operation. Any other result will continue.
+ */
+ public function beforeValidate(Model $model) {
+ return true;
+ }
+
+/**
+ * afterValidate is called just after model data was validated, you can use this callback
+ * to perform any data cleanup or preparation if needed
+ *
+ * @param Model $model Model using this behavior
+ * @return mixed False will stop this event from being passed to other behaviors
+ */
+ public function afterValidate(Model $model) {
+ return true;
+ }
+
+/**
+ * beforeSave is called before a model is saved. Returning false from a beforeSave callback
+ * will abort the save operation.
+ *
+ * @param Model $model Model using this behavior
+ * @return mixed False if the operation should abort. Any other result will continue.
+ */
+ public function beforeSave(Model $model) {
+ return true;
+ }
+
+/**
+ * afterSave is called after a model is saved.
+ *
+ * @param Model $model Model using this behavior
+ * @param boolean $created True if this save created a new record
+ * @return boolean
+ */
+ public function afterSave(Model $model, $created) {
+ return true;
+ }
+
+/**
+ * Before delete is called before any delete occurs on the attached model, but after the model's
+ * beforeDelete is called. Returning false from a beforeDelete will abort the delete.
+ *
+ * @param Model $model Model using this behavior
+ * @param boolean $cascade If true records that depend on this record will also be deleted
+ * @return mixed False if the operation should abort. Any other result will continue.
+ */
+ public function beforeDelete(Model $model, $cascade = true) {
+ return true;
+ }
+
+/**
+ * After delete is called after any delete occurs on the attached model.
+ *
+ * @param Model $model Model using this behavior
+ * @return void
+ */
+ public function afterDelete(Model $model) {
+ }
+
+/**
+ * DataSource error callback
+ *
+ * @param Model $model Model using this behavior
+ * @param string $error Error generated in DataSource
+ * @return void
+ */
+ public function onError(Model $model, $error) {
+ }
+
+/**
+ * If $model's whitelist property is non-empty, $field will be added to it.
+ * Note: this method should *only* be used in beforeValidate or beforeSave to ensure
+ * that it only modifies the whitelist for the current save operation. Also make sure
+ * you explicitly set the value of the field which you are allowing.
+ *
+ * @param Model $model Model using this behavior
+ * @param string $field Field to be added to $model's whitelist
+ * @return void
+ */
+ protected function _addToWhitelist(Model $model, $field) {
+ if (is_array($field)) {
+ foreach ($field as $f) {
+ $this->_addToWhitelist($model, $f);
+ }
+ return;
+ }
+ if (!empty($model->whitelist) && !in_array($field, $model->whitelist)) {
+ $model->whitelist[] = $field;
+ }
+ }
+
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelValidator.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelValidator.php
new file mode 100644
index 0000000..dbe58ce
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/ModelValidator.php
@@ -0,0 +1,599 @@
+<?php
+/**
+ * ModelValidator.
+ *
+ * Provides the Model validation logic.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeValidationSet', 'Model/Validator');
+
+/**
+ * ModelValidator object encapsulates all methods related to data validations for a model
+ * It also provides an API to dynamically change validation rules for each model field.
+ *
+ * Implements ArrayAccess to easily modify rules as usually done with `Model::$validate`
+ * definition array
+ *
+ * @package Cake.Model
+ * @link http://book.cakephp.org/2.0/en/data-validation.html
+ */
+class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
+
+/**
+ * Holds the CakeValidationSet objects array
+ *
+ * @var array
+ */
+ protected $_fields = array();
+
+/**
+ * Holds the reference to the model this Validator is attached to
+ *
+ * @var Model
+ */
+ protected $_model = array();
+
+/**
+ * The validators $validate property, used for checking wheter validation
+ * rules definition changed in the model and should be refreshed in this class
+ *
+ * @var array
+ */
+ protected $_validate = array();
+
+/**
+ * Holds the available custom callback methods, usually taken from model methods
+ * and behavior methods
+ *
+ * @var array
+ */
+ protected $_methods = array();
+
+/**
+ * Constructor
+ *
+ * @param Model $Model A reference to the Model the Validator is attached to
+ */
+ public function __construct(Model $Model) {
+ $this->_model = $Model;
+ }
+
+/**
+ * Returns true if all fields pass validation. Will validate hasAndBelongsToMany associations
+ * that use the 'with' key as well. Since `Model::_saveMulti` is incapable of exiting a save operation.
+ *
+ * Will validate the currently set data. Use `Model::set()` or `Model::create()` to set the active data.
+ *
+ * @param array $options An optional array of custom options to be made available in the beforeValidate callback
+ * @return boolean True if there are no errors
+ */
+ public function validates($options = array()) {
+ $errors = $this->errors($options);
+ if (empty($errors) && $errors !== false) {
+ $errors = $this->_validateWithModels($options);
+ }
+ if (is_array($errors)) {
+ return count($errors) === 0;
+ }
+ return $errors;
+ }
+
+/**
+ * Validates a single record, as well as all its directly associated records.
+ *
+ * #### Options
+ *
+ * - atomic: If true (default), returns boolean. If false returns array.
+ * - fieldList: Equivalent to the $fieldList parameter in Model::save()
+ * - deep: If set to true, not only directly associated data , but deeper nested associated data is validated as well.
+ *
+ * Warning: This method could potentially change the passed argument `$data`,
+ * If you do not want this to happen, make a copy of `$data` before passing it
+ * to this method
+ *
+ * @param array $data Record data to validate. This should be an array indexed by association name.
+ * @param array $options Options to use when validating record data (see above), See also $options of validates().
+ * @return array|boolean If atomic: True on success, or false on failure.
+ * Otherwise: array similar to the $data array passed, but values are set to true/false
+ * depending on whether each record validated successfully.
+ */
+ public function validateAssociated(&$data, $options = array()) {
+ $model = $this->getModel();
+ $options = array_merge(array('atomic' => true, 'deep' => false), $options);
+ $model->validationErrors = $validationErrors = $return = array();
+ $model->create(null);
+ if (!($model->set($data) && $model->validates($options))) {
+ $validationErrors[$model->alias] = $model->validationErrors;
+ $return[$model->alias] = false;
+ } else {
+ $return[$model->alias] = true;
+ }
+ $data = $model->data;
+ if (!empty($options['deep']) && isset($data[$model->alias])) {
+ $recordData = $data[$model->alias];
+ unset($data[$model->alias]);
+ $data = array_merge($data, $recordData);
+ }
+
+ $associations = $model->getAssociated();
+ foreach ($data as $association => &$values) {
+ $validates = true;
+ if (isset($associations[$association])) {
+ if (in_array($associations[$association], array('belongsTo', 'hasOne'))) {
+ if ($options['deep']) {
+ $validates = $model->{$association}->validateAssociated($values, $options);
+ } else {
+ $model->{$association}->create(null);
+ $validates = $model->{$association}->set($values) && $model->{$association}->validates($options);
+ $data[$association] = $model->{$association}->data[$model->{$association}->alias];
+ }
+ if (is_array($validates)) {
+ if (in_array(false, $validates, true)) {
+ $validates = false;
+ } else {
+ $validates = true;
+ }
+ }
+ $return[$association] = $validates;
+ } elseif ($associations[$association] === 'hasMany') {
+ $validates = $model->{$association}->validateMany($values, $options);
+ $return[$association] = $validates;
+ }
+ if (!$validates || (is_array($validates) && in_array(false, $validates, true))) {
+ $validationErrors[$association] = $model->{$association}->validationErrors;
+ }
+ }
+ }
+
+ $model->validationErrors = $validationErrors;
+ if (isset($validationErrors[$model->alias])) {
+ $model->validationErrors = $validationErrors[$model->alias];
+ unset($validationErrors[$model->alias]);
+ $model->validationErrors = array_merge($model->validationErrors, $validationErrors);
+ }
+ if (!$options['atomic']) {
+ return $return;
+ }
+ if ($return[$model->alias] === false || !empty($model->validationErrors)) {
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Validates multiple individual records for a single model
+ *
+ * #### Options
+ *
+ * - atomic: If true (default), returns boolean. If false returns array.
+ * - fieldList: Equivalent to the $fieldList parameter in Model::save()
+ * - deep: If set to true, all associated data will be validated as well.
+ *
+ * Warning: This method could potentially change the passed argument `$data`,
+ * If you do not want this to happen, make a copy of `$data` before passing it
+ * to this method
+ *
+ * @param array $data Record data to validate. This should be a numerically-indexed array
+ * @param array $options Options to use when validating record data (see above), See also $options of validates().
+ * @return boolean True on success, or false on failure.
+ * @return mixed If atomic: True on success, or false on failure.
+ * Otherwise: array similar to the $data array passed, but values are set to true/false
+ * depending on whether each record validated successfully.
+ */
+ public function validateMany(&$data, $options = array()) {
+ $model = $this->getModel();
+ $options = array_merge(array('atomic' => true, 'deep' => false), $options);
+ $model->validationErrors = $validationErrors = $return = array();
+ foreach ($data as $key => &$record) {
+ if ($options['deep']) {
+ $validates = $model->validateAssociated($record, $options);
+ } else {
+ $model->create(null);
+ $validates = $model->set($record) && $model->validates($options);
+ $data[$key] = $model->data;
+ }
+ if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) {
+ $validationErrors[$key] = $model->validationErrors;
+ $validates = false;
+ } else {
+ $validates = true;
+ }
+ $return[$key] = $validates;
+ }
+ $model->validationErrors = $validationErrors;
+ if (!$options['atomic']) {
+ return $return;
+ }
+ if (empty($model->validationErrors)) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Returns an array of fields that have failed validation. On the current model. This method will
+ * actually run validation rules over data, not just return the messages.
+ *
+ * @param string $options An optional array of custom options to be made available in the beforeValidate callback
+ * @return array Array of invalid fields
+ * @see ModelValidator::validates()
+ */
+ public function errors($options = array()) {
+ if (!$this->_triggerBeforeValidate($options)) {
+ return false;
+ }
+ $model = $this->getModel();
+
+ if (!$this->_parseRules()) {
+ return $model->validationErrors;
+ }
+
+ $fieldList = isset($options['fieldList']) ? $options['fieldList'] : array();
+ $exists = $model->exists();
+ $methods = $this->getMethods();
+ $fields = $this->_validationList($fieldList);
+
+ foreach ($fields as $field) {
+ $field->setMethods($methods);
+ $field->setValidationDomain($model->validationDomain);
+ $data = isset($model->data[$model->alias]) ? $model->data[$model->alias] : array();
+ $errors = $field->validate($data, $exists);
+ foreach ($errors as $error) {
+ $this->invalidate($field->field, $error);
+ }
+ }
+
+ $model->getEventManager()->dispatch(new CakeEvent('Model.afterValidate', $model));
+ return $model->validationErrors;
+ }
+
+/**
+ * Marks a field as invalid, optionally setting a message explaining
+ * why the rule failed
+ *
+ * @param string $field The name of the field to invalidate
+ * @param string $message Validation message explaining why the rule failed, defaults to true.
+ * @return void
+ */
+ public function invalidate($field, $message = true) {
+ $this->getModel()->validationErrors[$field][] = $message;
+ }
+
+/**
+ * Gets all possible custom methods from the Model and attached Behaviors
+ * to be used as validators
+ *
+ * @return array List of callables to be used as validation methods
+ */
+ public function getMethods() {
+ if (!empty($this->_methods)) {
+ return $this->_methods;
+ }
+
+ $methods = array();
+ foreach (get_class_methods($this->_model) as $method) {
+ $methods[strtolower($method)] = array($this->_model, $method);
+ }
+
+ foreach (array_keys($this->_model->Behaviors->methods()) as $method) {
+ $methods += array(strtolower($method) => array($this->_model, $method));
+ }
+
+ return $this->_methods = $methods;
+ }
+
+/**
+ * Returns a CakeValidationSet object containing all validation rules for a field, if no
+ * params are passed then it returns an array with all CakeValidationSet objects for each field
+ *
+ * @param string $name [optional] The fieldname to fetch. Defaults to null.
+ * @return CakeValidationSet|array
+ */
+ public function getField($name = null) {
+ $this->_parseRules();
+ if ($name !== null && !empty($this->_fields[$name])) {
+ return $this->_fields[$name];
+ } elseif ($name !== null) {
+ return null;
+ }
+ return $this->_fields;
+ }
+
+/**
+ * Sets the CakeValidationSet objects from the `Model::$validate` property
+ * If `Model::$validate` is not set or empty, this method returns false. True otherwise.
+ *
+ * @return boolean true if `Model::$validate` was processed, false otherwise
+ */
+ protected function _parseRules() {
+ if ($this->_validate === $this->_model->validate) {
+ return true;
+ }
+
+ if (empty($this->_model->validate)) {
+ $this->_validate = array();
+ $this->_fields = array();
+ return false;
+ }
+
+ $this->_validate = $this->_model->validate;
+ $this->_fields = array();
+ $methods = $this->getMethods();
+ foreach ($this->_validate as $fieldName => $ruleSet) {
+ $this->_fields[$fieldName] = new CakeValidationSet($fieldName, $ruleSet);
+ $this->_fields[$fieldName]->setMethods($methods);
+ }
+ return true;
+ }
+
+/**
+ * Sets the I18n domain for validation messages. This method is chainable.
+ *
+ * @param string $validationDomain [optional] The validation domain to be used.
+ * @return ModelValidator
+ */
+ public function setValidationDomain($validationDomain = null) {
+ if (empty($validationDomain)) {
+ $validationDomain = 'default';
+ }
+ $this->getModel()->validationDomain = $validationDomain;
+ return $this;
+ }
+
+/**
+ * Gets the model related to this validator
+ *
+ * @return Model
+ */
+ public function getModel() {
+ return $this->_model;
+ }
+
+/**
+ * Processes the Model's whitelist or passed fieldList and returns the list of fields
+ * to be validated
+ *
+ * @param array $fieldList list of fields to be used for validation
+ * @return array List of validation rules to be applied
+ */
+ protected function _validationList($fieldList = array()) {
+ $model = $this->getModel();
+ $whitelist = $model->whitelist;
+
+ if (!empty($fieldList)) {
+ if (!empty($fieldList[$model->alias]) && is_array($fieldList[$model->alias])) {
+ $whitelist = $fieldList[$model->alias];
+ } else {
+ $whitelist = $fieldList;
+ }
+ }
+ unset($fieldList);
+
+ $validateList = array();
+ if (!empty($whitelist)) {
+ $this->validationErrors = array();
+
+ foreach ((array)$whitelist as $f) {
+ if (!empty($this->_fields[$f])) {
+ $validateList[$f] = $this->_fields[$f];
+ }
+ }
+ } else {
+ return $this->_fields;
+ }
+
+ return $validateList;
+ }
+
+/**
+ * Runs validation for hasAndBelongsToMany associations that have 'with' keys
+ * set and data in the data set.
+ *
+ * @param array $options Array of options to use on Validation of with models
+ * @return boolean Failure of validation on with models.
+ * @see Model::validates()
+ */
+ protected function _validateWithModels($options) {
+ $valid = true;
+ $model = $this->getModel();
+
+ foreach ($model->hasAndBelongsToMany as $assoc => $association) {
+ if (empty($association['with']) || !isset($model->data[$assoc])) {
+ continue;
+ }
+ list($join) = $model->joinModel($model->hasAndBelongsToMany[$assoc]['with']);
+ $data = $model->data[$assoc];
+
+ $newData = array();
+ foreach ((array)$data as $row) {
+ if (isset($row[$model->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
+ $newData[] = $row;
+ } elseif (isset($row[$join]) && isset($row[$join][$model->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
+ $newData[] = $row[$join];
+ }
+ }
+ if (empty($newData)) {
+ continue;
+ }
+ foreach ($newData as $data) {
+ $data[$model->hasAndBelongsToMany[$assoc]['foreignKey']] = $model->id;
+ $model->{$join}->create($data);
+ $valid = ($valid && $model->{$join}->validator()->validates($options));
+ }
+ }
+ return $valid;
+ }
+
+/**
+ * Propagates beforeValidate event
+ *
+ * @param array $options
+ * @return boolean
+ */
+ protected function _triggerBeforeValidate($options = array()) {
+ $model = $this->getModel();
+ $event = new CakeEvent('Model.beforeValidate', $model, array($options));
+ list($event->break, $event->breakOn) = array(true, false);
+ $model->getEventManager()->dispatch($event);
+ if ($event->isStopped()) {
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Returns wheter a rule set is defined for a field or not
+ *
+ * @param string $field name of the field to check
+ * @return boolean
+ **/
+ public function offsetExists($field) {
+ $this->_parseRules();
+ return isset($this->_fields[$field]);
+ }
+
+/**
+ * Returns the rule set for a field
+ *
+ * @param string $field name of the field to check
+ * @return CakeValidationSet
+ **/
+ public function offsetGet($field) {
+ $this->_parseRules();
+ return $this->_fields[$field];
+ }
+
+/**
+ * Sets the rule set for a field
+ *
+ * @param string $field name of the field to set
+ * @param array|CakeValidationSet $rules set of rules to apply to field
+ * @return void
+ **/
+ public function offsetSet($field, $rules) {
+ $this->_parseRules();
+ if (!$rules instanceof CakeValidationSet) {
+ $rules = new CakeValidationSet($field, $rules);
+ $methods = $this->getMethods();
+ $rules->setMethods($methods);
+ }
+ $this->_fields[$field] = $rules;
+ }
+
+/**
+ * Unsets the rulset for a field
+ *
+ * @param string $field name of the field to unset
+ * @return void
+ **/
+ public function offsetUnset($field) {
+ $this->_parseRules();
+ unset($this->_fields[$field]);
+ }
+
+/**
+ * Returns an iterator for each of the fields to be validated
+ *
+ * @return ArrayIterator
+ **/
+ public function getIterator() {
+ $this->_parseRules();
+ return new ArrayIterator($this->_fields);
+ }
+
+/**
+ * Returns the number of fields having validation rules
+ *
+ * @return int
+ **/
+ public function count() {
+ $this->_parseRules();
+ return count($this->_fields);
+ }
+
+/**
+ * Adds a new rule to a field's rule set. If second argumet is an array or instance of
+ * CakeValidationSet then rules list for the field will be replaced with second argument and
+ * third argument will be ignored.
+ *
+ * ## Example:
+ *
+ * {{{
+ * $validator
+ * ->add('title', 'required', array('rule' => 'notEmpty', 'required' => true))
+ * ->add('user_id', 'valid', array('rule' => 'numeric', 'message' => 'Invalid User'))
+ *
+ * $validator->add('password', array(
+ * 'size' => array('rule' => array('between', 8, 20)),
+ * 'hasSpecialCharacter' => array('rule' => 'validateSpecialchar', 'message' => 'not valid')
+ * ));
+ * }}}
+ *
+ * @param string $field The name of the field from wich the rule will be removed
+ * @param string|array|CakeValidationSet $name name of the rule to be added or list of rules for the field
+ * @param array|CakeValidationRule $rule or list of rules to be added to the field's rule set
+ * @return ModelValidator this instance
+ **/
+ public function add($field, $name, $rule = null) {
+ $this->_parseRules();
+ if ($name instanceof CakeValidationSet) {
+ $this->_fields[$field] = $name;
+ return $this;
+ }
+
+ if (!isset($this->_fields[$field])) {
+ $rule = (is_string($name)) ? array($name => $rule) : $name;
+ $this->_fields[$field] = new CakeValidationSet($field, $rule);
+ } else {
+ if (is_string($name)) {
+ $this->_fields[$field]->setRule($name, $rule);
+ } else {
+ $this->_fields[$field]->setRules($name);
+ }
+ }
+
+ $methods = $this->getMethods();
+ $this->_fields[$field]->setMethods($methods);
+
+ return $this;
+ }
+
+/**
+ * Removes a rule from the set by its name
+ *
+ * ## Example:
+ *
+ * {{{
+ * $validator
+ * ->remove('title', 'required')
+ * ->remove('user_id')
+ * }}}
+ *
+ * @param string $field The name of the field from wich the rule will be removed
+ * @param string $rule the name of the rule to be removed
+ * @return ModelValidator this instance
+ **/
+ public function remove($field, $rule = null) {
+ $this->_parseRules();
+ if ($rule === null) {
+ unset($this->_fields[$field]);
+ } else {
+ $this->_fields[$field]->removeRule($rule);
+ }
+ return $this;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Permission.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Permission.php
new file mode 100644
index 0000000..8decc7f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Permission.php
@@ -0,0 +1,257 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppModel', 'Model');
+
+/**
+ * Permissions linking AROs with ACOs
+ *
+ * @package Cake.Model
+ */
+class Permission extends AppModel {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'Permission';
+
+/**
+ * Explicitly disable in-memory query caching
+ *
+ * @var boolean
+ */
+ public $cacheQueries = false;
+
+/**
+ * Override default table name
+ *
+ * @var string
+ */
+ public $useTable = 'aros_acos';
+
+/**
+ * Permissions link AROs with ACOs
+ *
+ * @var array
+ */
+ public $belongsTo = array('Aro', 'Aco');
+
+/**
+ * No behaviors for this model
+ *
+ * @var array
+ */
+ public $actsAs = null;
+
+/**
+ * Constructor, used to tell this model to use the
+ * database configured for ACL
+ */
+ public function __construct() {
+ $config = Configure::read('Acl.database');
+ if (!empty($config)) {
+ $this->useDbConfig = $config;
+ }
+ parent::__construct();
+ }
+
+/**
+ * Checks if the given $aro has access to action $action in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $action Action (defaults to *)
+ * @return boolean Success (true if ARO has access to action in ACO, false otherwise)
+ */
+ public function check($aro, $aco, $action = "*") {
+ if ($aro == null || $aco == null) {
+ return false;
+ }
+
+ $permKeys = $this->getAcoKeys($this->schema());
+ $aroPath = $this->Aro->node($aro);
+ $acoPath = $this->Aco->node($aco);
+
+ if (empty($aroPath) || empty($acoPath)) {
+ trigger_error(__d('cake_dev', "DbAcl::check() - Failed ARO/ACO node lookup in permissions check. Node references:\nAro: ") . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
+ return false;
+ }
+
+ if ($acoPath == null || $acoPath == array()) {
+ trigger_error(__d('cake_dev', "DbAcl::check() - Failed ACO node lookup in permissions check. Node references:\nAro: ") . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
+ return false;
+ }
+
+ if ($action != '*' && !in_array('_' . $action, $permKeys)) {
+ trigger_error(__d('cake_dev', "ACO permissions key %s does not exist in DbAcl::check()", $action), E_USER_NOTICE);
+ return false;
+ }
+
+ $inherited = array();
+ $acoIDs = Hash::extract($acoPath, '{n}.' . $this->Aco->alias . '.id');
+
+ $count = count($aroPath);
+ for ($i = 0; $i < $count; $i++) {
+ $permAlias = $this->alias;
+
+ $perms = $this->find('all', array(
+ 'conditions' => array(
+ "{$permAlias}.aro_id" => $aroPath[$i][$this->Aro->alias]['id'],
+ "{$permAlias}.aco_id" => $acoIDs
+ ),
+ 'order' => array($this->Aco->alias . '.lft' => 'desc'),
+ 'recursive' => 0
+ ));
+
+ if (empty($perms)) {
+ continue;
+ } else {
+ $perms = Hash::extract($perms, '{n}.' . $this->alias);
+ foreach ($perms as $perm) {
+ if ($action == '*') {
+
+ foreach ($permKeys as $key) {
+ if (!empty($perm)) {
+ if ($perm[$key] == -1) {
+ return false;
+ } elseif ($perm[$key] == 1) {
+ $inherited[$key] = 1;
+ }
+ }
+ }
+
+ if (count($inherited) === count($permKeys)) {
+ return true;
+ }
+ } else {
+ switch ($perm['_' . $action]) {
+ case -1:
+ return false;
+ case 0:
+ continue;
+ break;
+ case 1:
+ return true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Allow $aro to have access to action $actions in $aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @param string $actions Action (defaults to *)
+ * @param integer $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit)
+ * @return boolean Success
+ */
+ public function allow($aro, $aco, $actions = "*", $value = 1) {
+ $perms = $this->getAclLink($aro, $aco);
+ $permKeys = $this->getAcoKeys($this->schema());
+ $save = array();
+
+ if ($perms == false) {
+ trigger_error(__d('cake_dev', 'DbAcl::allow() - Invalid node'), E_USER_WARNING);
+ return false;
+ }
+ if (isset($perms[0])) {
+ $save = $perms[0][$this->alias];
+ }
+
+ if ($actions == "*") {
+ $save = array_combine($permKeys, array_pad(array(), count($permKeys), $value));
+ } else {
+ if (!is_array($actions)) {
+ $actions = array('_' . $actions);
+ }
+ if (is_array($actions)) {
+ foreach ($actions as $action) {
+ if ($action{0} != '_') {
+ $action = '_' . $action;
+ }
+ if (in_array($action, $permKeys)) {
+ $save[$action] = $value;
+ }
+ }
+ }
+ }
+ list($save['aro_id'], $save['aco_id']) = array($perms['aro'], $perms['aco']);
+
+ if ($perms['link'] != null && !empty($perms['link'])) {
+ $save['id'] = $perms['link'][0][$this->alias]['id'];
+ } else {
+ unset($save['id']);
+ $this->id = null;
+ }
+ return ($this->save($save) !== false);
+ }
+
+/**
+ * Get an array of access-control links between the given Aro and Aco
+ *
+ * @param string $aro ARO The requesting object identifier.
+ * @param string $aco ACO The controlled object identifier.
+ * @return array Indexed array with: 'aro', 'aco' and 'link'
+ */
+ public function getAclLink($aro, $aco) {
+ $obj = array();
+ $obj['Aro'] = $this->Aro->node($aro);
+ $obj['Aco'] = $this->Aco->node($aco);
+
+ if (empty($obj['Aro']) || empty($obj['Aco'])) {
+ return false;
+ }
+ $aro = Hash::extract($obj, 'Aro.0.' . $this->Aro->alias . '.id');
+ $aco = Hash::extract($obj, 'Aco.0.' . $this->Aco->alias . '.id');
+ $aro = current($aro);
+ $aco = current($aco);
+
+ return array(
+ 'aro' => $aro,
+ 'aco' => $aco,
+ 'link' => $this->find('all', array('conditions' => array(
+ $this->alias . '.aro_id' => $aro,
+ $this->alias . '.aco_id' => $aco
+ )))
+ );
+ }
+
+/**
+ * Get the crud type keys
+ *
+ * @param array $keys Permission schema
+ * @return array permission keys
+ */
+ public function getAcoKeys($keys) {
+ $newKeys = array();
+ $keys = array_keys($keys);
+ foreach ($keys as $key) {
+ if (!in_array($key, array('id', 'aro_id', 'aco_id'))) {
+ $newKeys[] = $key;
+ }
+ }
+ return $newKeys;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationRule.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationRule.php
new file mode 100644
index 0000000..8ebf825
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationRule.php
@@ -0,0 +1,333 @@
+<?php
+/**
+ * CakeValidationRule.
+ *
+ * Provides the Model validation logic.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Validator
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ModelValidator', 'Model');
+App::uses('CakeValidationSet', 'Model/Validator');
+App::uses('Validation', 'Utility');
+
+/**
+ * CakeValidationRule object. Represents a validation method, error message and
+ * rules for applying such method to a field.
+ *
+ * @package Cake.Model.Validator
+ * @link http://book.cakephp.org/2.0/en/data-validation.html
+ */
+class CakeValidationRule {
+
+/**
+ * Whether the field passed this validation rule
+ *
+ * @var mixed
+ */
+ protected $_valid = true;
+
+/**
+ * Holds whether the record being validated exists in datasource or not
+ *
+ * @var boolean
+ */
+ protected $_recordExists = false;
+
+/**
+ * Validation method
+ *
+ * @var mixed
+ */
+ protected $_rule = null;
+
+/**
+ * Validation method arguments
+ *
+ * @var array
+ */
+ protected $_ruleParams = array();
+
+/**
+ * Holds passed in options
+ *
+ * @var array
+ */
+ protected $_passedOptions = array();
+
+/**
+ * The 'rule' key
+ *
+ * @var mixed
+ */
+ public $rule = 'blank';
+
+/**
+ * The 'required' key
+ *
+ * @var mixed
+ */
+ public $required = null;
+
+/**
+ * The 'allowEmpty' key
+ *
+ * @var boolean
+ */
+ public $allowEmpty = null;
+
+/**
+ * The 'on' key
+ *
+ * @var string
+ */
+ public $on = null;
+
+/**
+ * The 'last' key
+ *
+ * @var boolean
+ */
+ public $last = true;
+
+/**
+ * The 'message' key
+ *
+ * @var string
+ */
+ public $message = null;
+
+/**
+ * Constructor
+ *
+ * @param array $validator [optional] The validator properties
+ */
+ public function __construct($validator = array()) {
+ $this->_addValidatorProps($validator);
+ }
+
+/**
+ * Checks if the rule is valid
+ *
+ * @return boolean
+ */
+ public function isValid() {
+ if (!$this->_valid || (is_string($this->_valid) && !empty($this->_valid))) {
+ return false;
+ }
+
+ return true;
+ }
+
+/**
+ * Returns whether the field can be left blank according to this rule
+ *
+ * @return boolean
+ */
+ public function isEmptyAllowed() {
+ return $this->skip() || $this->allowEmpty === true;
+ }
+
+/**
+ * Checks if the field is required according to the `required` property
+ *
+ * @return boolean
+ */
+ public function isRequired() {
+ if (in_array($this->required, array('create', 'update'), true)) {
+ if ($this->required === 'create' && !$this->isUpdate() || $this->required === 'update' && $this->isUpdate()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ return $this->required;
+ }
+
+/**
+ * Checks whether the field failed the `field should be present` validation
+ *
+ * @param array $data data to check rule against
+ * @return boolean
+ */
+ public function checkRequired($field, &$data) {
+ return (
+ (!isset($data[$field]) && $this->isRequired() === true) ||
+ (
+ isset($data[$field]) && (empty($data[$field]) &&
+ !is_numeric($data[$field])) && $this->allowEmpty === false
+ )
+ );
+ }
+
+/**
+ * Checks if the allowEmpty key applies
+ *
+ * @param array $data data to check rule against
+ * @return boolean
+ */
+ public function checkEmpty($field, &$data) {
+ if (empty($data[$field]) && $data[$field] != '0' && $this->allowEmpty === true) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Checks if the validation rule should be skipped
+ *
+ * @return boolean True if the ValidationRule can be skipped
+ */
+ public function skip() {
+ if (!empty($this->on)) {
+ if ($this->on == 'create' && $this->isUpdate() || $this->on == 'update' && !$this->isUpdate()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns whethere this rule should break validation process for associated field
+ * after it fails
+ *
+ * @return boolean
+ */
+ public function isLast() {
+ return (bool)$this->last;
+ }
+
+/**
+ * Gets the validation error message
+ *
+ * @return string
+ */
+ public function getValidationResult() {
+ return $this->_valid;
+ }
+
+/**
+ * Gets an array with the rule properties
+ *
+ * @return array
+ */
+ protected function _getPropertiesArray() {
+ $rule = $this->rule;
+ if (!is_string($rule)) {
+ unset($rule[0]);
+ }
+ return array(
+ 'rule' => $rule,
+ 'required' => $this->required,
+ 'allowEmpty' => $this->allowEmpty,
+ 'on' => $this->on,
+ 'last' => $this->last,
+ 'message' => $this->message
+ );
+ }
+
+/**
+ * Sets the recordExists configuration value for this rule,
+ * ir refers to wheter the model record it is validating exists
+ * exists in the collection or not (create or update operation)
+ *
+ * If called with no parameters it will return whether this rule
+ * is configured for update operations or not.
+ *
+ * @return boolean
+ **/
+ public function isUpdate($exists = null) {
+ if ($exists === null) {
+ return $this->_recordExists;
+ }
+ return $this->_recordExists = $exists;
+ }
+
+/**
+ * Dispatches the validation rule to the given validator method
+ *
+ * @return boolean True if the rule could be dispatched, false otherwise
+ */
+ public function process($field, &$data, &$methods) {
+ $this->_valid = true;
+ $this->_parseRule($field, $data);
+
+ $validator = $this->_getPropertiesArray();
+ $rule = strtolower($this->_rule);
+ if (isset($methods[$rule])) {
+ $this->_ruleParams[] = array_merge($validator, $this->_passedOptions);
+ $this->_ruleParams[0] = array($field => $this->_ruleParams[0]);
+ $this->_valid = call_user_func_array($methods[$rule], $this->_ruleParams);
+ } elseif (class_exists('Validation') && method_exists('Validation', $this->_rule)) {
+ $this->_valid = call_user_func_array(array('Validation', $this->_rule), $this->_ruleParams);
+ } elseif (is_string($validator['rule'])) {
+ $this->_valid = preg_match($this->_rule, $data[$field]);
+ } elseif (Configure::read('debug') > 0) {
+ trigger_error(__d('cake_dev', 'Could not find validation handler %s for %s', $this->_rule, $field), E_USER_WARNING);
+ return false;
+ }
+
+ return true;
+ }
+
+/**
+ * Returns passed options for this rule
+ *
+ * @return array
+ **/
+ public function getOptions($key) {
+ if (!isset($this->_passedOptions[$key])) {
+ return null;
+ }
+ return $this->_passedOptions[$key];
+ }
+
+/**
+ * Sets the rule properties from the rule entry in validate
+ *
+ * @param array $validator [optional]
+ * @return void
+ */
+ protected function _addValidatorProps($validator = array()) {
+ if (!is_array($validator)) {
+ $validator = array('rule' => $validator);
+ }
+ foreach ($validator as $key => $value) {
+ if (isset($value) || !empty($value)) {
+ if (in_array($key, array('rule', 'required', 'allowEmpty', 'on', 'message', 'last'))) {
+ $this->{$key} = $validator[$key];
+ } else {
+ $this->_passedOptions[$key] = $value;
+ }
+ }
+ }
+ }
+
+/**
+ * Parses the rule and sets the rule and ruleParams
+ *
+ * @return void
+ */
+ protected function _parseRule($field, &$data) {
+ if (is_array($this->rule)) {
+ $this->_rule = $this->rule[0];
+ $this->_ruleParams = array_merge(array($data[$field]), array_values(array_slice($this->rule, 1)));
+ } else {
+ $this->_rule = $this->rule;
+ $this->_ruleParams = array($data[$field]);
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationSet.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationSet.php
new file mode 100644
index 0000000..fdecdc1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Model/Validator/CakeValidationSet.php
@@ -0,0 +1,350 @@
+<?php
+/**
+ * CakeValidationSet.
+ *
+ * Provides the Model validation logic.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model.Validator
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ModelValidator', 'Model');
+App::uses('CakeValidationRule', 'Model/Validator');
+
+/**
+ * CakeValidationSet object. Holds all validation rules for a field and exposes
+ * methods to dynamically add or remove validation rules
+ *
+ * @package Cake.Model.Validator
+ * @link http://book.cakephp.org/2.0/en/data-validation.html
+ */
+class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable {
+
+/**
+ * Holds the CakeValidationRule objects
+ *
+ * @var array
+ */
+ protected $_rules = array();
+
+/**
+ * List of methods available for validation
+ *
+ * @var array
+ **/
+ protected $_methods = array();
+
+/**
+ * I18n domain for validation messages.
+ *
+ * @var string
+ **/
+ protected $_validationDomain = null;
+
+/**
+ * Whether the validation is stopped
+ *
+ * @var boolean
+ */
+ public $isStopped = false;
+
+/**
+ * Holds the fieldname
+ *
+ * @var string
+ */
+ public $field = null;
+
+/**
+ * Holds the original ruleSet
+ *
+ * @var array
+ */
+ public $ruleSet = array();
+
+/**
+ * Constructor
+ *
+ * @param string $fieldName The fieldname
+ * @param array $ruleset
+ */
+ public function __construct($fieldName, $ruleSet) {
+ $this->field = $fieldName;
+
+ if (!is_array($ruleSet) || (is_array($ruleSet) && isset($ruleSet['rule']))) {
+ $ruleSet = array($ruleSet);
+ }
+
+ foreach ($ruleSet as $index => $validateProp) {
+ $this->_rules[$index] = new CakeValidationRule($validateProp);
+ }
+ $this->ruleSet = $ruleSet;
+ }
+
+/**
+ * Sets the list of methods to use for validation
+ *
+ * @return void
+ **/
+ public function setMethods(&$methods) {
+ $this->_methods =& $methods;
+ }
+
+/**
+ * Sets the I18n domain for validation messages.
+ *
+ * @param string $validationDomain The validation domain to be used.
+ * @return void
+ */
+ public function setValidationDomain($validationDomain) {
+ $this->_validationDomain = $validationDomain;
+ }
+
+/**
+ * Runs all validation rules in this set and returns a list of
+ * validation errors
+ *
+ * @return array list of validation errors for this field
+ */
+ public function validate($data, $isUpdate = false) {
+ $errors = array();
+ foreach ($this->getRules() as $name => $rule) {
+ $rule->isUpdate($isUpdate);
+ if ($rule->skip()) {
+ continue;
+ }
+
+ $checkRequired = $rule->checkRequired($this->field, $data);
+ if (!$checkRequired && array_key_exists($this->field, $data)) {
+ if ($rule->checkEmpty($this->field, $data)) {
+ break;
+ }
+ $rule->process($this->field, $data, $this->_methods);
+ }
+
+ if ($checkRequired || !$rule->isValid()) {
+ $errors[] = $this->_processValidationResponse($name, $rule);
+ if ($rule->isLast()) {
+ break;
+ }
+ }
+ }
+
+ return $errors;
+ }
+
+/**
+ * Gets a rule for a given name if exists
+ *
+ * @param string $name
+ * @return CakeValidationRule
+ */
+ public function getRule($name) {
+ if (!empty($this->_rules[$name])) {
+ return $this->_rules[$name];
+ }
+ }
+
+/**
+ * Returns all rules for this validation set
+ *
+ * @return array
+ */
+ public function getRules() {
+ return $this->_rules;
+ }
+
+/**
+ * Sets a CakeValidationRule $rule with a $name
+ *
+ * ## Example:
+ *
+ * {{{
+ * $set
+ * ->setRule('required', array('rule' => 'notEmpty', 'required' => true))
+ * ->setRule('inRange', array('rule' => array('between', 4, 10))
+ * }}}
+ *
+ * @param string $name The name under which the rule should be set
+ * @param CakeValidationRule|array $rule The validation rule to be set
+ * @return CakeValidationSet this instance
+ */
+ public function setRule($name, $rule) {
+ if (!$rule instanceof CakeValidationRule) {
+ $rule = new CakeValidationRule($rule);
+ }
+ $this->_rules[$name] = $rule;
+ return $this;
+ }
+
+/**
+ * Removes a validation rule from the set
+ *
+ * ## Example:
+ *
+ * {{{
+ * $set
+ * ->removeRule('required')
+ * ->removeRule('inRange')
+ * }}}
+ *
+ * @param string $name The name under which the rule should be unset
+ * @return CakeValidationSet this instance
+ */
+ public function removeRule($name) {
+ unset($this->_rules[$name]);
+ return $this;
+ }
+
+/**
+ * Sets the rules for a given field
+ *
+ * ## Example:
+ *
+ * {{{
+ * $set->setRules(array(
+ * 'required' => array('rule' => 'notEmpty', 'required' => true),
+ * 'inRange' => array('rule' => array('between', 4, 10)
+ * ));
+ * }}}
+ *
+ * @param array $rules The rules to be set
+ * @param bolean $mergeVars [optional] If true, merges vars instead of replace. Defaults to true.
+ * @return ModelField
+ */
+ public function setRules($rules = array(), $mergeVars = true) {
+ if ($mergeVars === false) {
+ $this->_rules = $rules;
+ } else {
+ $this->_rules = array_merge($this->_rules, $rules);
+ }
+ return $this;
+ }
+
+/**
+ * Fetches the correct error message for a failed validation
+ *
+ * @param string $name the name of the rule as it was configured
+ * @param CakeValidationRule $rule the object containing validation information
+ * @return string
+ */
+ protected function _processValidationResponse($name, $rule) {
+ $message = $rule->getValidationResult();
+ if (is_string($message)) {
+ return $message;
+ }
+ $message = $rule->message;
+
+ if ($message !== null) {
+ $args = null;
+ if (is_array($message)) {
+ $result = $message[0];
+ $args = array_slice($message, 1);
+ } else {
+ $result = $message;
+ }
+ if (is_array($rule->rule) && $args === null) {
+ $args = array_slice($rule->rule, 1);
+ }
+ $args = $this->_translateArgs($args);
+
+ $message = __d($this->_validationDomain, $result, $args);
+ } elseif (is_string($name)) {
+ if (is_array($rule->rule)) {
+ $args = array_slice($rule->rule, 1);
+ $args = $this->_translateArgs($args);
+ $message = __d($this->_validationDomain, $name, $args);
+ } else {
+ $message = __d($this->_validationDomain, $name);
+ }
+ } else {
+ $message = __d('cake_dev', 'This field cannot be left blank');
+ }
+
+ return $message;
+ }
+
+/**
+ * Applies translations to validator arguments.
+ *
+ * @param array $args The args to translate
+ * @return array Translated args.
+ */
+ protected function _translateArgs($args) {
+ foreach ((array)$args as $k => $arg) {
+ if (is_string($arg)) {
+ $args[$k] = __d($this->_validationDomain, $arg);
+ }
+ }
+ return $args;
+ }
+
+/**
+ * Returns wheter an index exists in the rule set
+ *
+ * @param string $index name of the rule
+ * @return boolean
+ **/
+ public function offsetExists($index) {
+ return isset($this->_rules[$index]);
+ }
+
+/**
+ * Returns a rule object by its index
+ *
+ * @param string $index name of the rule
+ * @return CakeValidationRule
+ **/
+ public function offsetGet($index) {
+ return $this->_rules[$index];
+ }
+
+/**
+ * Sets or replace a validation rule
+ *
+ * @param string $index name of the rule
+ * @param CakeValidationRule|array rule to add to $index
+ **/
+ public function offsetSet($index, $rule) {
+ $this->setRule($index, $rule);
+ }
+
+/**
+ * Unsets a validation rule
+ *
+ * @param string $index name of the rule
+ * @return void
+ **/
+ public function offsetUnset($index) {
+ unset($this->_rules[$index]);
+ }
+
+/**
+ * Returns an iterator for each of the rules to be applied
+ *
+ * @return ArrayIterator
+ **/
+ public function getIterator() {
+ return new ArrayIterator($this->_rules);
+ }
+
+/**
+ * Returns the number of rules in this set
+ *
+ * @return int
+ **/
+ public function count() {
+ return count($this->_rules);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeRequest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeRequest.php
new file mode 100644
index 0000000..cadbbbd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeRequest.php
@@ -0,0 +1,871 @@
+<?php
+/**
+ * CakeRequest
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Set', 'Utility');
+
+/**
+ * A class that helps wrap Request information and particulars about a single request.
+ * Provides methods commonly used to introspect on the request headers and request body.
+ *
+ * Has both an Array and Object interface. You can access framework parameters using indexes:
+ *
+ * `$request['controller']` or `$request->controller`.
+ *
+ * @package Cake.Network
+ */
+class CakeRequest implements ArrayAccess {
+
+/**
+ * Array of parameters parsed from the url.
+ *
+ * @var array
+ */
+ public $params = array(
+ 'plugin' => null,
+ 'controller' => null,
+ 'action' => null,
+ 'named' => array(),
+ 'pass' => array(),
+ );
+
+/**
+ * Array of POST data. Will contain form data as well as uploaded files.
+ * Inputs prefixed with 'data' will have the data prefix removed. If there is
+ * overlap between an input prefixed with data and one without, the 'data' prefixed
+ * value will take precedence.
+ *
+ * @var array
+ */
+ public $data = array();
+
+/**
+ * Array of querystring arguments
+ *
+ * @var array
+ */
+ public $query = array();
+
+/**
+ * The url string used for the request.
+ *
+ * @var string
+ */
+ public $url;
+
+/**
+ * Base url path.
+ *
+ * @var string
+ */
+ public $base = false;
+
+/**
+ * webroot path segment for the request.
+ *
+ * @var string
+ */
+ public $webroot = '/';
+
+/**
+ * The full address to the current request
+ *
+ * @var string
+ */
+ public $here = null;
+
+/**
+ * The built in detectors used with `is()` can be modified with `addDetector()`.
+ *
+ * There are several ways to specify a detector, see CakeRequest::addDetector() for the
+ * various formats and ways to define detectors.
+ *
+ * @var array
+ */
+ protected $_detectors = array(
+ 'get' => array('env' => 'REQUEST_METHOD', 'value' => 'GET'),
+ 'post' => array('env' => 'REQUEST_METHOD', 'value' => 'POST'),
+ 'put' => array('env' => 'REQUEST_METHOD', 'value' => 'PUT'),
+ 'delete' => array('env' => 'REQUEST_METHOD', 'value' => 'DELETE'),
+ 'head' => array('env' => 'REQUEST_METHOD', 'value' => 'HEAD'),
+ 'options' => array('env' => 'REQUEST_METHOD', 'value' => 'OPTIONS'),
+ 'ssl' => array('env' => 'HTTPS', 'value' => 1),
+ 'ajax' => array('env' => 'HTTP_X_REQUESTED_WITH', 'value' => 'XMLHttpRequest'),
+ 'flash' => array('env' => 'HTTP_USER_AGENT', 'pattern' => '/^(Shockwave|Adobe) Flash/'),
+ 'mobile' => array('env' => 'HTTP_USER_AGENT', 'options' => array(
+ 'Android', 'AvantGo', 'BlackBerry', 'DoCoMo', 'Fennec', 'iPod', 'iPhone', 'iPad',
+ 'J2ME', 'MIDP', 'NetFront', 'Nokia', 'Opera Mini', 'Opera Mobi', 'PalmOS', 'PalmSource',
+ 'portalmmm', 'Plucker', 'ReqwirelessWeb', 'SonyEricsson', 'Symbian', 'UP\\.Browser',
+ 'webOS', 'Windows CE', 'Windows Phone OS', 'Xiino'
+ )),
+ 'requested' => array('param' => 'requested', 'value' => 1)
+ );
+
+/**
+ * Copy of php://input. Since this stream can only be read once in most SAPI's
+ * keep a copy of it so users don't need to know about that detail.
+ *
+ * @var string
+ */
+ protected $_input = '';
+
+/**
+ * Constructor
+ *
+ * @param string $url Trimmed url string to use. Should not contain the application base path.
+ * @param boolean $parseEnvironment Set to false to not auto parse the environment. ie. GET, POST and FILES.
+ */
+ public function __construct($url = null, $parseEnvironment = true) {
+ $this->_base();
+ if (empty($url)) {
+ $url = $this->_url();
+ }
+ if ($url[0] == '/') {
+ $url = substr($url, 1);
+ }
+ $this->url = $url;
+
+ if ($parseEnvironment) {
+ $this->_processPost();
+ $this->_processGet();
+ $this->_processFiles();
+ }
+ $this->here = $this->base . '/' . $this->url;
+ }
+
+/**
+ * process the post data and set what is there into the object.
+ * processed data is available at `$this->data`
+ *
+ * Will merge POST vars prefixed with `data`, and ones without
+ * into a single array. Variables prefixed with `data` will overwrite those without.
+ *
+ * If you have mixed POST values be careful not to make any top level keys numeric
+ * containing arrays. Hash::merge() is used to merge data, and it has possibly
+ * unexpected behavior in this situation.
+ *
+ * @return void
+ */
+ protected function _processPost() {
+ if ($_POST) {
+ $this->data = $_POST;
+ } elseif ($this->is('put') || $this->is('delete')) {
+ $this->data = $this->_readInput();
+ if (env('CONTENT_TYPE') === 'application/x-www-form-urlencoded') {
+ parse_str($this->data, $this->data);
+ }
+ }
+ if (ini_get('magic_quotes_gpc') === '1') {
+ $this->data = stripslashes_deep($this->data);
+ }
+ if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
+ $this->data['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
+ }
+ $isArray = is_array($this->data);
+ if ($isArray && isset($this->data['_method'])) {
+ if (!empty($_SERVER)) {
+ $_SERVER['REQUEST_METHOD'] = $this->data['_method'];
+ } else {
+ $_ENV['REQUEST_METHOD'] = $this->data['_method'];
+ }
+ unset($this->data['_method']);
+ }
+ if ($isArray && isset($this->data['data'])) {
+ $data = $this->data['data'];
+ if (count($this->data) <= 1) {
+ $this->data = $data;
+ } else {
+ unset($this->data['data']);
+ $this->data = Hash::merge($this->data, $data);
+ }
+ }
+ }
+
+/**
+ * Process the GET parameters and move things into the object.
+ *
+ * @return void
+ */
+ protected function _processGet() {
+ if (ini_get('magic_quotes_gpc') === '1') {
+ $query = stripslashes_deep($_GET);
+ } else {
+ $query = $_GET;
+ }
+
+ unset($query['/' . str_replace('.', '_', urldecode($this->url))]);
+ if (strpos($this->url, '?') !== false) {
+ list(, $querystr) = explode('?', $this->url);
+ parse_str($querystr, $queryArgs);
+ $query += $queryArgs;
+ }
+ if (isset($this->params['url'])) {
+ $query = array_merge($this->params['url'], $query);
+ }
+ $this->query = $query;
+ }
+
+/**
+ * Get the request uri. Looks in PATH_INFO first, as this is the exact value we need prepared
+ * by PHP. Following that, REQUEST_URI, PHP_SELF, HTTP_X_REWRITE_URL and argv are checked in that order.
+ * Each of these server variables have the base path, and query strings stripped off
+ *
+ * @return string URI The CakePHP request path that is being accessed.
+ */
+ protected function _url() {
+ if (!empty($_SERVER['PATH_INFO'])) {
+ return $_SERVER['PATH_INFO'];
+ } elseif (isset($_SERVER['REQUEST_URI'])) {
+ $uri = $_SERVER['REQUEST_URI'];
+ } elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) {
+ $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);
+ } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
+ $uri = $_SERVER['HTTP_X_REWRITE_URL'];
+ } elseif ($var = env('argv')) {
+ $uri = $var[0];
+ }
+
+ $base = $this->base;
+
+ if (strlen($base) > 0 && strpos($uri, $base) === 0) {
+ $uri = substr($uri, strlen($base));
+ }
+ if (strpos($uri, '?') !== false) {
+ list($uri) = explode('?', $uri, 2);
+ }
+ if (empty($uri) || $uri == '/' || $uri == '//') {
+ return '/';
+ }
+ return $uri;
+ }
+
+/**
+ * Returns a base URL and sets the proper webroot
+ *
+ * @return string Base URL
+ */
+ protected function _base() {
+ $dir = $webroot = null;
+ $config = Configure::read('App');
+ extract($config);
+
+ if (!isset($base)) {
+ $base = $this->base;
+ }
+ if ($base !== false) {
+ $this->webroot = $base . '/';
+ return $this->base = $base;
+ }
+
+ if (!$baseUrl) {
+ $base = dirname(env('PHP_SELF'));
+
+ if ($webroot === 'webroot' && $webroot === basename($base)) {
+ $base = dirname($base);
+ }
+ if ($dir === 'app' && $dir === basename($base)) {
+ $base = dirname($base);
+ }
+
+ if ($base === DS || $base === '.') {
+ $base = '';
+ }
+
+ $this->webroot = $base . '/';
+ return $this->base = $base;
+ }
+
+ $file = '/' . basename($baseUrl);
+ $base = dirname($baseUrl);
+
+ if ($base === DS || $base === '.') {
+ $base = '';
+ }
+ $this->webroot = $base . '/';
+
+ $docRoot = env('DOCUMENT_ROOT');
+ $docRootContainsWebroot = strpos($docRoot, $dir . '/' . $webroot);
+
+ if (!empty($base) || !$docRootContainsWebroot) {
+ if (strpos($this->webroot, '/' . $dir . '/') === false) {
+ $this->webroot .= $dir . '/';
+ }
+ if (strpos($this->webroot, '/' . $webroot . '/') === false) {
+ $this->webroot .= $webroot . '/';
+ }
+ }
+ return $this->base = $base . $file;
+ }
+
+/**
+ * Process $_FILES and move things into the object.
+ *
+ * @return void
+ */
+ protected function _processFiles() {
+ if (isset($_FILES) && is_array($_FILES)) {
+ foreach ($_FILES as $name => $data) {
+ if ($name != 'data') {
+ $this->params['form'][$name] = $data;
+ }
+ }
+ }
+
+ if (isset($_FILES['data'])) {
+ foreach ($_FILES['data'] as $key => $data) {
+ $this->_processFileData('', $data, $key);
+ }
+ }
+ }
+
+/**
+ * Recursively walks the FILES array restructuring the data
+ * into something sane and useable.
+ *
+ * @param string $path The dot separated path to insert $data into.
+ * @param array $data The data to traverse/insert.
+ * @param string $field The terminal field name, which is the top level key in $_FILES.
+ * @return void
+ */
+ protected function _processFileData($path, $data, $field) {
+ foreach ($data as $key => $fields) {
+ $newPath = $key;
+ if (!empty($path)) {
+ $newPath = $path . '.' . $key;
+ }
+ if (is_array($fields)) {
+ $this->_processFileData($newPath, $fields, $field);
+ } else {
+ $newPath .= '.' . $field;
+ $this->data = Set::insert($this->data, $newPath, $fields);
+ }
+ }
+ }
+
+/**
+ * Get the IP the client is using, or says they are using.
+ *
+ * @param boolean $safe Use safe = false when you think the user might manipulate their HTTP_CLIENT_IP
+ * header. Setting $safe = false will will also look at HTTP_X_FORWARDED_FOR
+ * @return string The client IP.
+ */
+ public function clientIp($safe = true) {
+ if (!$safe && env('HTTP_X_FORWARDED_FOR') != null) {
+ $ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR'));
+ } else {
+ if (env('HTTP_CLIENT_IP') != null) {
+ $ipaddr = env('HTTP_CLIENT_IP');
+ } else {
+ $ipaddr = env('REMOTE_ADDR');
+ }
+ }
+
+ if (env('HTTP_CLIENTADDRESS') != null) {
+ $tmpipaddr = env('HTTP_CLIENTADDRESS');
+
+ if (!empty($tmpipaddr)) {
+ $ipaddr = preg_replace('/(?:,.*)/', '', $tmpipaddr);
+ }
+ }
+ return trim($ipaddr);
+ }
+
+/**
+ * Returns the referer that referred this request.
+ *
+ * @param boolean $local Attempt to return a local address. Local addresses do not contain hostnames.
+ * @return string The referring address for this request.
+ */
+ public function referer($local = false) {
+ $ref = env('HTTP_REFERER');
+ $forwarded = env('HTTP_X_FORWARDED_HOST');
+ if ($forwarded) {
+ $ref = $forwarded;
+ }
+
+ $base = '';
+ if (defined('FULL_BASE_URL')) {
+ $base = FULL_BASE_URL . $this->webroot;
+ }
+ if (!empty($ref) && !empty($base)) {
+ if ($local && strpos($ref, $base) === 0) {
+ $ref = substr($ref, strlen($base));
+ if ($ref[0] != '/') {
+ $ref = '/' . $ref;
+ }
+ return $ref;
+ } elseif (!$local) {
+ return $ref;
+ }
+ }
+ return '/';
+ }
+
+/**
+ * Missing method handler, handles wrapping older style isAjax() type methods
+ *
+ * @param string $name The method called
+ * @param array $params Array of parameters for the method call
+ * @return mixed
+ * @throws CakeException when an invalid method is called.
+ */
+ public function __call($name, $params) {
+ if (strpos($name, 'is') === 0) {
+ $type = strtolower(substr($name, 2));
+ return $this->is($type);
+ }
+ throw new CakeException(__d('cake_dev', 'Method %s does not exist', $name));
+ }
+
+/**
+ * Magic get method allows access to parsed routing parameters directly on the object.
+ *
+ * Allows access to `$this->params['controller']` via `$this->controller`
+ *
+ * @param string $name The property being accessed.
+ * @return mixed Either the value of the parameter or null.
+ */
+ public function __get($name) {
+ if (isset($this->params[$name])) {
+ return $this->params[$name];
+ }
+ return null;
+ }
+
+/**
+ * Magic isset method allows isset/empty checks
+ * on routing parameters.
+ *
+ * @param string $name The property being accessed.
+ * @return bool Existence
+ */
+ public function __isset($name) {
+ return isset($this->params[$name]);
+ }
+
+/**
+ * Check whether or not a Request is a certain type. Uses the built in detection rules
+ * as well as additional rules defined with CakeRequest::addDetector(). Any detector can be called
+ * as `is($type)` or `is$Type()`.
+ *
+ * @param string $type The type of request you want to check.
+ * @return boolean Whether or not the request is the type you are checking.
+ */
+ public function is($type) {
+ $type = strtolower($type);
+ if (!isset($this->_detectors[$type])) {
+ return false;
+ }
+ $detect = $this->_detectors[$type];
+ if (isset($detect['env'])) {
+ if (isset($detect['value'])) {
+ return env($detect['env']) == $detect['value'];
+ }
+ if (isset($detect['pattern'])) {
+ return (bool)preg_match($detect['pattern'], env($detect['env']));
+ }
+ if (isset($detect['options'])) {
+ $pattern = '/' . implode('|', $detect['options']) . '/i';
+ return (bool)preg_match($pattern, env($detect['env']));
+ }
+ }
+ if (isset($detect['param'])) {
+ $key = $detect['param'];
+ $value = $detect['value'];
+ return isset($this->params[$key]) ? $this->params[$key] == $value : false;
+ }
+ if (isset($detect['callback']) && is_callable($detect['callback'])) {
+ return call_user_func($detect['callback'], $this);
+ }
+ return false;
+ }
+
+/**
+ * Add a new detector to the list of detectors that a request can use.
+ * There are several different formats and types of detectors that can be set.
+ *
+ * ### Environment value comparison
+ *
+ * An environment value comparison, compares a value fetched from `env()` to a known value
+ * the environment value is equality checked against the provided value.
+ *
+ * e.g `addDetector('post', array('env' => 'REQUEST_METHOD', 'value' => 'POST'))`
+ *
+ * ### Pattern value comparison
+ *
+ * Pattern value comparison allows you to compare a value fetched from `env()` to a regular expression.
+ *
+ * e.g `addDetector('iphone', array('env' => 'HTTP_USER_AGENT', 'pattern' => '/iPhone/i'));`
+ *
+ * ### Option based comparison
+ *
+ * Option based comparisons use a list of options to create a regular expression. Subsequent calls
+ * to add an already defined options detector will merge the options.
+ *
+ * e.g `addDetector('mobile', array('env' => 'HTTP_USER_AGENT', 'options' => array('Fennec')));`
+ *
+ * ### Callback detectors
+ *
+ * Callback detectors allow you to provide a 'callback' type to handle the check. The callback will
+ * receive the request object as its only parameter.
+ *
+ * e.g `addDetector('custom', array('callback' => array('SomeClass', 'somemethod')));`
+ *
+ * ### Request parameter detectors
+ *
+ * Allows for custom detectors on the request parameters.
+ *
+ * e.g `addDetector('post', array('param' => 'requested', 'value' => 1)`
+ *
+ * @param string $name The name of the detector.
+ * @param array $options The options for the detector definition. See above.
+ * @return void
+ */
+ public function addDetector($name, $options) {
+ $name = strtolower($name);
+ if (isset($this->_detectors[$name]) && isset($options['options'])) {
+ $options = Hash::merge($this->_detectors[$name], $options);
+ }
+ $this->_detectors[$name] = $options;
+ }
+
+/**
+ * Add parameters to the request's parsed parameter set. This will overwrite any existing parameters.
+ * This modifies the parameters available through `$request->params`.
+ *
+ * @param array $params Array of parameters to merge in
+ * @return The current object, you can chain this method.
+ */
+ public function addParams($params) {
+ $this->params = array_merge($this->params, (array)$params);
+ return $this;
+ }
+
+/**
+ * Add paths to the requests' paths vars. This will overwrite any existing paths.
+ * Provides an easy way to modify, here, webroot and base.
+ *
+ * @param array $paths Array of paths to merge in
+ * @return CakeRequest the current object, you can chain this method.
+ */
+ public function addPaths($paths) {
+ foreach (array('webroot', 'here', 'base') as $element) {
+ if (isset($paths[$element])) {
+ $this->{$element} = $paths[$element];
+ }
+ }
+ return $this;
+ }
+
+/**
+ * Get the value of the current requests url. Will include named parameters and querystring arguments.
+ *
+ * @param boolean $base Include the base path, set to false to trim the base path off.
+ * @return string the current request url including query string args.
+ */
+ public function here($base = true) {
+ $url = $this->here;
+ if (!empty($this->query)) {
+ $url .= '?' . http_build_query($this->query, null, '&');
+ }
+ if (!$base) {
+ $url = preg_replace('/^' . preg_quote($this->base, '/') . '/', '', $url, 1);
+ }
+ return $url;
+ }
+
+/**
+ * Read an HTTP header from the Request information.
+ *
+ * @param string $name Name of the header you want.
+ * @return mixed Either false on no header being set or the value of the header.
+ */
+ public static function header($name) {
+ $name = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
+ if (!empty($_SERVER[$name])) {
+ return $_SERVER[$name];
+ }
+ return false;
+ }
+
+/**
+ * Get the HTTP method used for this request.
+ * There are a few ways to specify a method.
+ *
+ * - If your client supports it you can use native HTTP methods.
+ * - You can set the HTTP-X-Method-Override header.
+ * - You can submit an input with the name `_method`
+ *
+ * Any of these 3 approaches can be used to set the HTTP method used
+ * by CakePHP internally, and will effect the result of this method.
+ *
+ * @return string The name of the HTTP method used.
+ */
+ public function method() {
+ return env('REQUEST_METHOD');
+ }
+
+/**
+ * Get the host that the request was handled on.
+ *
+ * @return string
+ */
+ public function host() {
+ return env('HTTP_HOST');
+ }
+
+/**
+ * Get the domain name and include $tldLength segments of the tld.
+ *
+ * @param integer $tldLength Number of segments your tld contains. For example: `example.com` contains 1 tld.
+ * While `example.co.uk` contains 2.
+ * @return string Domain name without subdomains.
+ */
+ public function domain($tldLength = 1) {
+ $segments = explode('.', $this->host());
+ $domain = array_slice($segments, -1 * ($tldLength + 1));
+ return implode('.', $domain);
+ }
+
+/**
+ * Get the subdomains for a host.
+ *
+ * @param integer $tldLength Number of segments your tld contains. For example: `example.com` contains 1 tld.
+ * While `example.co.uk` contains 2.
+ * @return array of subdomains.
+ */
+ public function subdomains($tldLength = 1) {
+ $segments = explode('.', $this->host());
+ return array_slice($segments, 0, -1 * ($tldLength + 1));
+ }
+
+/**
+ * Find out which content types the client accepts or check if they accept a
+ * particular type of content.
+ *
+ * #### Get all types:
+ *
+ * `$this->request->accepts();`
+ *
+ * #### Check for a single type:
+ *
+ * `$this->request->accepts('application/json');`
+ *
+ * This method will order the returned content types by the preference values indicated
+ * by the client.
+ *
+ * @param string $type The content type to check for. Leave null to get all types a client accepts.
+ * @return mixed Either an array of all the types the client accepts or a boolean if they accept the
+ * provided type.
+ */
+ public function accepts($type = null) {
+ $raw = $this->parseAccept();
+ $accept = array();
+ foreach ($raw as $value => $types) {
+ $accept = array_merge($accept, $types);
+ }
+ if ($type === null) {
+ return $accept;
+ }
+ return in_array($type, $accept);
+ }
+
+/**
+ * Parse the HTTP_ACCEPT header and return a sorted array with content types
+ * as the keys, and pref values as the values.
+ *
+ * Generally you want to use CakeRequest::accept() to get a simple list
+ * of the accepted content types.
+ *
+ * @return array An array of prefValue => array(content/types)
+ */
+ public function parseAccept() {
+ $accept = array();
+ $header = explode(',', $this->header('accept'));
+ foreach (array_filter($header) as $value) {
+ $prefPos = strpos($value, ';');
+ if ($prefPos !== false) {
+ $prefValue = substr($value, strpos($value, '=') + 1);
+ $value = trim(substr($value, 0, $prefPos));
+ } else {
+ $prefValue = '1.0';
+ $value = trim($value);
+ }
+ if (!isset($accept[$prefValue])) {
+ $accept[$prefValue] = array();
+ }
+ if ($prefValue) {
+ $accept[$prefValue][] = $value;
+ }
+ }
+ krsort($accept);
+ return $accept;
+ }
+
+/**
+ * Get the languages accepted by the client, or check if a specific language is accepted.
+ *
+ * Get the list of accepted languages:
+ *
+ * {{{ CakeRequest::acceptLanguage(); }}}
+ *
+ * Check if a specific language is accepted:
+ *
+ * {{{ CakeRequest::acceptLanguage('es-es'); }}}
+ *
+ * @param string $language The language to test.
+ * @return If a $language is provided, a boolean. Otherwise the array of accepted languages.
+ */
+ public static function acceptLanguage($language = null) {
+ $accepts = preg_split('/[;,]/', self::header('Accept-Language'));
+ foreach ($accepts as &$accept) {
+ $accept = strtolower($accept);
+ if (strpos($accept, '_') !== false) {
+ $accept = str_replace('_', '-', $accept);
+ }
+ }
+ if ($language === null) {
+ return $accepts;
+ }
+ return in_array($language, $accepts);
+ }
+
+/**
+ * Provides a read/write accessor for `$this->data`. Allows you
+ * to use a syntax similar to `CakeSession` for reading post data.
+ *
+ * ## Reading values.
+ *
+ * `$request->data('Post.title');`
+ *
+ * When reading values you will get `null` for keys/values that do not exist.
+ *
+ * ## Writing values
+ *
+ * `$request->data('Post.title', 'New post!');`
+ *
+ * You can write to any value, even paths/keys that do not exist, and the arrays
+ * will be created for you.
+ *
+ * @param string $name,... Dot separated name of the value to read/write
+ * @return mixed Either the value being read, or this so you can chain consecutive writes.
+ */
+ public function data($name) {
+ $args = func_get_args();
+ if (count($args) == 2) {
+ $this->data = Hash::insert($this->data, $name, $args[1]);
+ return $this;
+ }
+ return Hash::get($this->data, $name);
+ }
+
+/**
+ * Read data from `php://input`. Useful when interacting with XML or JSON
+ * request body content.
+ *
+ * Getting input with a decoding function:
+ *
+ * `$this->request->input('json_decode');`
+ *
+ * Getting input using a decoding function, and additional params:
+ *
+ * `$this->request->input('Xml::build', array('return' => 'DOMDocument'));`
+ *
+ * Any additional parameters are applied to the callback in the order they are given.
+ *
+ * @param string $callback A decoding callback that will convert the string data to another
+ * representation. Leave empty to access the raw input data. You can also
+ * supply additional parameters for the decoding callback using var args, see above.
+ * @return The decoded/processed request data.
+ */
+ public function input($callback = null) {
+ $input = $this->_readInput();
+ $args = func_get_args();
+ if (!empty($args)) {
+ $callback = array_shift($args);
+ array_unshift($args, $input);
+ return call_user_func_array($callback, $args);
+ }
+ return $input;
+ }
+
+/**
+ * Read data from php://input, mocked in tests.
+ *
+ * @return string contents of php://input
+ */
+ protected function _readInput() {
+ if (empty($this->_input)) {
+ $fh = fopen('php://input', 'r');
+ $content = stream_get_contents($fh);
+ fclose($fh);
+ $this->_input = $content;
+ }
+ return $this->_input;
+ }
+
+/**
+ * Array access read implementation
+ *
+ * @param string $name Name of the key being accessed.
+ * @return mixed
+ */
+ public function offsetGet($name) {
+ if (isset($this->params[$name])) {
+ return $this->params[$name];
+ }
+ if ($name == 'url') {
+ return $this->query;
+ }
+ if ($name == 'data') {
+ return $this->data;
+ }
+ return null;
+ }
+
+/**
+ * Array access write implementation
+ *
+ * @param string $name Name of the key being written
+ * @param mixed $value The value being written.
+ * @return void
+ */
+ public function offsetSet($name, $value) {
+ $this->params[$name] = $value;
+ }
+
+/**
+ * Array access isset() implementation
+ *
+ * @param string $name thing to check.
+ * @return boolean
+ */
+ public function offsetExists($name) {
+ return isset($this->params[$name]);
+ }
+
+/**
+ * Array access unset() implementation
+ *
+ * @param string $name Name to unset.
+ * @return void
+ */
+ public function offsetUnset($name) {
+ unset($this->params[$name]);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeResponse.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeResponse.php
new file mode 100644
index 0000000..a763705
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeResponse.php
@@ -0,0 +1,1154 @@
+<?php
+/**
+ * CakeResponse
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * CakeResponse is responsible for managing the response text, status and headers of a HTTP response.
+ *
+ * By default controllers will use this class to render their response. If you are going to use
+ * a custom response class it should subclass this object in order to ensure compatibility.
+ *
+ * @package Cake.Network
+ */
+class CakeResponse {
+
+/**
+ * Holds HTTP response statuses
+ *
+ * @var array
+ */
+ protected $_statusCodes = array(
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Time-out',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Large',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested range not satisfiable',
+ 417 => 'Expectation Failed',
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Time-out'
+ );
+
+/**
+ * Holds known mime type mappings
+ *
+ * @var array
+ */
+ protected $_mimeTypes = array(
+ 'html' => array('text/html', '*/*'),
+ 'json' => 'application/json',
+ 'xml' => array('application/xml', 'text/xml'),
+ 'rss' => 'application/rss+xml',
+ 'ai' => 'application/postscript',
+ 'bcpio' => 'application/x-bcpio',
+ 'bin' => 'application/octet-stream',
+ 'ccad' => 'application/clariscad',
+ 'cdf' => 'application/x-netcdf',
+ 'class' => 'application/octet-stream',
+ 'cpio' => 'application/x-cpio',
+ 'cpt' => 'application/mac-compactpro',
+ 'csh' => 'application/x-csh',
+ 'csv' => array('text/csv', 'application/vnd.ms-excel', 'text/plain'),
+ 'dcr' => 'application/x-director',
+ 'dir' => 'application/x-director',
+ 'dms' => 'application/octet-stream',
+ 'doc' => 'application/msword',
+ 'drw' => 'application/drafting',
+ 'dvi' => 'application/x-dvi',
+ 'dwg' => 'application/acad',
+ 'dxf' => 'application/dxf',
+ 'dxr' => 'application/x-director',
+ 'eot' => 'application/vnd.ms-fontobject',
+ 'eps' => 'application/postscript',
+ 'exe' => 'application/octet-stream',
+ 'ez' => 'application/andrew-inset',
+ 'flv' => 'video/x-flv',
+ 'gtar' => 'application/x-gtar',
+ 'gz' => 'application/x-gzip',
+ 'bz2' => 'application/x-bzip',
+ '7z' => 'application/x-7z-compressed',
+ 'hdf' => 'application/x-hdf',
+ 'hqx' => 'application/mac-binhex40',
+ 'ico' => 'image/vnd.microsoft.icon',
+ 'ips' => 'application/x-ipscript',
+ 'ipx' => 'application/x-ipix',
+ 'js' => 'text/javascript',
+ 'latex' => 'application/x-latex',
+ 'lha' => 'application/octet-stream',
+ 'lsp' => 'application/x-lisp',
+ 'lzh' => 'application/octet-stream',
+ 'man' => 'application/x-troff-man',
+ 'me' => 'application/x-troff-me',
+ 'mif' => 'application/vnd.mif',
+ 'ms' => 'application/x-troff-ms',
+ 'nc' => 'application/x-netcdf',
+ 'oda' => 'application/oda',
+ 'otf' => 'font/otf',
+ 'pdf' => 'application/pdf',
+ 'pgn' => 'application/x-chess-pgn',
+ 'pot' => 'application/mspowerpoint',
+ 'pps' => 'application/mspowerpoint',
+ 'ppt' => 'application/mspowerpoint',
+ 'ppz' => 'application/mspowerpoint',
+ 'pre' => 'application/x-freelance',
+ 'prt' => 'application/pro_eng',
+ 'ps' => 'application/postscript',
+ 'roff' => 'application/x-troff',
+ 'scm' => 'application/x-lotusscreencam',
+ 'set' => 'application/set',
+ 'sh' => 'application/x-sh',
+ 'shar' => 'application/x-shar',
+ 'sit' => 'application/x-stuffit',
+ 'skd' => 'application/x-koan',
+ 'skm' => 'application/x-koan',
+ 'skp' => 'application/x-koan',
+ 'skt' => 'application/x-koan',
+ 'smi' => 'application/smil',
+ 'smil' => 'application/smil',
+ 'sol' => 'application/solids',
+ 'spl' => 'application/x-futuresplash',
+ 'src' => 'application/x-wais-source',
+ 'step' => 'application/STEP',
+ 'stl' => 'application/SLA',
+ 'stp' => 'application/STEP',
+ 'sv4cpio' => 'application/x-sv4cpio',
+ 'sv4crc' => 'application/x-sv4crc',
+ 'svg' => 'image/svg+xml',
+ 'svgz' => 'image/svg+xml',
+ 'swf' => 'application/x-shockwave-flash',
+ 't' => 'application/x-troff',
+ 'tar' => 'application/x-tar',
+ 'tcl' => 'application/x-tcl',
+ 'tex' => 'application/x-tex',
+ 'texi' => 'application/x-texinfo',
+ 'texinfo' => 'application/x-texinfo',
+ 'tr' => 'application/x-troff',
+ 'tsp' => 'application/dsptype',
+ 'ttf' => 'font/ttf',
+ 'unv' => 'application/i-deas',
+ 'ustar' => 'application/x-ustar',
+ 'vcd' => 'application/x-cdlink',
+ 'vda' => 'application/vda',
+ 'xlc' => 'application/vnd.ms-excel',
+ 'xll' => 'application/vnd.ms-excel',
+ 'xlm' => 'application/vnd.ms-excel',
+ 'xls' => 'application/vnd.ms-excel',
+ 'xlw' => 'application/vnd.ms-excel',
+ 'zip' => 'application/zip',
+ 'aif' => 'audio/x-aiff',
+ 'aifc' => 'audio/x-aiff',
+ 'aiff' => 'audio/x-aiff',
+ 'au' => 'audio/basic',
+ 'kar' => 'audio/midi',
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mp2' => 'audio/mpeg',
+ 'mp3' => 'audio/mpeg',
+ 'mpga' => 'audio/mpeg',
+ 'ogg' => 'audio/ogg',
+ 'oga' => 'audio/ogg',
+ 'spx' => 'audio/ogg',
+ 'ra' => 'audio/x-realaudio',
+ 'ram' => 'audio/x-pn-realaudio',
+ 'rm' => 'audio/x-pn-realaudio',
+ 'rpm' => 'audio/x-pn-realaudio-plugin',
+ 'snd' => 'audio/basic',
+ 'tsi' => 'audio/TSP-audio',
+ 'wav' => 'audio/x-wav',
+ 'aac' => 'audio/aac',
+ 'asc' => 'text/plain',
+ 'c' => 'text/plain',
+ 'cc' => 'text/plain',
+ 'css' => 'text/css',
+ 'etx' => 'text/x-setext',
+ 'f' => 'text/plain',
+ 'f90' => 'text/plain',
+ 'h' => 'text/plain',
+ 'hh' => 'text/plain',
+ 'htm' => array('text/html', '*/*'),
+ 'ics' => 'text/calendar',
+ 'm' => 'text/plain',
+ 'rtf' => 'text/rtf',
+ 'rtx' => 'text/richtext',
+ 'sgm' => 'text/sgml',
+ 'sgml' => 'text/sgml',
+ 'tsv' => 'text/tab-separated-values',
+ 'tpl' => 'text/template',
+ 'txt' => 'text/plain',
+ 'text' => 'text/plain',
+ 'avi' => 'video/x-msvideo',
+ 'fli' => 'video/x-fli',
+ 'mov' => 'video/quicktime',
+ 'movie' => 'video/x-sgi-movie',
+ 'mpe' => 'video/mpeg',
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'qt' => 'video/quicktime',
+ 'viv' => 'video/vnd.vivo',
+ 'vivo' => 'video/vnd.vivo',
+ 'ogv' => 'video/ogg',
+ 'webm' => 'video/webm',
+ 'mp4' => 'video/mp4',
+ 'gif' => 'image/gif',
+ 'ief' => 'image/ief',
+ 'jpe' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'jpg' => 'image/jpeg',
+ 'pbm' => 'image/x-portable-bitmap',
+ 'pgm' => 'image/x-portable-graymap',
+ 'png' => 'image/png',
+ 'pnm' => 'image/x-portable-anymap',
+ 'ppm' => 'image/x-portable-pixmap',
+ 'ras' => 'image/cmu-raster',
+ 'rgb' => 'image/x-rgb',
+ 'tif' => 'image/tiff',
+ 'tiff' => 'image/tiff',
+ 'xbm' => 'image/x-xbitmap',
+ 'xpm' => 'image/x-xpixmap',
+ 'xwd' => 'image/x-xwindowdump',
+ 'ice' => 'x-conference/x-cooltalk',
+ 'iges' => 'model/iges',
+ 'igs' => 'model/iges',
+ 'mesh' => 'model/mesh',
+ 'msh' => 'model/mesh',
+ 'silo' => 'model/mesh',
+ 'vrml' => 'model/vrml',
+ 'wrl' => 'model/vrml',
+ 'mime' => 'www/mime',
+ 'pdb' => 'chemical/x-pdb',
+ 'xyz' => 'chemical/x-pdb',
+ 'javascript' => 'text/javascript',
+ 'form' => 'application/x-www-form-urlencoded',
+ 'file' => 'multipart/form-data',
+ 'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
+ 'xhtml-mobile' => 'application/vnd.wap.xhtml+xml',
+ 'atom' => 'application/atom+xml',
+ 'amf' => 'application/x-amf',
+ 'wap' => array('text/vnd.wap.wml', 'text/vnd.wap.wmlscript', 'image/vnd.wap.wbmp'),
+ 'wml' => 'text/vnd.wap.wml',
+ 'wmlscript' => 'text/vnd.wap.wmlscript',
+ 'wbmp' => 'image/vnd.wap.wbmp',
+ );
+
+/**
+ * Protocol header to send to the client
+ *
+ * @var string
+ */
+ protected $_protocol = 'HTTP/1.1';
+
+/**
+ * Status code to send to the client
+ *
+ * @var integer
+ */
+ protected $_status = 200;
+
+/**
+ * Content type to send. This can be an 'extension' that will be transformed using the $_mimetypes array
+ * or a complete mime-type
+ *
+ * @var integer
+ */
+ protected $_contentType = 'text/html';
+
+/**
+ * Buffer list of headers
+ *
+ * @var array
+ */
+ protected $_headers = array();
+
+/**
+ * Buffer string for response message
+ *
+ * @var string
+ */
+ protected $_body = null;
+
+/**
+ * The charset the response body is encoded with
+ *
+ * @var string
+ */
+ protected $_charset = 'UTF-8';
+
+/**
+ * Holds all the cache directives that will be converted
+ * into headers when sending the request
+ *
+ * @var string
+ */
+ protected $_cacheDirectives = array();
+
+/**
+ * Holds cookies to be sent to the client
+ *
+ * @var array
+ */
+ protected $_cookies = array();
+
+/**
+ * Class constructor
+ *
+ * @param array $options list of parameters to setup the response. Possible values are:
+ * - body: the response text that should be sent to the client
+ * - status: the HTTP status code to respond with
+ * - type: a complete mime-type string or an extension mapped in this class
+ * - charset: the charset for the response body
+ */
+ public function __construct(array $options = array()) {
+ if (isset($options['body'])) {
+ $this->body($options['body']);
+ }
+ if (isset($options['status'])) {
+ $this->statusCode($options['status']);
+ }
+ if (isset($options['type'])) {
+ $this->type($options['type']);
+ }
+ if (isset($options['charset'])) {
+ $this->charset($options['charset']);
+ }
+ }
+
+/**
+ * Sends the complete response to the client including headers and message body.
+ * Will echo out the content in the response body.
+ *
+ * @return void
+ */
+ public function send() {
+ if (isset($this->_headers['Location']) && $this->_status === 200) {
+ $this->statusCode(302);
+ }
+
+ $codeMessage = $this->_statusCodes[$this->_status];
+ $this->_setCookies();
+ $this->_sendHeader("{$this->_protocol} {$this->_status} {$codeMessage}");
+ $this->_setContent();
+ $this->_setContentLength();
+ $this->_setContentType();
+ foreach ($this->_headers as $header => $value) {
+ $this->_sendHeader($header, $value);
+ }
+ $this->_sendContent($this->_body);
+ }
+
+/**
+ * Sets the cookies that have been added via static method CakeResponse::addCookie()
+ * before any other output is sent to the client.
+ * Will set the cookies in the order they have been set.
+ *
+ * @return void
+ */
+ protected function _setCookies() {
+ foreach ($this->_cookies as $name => $c) {
+ setcookie(
+ $name, $c['value'], $c['expire'], $c['path'],
+ $c['domain'], $c['secure'], $c['httpOnly']
+ );
+ }
+ }
+
+/**
+ * Formats the Content-Type header based on the configured contentType and charset
+ * the charset will only be set in the header if the response is of type text/*
+ *
+ * @return void
+ */
+ protected function _setContentType() {
+ if (in_array($this->_status, array(304, 204))) {
+ return;
+ }
+ if (strpos($this->_contentType, 'text/') === 0) {
+ $this->header('Content-Type', "{$this->_contentType}; charset={$this->_charset}");
+ } else {
+ $this->header('Content-Type', "{$this->_contentType}");
+ }
+ }
+
+/**
+ * Sets the response body to an empty text if the status code is 204 or 304
+ *
+ * @return void
+ */
+ protected function _setContent() {
+ if (in_array($this->_status, array(304, 204))) {
+ $this->body('');
+ }
+ }
+
+/**
+ * Calculates the correct Content-Length and sets it as a header in the response
+ * Will not set the value if already set or if the output is compressed.
+ *
+ * @return void
+ */
+ protected function _setContentLength() {
+ $shouldSetLength = !isset($this->_headers['Content-Length']) && !in_array($this->_status, range(301, 307));
+ if (isset($this->_headers['Content-Length']) && $this->_headers['Content-Length'] === false) {
+ unset($this->_headers['Content-Length']);
+ return;
+ }
+ if ($shouldSetLength && !$this->outputCompressed()) {
+ $offset = ob_get_level() ? ob_get_length() : 0;
+ if (ini_get('mbstring.func_overload') & 2 && function_exists('mb_strlen')) {
+ $this->length($offset + mb_strlen($this->_body, '8bit'));
+ } else {
+ $this->length($this->_headers['Content-Length'] = $offset + strlen($this->_body));
+ }
+ }
+ }
+
+/**
+ * Sends a header to the client.
+ *
+ * @param string $name the header name
+ * @param string $value the header value
+ * @return void
+ */
+ protected function _sendHeader($name, $value = null) {
+ if (!headers_sent()) {
+ if (is_null($value)) {
+ header($name);
+ } else {
+ header("{$name}: {$value}");
+ }
+ }
+ }
+
+/**
+ * Sends a content string to the client.
+ *
+ * @param string $content string to send as response body
+ * @return void
+ */
+ protected function _sendContent($content) {
+ echo $content;
+ }
+
+/**
+ * Buffers a header string to be sent
+ * Returns the complete list of buffered headers
+ *
+ * ### Single header
+ * e.g `header('Location', 'http://example.com');`
+ *
+ * ### Multiple headers
+ * e.g `header(array('Location' => 'http://example.com', 'X-Extra' => 'My header'));`
+ *
+ * ### String header
+ * e.g `header('WWW-Authenticate: Negotiate');`
+ *
+ * ### Array of string headers
+ * e.g `header(array('WWW-Authenticate: Negotiate', 'Content-type: application/pdf'));`
+ *
+ * Multiple calls for setting the same header name will have the same effect as setting the header once
+ * with the last value sent for it
+ * e.g `header('WWW-Authenticate: Negotiate'); header('WWW-Authenticate: Not-Negotiate');`
+ * will have the same effect as only doing `header('WWW-Authenticate: Not-Negotiate');`
+ *
+ * @param string|array $header. An array of header strings or a single header string
+ * - an associative array of "header name" => "header value" is also accepted
+ * - an array of string headers is also accepted
+ * @param string $value. The header value.
+ * @return array list of headers to be sent
+ */
+ public function header($header = null, $value = null) {
+ if (is_null($header)) {
+ return $this->_headers;
+ }
+ if (is_array($header)) {
+ foreach ($header as $h => $v) {
+ if (is_numeric($h)) {
+ $this->header($v);
+ continue;
+ }
+ $this->_headers[$h] = trim($v);
+ }
+ return $this->_headers;
+ }
+
+ if (!is_null($value)) {
+ $this->_headers[$header] = $value;
+ return $this->_headers;
+ }
+
+ list($header, $value) = explode(':', $header, 2);
+ $this->_headers[$header] = trim($value);
+ return $this->_headers;
+ }
+
+/**
+ * Buffers the response message to be sent
+ * if $content is null the current buffer is returned
+ *
+ * @param string $content the string message to be sent
+ * @return string current message buffer if $content param is passed as null
+ */
+ public function body($content = null) {
+ if (is_null($content)) {
+ return $this->_body;
+ }
+ return $this->_body = $content;
+ }
+
+/**
+ * Sets the HTTP status code to be sent
+ * if $code is null the current code is returned
+ *
+ * @param integer $code
+ * @return integer current status code
+ * @throws CakeException When an unknown status code is reached.
+ */
+ public function statusCode($code = null) {
+ if (is_null($code)) {
+ return $this->_status;
+ }
+ if (!isset($this->_statusCodes[$code])) {
+ throw new CakeException(__d('cake_dev', 'Unknown status code'));
+ }
+ return $this->_status = $code;
+ }
+
+/**
+ * Queries & sets valid HTTP response codes & messages.
+ *
+ * @param integer|array $code If $code is an integer, then the corresponding code/message is
+ * returned if it exists, null if it does not exist. If $code is an array,
+ * then the 'code' and 'message' keys of each nested array are added to the default
+ * HTTP codes. Example:
+ *
+ * httpCodes(404); // returns array(404 => 'Not Found')
+ *
+ * httpCodes(array(
+ * 701 => 'Unicorn Moved',
+ * 800 => 'Unexpected Minotaur'
+ * )); // sets these new values, and returns true
+ *
+ * @return mixed associative array of the HTTP codes as keys, and the message
+ * strings as values, or null of the given $code does not exist.
+ */
+ public function httpCodes($code = null) {
+ if (empty($code)) {
+ return $this->_statusCodes;
+ }
+
+ if (is_array($code)) {
+ $this->_statusCodes = $code + $this->_statusCodes;
+ return true;
+ }
+
+ if (!isset($this->_statusCodes[$code])) {
+ return null;
+ }
+ return array($code => $this->_statusCodes[$code]);
+ }
+
+/**
+ * Sets the response content type. It can be either a file extension
+ * which will be mapped internally to a mime-type or a string representing a mime-type
+ * if $contentType is null the current content type is returned
+ * if $contentType is an associative array, content type definitions will be stored/replaced
+ *
+ * ### Setting the content type
+ *
+ * e.g `type('jpg');`
+ *
+ * ### Returning the current content type
+ *
+ * e.g `type();`
+ *
+ * ### Storing content type definitions
+ *
+ * e.g `type(array('keynote' => 'application/keynote', 'bat' => 'application/bat'));`
+ *
+ * ### Replacing a content type definition
+ *
+ * e.g `type(array('jpg' => 'text/plain'));`
+ *
+ * @param string $contentType
+ * @return mixed current content type or false if supplied an invalid content type
+ */
+ public function type($contentType = null) {
+ if (is_null($contentType)) {
+ return $this->_contentType;
+ }
+ if (is_array($contentType)) {
+ foreach ($contentType as $type => $definition) {
+ $this->_mimeTypes[$type] = $definition;
+ }
+ return $this->_contentType;
+ }
+ if (isset($this->_mimeTypes[$contentType])) {
+ $contentType = $this->_mimeTypes[$contentType];
+ $contentType = is_array($contentType) ? current($contentType) : $contentType;
+ }
+ if (strpos($contentType, '/') === false) {
+ return false;
+ }
+ return $this->_contentType = $contentType;
+ }
+
+/**
+ * Returns the mime type definition for an alias
+ *
+ * e.g `getMimeType('pdf'); // returns 'application/pdf'`
+ *
+ * @param string $alias the content type alias to map
+ * @return mixed string mapped mime type or false if $alias is not mapped
+ */
+ public function getMimeType($alias) {
+ if (isset($this->_mimeTypes[$alias])) {
+ return $this->_mimeTypes[$alias];
+ }
+ return false;
+ }
+
+/**
+ * Maps a content-type back to an alias
+ *
+ * e.g `mapType('application/pdf'); // returns 'pdf'`
+ *
+ * @param string|array $ctype Either a string content type to map, or an array of types.
+ * @return mixed Aliases for the types provided.
+ */
+ public function mapType($ctype) {
+ if (is_array($ctype)) {
+ return array_map(array($this, 'mapType'), $ctype);
+ }
+
+ foreach ($this->_mimeTypes as $alias => $types) {
+ if (is_array($types) && in_array($ctype, $types)) {
+ return $alias;
+ } elseif (is_string($types) && $types == $ctype) {
+ return $alias;
+ }
+ }
+ return null;
+ }
+
+/**
+ * Sets the response charset
+ * if $charset is null the current charset is returned
+ *
+ * @param string $charset
+ * @return string current charset
+ */
+ public function charset($charset = null) {
+ if (is_null($charset)) {
+ return $this->_charset;
+ }
+ return $this->_charset = $charset;
+ }
+
+/**
+ * Sets the correct headers to instruct the client to not cache the response
+ *
+ * @return void
+ */
+ public function disableCache() {
+ $this->header(array(
+ 'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
+ 'Last-Modified' => gmdate("D, d M Y H:i:s") . " GMT",
+ 'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
+ ));
+ }
+
+/**
+ * Sets the correct headers to instruct the client to cache the response.
+ *
+ * @param string $since a valid time since the response text has not been modified
+ * @param string $time a valid time for cache expiry
+ * @return void
+ */
+ public function cache($since, $time = '+1 day') {
+ if (!is_integer($time)) {
+ $time = strtotime($time);
+ }
+ $this->header(array(
+ 'Date' => gmdate("D, j M Y G:i:s ", time()) . 'GMT'
+ ));
+ $this->modified($since);
+ $this->expires($time);
+ $this->sharable(true);
+ $this->maxAge($time - time());
+ }
+
+/**
+ * Sets whether a response is eligible to be cached by intermediate proxies
+ * This method controls the `public` or `private` directive in the Cache-Control
+ * header
+ *
+ * @param boolean $public if set to true, the Cache-Control header will be set as public
+ * if set to false, the response will be set to private
+ * if no value is provided, it will return whether the response is sharable or not
+ * @param integer $time time in seconds after which the response should no longer be considered fresh
+ * @return boolean
+ */
+ public function sharable($public = null, $time = null) {
+ if ($public === null) {
+ $public = array_key_exists('public', $this->_cacheDirectives);
+ $private = array_key_exists('private', $this->_cacheDirectives);
+ $noCache = array_key_exists('no-cache', $this->_cacheDirectives);
+ if (!$public && !$private && !$noCache) {
+ return null;
+ }
+ $sharable = $public || ! ($private || $noCache);
+ return $sharable;
+ }
+ if ($public) {
+ $this->_cacheDirectives['public'] = true;
+ unset($this->_cacheDirectives['private']);
+ $this->sharedMaxAge($time);
+ } else {
+ $this->_cacheDirectives['private'] = true;
+ unset($this->_cacheDirectives['public']);
+ $this->maxAge($time);
+ }
+ if ($time == null) {
+ $this->_setCacheControl();
+ }
+ return (bool)$public;
+ }
+
+/**
+ * Sets the Cache-Control s-maxage directive.
+ * The max-age is the number of seconds after which the response should no longer be considered
+ * a good candidate to be fetched from a shared cache (like in a proxy server).
+ * If called with no parameters, this function will return the current max-age value if any
+ *
+ * @param integer $seconds if null, the method will return the current s-maxage value
+ * @return int
+ */
+ public function sharedMaxAge($seconds = null) {
+ if ($seconds !== null) {
+ $this->_cacheDirectives['s-maxage'] = $seconds;
+ $this->_setCacheControl();
+ }
+ if (isset($this->_cacheDirectives['s-maxage'])) {
+ return $this->_cacheDirectives['s-maxage'];
+ }
+ return null;
+ }
+
+/**
+ * Sets the Cache-Control max-age directive.
+ * The max-age is the number of seconds after which the response should no longer be considered
+ * a good candidate to be fetched from the local (client) cache.
+ * If called with no parameters, this function will return the current max-age value if any
+ *
+ * @param integer $seconds if null, the method will return the current max-age value
+ * @return int
+ */
+ public function maxAge($seconds = null) {
+ if ($seconds !== null) {
+ $this->_cacheDirectives['max-age'] = $seconds;
+ $this->_setCacheControl();
+ }
+ if (isset($this->_cacheDirectives['max-age'])) {
+ return $this->_cacheDirectives['max-age'];
+ }
+ return null;
+ }
+
+/**
+ * Sets the Cache-Control must-revalidate directive.
+ * must-revalidate indicates that the response should not be served
+ * stale by a cache under any cirumstance without first revalidating
+ * with the origin.
+ * If called with no parameters, this function will return wheter must-revalidate is present.
+ *
+ * @param integer $seconds if null, the method will return the current
+ * must-revalidate value
+ * @return boolean
+ */
+ public function mustRevalidate($enable = null) {
+ if ($enable !== null) {
+ if ($enable) {
+ $this->_cacheDirectives['must-revalidate'] = true;
+ } else {
+ unset($this->_cacheDirectives['must-revalidate']);
+ }
+ $this->_setCacheControl();
+ }
+ return array_key_exists('must-revalidate', $this->_cacheDirectives);
+ }
+
+/**
+ * Helper method to generate a valid Cache-Control header from the options set
+ * in other methods
+ *
+ * @return void
+ */
+ protected function _setCacheControl() {
+ $control = '';
+ foreach ($this->_cacheDirectives as $key => $val) {
+ $control .= $val === true ? $key : sprintf('%s=%s', $key, $val);
+ $control .= ', ';
+ }
+ $control = rtrim($control, ', ');
+ $this->header('Cache-Control', $control);
+ }
+
+/**
+ * Sets the Expires header for the response by taking an expiration time
+ * If called with no parameters it will return the current Expires value
+ *
+ * ## Examples:
+ *
+ * `$response->expires('now')` Will Expire the response cache now
+ * `$response->expires(new DateTime('+1 day'))` Will set the expiration in next 24 hours
+ * `$response->expires()` Will return the current expiration header value
+ *
+ * @param string|DateTime $time
+ * @return string
+ */
+ public function expires($time = null) {
+ if ($time !== null) {
+ $date = $this->_getUTCDate($time);
+ $this->_headers['Expires'] = $date->format('D, j M Y H:i:s') . ' GMT';
+ }
+ if (isset($this->_headers['Expires'])) {
+ return $this->_headers['Expires'];
+ }
+ return null;
+ }
+
+/**
+ * Sets the Last-Modified header for the response by taking an modification time
+ * If called with no parameters it will return the current Last-Modified value
+ *
+ * ## Examples:
+ *
+ * `$response->modified('now')` Will set the Last-Modified to the current time
+ * `$response->modified(new DateTime('+1 day'))` Will set the modification date in the past 24 hours
+ * `$response->modified()` Will return the current Last-Modified header value
+ *
+ * @param string|DateTime $time
+ * @return string
+ */
+ public function modified($time = null) {
+ if ($time !== null) {
+ $date = $this->_getUTCDate($time);
+ $this->_headers['Last-Modified'] = $date->format('D, j M Y H:i:s') . ' GMT';
+ }
+ if (isset($this->_headers['Last-Modified'])) {
+ return $this->_headers['Last-Modified'];
+ }
+ return null;
+ }
+
+/**
+ * Sets the response as Not Modified by removing any body contents
+ * setting the status code to "304 Not Modified" and removing all
+ * conflicting headers
+ *
+ * @return void
+ **/
+ public function notModified() {
+ $this->statusCode(304);
+ $this->body('');
+ $remove = array(
+ 'Allow',
+ 'Content-Encoding',
+ 'Content-Language',
+ 'Content-Length',
+ 'Content-MD5',
+ 'Content-Type',
+ 'Last-Modified'
+ );
+ foreach ($remove as $header) {
+ unset($this->_headers[$header]);
+ }
+ }
+
+/**
+ * Sets the Vary header for the response, if an array is passed,
+ * values will be imploded into a comma separated string. If no
+ * parameters are passed, then an array with the current Vary header
+ * value is returned
+ *
+ * @param string|array $cacheVariances a single Vary string or a array
+ * containig the list for variances.
+ * @return array
+ **/
+ public function vary($cacheVariances = null) {
+ if ($cacheVariances !== null) {
+ $cacheVariances = (array)$cacheVariances;
+ $this->_headers['Vary'] = implode(', ', $cacheVariances);
+ }
+ if (isset($this->_headers['Vary'])) {
+ return explode(', ', $this->_headers['Vary']);
+ }
+ return null;
+ }
+
+/**
+ * Sets the response Etag, Etags are a strong indicative that a response
+ * can be cached by a HTTP client. A bad way of generaing Etags is
+ * creating a hash of the response output, instead generate a unique
+ * hash of the unique components that identifies a request, such as a
+ * modification time, a resource Id, and anything else you consider it
+ * makes it unique.
+ *
+ * Second parameter is used to instuct clients that the content has
+ * changed, but sematicallly, it can be used as the same thing. Think
+ * for instance of a page with a hit counter, two different page views
+ * are equivalent, but they differ by a few bytes. This leaves off to
+ * the Client the decision of using or not the cached page.
+ *
+ * If no parameters are passed, current Etag header is returned.
+ *
+ * @param string $hash the unique has that identifies this resposnse
+ * @param boolean $weak whether the response is semantically the same as
+ * other with th same hash or not
+ * @return string
+ **/
+ public function etag($tag = null, $weak = false) {
+ if ($tag !== null) {
+ $this->_headers['Etag'] = sprintf('%s"%s"', ($weak) ? 'W/' : null, $tag);
+ }
+ if (isset($this->_headers['Etag'])) {
+ return $this->_headers['Etag'];
+ }
+ return null;
+ }
+
+/**
+ * Returns a DateTime object initialized at the $time param and using UTC
+ * as timezone
+ *
+ * @param string|integer|DateTime $time
+ * @return DateTime
+ */
+ protected function _getUTCDate($time = null) {
+ if ($time instanceof DateTime) {
+ $result = clone $time;
+ } elseif (is_integer($time)) {
+ $result = new DateTime(date('Y-m-d H:i:s', $time));
+ } else {
+ $result = new DateTime($time);
+ }
+ $result->setTimeZone(new DateTimeZone('UTC'));
+ return $result;
+ }
+
+/**
+ * Sets the correct output buffering handler to send a compressed response. Responses will
+ * be compressed with zlib, if the extension is available.
+ *
+ * @return boolean false if client does not accept compressed responses or no handler is available, true otherwise
+ */
+ public function compress() {
+ $compressionEnabled = ini_get("zlib.output_compression") !== '1' &&
+ extension_loaded("zlib") &&
+ (strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false);
+ return $compressionEnabled && ob_start('ob_gzhandler');
+ }
+
+/**
+ * Returns whether the resulting output will be compressed by PHP
+ *
+ * @return boolean
+ */
+ public function outputCompressed() {
+ return strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false
+ && (ini_get("zlib.output_compression") === '1' || in_array('ob_gzhandler', ob_list_handlers()));
+ }
+
+/**
+ * Sets the correct headers to instruct the browser to download the response as a file.
+ *
+ * @param string $filename the name of the file as the browser will download the response
+ * @return void
+ */
+ public function download($filename) {
+ $this->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
+ }
+
+/**
+ * Sets the protocol to be used when sending the response. Defaults to HTTP/1.1
+ * If called with no arguments, it will return the current configured protocol
+ *
+ * @return string protocol to be used for sending response
+ */
+ public function protocol($protocol = null) {
+ if ($protocol !== null) {
+ $this->_protocol = $protocol;
+ }
+ return $this->_protocol;
+ }
+
+/**
+ * Sets the Content-Length header for the response
+ * If called with no arguments returns the last Content-Length set
+ *
+ * @return int
+ */
+ public function length($bytes = null) {
+ if ($bytes !== null ) {
+ $this->_headers['Content-Length'] = $bytes;
+ }
+ if (isset($this->_headers['Content-Length'])) {
+ return $this->_headers['Content-Length'];
+ }
+ return null;
+ }
+
+/**
+ * Checks whether a response has not been modified according to the 'If-None-Match'
+ * (Etags) and 'If-Modified-Since' (last modification date) request
+ * headers headers. If the response is detected to be not modified, it
+ * is marked as so accordingly so the client can be informed of that.
+ *
+ * In order to mark a response as not modified, you need to set at least
+ * the Last-Modified response header or a response etag to be compared
+ * with the request itself
+ *
+ * @return boolean whether the response was marked as not modified or
+ * not
+ **/
+ public function checkNotModified(CakeRequest $request) {
+ $etags = preg_split('/\s*,\s*/', $request->header('If-None-Match'), null, PREG_SPLIT_NO_EMPTY);
+ $modifiedSince = $request->header('If-Modified-Since');
+ if ($responseTag = $this->etag()) {
+ $etagMatches = in_array('*', $etags) || in_array($responseTag, $etags);
+ }
+ if ($modifiedSince) {
+ $timeMatches = strtotime($this->modified()) == strtotime($modifiedSince);
+ }
+ $checks = compact('etagMatches', 'timeMatches');
+ if (empty($checks)) {
+ return false;
+ }
+ $notModified = !in_array(false, $checks, true);
+ if ($notModified) {
+ $this->notModified();
+ }
+ return $notModified;
+ }
+
+/**
+ * String conversion. Fetches the response body as a string.
+ * Does *not* send headers.
+ *
+ * @return string
+ */
+ public function __toString() {
+ return (string)$this->_body;
+ }
+
+/**
+ * Getter/Setter for cookie configs
+ *
+ * This method acts as a setter/getter depending on the type of the argument.
+ * If the method is called with no arguments, it returns all configurations.
+ *
+ * If the method is called with a string as argument, it returns either the
+ * given configuration if it is set, or null, if it's not set.
+ *
+ * If the method is called with an array as argument, it will set the cookie
+ * configuration to the cookie container.
+ *
+ * @param $options Either null to get all cookies, string for a specific cookie
+ * or array to set cookie.
+ *
+ * ### Options (when setting a configuration)
+ * - name: The Cookie name
+ * - value: Value of the cookie
+ * - expire: Time the cookie expires in
+ * - path: Path the cookie applies to
+ * - domain: Domain the cookie is for.
+ * - secure: Is the cookie https?
+ * - httpOnly: Is the cookie available in the client?
+ *
+ * ## Examples
+ *
+ * ### Getting all cookies
+ *
+ * `$this->cookie()`
+ *
+ * ### Getting a certain cookie configuration
+ *
+ * `$this->cookie('MyCookie')`
+ *
+ * ### Setting a cookie configuration
+ *
+ * `$this->cookie((array) $options)`
+ *
+ * @return mixed
+ */
+ public function cookie($options = null) {
+ if ($options === null) {
+ return $this->_cookies;
+ }
+
+ if (is_string($options)) {
+ if (!isset($this->_cookies[$options])) {
+ return null;
+ }
+ return $this->_cookies[$options];
+ }
+
+ $defaults = array(
+ 'name' => 'CakeCookie[default]',
+ 'value' => '',
+ 'expire' => 0,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => false,
+ 'httpOnly' => false
+ );
+ $options += $defaults;
+
+ $this->_cookies[$options['name']] = $options;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeSocket.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeSocket.php
new file mode 100644
index 0000000..aa0eb4f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/CakeSocket.php
@@ -0,0 +1,280 @@
+<?php
+/**
+ * Cake Socket connection class.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Validation', 'Utility');
+
+/**
+ * Cake network socket connection class.
+ *
+ * Core base class for network communication.
+ *
+ * @package Cake.Network
+ */
+class CakeSocket {
+
+/**
+ * Object description
+ *
+ * @var string
+ */
+ public $description = 'Remote DataSource Network Socket Interface';
+
+/**
+ * Base configuration settings for the socket connection
+ *
+ * @var array
+ */
+ protected $_baseConfig = array(
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'protocol' => 'tcp',
+ 'port' => 80,
+ 'timeout' => 30
+ );
+
+/**
+ * Configuration settings for the socket connection
+ *
+ * @var array
+ */
+ public $config = array();
+
+/**
+ * Reference to socket connection resource
+ *
+ * @var resource
+ */
+ public $connection = null;
+
+/**
+ * This boolean contains the current state of the CakeSocket class
+ *
+ * @var boolean
+ */
+ public $connected = false;
+
+/**
+ * This variable contains an array with the last error number (num) and string (str)
+ *
+ * @var array
+ */
+ public $lastError = array();
+
+/**
+ * Constructor.
+ *
+ * @param array $config Socket configuration, which will be merged with the base configuration
+ * @see CakeSocket::$_baseConfig
+ */
+ public function __construct($config = array()) {
+ $this->config = array_merge($this->_baseConfig, $config);
+ if (!is_numeric($this->config['protocol'])) {
+ $this->config['protocol'] = getprotobyname($this->config['protocol']);
+ }
+ }
+
+/**
+ * Connect the socket to the given host and port.
+ *
+ * @return boolean Success
+ * @throws SocketException
+ */
+ public function connect() {
+ if ($this->connection != null) {
+ $this->disconnect();
+ }
+
+ $scheme = null;
+ if (isset($this->config['request']) && $this->config['request']['uri']['scheme'] == 'https') {
+ $scheme = 'ssl://';
+ }
+
+ if ($this->config['persistent'] == true) {
+ $this->connection = @pfsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
+ } else {
+ $this->connection = @fsockopen($scheme . $this->config['host'], $this->config['port'], $errNum, $errStr, $this->config['timeout']);
+ }
+
+ if (!empty($errNum) || !empty($errStr)) {
+ $this->setLastError($errNum, $errStr);
+ throw new SocketException($errStr, $errNum);
+ }
+
+ $this->connected = is_resource($this->connection);
+ if ($this->connected) {
+ stream_set_timeout($this->connection, $this->config['timeout']);
+ }
+ return $this->connected;
+ }
+
+/**
+ * Get the host name of the current connection.
+ *
+ * @return string Host name
+ */
+ public function host() {
+ if (Validation::ip($this->config['host'])) {
+ return gethostbyaddr($this->config['host']);
+ }
+ return gethostbyaddr($this->address());
+ }
+
+/**
+ * Get the IP address of the current connection.
+ *
+ * @return string IP address
+ */
+ public function address() {
+ if (Validation::ip($this->config['host'])) {
+ return $this->config['host'];
+ }
+ return gethostbyname($this->config['host']);
+ }
+
+/**
+ * Get all IP addresses associated with the current connection.
+ *
+ * @return array IP addresses
+ */
+ public function addresses() {
+ if (Validation::ip($this->config['host'])) {
+ return array($this->config['host']);
+ }
+ return gethostbynamel($this->config['host']);
+ }
+
+/**
+ * Get the last error as a string.
+ *
+ * @return string Last error
+ */
+ public function lastError() {
+ if (!empty($this->lastError)) {
+ return $this->lastError['num'] . ': ' . $this->lastError['str'];
+ }
+ return null;
+ }
+
+/**
+ * Set the last error.
+ *
+ * @param integer $errNum Error code
+ * @param string $errStr Error string
+ * @return void
+ */
+ public function setLastError($errNum, $errStr) {
+ $this->lastError = array('num' => $errNum, 'str' => $errStr);
+ }
+
+/**
+ * Write data to the socket.
+ *
+ * @param string $data The data to write to the socket
+ * @return boolean Success
+ */
+ public function write($data) {
+ if (!$this->connected) {
+ if (!$this->connect()) {
+ return false;
+ }
+ }
+ $totalBytes = strlen($data);
+ for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
+ $rv = fwrite($this->connection, substr($data, $written));
+ if ($rv === false || $rv === 0) {
+ return $written;
+ }
+ }
+ return $written;
+ }
+
+/**
+ * Read data from the socket. Returns false if no data is available or no connection could be
+ * established.
+ *
+ * @param integer $length Optional buffer length to read; defaults to 1024
+ * @return mixed Socket data
+ */
+ public function read($length = 1024) {
+ if (!$this->connected) {
+ if (!$this->connect()) {
+ return false;
+ }
+ }
+
+ if (!feof($this->connection)) {
+ $buffer = fread($this->connection, $length);
+ $info = stream_get_meta_data($this->connection);
+ if ($info['timed_out']) {
+ $this->setLastError(E_WARNING, __d('cake_dev', 'Connection timed out'));
+ return false;
+ }
+ return $buffer;
+ }
+ return false;
+ }
+
+/**
+ * Disconnect the socket from the current connection.
+ *
+ * @return boolean Success
+ */
+ public function disconnect() {
+ if (!is_resource($this->connection)) {
+ $this->connected = false;
+ return true;
+ }
+ $this->connected = !fclose($this->connection);
+
+ if (!$this->connected) {
+ $this->connection = null;
+ }
+ return !$this->connected;
+ }
+
+/**
+ * Destructor, used to disconnect from current connection.
+ *
+ */
+ public function __destruct() {
+ $this->disconnect();
+ }
+
+/**
+ * Resets the state of this Socket instance to it's initial state (before Object::__construct got executed)
+ *
+ * @param array $state Array with key and values to reset
+ * @return boolean True on success
+ */
+ public function reset($state = null) {
+ if (empty($state)) {
+ static $initalState = array();
+ if (empty($initalState)) {
+ $initalState = get_class_vars(__CLASS__);
+ }
+ $state = $initalState;
+ }
+
+ foreach ($state as $property => $value) {
+ $this->{$property} = $value;
+ }
+ return true;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/AbstractTransport.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/AbstractTransport.php
new file mode 100644
index 0000000..401d511
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/AbstractTransport.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Abstract send email
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Abstract transport for sending email
+ *
+ * @package Cake.Network.Email
+ */
+abstract class AbstractTransport {
+
+/**
+ * Configurations
+ *
+ * @var array
+ */
+ protected $_config = array();
+
+/**
+ * Send mail
+ *
+ * @params CakeEmail $email
+ * @return array
+ */
+ abstract public function send(CakeEmail $email);
+
+/**
+ * Set the config
+ *
+ * @param array $config
+ * @return array Returns configs
+ */
+ public function config($config = null) {
+ if (is_array($config)) {
+ $this->_config = $config;
+ }
+ return $this->_config;
+ }
+
+/**
+ * Help to convert headers in string
+ *
+ * @param array $headers Headers in format key => value
+ * @param string $eol
+ * @return string
+ */
+ protected function _headersToString($headers, $eol = "\r\n") {
+ $out = '';
+ foreach ($headers as $key => $value) {
+ if ($value === false || $value === null || $value === '') {
+ continue;
+ }
+ $out .= $key . ': ' . $value . $eol;
+ }
+ if (!empty($out)) {
+ $out = substr($out, 0, -1 * strlen($eol));
+ }
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/CakeEmail.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/CakeEmail.php
new file mode 100644
index 0000000..9e5ed09
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/CakeEmail.php
@@ -0,0 +1,1588 @@
+<?php
+/**
+ * Cake E-Mail
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Validation', 'Utility');
+App::uses('Multibyte', 'I18n');
+App::uses('AbstractTransport', 'Network/Email');
+App::uses('String', 'Utility');
+App::uses('View', 'View');
+App::import('I18n', 'Multibyte');
+
+/**
+ * Cake e-mail class.
+ *
+ * This class is used for handling Internet Message Format based
+ * based on the standard outlined in http://www.rfc-editor.org/rfc/rfc2822.txt
+ *
+ * @package Cake.Network.Email
+ */
+class CakeEmail {
+/**
+ * Default X-Mailer
+ *
+ * @constant EMAIL_CLIENT
+ */
+ const EMAIL_CLIENT = 'CakePHP Email';
+
+/**
+ * Line length - no should more - RFC 2822 - 2.1.1
+ *
+ * @constant LINE_LENGTH_SHOULD
+ */
+ const LINE_LENGTH_SHOULD = 78;
+
+/**
+ * Line length - no must more - RFC 2822 - 2.1.1
+ *
+ * @constant LINE_LENGTH_MUST
+ */
+ const LINE_LENGTH_MUST = 998;
+
+/**
+ * Type of message - HTML
+ *
+ * @constant MESSAGE_HTML
+ */
+ const MESSAGE_HTML = 'html';
+
+/**
+ * Type of message - TEXT
+ *
+ * @constant MESSAGE_TEXT
+ */
+ const MESSAGE_TEXT = 'text';
+
+/**
+ * Recipient of the email
+ *
+ * @var array
+ */
+ protected $_to = array();
+
+/**
+ * The mail which the email is sent from
+ *
+ * @var array
+ */
+ protected $_from = array();
+
+/**
+ * The sender email
+ *
+ * @var array();
+ */
+ protected $_sender = array();
+
+/**
+ * The email the recipient will reply to
+ *
+ * @var array
+ */
+ protected $_replyTo = array();
+
+/**
+ * The read receipt email
+ *
+ * @var array
+ */
+ protected $_readReceipt = array();
+
+/**
+ * The mail that will be used in case of any errors like
+ * - Remote mailserver down
+ * - Remote user has exceeded his quota
+ * - Unknown user
+ *
+ * @var array
+ */
+ protected $_returnPath = array();
+
+/**
+ * Carbon Copy
+ *
+ * List of email's that should receive a copy of the email.
+ * The Recipient WILL be able to see this list
+ *
+ * @var array
+ */
+ protected $_cc = array();
+
+/**
+ * Blind Carbon Copy
+ *
+ * List of email's that should receive a copy of the email.
+ * The Recipient WILL NOT be able to see this list
+ *
+ * @var array
+ */
+ protected $_bcc = array();
+
+/**
+ * Message ID
+ *
+ * @var boolean|string True to generate, False to ignore, String with value
+ */
+ protected $_messageId = true;
+
+/**
+ * Domain for messageId generation.
+ * Needs to be manually set for CLI mailing as env('HTTP_HOST') is empty
+ *
+ * @var string
+ */
+ protected $_domain = null;
+
+/**
+ * The subject of the email
+ *
+ * @var string
+ */
+ protected $_subject = '';
+
+/**
+ * Associative array of a user defined headers
+ * Keys will be prefixed 'X-' as per RFC2822 Section 4.7.5
+ *
+ * @var array
+ */
+ protected $_headers = array();
+
+/**
+ * Layout for the View
+ *
+ * @var string
+ */
+ protected $_layout = 'default';
+
+/**
+ * Template for the view
+ *
+ * @var string
+ */
+ protected $_template = '';
+
+/**
+ * View for render
+ *
+ * @var string
+ */
+ protected $_viewRender = 'View';
+
+/**
+ * Vars to sent to render
+ *
+ * @var array
+ */
+ protected $_viewVars = array();
+
+/**
+ * Theme for the View
+ *
+ * @var array
+ */
+ protected $_theme = null;
+
+/**
+ * Helpers to be used in the render
+ *
+ * @var array
+ */
+ protected $_helpers = array('Html');
+
+/**
+ * Text message
+ *
+ * @var string
+ */
+ protected $_textMessage = '';
+
+/**
+ * Html message
+ *
+ * @var string
+ */
+ protected $_htmlMessage = '';
+
+/**
+ * Final message to send
+ *
+ * @var array
+ */
+ protected $_message = array();
+
+/**
+ * Available formats to be sent.
+ *
+ * @var array
+ */
+ protected $_emailFormatAvailable = array('text', 'html', 'both');
+
+/**
+ * What format should the email be sent in
+ *
+ * @var string
+ */
+ protected $_emailFormat = 'text';
+
+/**
+ * What method should the email be sent
+ *
+ * @var string
+ */
+ protected $_transportName = 'Mail';
+
+/**
+ * Instance of transport class
+ *
+ * @var AbstractTransport
+ */
+ protected $_transportClass = null;
+
+/**
+ * Charset the email body is sent in
+ *
+ * @var string
+ */
+ public $charset = 'utf-8';
+
+/**
+ * Charset the email header is sent in
+ * If null, the $charset property will be used as default
+ *
+ * @var string
+ */
+ public $headerCharset = null;
+
+/**
+ * The application wide charset, used to encode headers and body
+ *
+ * @var string
+ */
+ protected $_appCharset = null;
+
+/**
+ * List of files that should be attached to the email.
+ *
+ * Only absolute paths
+ *
+ * @var array
+ */
+ protected $_attachments = array();
+
+/**
+ * If set, boundary to use for multipart mime messages
+ *
+ * @var string
+ */
+ protected $_boundary = null;
+
+/**
+ * Configuration to transport
+ *
+ * @var string|array
+ */
+ protected $_config = array();
+
+/**
+ * 8Bit character sets
+ *
+ * @var array
+ */
+ protected $_charset8bit = array('UTF-8', 'SHIFT_JIS');
+
+/**
+ * Define Content-Type charset name
+ *
+ * @var array
+ */
+ protected $_contentTypeCharset = array(
+ 'ISO-2022-JP-MS' => 'ISO-2022-JP'
+ );
+
+/**
+ * Constructor
+ * @param array|string $config Array of configs, or string to load configs from email.php
+ *
+ */
+ public function __construct($config = null) {
+ $this->_appCharset = Configure::read('App.encoding');
+ if ($this->_appCharset !== null) {
+ $this->charset = $this->_appCharset;
+ }
+ $this->_domain = env('HTTP_HOST');
+ if (empty($this->_domain)) {
+ $this->_domain = php_uname('n');
+ }
+
+ if ($config) {
+ $this->config($config);
+ }
+ if (empty($this->headerCharset)) {
+ $this->headerCharset = $this->charset;
+ }
+ }
+
+/**
+ * From
+ *
+ * @param string|array $email
+ * @param string $name
+ * @return array|CakeEmail
+ * @throws SocketException
+ */
+ public function from($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_from;
+ }
+ return $this->_setEmailSingle('_from', $email, $name, __d('cake_dev', 'From requires only 1 email address.'));
+ }
+
+/**
+ * Sender
+ *
+ * @param string|array $email
+ * @param string $name
+ * @return array|CakeEmail
+ * @throws SocketException
+ */
+ public function sender($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_sender;
+ }
+ return $this->_setEmailSingle('_sender', $email, $name, __d('cake_dev', 'Sender requires only 1 email address.'));
+ }
+
+/**
+ * Reply-To
+ *
+ * @param string|array $email
+ * @param string $name
+ * @return array|CakeEmail
+ * @throws SocketException
+ */
+ public function replyTo($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_replyTo;
+ }
+ return $this->_setEmailSingle('_replyTo', $email, $name, __d('cake_dev', 'Reply-To requires only 1 email address.'));
+ }
+
+/**
+ * Read Receipt (Disposition-Notification-To header)
+ *
+ * @param string|array $email
+ * @param string $name
+ * @return array|CakeEmail
+ * @throws SocketException
+ */
+ public function readReceipt($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_readReceipt;
+ }
+ return $this->_setEmailSingle('_readReceipt', $email, $name, __d('cake_dev', 'Disposition-Notification-To requires only 1 email address.'));
+ }
+
+/**
+ * Return Path
+ *
+ * @param string|array $email
+ * @param string $name
+ * @return array|CakeEmail
+ * @throws SocketException
+ */
+ public function returnPath($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_returnPath;
+ }
+ return $this->_setEmailSingle('_returnPath', $email, $name, __d('cake_dev', 'Return-Path requires only 1 email address.'));
+ }
+
+/**
+ * To
+ *
+ * @param string|array $email Null to get, String with email, Array with email as key, name as value or email as value (without name)
+ * @param string $name
+ * @return array|CakeEmail
+ */
+ public function to($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_to;
+ }
+ return $this->_setEmail('_to', $email, $name);
+ }
+
+/**
+ * Add To
+ *
+ * @param string|array $email String with email, Array with email as key, name as value or email as value (without name)
+ * @param string $name
+ * @return CakeEmail $this
+ */
+ public function addTo($email, $name = null) {
+ return $this->_addEmail('_to', $email, $name);
+ }
+
+/**
+ * Cc
+ *
+ * @param string|array $email String with email, Array with email as key, name as value or email as value (without name)
+ * @param string $name
+ * @return array|CakeEmail
+ */
+ public function cc($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_cc;
+ }
+ return $this->_setEmail('_cc', $email, $name);
+ }
+
+/**
+ * Add Cc
+ *
+ * @param string|array $email String with email, Array with email as key, name as value or email as value (without name)
+ * @param string $name
+ * @return CakeEmail $this
+ */
+ public function addCc($email, $name = null) {
+ return $this->_addEmail('_cc', $email, $name);
+ }
+
+/**
+ * Bcc
+ *
+ * @param string|array $email String with email, Array with email as key, name as value or email as value (without name)
+ * @param string $name
+ * @return array|CakeEmail
+ */
+ public function bcc($email = null, $name = null) {
+ if ($email === null) {
+ return $this->_bcc;
+ }
+ return $this->_setEmail('_bcc', $email, $name);
+ }
+
+/**
+ * Add Bcc
+ *
+ * @param string|array $email String with email, Array with email as key, name as value or email as value (without name)
+ * @param string $name
+ * @return CakeEmail $this
+ */
+ public function addBcc($email, $name = null) {
+ return $this->_addEmail('_bcc', $email, $name);
+ }
+
+/**
+ * Charset setter/getter
+ *
+ * @param string $charset
+ * @return string $this->charset
+ */
+ public function charset($charset = null) {
+ if ($charset === null) {
+ return $this->charset;
+ }
+ $this->charset = $charset;
+ if (empty($this->headerCharset)) {
+ $this->headerCharset = $charset;
+ }
+ return $this->charset;
+ }
+
+/**
+ * HeaderCharset setter/getter
+ *
+ * @param string $charset
+ * @return string $this->charset
+ */
+ public function headerCharset($charset = null) {
+ if ($charset === null) {
+ return $this->headerCharset;
+ }
+ return $this->headerCharset = $charset;
+ }
+
+/**
+ * Set email
+ *
+ * @param string $varName
+ * @param string|array $email
+ * @param string $name
+ * @return CakeEmail $this
+ * @throws SocketException
+ */
+ protected function _setEmail($varName, $email, $name) {
+ if (!is_array($email)) {
+ if (!Validation::email($email)) {
+ throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email));
+ }
+ if ($name === null) {
+ $name = $email;
+ }
+ $this->{$varName} = array($email => $name);
+ return $this;
+ }
+ $list = array();
+ foreach ($email as $key => $value) {
+ if (is_int($key)) {
+ $key = $value;
+ }
+ if (!Validation::email($key)) {
+ throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $key));
+ }
+ $list[$key] = $value;
+ }
+ $this->{$varName} = $list;
+ return $this;
+ }
+
+/**
+ * Set only 1 email
+ *
+ * @param string $varName
+ * @param string|array $email
+ * @param string $name
+ * @param string $throwMessage
+ * @return CakeEmail $this
+ * @throws SocketException
+ */
+ protected function _setEmailSingle($varName, $email, $name, $throwMessage) {
+ $current = $this->{$varName};
+ $this->_setEmail($varName, $email, $name);
+ if (count($this->{$varName}) !== 1) {
+ $this->{$varName} = $current;
+ throw new SocketException($throwMessage);
+ }
+ return $this;
+ }
+
+/**
+ * Add email
+ *
+ * @param string $varName
+ * @param string|array $email
+ * @param string $name
+ * @return CakeEmail $this
+ * @throws SocketException
+ */
+ protected function _addEmail($varName, $email, $name) {
+ if (!is_array($email)) {
+ if (!Validation::email($email)) {
+ throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email));
+ }
+ if ($name === null) {
+ $name = $email;
+ }
+ $this->{$varName}[$email] = $name;
+ return $this;
+ }
+ $list = array();
+ foreach ($email as $key => $value) {
+ if (is_int($key)) {
+ $key = $value;
+ }
+ if (!Validation::email($key)) {
+ throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $key));
+ }
+ $list[$key] = $value;
+ }
+ $this->{$varName} = array_merge($this->{$varName}, $list);
+ return $this;
+ }
+
+/**
+ * Get/Set Subject.
+ *
+ * @param string $subject
+ * @return string|CakeEmail
+ */
+ public function subject($subject = null) {
+ if ($subject === null) {
+ return $this->_subject;
+ }
+ $this->_subject = $this->_encode((string)$subject);
+ return $this;
+ }
+
+/**
+ * Sets headers for the message
+ *
+ * @param array $headers Associative array containing headers to be set.
+ * @return CakeEmail $this
+ * @throws SocketException
+ */
+ public function setHeaders($headers) {
+ if (!is_array($headers)) {
+ throw new SocketException(__d('cake_dev', '$headers should be an array.'));
+ }
+ $this->_headers = $headers;
+ return $this;
+ }
+
+/**
+ * Add header for the message
+ *
+ * @param array $headers
+ * @return object $this
+ * @throws SocketException
+ */
+ public function addHeaders($headers) {
+ if (!is_array($headers)) {
+ throw new SocketException(__d('cake_dev', '$headers should be an array.'));
+ }
+ $this->_headers = array_merge($this->_headers, $headers);
+ return $this;
+ }
+
+/**
+ * Get list of headers
+ *
+ * ### Includes:
+ *
+ * - `from`
+ * - `replyTo`
+ * - `readReceipt`
+ * - `returnPath`
+ * - `to`
+ * - `cc`
+ * - `bcc`
+ * - `subject`
+ *
+ * @param array $include
+ * @return array
+ */
+ public function getHeaders($include = array()) {
+ if ($include == array_values($include)) {
+ $include = array_fill_keys($include, true);
+ }
+ $defaults = array_fill_keys(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), false);
+ $include += $defaults;
+
+ $headers = array();
+ $relation = array(
+ 'from' => 'From',
+ 'replyTo' => 'Reply-To',
+ 'readReceipt' => 'Disposition-Notification-To',
+ 'returnPath' => 'Return-Path'
+ );
+ foreach ($relation as $var => $header) {
+ if ($include[$var]) {
+ $var = '_' . $var;
+ $headers[$header] = current($this->_formatAddress($this->{$var}));
+ }
+ }
+ if ($include['sender']) {
+ if (key($this->_sender) === key($this->_from)) {
+ $headers['Sender'] = '';
+ } else {
+ $headers['Sender'] = current($this->_formatAddress($this->_sender));
+ }
+ }
+
+ foreach (array('to', 'cc', 'bcc') as $var) {
+ if ($include[$var]) {
+ $classVar = '_' . $var;
+ $headers[ucfirst($var)] = implode(', ', $this->_formatAddress($this->{$classVar}));
+ }
+ }
+
+ $headers += $this->_headers;
+ if (!isset($headers['X-Mailer'])) {
+ $headers['X-Mailer'] = self::EMAIL_CLIENT;
+ }
+ if (!isset($headers['Date'])) {
+ $headers['Date'] = date(DATE_RFC2822);
+ }
+ if ($this->_messageId !== false) {
+ if ($this->_messageId === true) {
+ $headers['Message-ID'] = '<' . str_replace('-', '', String::UUID()) . '@' . $this->_domain . '>';
+ } else {
+ $headers['Message-ID'] = $this->_messageId;
+ }
+ }
+
+ if ($include['subject']) {
+ $headers['Subject'] = $this->_subject;
+ }
+
+ $headers['MIME-Version'] = '1.0';
+ if (!empty($this->_attachments) || $this->_emailFormat === 'both') {
+ $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"';
+ } elseif ($this->_emailFormat === 'text') {
+ $headers['Content-Type'] = 'text/plain; charset=' . $this->_getContentTypeCharset();
+ } elseif ($this->_emailFormat === 'html') {
+ $headers['Content-Type'] = 'text/html; charset=' . $this->_getContentTypeCharset();
+ }
+ $headers['Content-Transfer-Encoding'] = $this->_getContentTransferEncoding();
+
+ return $headers;
+ }
+
+/**
+ * Format addresses
+ *
+ * @param array $address
+ * @return array
+ */
+ protected function _formatAddress($address) {
+ $return = array();
+ foreach ($address as $email => $alias) {
+ if ($email === $alias) {
+ $return[] = $email;
+ } else {
+ if (strpos($alias, ',') !== false) {
+ $alias = '"' . $alias . '"';
+ }
+ $return[] = sprintf('%s <%s>', $this->_encode($alias), $email);
+ }
+ }
+ return $return;
+ }
+
+/**
+ * Template and layout
+ *
+ * @param boolean|string $template Template name or null to not use
+ * @param boolean|string $layout Layout name or null to not use
+ * @return array|CakeEmail
+ */
+ public function template($template = false, $layout = false) {
+ if ($template === false) {
+ return array(
+ 'template' => $this->_template,
+ 'layout' => $this->_layout
+ );
+ }
+ $this->_template = $template;
+ if ($layout !== false) {
+ $this->_layout = $layout;
+ }
+ return $this;
+ }
+
+/**
+ * View class for render
+ *
+ * @param string $viewClass
+ * @return string|CakeEmail
+ */
+ public function viewRender($viewClass = null) {
+ if ($viewClass === null) {
+ return $this->_viewRender;
+ }
+ $this->_viewRender = $viewClass;
+ return $this;
+ }
+
+/**
+ * Variables to be set on render
+ *
+ * @param array $viewVars
+ * @return array|CakeEmail
+ */
+ public function viewVars($viewVars = null) {
+ if ($viewVars === null) {
+ return $this->_viewVars;
+ }
+ $this->_viewVars = array_merge($this->_viewVars, (array)$viewVars);
+ return $this;
+ }
+
+/**
+ * Theme to use when rendering
+ *
+ * @param string $theme
+ * @return string|CakeEmail
+ */
+ public function theme($theme = null) {
+ if ($theme === null) {
+ return $this->_theme;
+ }
+ $this->_theme = $theme;
+ return $this;
+ }
+
+/**
+ * Helpers to be used in render
+ *
+ * @param array $helpers
+ * @return array|CakeEmail
+ */
+ public function helpers($helpers = null) {
+ if ($helpers === null) {
+ return $this->_helpers;
+ }
+ $this->_helpers = (array)$helpers;
+ return $this;
+ }
+
+/**
+ * Email format
+ *
+ * @param string $format
+ * @return string|CakeEmail
+ * @throws SocketException
+ */
+ public function emailFormat($format = null) {
+ if ($format === null) {
+ return $this->_emailFormat;
+ }
+ if (!in_array($format, $this->_emailFormatAvailable)) {
+ throw new SocketException(__d('cake_dev', 'Format not available.'));
+ }
+ $this->_emailFormat = $format;
+ return $this;
+ }
+
+/**
+ * Transport name
+ *
+ * @param string $name
+ * @return string|CakeEmail
+ */
+ public function transport($name = null) {
+ if ($name === null) {
+ return $this->_transportName;
+ }
+ $this->_transportName = (string)$name;
+ $this->_transportClass = null;
+ return $this;
+ }
+
+/**
+ * Return the transport class
+ *
+ * @return CakeEmail
+ * @throws SocketException
+ */
+ public function transportClass() {
+ if ($this->_transportClass) {
+ return $this->_transportClass;
+ }
+ list($plugin, $transportClassname) = pluginSplit($this->_transportName, true);
+ $transportClassname .= 'Transport';
+ App::uses($transportClassname, $plugin . 'Network/Email');
+ if (!class_exists($transportClassname)) {
+ throw new SocketException(__d('cake_dev', 'Class "%s" not found.', $transportClassname));
+ } elseif (!method_exists($transportClassname, 'send')) {
+ throw new SocketException(__d('cake_dev', 'The "%s" do not have send method.', $transportClassname));
+ }
+
+ return $this->_transportClass = new $transportClassname();
+ }
+
+/**
+ * Message-ID
+ *
+ * @param boolean|string $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID
+ * @return boolean|string|CakeEmail
+ * @throws SocketException
+ */
+ public function messageId($message = null) {
+ if ($message === null) {
+ return $this->_messageId;
+ }
+ if (is_bool($message)) {
+ $this->_messageId = $message;
+ } else {
+ if (!preg_match('/^\<.+@.+\>$/', $message)) {
+ throw new SocketException(__d('cake_dev', 'Invalid format for Message-ID. The text should be something like "<uuid@server.com>"'));
+ }
+ $this->_messageId = $message;
+ }
+ return $this;
+ }
+
+/**
+ * Domain as top level (the part after @)
+ *
+ * @param string $domain Manually set the domain for CLI mailing
+ * @return string|CakeEmail
+ */
+ public function domain($domain = null) {
+ if ($domain === null) {
+ return $this->_domain;
+ }
+ $this->_domain = $domain;
+ return $this;
+ }
+
+/**
+ * Add attachments to the email message
+ *
+ * Attachments can be defined in a few forms depending on how much control you need:
+ *
+ * Attach a single file:
+ *
+ * {{{
+ * $email->attachments('path/to/file');
+ * }}}
+ *
+ * Attach a file with a different filename:
+ *
+ * {{{
+ * $email->attachments(array('custom_name.txt' => 'path/to/file.txt'));
+ * }}}
+ *
+ * Attach a file and specify additional properties:
+ *
+ * {{{
+ * $email->attachments(array('custom_name.png' => array(
+ * 'file' => 'path/to/file',
+ * 'mimetype' => 'image/png',
+ * 'contentId' => 'abc123'
+ * ));
+ * }}}
+ *
+ * The `contentId` key allows you to specify an inline attachment. In your email text, you
+ * can use `<img src="cid:abc123" />` to display the image inline.
+ *
+ * @param string|array $attachments String with the filename or array with filenames
+ * @return array|CakeEmail Either the array of attachments when getting or $this when setting.
+ * @throws SocketException
+ */
+ public function attachments($attachments = null) {
+ if ($attachments === null) {
+ return $this->_attachments;
+ }
+ $attach = array();
+ foreach ((array)$attachments as $name => $fileInfo) {
+ if (!is_array($fileInfo)) {
+ $fileInfo = array('file' => $fileInfo);
+ }
+ if (!isset($fileInfo['file'])) {
+ throw new SocketException(__d('cake_dev', 'File not specified.'));
+ }
+ $fileInfo['file'] = realpath($fileInfo['file']);
+ if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) {
+ throw new SocketException(__d('cake_dev', 'File not found: "%s"', $fileInfo['file']));
+ }
+ if (is_int($name)) {
+ $name = basename($fileInfo['file']);
+ }
+ if (!isset($fileInfo['mimetype'])) {
+ $fileInfo['mimetype'] = 'application/octet-stream';
+ }
+ $attach[$name] = $fileInfo;
+ }
+ $this->_attachments = $attach;
+ return $this;
+ }
+
+/**
+ * Add attachments
+ *
+ * @param string|array $attachments String with the filename or array with filenames
+ * @return CakeEmail $this
+ * @throws SocketException
+ */
+ public function addAttachments($attachments) {
+ $current = $this->_attachments;
+ $this->attachments($attachments);
+ $this->_attachments = array_merge($current, $this->_attachments);
+ return $this;
+ }
+
+/**
+ * Get generated message (used by transport classes)
+ *
+ * @param string $type Use MESSAGE_* constants or null to return the full message as array
+ * @return string|array String if have type, array if type is null
+ */
+ public function message($type = null) {
+ switch ($type) {
+ case self::MESSAGE_HTML:
+ return $this->_htmlMessage;
+ case self::MESSAGE_TEXT:
+ return $this->_textMessage;
+ }
+ return $this->_message;
+ }
+
+/**
+ * Configuration to use when send email
+ *
+ * @param string|array $config String with configuration name (from email.php), array with config or null to return current config
+ * @return string|array|CakeEmail
+ */
+ public function config($config = null) {
+ if ($config === null) {
+ return $this->_config;
+ }
+ if (!is_array($config)) {
+ $config = (string)$config;
+ }
+
+ $this->_applyConfig($config);
+ return $this;
+ }
+
+/**
+ * Send an email using the specified content, template and layout
+ *
+ * @param string|array $content String with message or array with messages
+ * @return array
+ * @throws SocketException
+ */
+ public function send($content = null) {
+ if (empty($this->_from)) {
+ throw new SocketException(__d('cake_dev', 'From is not specified.'));
+ }
+ if (empty($this->_to) && empty($this->_cc) && empty($this->_bcc)) {
+ throw new SocketException(__d('cake_dev', 'You need to specify at least one destination for to, cc or bcc.'));
+ }
+
+ if (is_array($content)) {
+ $content = implode("\n", $content) . "\n";
+ }
+
+ $this->_textMessage = $this->_htmlMessage = '';
+ $this->_createBoundary();
+ $this->_message = $this->_render($this->_wrap($content));
+
+ $contents = $this->transportClass()->send($this);
+ if (!empty($this->_config['log'])) {
+ $level = LOG_DEBUG;
+ if ($this->_config['log'] !== true) {
+ $level = $this->_config['log'];
+ }
+ CakeLog::write($level, PHP_EOL . $contents['headers'] . PHP_EOL . $contents['message']);
+ }
+ return $contents;
+ }
+
+/**
+ * Static method to fast create an instance of CakeEmail
+ *
+ * @param string|array $to Address to send (see CakeEmail::to()). If null, will try to use 'to' from transport config
+ * @param string $subject String of subject or null to use 'subject' from transport config
+ * @param string|array $message String with message or array with variables to be used in render
+ * @param string|array $transportConfig String to use config from EmailConfig or array with configs
+ * @param boolean $send Send the email or just return the instance pre-configured
+ * @return CakeEmail Instance of CakeEmail
+ * @throws SocketException
+ */
+ public static function deliver($to = null, $subject = null, $message = null, $transportConfig = 'fast', $send = true) {
+ $class = __CLASS__;
+ $instance = new $class($transportConfig);
+ if ($to !== null) {
+ $instance->to($to);
+ }
+ if ($subject !== null) {
+ $instance->subject($subject);
+ }
+ if (is_array($message)) {
+ $instance->viewVars($message);
+ $message = null;
+ } elseif ($message === null && array_key_exists('message', $config = $instance->config())) {
+ $message = $config['message'];
+ }
+
+ if ($send === true) {
+ $instance->send($message);
+ }
+
+ return $instance;
+ }
+
+/**
+ * Apply the config to an instance
+ *
+ * @param CakeEmail $obj CakeEmail
+ * @param array $config
+ * @return void
+ * @throws ConfigureException When configuration file cannot be found, or is missing
+ * the named config.
+ */
+ protected function _applyConfig($config) {
+ if (is_string($config)) {
+ if (!class_exists('EmailConfig') && !config('email')) {
+ throw new ConfigureException(__d('cake_dev', '%s not found.', APP . 'Config' . DS . 'email.php'));
+ }
+ $configs = new EmailConfig();
+ if (!isset($configs->{$config})) {
+ throw new ConfigureException(__d('cake_dev', 'Unknown email configuration "%s".', $config));
+ }
+ $config = $configs->{$config};
+ }
+ $this->_config += $config;
+ if (!empty($config['charset'])) {
+ $this->charset = $config['charset'];
+ }
+ if (!empty($config['headerCharset'])) {
+ $this->headerCharset = $config['headerCharset'];
+ }
+ if (empty($this->headerCharset)) {
+ $this->headerCharset = $this->charset;
+ }
+ $simpleMethods = array(
+ 'from', 'sender', 'to', 'replyTo', 'readReceipt', 'returnPath', 'cc', 'bcc',
+ 'messageId', 'domain', 'subject', 'viewRender', 'viewVars', 'attachments',
+ 'transport', 'emailFormat', 'theme', 'helpers'
+ );
+ foreach ($simpleMethods as $method) {
+ if (isset($config[$method])) {
+ $this->$method($config[$method]);
+ unset($config[$method]);
+ }
+ }
+ if (isset($config['headers'])) {
+ $this->setHeaders($config['headers']);
+ unset($config['headers']);
+ }
+ if (array_key_exists('template', $config)) {
+ $layout = false;
+ if (array_key_exists('layout', $config)) {
+ $layout = $config['layout'];
+ unset($config['layout']);
+ }
+ $this->template($config['template'], $layout);
+ unset($config['template']);
+ }
+ $this->transportClass()->config($config);
+ }
+
+/**
+ * Reset all EmailComponent internal variables to be able to send out a new email.
+ *
+ * @return CakeEmail $this
+ */
+ public function reset() {
+ $this->_to = array();
+ $this->_from = array();
+ $this->_sender = array();
+ $this->_replyTo = array();
+ $this->_readReceipt = array();
+ $this->_returnPath = array();
+ $this->_cc = array();
+ $this->_bcc = array();
+ $this->_messageId = true;
+ $this->_subject = '';
+ $this->_headers = array();
+ $this->_layout = 'default';
+ $this->_template = '';
+ $this->_viewRender = 'View';
+ $this->_viewVars = array();
+ $this->_theme = null;
+ $this->_helpers = array('Html');
+ $this->_textMessage = '';
+ $this->_htmlMessage = '';
+ $this->_message = '';
+ $this->_emailFormat = 'text';
+ $this->_transportName = 'Mail';
+ $this->_transportClass = null;
+ $this->charset = 'utf-8';
+ $this->headerCharset = null;
+ $this->_attachments = array();
+ $this->_config = array();
+ return $this;
+ }
+
+/**
+ * Encode the specified string using the current charset
+ *
+ * @param string $text String to encode
+ * @return string Encoded string
+ */
+ protected function _encode($text) {
+ $internalEncoding = function_exists('mb_internal_encoding');
+ if ($internalEncoding) {
+ $restore = mb_internal_encoding();
+ mb_internal_encoding($this->_appCharset);
+ }
+ if (empty($this->headerCharset)) {
+ $this->headerCharset = $this->charset;
+ }
+ $return = mb_encode_mimeheader($text, $this->headerCharset, 'B');
+ if ($internalEncoding) {
+ mb_internal_encoding($restore);
+ }
+ return $return;
+ }
+
+/**
+ * Translates a string for one charset to another if the App.encoding value
+ * differs and the mb_convert_encoding function exists
+ *
+ * @param string $text The text to be converted
+ * @param string $charset the target encoding
+ * @return string
+ */
+ protected function _encodeString($text, $charset) {
+ if ($this->_appCharset === $charset || !function_exists('mb_convert_encoding')) {
+ return $text;
+ }
+ return mb_convert_encoding($text, $charset, $this->_appCharset);
+ }
+
+/**
+ * Wrap the message to follow the RFC 2822 - 2.1.1
+ *
+ * @param string $message Message to wrap
+ * @return array Wrapped message
+ */
+ protected function _wrap($message) {
+ $message = str_replace(array("\r\n", "\r"), "\n", $message);
+ $lines = explode("\n", $message);
+ $formatted = array();
+
+ foreach ($lines as $line) {
+ if (empty($line)) {
+ $formatted[] = '';
+ continue;
+ }
+ if (!preg_match('/\<[a-z]/i', $line)) {
+ $formatted = array_merge($formatted, explode("\n", wordwrap($line, self::LINE_LENGTH_SHOULD, "\n")));
+ continue;
+ }
+
+ $tagOpen = false;
+ $tmpLine = $tag = '';
+ $tmpLineLength = 0;
+ for ($i = 0, $count = strlen($line); $i < $count; $i++) {
+ $char = $line[$i];
+ if ($tagOpen) {
+ $tag .= $char;
+ if ($char === '>') {
+ $tagLength = strlen($tag);
+ if ($tagLength + $tmpLineLength < self::LINE_LENGTH_SHOULD) {
+ $tmpLine .= $tag;
+ $tmpLineLength += $tagLength;
+ } else {
+ if ($tmpLineLength > 0) {
+ $formatted[] = trim($tmpLine);
+ $tmpLine = '';
+ $tmpLineLength = 0;
+ }
+ if ($tagLength > self::LINE_LENGTH_SHOULD) {
+ $formatted[] = $tag;
+ } else {
+ $tmpLine = $tag;
+ $tmpLineLength = $tagLength;
+ }
+ }
+ $tag = '';
+ $tagOpen = false;
+ }
+ continue;
+ }
+ if ($char === '<') {
+ $tagOpen = true;
+ $tag = '<';
+ continue;
+ }
+ if ($char === ' ' && $tmpLineLength >= self::LINE_LENGTH_SHOULD) {
+ $formatted[] = $tmpLine;
+ $tmpLineLength = 0;
+ continue;
+ }
+ $tmpLine .= $char;
+ $tmpLineLength++;
+ if ($tmpLineLength === self::LINE_LENGTH_SHOULD) {
+ $nextChar = $line[$i + 1];
+ if ($nextChar === ' ' || $nextChar === '<') {
+ $formatted[] = trim($tmpLine);
+ $tmpLine = '';
+ $tmpLineLength = 0;
+ if ($nextChar === ' ') {
+ $i++;
+ }
+ } else {
+ $lastSpace = strrpos($tmpLine, ' ');
+ if ($lastSpace === false) {
+ continue;
+ }
+ $formatted[] = trim(substr($tmpLine, 0, $lastSpace));
+ $tmpLine = substr($tmpLine, $lastSpace + 1);
+
+ $tmpLineLength = strlen($tmpLine);
+ }
+ }
+ }
+ if (!empty($tmpLine)) {
+ $formatted[] = $tmpLine;
+ }
+ }
+ $formatted[] = '';
+ return $formatted;
+ }
+
+/**
+ * Create unique boundary identifier
+ *
+ * @return void
+ */
+ protected function _createBoundary() {
+ if (!empty($this->_attachments) || $this->_emailFormat === 'both') {
+ $this->_boundary = md5(uniqid(time()));
+ }
+ }
+
+/**
+ * Attach non-embedded files by adding file contents inside boundaries.
+ *
+ * @param string $boundary Boundary to use. If null, will default to $this->_boundary
+ * @return array An array of lines to add to the message
+ */
+ protected function _attachFiles($boundary = null) {
+ if ($boundary === null) {
+ $boundary = $this->_boundary;
+ }
+
+ $msg = array();
+ foreach ($this->_attachments as $filename => $fileInfo) {
+ if (!empty($fileInfo['contentId'])) {
+ continue;
+ }
+ $data = $this->_readFile($fileInfo['file']);
+
+ $msg[] = '--' . $boundary;
+ $msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
+ $msg[] = 'Content-Transfer-Encoding: base64';
+ $msg[] = 'Content-Disposition: attachment; filename="' . $filename . '"';
+ $msg[] = '';
+ $msg[] = $data;
+ $msg[] = '';
+ }
+ return $msg;
+ }
+
+/**
+ * Read the file contents and return a base64 version of the file contents.
+ *
+ * @param string $file The file to read.
+ * @return string File contents in base64 encoding
+ */
+ protected function _readFile($file) {
+ $handle = fopen($file, 'rb');
+ $data = fread($handle, filesize($file));
+ $data = chunk_split(base64_encode($data));
+ fclose($handle);
+ return $data;
+ }
+
+/**
+ * Attach inline/embedded files to the message.
+ *
+ * @param string $boundary Boundary to use. If null, will default to $this->_boundary
+ * @return array An array of lines to add to the message
+ */
+ protected function _attachInlineFiles($boundary = null) {
+ if ($boundary === null) {
+ $boundary = $this->_boundary;
+ }
+
+ $msg = array();
+ foreach ($this->_attachments as $filename => $fileInfo) {
+ if (empty($fileInfo['contentId'])) {
+ continue;
+ }
+ $data = $this->_readFile($fileInfo['file']);
+
+ $msg[] = '--' . $boundary;
+ $msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
+ $msg[] = 'Content-Transfer-Encoding: base64';
+ $msg[] = 'Content-ID: <' . $fileInfo['contentId'] . '>';
+ $msg[] = 'Content-Disposition: inline; filename="' . $filename . '"';
+ $msg[] = '';
+ $msg[] = $data;
+ $msg[] = '';
+ }
+ return $msg;
+ }
+
+/**
+ * Render the body of the email.
+ *
+ * @param string $content Content to render
+ * @return array Email body ready to be sent
+ */
+ protected function _render($content) {
+ $content = implode("\n", $content);
+ $rendered = $this->_renderTemplates($content);
+
+ $msg = array();
+
+ $contentIds = array_filter((array)Hash::extract($this->_attachments, '{s}.contentId'));
+ $hasInlineAttachments = count($contentIds) > 0;
+ $hasAttachments = !empty($this->_attachments);
+ $hasMultipleTypes = count($rendered) > 1;
+
+ $boundary = $relBoundary = $textBoundary = $this->_boundary;
+
+ if ($hasInlineAttachments) {
+ $msg[] = '--' . $boundary;
+ $msg[] = 'Content-Type: multipart/related; boundary="rel-' . $boundary . '"';
+ $msg[] = '';
+ $relBoundary = $textBoundary = 'rel-' . $boundary;
+ }
+
+ if ($hasMultipleTypes) {
+ $msg[] = '--' . $relBoundary;
+ $msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $boundary . '"';
+ $msg[] = '';
+ $textBoundary = 'alt-' . $boundary;
+ }
+
+ if (isset($rendered['text'])) {
+ if ($textBoundary !== $boundary || $hasAttachments) {
+ $msg[] = '--' . $textBoundary;
+ $msg[] = 'Content-Type: text/plain; charset=' . $this->_getContentTypeCharset();
+ $msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
+ $msg[] = '';
+ }
+ $this->_textMessage = $rendered['text'];
+ $content = explode("\n", $this->_textMessage);
+ $msg = array_merge($msg, $content);
+ $msg[] = '';
+ }
+
+ if (isset($rendered['html'])) {
+ if ($textBoundary !== $boundary || $hasAttachments) {
+ $msg[] = '--' . $textBoundary;
+ $msg[] = 'Content-Type: text/html; charset=' . $this->_getContentTypeCharset();
+ $msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
+ $msg[] = '';
+ }
+ $this->_htmlMessage = $rendered['html'];
+ $content = explode("\n", $this->_htmlMessage);
+ $msg = array_merge($msg, $content);
+ $msg[] = '';
+ }
+
+ if ($hasMultipleTypes) {
+ $msg[] = '--' . $textBoundary . '--';
+ $msg[] = '';
+ }
+
+ if ($hasInlineAttachments) {
+ $attachments = $this->_attachInlineFiles($relBoundary);
+ $msg = array_merge($msg, $attachments);
+ $msg[] = '';
+ $msg[] = '--' . $relBoundary . '--';
+ $msg[] = '';
+ }
+
+ if ($hasAttachments) {
+ $attachments = $this->_attachFiles($boundary);
+ $msg = array_merge($msg, $attachments);
+ }
+ if ($hasAttachments || $hasMultipleTypes) {
+ $msg[] = '';
+ $msg[] = '--' . $boundary . '--';
+ $msg[] = '';
+ }
+ return $msg;
+ }
+
+/**
+ * Gets the text body types that are in this email message
+ *
+ * @return array Array of types. Valid types are 'text' and 'html'
+ */
+ protected function _getTypes() {
+ $types = array($this->_emailFormat);
+ if ($this->_emailFormat == 'both') {
+ $types = array('html', 'text');
+ }
+ return $types;
+ }
+
+/**
+ * Build and set all the view properties needed to render the templated emails.
+ * If there is no template set, the $content will be returned in a hash
+ * of the text content types for the email.
+ *
+ * @param string $content The content passed in from send() in most cases.
+ * @return array The rendered content with html and text keys.
+ */
+ protected function _renderTemplates($content) {
+ $types = $this->_getTypes();
+ $rendered = array();
+ if (empty($this->_template)) {
+ foreach ($types as $type) {
+ $rendered[$type] = $this->_encodeString($content, $this->charset);
+ }
+ return $rendered;
+ }
+ $viewClass = $this->_viewRender;
+ if ($viewClass !== 'View') {
+ list($plugin, $viewClass) = pluginSplit($viewClass, true);
+ $viewClass .= 'View';
+ App::uses($viewClass, $plugin . 'View');
+ }
+
+ $View = new $viewClass(null);
+ $View->viewVars = $this->_viewVars;
+ $View->helpers = $this->_helpers;
+
+ list($templatePlugin, $template) = pluginSplit($this->_template);
+ list($layoutPlugin, $layout) = pluginSplit($this->_layout);
+ if ($templatePlugin) {
+ $View->plugin = $templatePlugin;
+ } elseif ($layoutPlugin) {
+ $View->plugin = $layoutPlugin;
+ }
+ if ($this->_theme) {
+ $View->theme = $this->_theme;
+ }
+
+ foreach ($types as $type) {
+ $View->set('content', $content);
+ $View->hasRendered = false;
+ $View->viewPath = $View->layoutPath = 'Emails' . DS . $type;
+
+ $render = $View->render($template, $layout);
+ $render = str_replace(array("\r\n", "\r"), "\n", $render);
+ $rendered[$type] = $this->_encodeString($render, $this->charset);
+ }
+ return $rendered;
+ }
+
+/**
+ * Return the Content-Transfer Encoding value based on the set charset
+ *
+ * @return void
+ */
+ protected function _getContentTransferEncoding() {
+ $charset = strtoupper($this->charset);
+ if (in_array($charset, $this->_charset8bit)) {
+ return '8bit';
+ }
+ return '7bit';
+ }
+
+/**
+ * Return charset value for Content-Type.
+ *
+ * Checks fallback/compatibility types which include workarounds
+ * for legacy japanese character sets.
+ *
+ * @return string
+ */
+ protected function _getContentTypeCharset() {
+ $charset = strtoupper($this->charset);
+ if (array_key_exists($charset, $this->_contentTypeCharset)) {
+ return strtoupper($this->_contentTypeCharset[$charset]);
+ } else {
+ return strtoupper($this->charset);
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/DebugTransport.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/DebugTransport.php
new file mode 100644
index 0000000..e1f31f1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/DebugTransport.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Emulates the email sending process for testing purposes
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Debug Transport class, useful for emulate the email sending process and inspect the resulted
+ * email message before actually send it during development
+ *
+ * @package Cake.Network.Email
+ */
+class DebugTransport extends AbstractTransport {
+
+/**
+ * Send mail
+ *
+ * @param CakeEmail $email CakeEmail
+ * @return array
+ */
+ public function send(CakeEmail $email) {
+ $headers = $email->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'subject'));
+ $headers = $this->_headersToString($headers);
+ $message = implode("\r\n", (array)$email->message());
+ return array('headers' => $headers, 'message' => $message);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/MailTransport.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/MailTransport.php
new file mode 100644
index 0000000..ae63b76
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/MailTransport.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Send mail using mail() function
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Send mail using mail() function
+ *
+ * @package Cake.Network.Email
+ */
+class MailTransport extends AbstractTransport {
+
+/**
+ * Send mail
+ *
+ * @param CakeEmail $email CakeEmail
+ * @return array
+ * @throws SocketException When mail cannot be sent.
+ */
+ public function send(CakeEmail $email) {
+ $eol = PHP_EOL;
+ if (isset($this->_config['eol'])) {
+ $eol = $this->_config['eol'];
+ }
+ $headers = $email->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'));
+ $to = $headers['To'];
+ unset($headers['To']);
+ $headers = $this->_headersToString($headers, $eol);
+ $message = implode($eol, $email->message());
+ if (ini_get('safe_mode') || !isset($this->_config['additionalParameters'])) {
+ if (!@mail($to, $email->subject(), $message, $headers)) {
+ throw new SocketException(__d('cake_dev', 'Could not send email.'));
+ }
+ } elseif (!@mail($to, $email->subject(), $message, $headers, $this->_config['additionalParameters'])) {
+ throw new SocketException(__d('cake_dev', 'Could not send email.'));
+ }
+ return array('headers' => $headers, 'message' => $message);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/SmtpTransport.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/SmtpTransport.php
new file mode 100644
index 0000000..363e477
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Email/SmtpTransport.php
@@ -0,0 +1,240 @@
+<?php
+/**
+ * Send mail using SMTP protocol
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeSocket', 'Network');
+
+/**
+ * Send mail using SMTP protocol
+ *
+ * @package Cake.Network.Email
+ */
+class SmtpTransport extends AbstractTransport {
+
+/**
+ * Socket to SMTP server
+ *
+ * @var CakeSocket
+ */
+ protected $_socket;
+
+/**
+ * CakeEmail
+ *
+ * @var CakeEmail
+ */
+ protected $_cakeEmail;
+
+/**
+ * Content of email to return
+ *
+ * @var string
+ */
+ protected $_content;
+
+/**
+ * Send mail
+ *
+ * @param CakeEmail $email CakeEmail
+ * @return array
+ * @throws SocketException
+ */
+ public function send(CakeEmail $email) {
+ $this->_cakeEmail = $email;
+
+ $this->_connect();
+ $this->_auth();
+ $this->_sendRcpt();
+ $this->_sendData();
+ $this->_disconnect();
+
+ return $this->_content;
+ }
+
+/**
+ * Set the configuration
+ *
+ * @param array $config
+ * @return void
+ */
+ public function config($config = array()) {
+ $default = array(
+ 'host' => 'localhost',
+ 'port' => 25,
+ 'timeout' => 30,
+ 'username' => null,
+ 'password' => null,
+ 'client' => null
+ );
+ $this->_config = $config + $default;
+ }
+
+/**
+ * Connect to SMTP Server
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _connect() {
+ $this->_generateSocket();
+ if (!$this->_socket->connect()) {
+ throw new SocketException(__d('cake_dev', 'Unable to connect to SMTP server.'));
+ }
+ $this->_smtpSend(null, '220');
+
+ if (isset($this->_config['client'])) {
+ $host = $this->_config['client'];
+ } elseif ($httpHost = env('HTTP_HOST')) {
+ list($host) = explode(':', $httpHost);
+ } else {
+ $host = 'localhost';
+ }
+
+ try {
+ $this->_smtpSend("EHLO {$host}", '250');
+ } catch (SocketException $e) {
+ try {
+ $this->_smtpSend("HELO {$host}", '250');
+ } catch (SocketException $e2) {
+ throw new SocketException(__d('cake_dev', 'SMTP server did not accept the connection.'));
+ }
+ }
+ }
+
+/**
+ * Send authentication
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _auth() {
+ if (isset($this->_config['username']) && isset($this->_config['password'])) {
+ $authRequired = $this->_smtpSend('AUTH LOGIN', '334|503');
+ if ($authRequired == '334') {
+ if (!$this->_smtpSend(base64_encode($this->_config['username']), '334')) {
+ throw new SocketException(__d('cake_dev', 'SMTP server did not accept the username.'));
+ }
+ if (!$this->_smtpSend(base64_encode($this->_config['password']), '235')) {
+ throw new SocketException(__d('cake_dev', 'SMTP server did not accept the password.'));
+ }
+ } elseif ($authRequired != '503') {
+ throw new SocketException(__d('cake_dev', 'SMTP does not require authentication.'));
+ }
+ }
+ }
+
+/**
+ * Send emails
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _sendRcpt() {
+ $from = $this->_cakeEmail->from();
+ $this->_smtpSend('MAIL FROM:<' . key($from) . '>');
+
+ $to = $this->_cakeEmail->to();
+ $cc = $this->_cakeEmail->cc();
+ $bcc = $this->_cakeEmail->bcc();
+ $emails = array_merge(array_keys($to), array_keys($cc), array_keys($bcc));
+ foreach ($emails as $email) {
+ $this->_smtpSend('RCPT TO:<' . $email . '>');
+ }
+ }
+
+/**
+ * Send Data
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _sendData() {
+ $this->_smtpSend('DATA', '354');
+
+ $headers = $this->_cakeEmail->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'subject'));
+ $headers = $this->_headersToString($headers);
+ $lines = $this->_cakeEmail->message();
+ $messages = array();
+ foreach ($lines as $line) {
+ if ((!empty($line)) && ($line[0] === '.')) {
+ $messages[] = '.' . $line;
+ } else {
+ $messages[] = $line;
+ }
+ }
+ $message = implode("\r\n", $messages);
+ $this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n.");
+ $this->_content = array('headers' => $headers, 'message' => $message);
+ }
+
+/**
+ * Disconnect
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _disconnect() {
+ $this->_smtpSend('QUIT', false);
+ $this->_socket->disconnect();
+ }
+
+/**
+ * Helper method to generate socket
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _generateSocket() {
+ $this->_socket = new CakeSocket($this->_config);
+ }
+
+/**
+ * Protected method for sending data to SMTP connection
+ *
+ * @param string $data data to be sent to SMTP server
+ * @param string|boolean $checkCode code to check for in server response, false to skip
+ * @return void
+ * @throws SocketException
+ */
+ protected function _smtpSend($data, $checkCode = '250') {
+ if (!is_null($data)) {
+ $this->_socket->write($data . "\r\n");
+ }
+ while ($checkCode !== false) {
+ $response = '';
+ $startTime = time();
+ while (substr($response, -2) !== "\r\n" && ((time() - $startTime) < $this->_config['timeout'])) {
+ $response .= $this->_socket->read();
+ }
+ if (substr($response, -2) !== "\r\n") {
+ throw new SocketException(__d('cake_dev', 'SMTP timeout.'));
+ }
+ $responseLines = explode("\r\n", rtrim($response, "\r\n"));
+ $response = end($responseLines);
+
+ if (preg_match('/^(' . $checkCode . ')(.)/', $response, $code)) {
+ if ($code[2] === '-') {
+ continue;
+ }
+ return $code[1];
+ }
+ throw new SocketException(__d('cake_dev', 'SMTP Error: %s', $response));
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/BasicAuthentication.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/BasicAuthentication.php
new file mode 100644
index 0000000..c39b2ee
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/BasicAuthentication.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Basic authentication
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Http
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Basic authentication
+ *
+ * @package Cake.Network.Http
+ */
+class BasicAuthentication {
+
+/**
+ * Authentication
+ *
+ * @param HttpSocket $http
+ * @param array $authInfo
+ * @return void
+ * @see http://www.ietf.org/rfc/rfc2617.txt
+ */
+ public static function authentication(HttpSocket $http, &$authInfo) {
+ if (isset($authInfo['user'], $authInfo['pass'])) {
+ $http->request['header']['Authorization'] = self::_generateHeader($authInfo['user'], $authInfo['pass']);
+ }
+ }
+
+/**
+ * Proxy Authentication
+ *
+ * @param HttpSocket $http
+ * @param array $proxyInfo
+ * @return void
+ * @see http://www.ietf.org/rfc/rfc2617.txt
+ */
+ public static function proxyAuthentication(HttpSocket $http, &$proxyInfo) {
+ if (isset($proxyInfo['user'], $proxyInfo['pass'])) {
+ $http->request['header']['Proxy-Authorization'] = self::_generateHeader($proxyInfo['user'], $proxyInfo['pass']);
+ }
+ }
+
+/**
+ * Generate basic [proxy] authentication header
+ *
+ * @param string $user
+ * @param string $pass
+ * @return string
+ */
+ protected static function _generateHeader($user, $pass) {
+ return 'Basic ' . base64_encode($user . ':' . $pass);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/DigestAuthentication.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/DigestAuthentication.php
new file mode 100644
index 0000000..5518ce9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/DigestAuthentication.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Digest authentication
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Http
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Digest authentication
+ *
+ * @package Cake.Network.Http
+ */
+class DigestAuthentication {
+
+/**
+ * Authentication
+ *
+ * @param HttpSocket $http
+ * @param array $authInfo
+ * @return void
+ * @link http://www.ietf.org/rfc/rfc2617.txt
+ */
+ public static function authentication(HttpSocket $http, &$authInfo) {
+ if (isset($authInfo['user'], $authInfo['pass'])) {
+ if (!isset($authInfo['realm']) && !self::_getServerInformation($http, $authInfo)) {
+ return;
+ }
+ $http->request['header']['Authorization'] = self::_generateHeader($http, $authInfo);
+ }
+ }
+
+/**
+ * Retrieve information about the authentication
+ *
+ * @param HttpSocket $http
+ * @param array $authInfo
+ * @return boolean
+ */
+ protected static function _getServerInformation(HttpSocket $http, &$authInfo) {
+ $originalRequest = $http->request;
+ $http->configAuth(false);
+ $http->request($http->request);
+ $http->request = $originalRequest;
+ $http->configAuth('Digest', $authInfo);
+
+ if (empty($http->response['header']['WWW-Authenticate'])) {
+ return false;
+ }
+ preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $http->response['header']['WWW-Authenticate'], $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $authInfo[$match[1]] = $match[2];
+ }
+ if (!empty($authInfo['qop']) && empty($authInfo['nc'])) {
+ $authInfo['nc'] = 1;
+ }
+ return true;
+ }
+
+/**
+ * Generate the header Authorization
+ *
+ * @param HttpSocket $http
+ * @param array $authInfo
+ * @return string
+ */
+ protected static function _generateHeader(HttpSocket $http, &$authInfo) {
+ $a1 = md5($authInfo['user'] . ':' . $authInfo['realm'] . ':' . $authInfo['pass']);
+ $a2 = md5($http->request['method'] . ':' . $http->request['uri']['path']);
+
+ if (empty($authInfo['qop'])) {
+ $response = md5($a1 . ':' . $authInfo['nonce'] . ':' . $a2);
+ } else {
+ $authInfo['cnonce'] = uniqid();
+ $nc = sprintf('%08x', $authInfo['nc']++);
+ $response = md5($a1 . ':' . $authInfo['nonce'] . ':' . $nc . ':' . $authInfo['cnonce'] . ':auth:' . $a2);
+ }
+
+ $authHeader = 'Digest ';
+ $authHeader .= 'username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $authInfo['user']) . '", ';
+ $authHeader .= 'realm="' . $authInfo['realm'] . '", ';
+ $authHeader .= 'nonce="' . $authInfo['nonce'] . '", ';
+ $authHeader .= 'uri="' . $http->request['uri']['path'] . '", ';
+ $authHeader .= 'response="' . $response . '"';
+ if (!empty($authInfo['opaque'])) {
+ $authHeader .= ', opaque="' . $authInfo['opaque'] . '"';
+ }
+ if (!empty($authInfo['qop'])) {
+ $authHeader .= ', qop="auth", nc=' . $nc . ', cnonce="' . $authInfo['cnonce'] . '"';
+ }
+ return $authHeader;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpResponse.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpResponse.php
new file mode 100644
index 0000000..dec5070
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpResponse.php
@@ -0,0 +1,448 @@
+<?php
+/**
+ * HTTP Response from HttpSocket.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Http
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * HTTP Response from HttpSocket.
+ *
+ * @package Cake.Network.Http
+ */
+class HttpResponse implements ArrayAccess {
+
+/**
+ * Body content
+ *
+ * @var string
+ */
+ public $body = '';
+
+/**
+ * Headers
+ *
+ * @var array
+ */
+ public $headers = array();
+
+/**
+ * Cookies
+ *
+ * @var array
+ */
+ public $cookies = array();
+
+/**
+ * HTTP version
+ *
+ * @var string
+ */
+ public $httpVersion = 'HTTP/1.1';
+
+/**
+ * Response code
+ *
+ * @var integer
+ */
+ public $code = 0;
+
+/**
+ * Reason phrase
+ *
+ * @var string
+ */
+ public $reasonPhrase = '';
+
+/**
+ * Pure raw content
+ *
+ * @var string
+ */
+ public $raw = '';
+
+/**
+ * Constructor
+ *
+ * @param string $message
+ */
+ public function __construct($message = null) {
+ if ($message !== null) {
+ $this->parseResponse($message);
+ }
+ }
+
+/**
+ * Body content
+ *
+ * @return string
+ */
+ public function body() {
+ return (string)$this->body;
+ }
+
+/**
+ * Get header in case insensitive
+ *
+ * @param string $name Header name
+ * @param array $headers
+ * @return mixed String if header exists or null
+ */
+ public function getHeader($name, $headers = null) {
+ if (!is_array($headers)) {
+ $headers =& $this->headers;
+ }
+ if (isset($headers[$name])) {
+ return $headers[$name];
+ }
+ foreach ($headers as $key => $value) {
+ if (strcasecmp($key, $name) == 0) {
+ return $value;
+ }
+ }
+ return null;
+ }
+
+/**
+ * If return is 200 (OK)
+ *
+ * @return boolean
+ */
+ public function isOk() {
+ return $this->code == 200;
+ }
+
+/**
+ * If return is a valid 3xx (Redirection)
+ *
+ * @return boolean
+ */
+ public function isRedirect() {
+ return in_array($this->code, array(301, 302, 303, 307)) && !is_null($this->getHeader('Location'));
+ }
+
+/**
+ * Parses the given message and breaks it down in parts.
+ *
+ * @param string $message Message to parse
+ * @return void
+ * @throws SocketException
+ */
+ public function parseResponse($message) {
+ if (!is_string($message)) {
+ throw new SocketException(__d('cake_dev', 'Invalid response.'));
+ }
+
+ if (!preg_match("/^(.+\r\n)(.*)(?<=\r\n)\r\n/Us", $message, $match)) {
+ throw new SocketException(__d('cake_dev', 'Invalid HTTP response.'));
+ }
+
+ list(, $statusLine, $header) = $match;
+ $this->raw = $message;
+ $this->body = (string)substr($message, strlen($match[0]));
+
+ if (preg_match("/(.+) ([0-9]{3}) (.+)\r\n/DU", $statusLine, $match)) {
+ $this->httpVersion = $match[1];
+ $this->code = $match[2];
+ $this->reasonPhrase = $match[3];
+ }
+
+ $this->headers = $this->_parseHeader($header);
+ $transferEncoding = $this->getHeader('Transfer-Encoding');
+ $decoded = $this->_decodeBody($this->body, $transferEncoding);
+ $this->body = $decoded['body'];
+
+ if (!empty($decoded['header'])) {
+ $this->headers = $this->_parseHeader($this->_buildHeader($this->headers) . $this->_buildHeader($decoded['header']));
+ }
+
+ if (!empty($this->headers)) {
+ $this->cookies = $this->parseCookies($this->headers);
+ }
+ }
+
+/**
+ * Generic function to decode a $body with a given $encoding. Returns either an array with the keys
+ * 'body' and 'header' or false on failure.
+ *
+ * @param string $body A string containing the body to decode.
+ * @param string|boolean $encoding Can be false in case no encoding is being used, or a string representing the encoding.
+ * @return mixed Array of response headers and body or false.
+ */
+ protected function _decodeBody($body, $encoding = 'chunked') {
+ if (!is_string($body)) {
+ return false;
+ }
+ if (empty($encoding)) {
+ return array('body' => $body, 'header' => false);
+ }
+ $decodeMethod = '_decode' . Inflector::camelize(str_replace('-', '_', $encoding)) . 'Body';
+
+ if (!is_callable(array(&$this, $decodeMethod))) {
+ return array('body' => $body, 'header' => false);
+ }
+ return $this->{$decodeMethod}($body);
+ }
+
+/**
+ * Decodes a chunked message $body and returns either an array with the keys 'body' and 'header' or false as
+ * a result.
+ *
+ * @param string $body A string containing the chunked body to decode.
+ * @return mixed Array of response headers and body or false.
+ * @throws SocketException
+ */
+ protected function _decodeChunkedBody($body) {
+ if (!is_string($body)) {
+ return false;
+ }
+
+ $decodedBody = null;
+ $chunkLength = null;
+
+ while ($chunkLength !== 0) {
+ if (!preg_match('/^([0-9a-f]+) *(?:;(.+)=(.+))?(?:\r\n|\n)/iU', $body, $match)) {
+ throw new SocketException(__d('cake_dev', 'HttpSocket::_decodeChunkedBody - Could not parse malformed chunk.'));
+ }
+
+ $chunkSize = 0;
+ $hexLength = 0;
+ $chunkExtensionName = '';
+ $chunkExtensionValue = '';
+ if (isset($match[0])) {
+ $chunkSize = $match[0];
+ }
+ if (isset($match[1])) {
+ $hexLength = $match[1];
+ }
+ if (isset($match[2])) {
+ $chunkExtensionName = $match[2];
+ }
+ if (isset($match[3])) {
+ $chunkExtensionValue = $match[3];
+ }
+
+ $body = substr($body, strlen($chunkSize));
+ $chunkLength = hexdec($hexLength);
+ $chunk = substr($body, 0, $chunkLength);
+ if (!empty($chunkExtensionName)) {
+ // @todo See if there are popular chunk extensions we should implement
+ }
+ $decodedBody .= $chunk;
+ if ($chunkLength !== 0) {
+ $body = substr($body, $chunkLength + strlen("\r\n"));
+ }
+ }
+
+ $entityHeader = false;
+ if (!empty($body)) {
+ $entityHeader = $this->_parseHeader($body);
+ }
+ return array('body' => $decodedBody, 'header' => $entityHeader);
+ }
+
+/**
+ * Parses an array based header.
+ *
+ * @param array $header Header as an indexed array (field => value)
+ * @return array Parsed header
+ */
+ protected function _parseHeader($header) {
+ if (is_array($header)) {
+ return $header;
+ } elseif (!is_string($header)) {
+ return false;
+ }
+
+ preg_match_all("/(.+):(.+)(?:(?<![\t ])\r\n|\$)/Uis", $header, $matches, PREG_SET_ORDER);
+
+ $header = array();
+ foreach ($matches as $match) {
+ list(, $field, $value) = $match;
+
+ $value = trim($value);
+ $value = preg_replace("/[\t ]\r\n/", "\r\n", $value);
+
+ $field = $this->_unescapeToken($field);
+
+ if (!isset($header[$field])) {
+ $header[$field] = $value;
+ } else {
+ $header[$field] = array_merge((array)$header[$field], (array)$value);
+ }
+ }
+ return $header;
+ }
+
+/**
+ * Parses cookies in response headers.
+ *
+ * @param array $header Header array containing one ore more 'Set-Cookie' headers.
+ * @return mixed Either false on no cookies, or an array of cookies received.
+ * @todo Make this 100% RFC 2965 confirm
+ */
+ public function parseCookies($header) {
+ $cookieHeader = $this->getHeader('Set-Cookie', $header);
+ if (!$cookieHeader) {
+ return false;
+ }
+
+ $cookies = array();
+ foreach ((array)$cookieHeader as $cookie) {
+ if (strpos($cookie, '";"') !== false) {
+ $cookie = str_replace('";"', "{__cookie_replace__}", $cookie);
+ $parts = str_replace("{__cookie_replace__}", '";"', explode(';', $cookie));
+ } else {
+ $parts = preg_split('/\;[ \t]*/', $cookie);
+ }
+
+ list($name, $value) = explode('=', array_shift($parts), 2);
+ $cookies[$name] = compact('value');
+
+ foreach ($parts as $part) {
+ if (strpos($part, '=') !== false) {
+ list($key, $value) = explode('=', $part);
+ } else {
+ $key = $part;
+ $value = true;
+ }
+
+ $key = strtolower($key);
+ if (!isset($cookies[$name][$key])) {
+ $cookies[$name][$key] = $value;
+ }
+ }
+ }
+ return $cookies;
+ }
+
+/**
+ * Unescapes a given $token according to RFC 2616 (HTTP 1.1 specs)
+ *
+ * @param string $token Token to unescape
+ * @param array $chars
+ * @return string Unescaped token
+ * @todo Test $chars parameter
+ */
+ protected function _unescapeToken($token, $chars = null) {
+ $regex = '/"([' . implode('', $this->_tokenEscapeChars(true, $chars)) . '])"/';
+ $token = preg_replace($regex, '\\1', $token);
+ return $token;
+ }
+
+/**
+ * Gets escape chars according to RFC 2616 (HTTP 1.1 specs).
+ *
+ * @param boolean $hex true to get them as HEX values, false otherwise
+ * @param array $chars
+ * @return array Escape chars
+ * @todo Test $chars parameter
+ */
+ protected function _tokenEscapeChars($hex = true, $chars = null) {
+ if (!empty($chars)) {
+ $escape = $chars;
+ } else {
+ $escape = array('"', "(", ")", "<", ">", "@", ",", ";", ":", "\\", "/", "[", "]", "?", "=", "{", "}", " ");
+ for ($i = 0; $i <= 31; $i++) {
+ $escape[] = chr($i);
+ }
+ $escape[] = chr(127);
+ }
+
+ if ($hex == false) {
+ return $escape;
+ }
+ foreach ($escape as $key => $char) {
+ $escape[$key] = '\\x' . str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
+ }
+ return $escape;
+ }
+
+/**
+ * ArrayAccess - Offset Exists
+ *
+ * @param string $offset
+ * @return boolean
+ */
+ public function offsetExists($offset) {
+ return in_array($offset, array('raw', 'status', 'header', 'body', 'cookies'));
+ }
+
+/**
+ * ArrayAccess - Offset Get
+ *
+ * @param string $offset
+ * @return mixed
+ */
+ public function offsetGet($offset) {
+ switch ($offset) {
+ case 'raw':
+ $firstLineLength = strpos($this->raw, "\r\n") + 2;
+ if ($this->raw[$firstLineLength] === "\r") {
+ $header = null;
+ } else {
+ $header = substr($this->raw, $firstLineLength, strpos($this->raw, "\r\n\r\n") - $firstLineLength) . "\r\n";
+ }
+ return array(
+ 'status-line' => $this->httpVersion . ' ' . $this->code . ' ' . $this->reasonPhrase . "\r\n",
+ 'header' => $header,
+ 'body' => $this->body,
+ 'response' => $this->raw
+ );
+ case 'status':
+ return array(
+ 'http-version' => $this->httpVersion,
+ 'code' => $this->code,
+ 'reason-phrase' => $this->reasonPhrase
+ );
+ case 'header':
+ return $this->headers;
+ case 'body':
+ return $this->body;
+ case 'cookies':
+ return $this->cookies;
+ }
+ return null;
+ }
+
+/**
+ * ArrayAccess - Offset Set
+ *
+ * @param string $offset
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($offset, $value) {
+ }
+
+/**
+ * ArrayAccess - Offset Unset
+ *
+ * @param string $offset
+ * @return void
+ */
+ public function offsetUnset($offset) {
+ }
+
+/**
+ * Instance as string
+ *
+ * @return string
+ */
+ public function __toString() {
+ return $this->body();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpSocket.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpSocket.php
new file mode 100644
index 0000000..5025056
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Network/Http/HttpSocket.php
@@ -0,0 +1,977 @@
+<?php
+/**
+ * HTTP Socket connection class.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Network.Http
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeSocket', 'Network');
+App::uses('Router', 'Routing');
+
+/**
+ * Cake network socket connection class.
+ *
+ * Core base class for HTTP network communication. HttpSocket can be used as an
+ * Object Oriented replacement for cURL in many places.
+ *
+ * @package Cake.Network.Http
+ */
+class HttpSocket extends CakeSocket {
+
+/**
+ * When one activates the $quirksMode by setting it to true, all checks meant to
+ * enforce RFC 2616 (HTTP/1.1 specs).
+ * will be disabled and additional measures to deal with non-standard responses will be enabled.
+ *
+ * @var boolean
+ */
+ public $quirksMode = false;
+
+/**
+ * Contain information about the last request (read only)
+ *
+ * @var array
+ */
+ public $request = array(
+ 'method' => 'GET',
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => null,
+ 'port' => 80,
+ 'user' => null,
+ 'pass' => null,
+ 'path' => null,
+ 'query' => null,
+ 'fragment' => null
+ ),
+ 'version' => '1.1',
+ 'body' => '',
+ 'line' => null,
+ 'header' => array(
+ 'Connection' => 'close',
+ 'User-Agent' => 'CakePHP'
+ ),
+ 'raw' => null,
+ 'redirect' => false,
+ 'cookies' => array()
+ );
+
+/**
+ * Contain information about the last response (read only)
+ *
+ * @var array
+ */
+ public $response = null;
+
+/**
+ * Response classname
+ *
+ * @var string
+ */
+ public $responseClass = 'HttpResponse';
+
+/**
+ * Configuration settings for the HttpSocket and the requests
+ *
+ * @var array
+ */
+ public $config = array(
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'protocol' => 'tcp',
+ 'port' => 80,
+ 'timeout' => 30,
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => array('http', 'https'),
+ 'host' => 'localhost',
+ 'port' => array(80, 443)
+ ),
+ 'redirect' => false,
+ 'cookies' => array()
+ )
+ );
+
+/**
+ * Authentication settings
+ *
+ * @var array
+ */
+ protected $_auth = array();
+
+/**
+ * Proxy settings
+ *
+ * @var array
+ */
+ protected $_proxy = array();
+
+/**
+ * Resource to receive the content of request
+ *
+ * @var mixed
+ */
+ protected $_contentResource = null;
+
+/**
+ * Build an HTTP Socket using the specified configuration.
+ *
+ * You can use a url string to set the url and use default configurations for
+ * all other options:
+ *
+ * `$http = new HttpSocket('http://cakephp.org/');`
+ *
+ * Or use an array to configure multiple options:
+ *
+ * {{{
+ * $http = new HttpSocket(array(
+ * 'host' => 'cakephp.org',
+ * 'timeout' => 20
+ * ));
+ * }}}
+ *
+ * See HttpSocket::$config for options that can be used.
+ *
+ * @param string|array $config Configuration information, either a string url or an array of options.
+ */
+ public function __construct($config = array()) {
+ if (is_string($config)) {
+ $this->_configUri($config);
+ } elseif (is_array($config)) {
+ if (isset($config['request']['uri']) && is_string($config['request']['uri'])) {
+ $this->_configUri($config['request']['uri']);
+ unset($config['request']['uri']);
+ }
+ $this->config = Hash::merge($this->config, $config);
+ }
+ parent::__construct($this->config);
+ }
+
+/**
+ * Set authentication settings.
+ *
+ * Accepts two forms of parameters. If all you need is a username + password, as with
+ * Basic authentication you can do the following:
+ *
+ * {{{
+ * $http->configAuth('Basic', 'mark', 'secret');
+ * }}}
+ *
+ * If you are using an authentication strategy that requires more inputs, like Digest authentication
+ * you can call `configAuth()` with an array of user information.
+ *
+ * {{{
+ * $http->configAuth('Digest', array(
+ * 'user' => 'mark',
+ * 'pass' => 'secret',
+ * 'realm' => 'my-realm',
+ * 'nonce' => 1235
+ * ));
+ * }}}
+ *
+ * To remove any set authentication strategy, call `configAuth()` with no parameters:
+ *
+ * `$http->configAuth();`
+ *
+ * @param string $method Authentication method (ie. Basic, Digest). If empty, disable authentication
+ * @param string|array $user Username for authentication. Can be an array with settings to authentication class
+ * @param string $pass Password for authentication
+ * @return void
+ */
+ public function configAuth($method, $user = null, $pass = null) {
+ if (empty($method)) {
+ $this->_auth = array();
+ return;
+ }
+ if (is_array($user)) {
+ $this->_auth = array($method => $user);
+ return;
+ }
+ $this->_auth = array($method => compact('user', 'pass'));
+ }
+
+/**
+ * Set proxy settings
+ *
+ * @param string|array $host Proxy host. Can be an array with settings to authentication class
+ * @param integer $port Port. Default 3128.
+ * @param string $method Proxy method (ie, Basic, Digest). If empty, disable proxy authentication
+ * @param string $user Username if your proxy need authentication
+ * @param string $pass Password to proxy authentication
+ * @return void
+ */
+ public function configProxy($host, $port = 3128, $method = null, $user = null, $pass = null) {
+ if (empty($host)) {
+ $this->_proxy = array();
+ return;
+ }
+ if (is_array($host)) {
+ $this->_proxy = $host + array('host' => null);
+ return;
+ }
+ $this->_proxy = compact('host', 'port', 'method', 'user', 'pass');
+ }
+
+/**
+ * Set the resource to receive the request content. This resource must support fwrite.
+ *
+ * @param resource|boolean $resource Resource or false to disable the resource use
+ * @return void
+ * @throws SocketException
+ */
+ public function setContentResource($resource) {
+ if ($resource === false) {
+ $this->_contentResource = null;
+ return;
+ }
+ if (!is_resource($resource)) {
+ throw new SocketException(__d('cake_dev', 'Invalid resource.'));
+ }
+ $this->_contentResource = $resource;
+ }
+
+/**
+ * Issue the specified request. HttpSocket::get() and HttpSocket::post() wrap this
+ * method and provide a more granular interface.
+ *
+ * @param string|array $request Either an URI string, or an array defining host/uri
+ * @return mixed false on error, HttpResponse on success
+ * @throws SocketException
+ */
+ public function request($request = array()) {
+ $this->reset(false);
+
+ if (is_string($request)) {
+ $request = array('uri' => $request);
+ } elseif (!is_array($request)) {
+ return false;
+ }
+
+ if (!isset($request['uri'])) {
+ $request['uri'] = null;
+ }
+ $uri = $this->_parseUri($request['uri']);
+ if (!isset($uri['host'])) {
+ $host = $this->config['host'];
+ }
+ if (isset($request['host'])) {
+ $host = $request['host'];
+ unset($request['host']);
+ }
+ $request['uri'] = $this->url($request['uri']);
+ $request['uri'] = $this->_parseUri($request['uri'], true);
+ $this->request = Hash::merge($this->request, array_diff_key($this->config['request'], array('cookies' => true)), $request);
+
+ $this->_configUri($this->request['uri']);
+
+ $Host = $this->request['uri']['host'];
+ if (!empty($this->config['request']['cookies'][$Host])) {
+ if (!isset($this->request['cookies'])) {
+ $this->request['cookies'] = array();
+ }
+ if (!isset($request['cookies'])) {
+ $request['cookies'] = array();
+ }
+ $this->request['cookies'] = array_merge($this->request['cookies'], $this->config['request']['cookies'][$Host], $request['cookies']);
+ }
+
+ if (isset($host)) {
+ $this->config['host'] = $host;
+ }
+ $this->_setProxy();
+ $this->request['proxy'] = $this->_proxy;
+
+ $cookies = null;
+
+ if (is_array($this->request['header'])) {
+ if (!empty($this->request['cookies'])) {
+ $cookies = $this->buildCookies($this->request['cookies']);
+ }
+ $scheme = '';
+ $port = 0;
+ if (isset($this->request['uri']['scheme'])) {
+ $scheme = $this->request['uri']['scheme'];
+ }
+ if (isset($this->request['uri']['port'])) {
+ $port = $this->request['uri']['port'];
+ }
+ if (
+ ($scheme === 'http' && $port != 80) ||
+ ($scheme === 'https' && $port != 443) ||
+ ($port != 80 && $port != 443)
+ ) {
+ $Host .= ':' . $port;
+ }
+ $this->request['header'] = array_merge(compact('Host'), $this->request['header']);
+ }
+
+ if (isset($this->request['uri']['user'], $this->request['uri']['pass'])) {
+ $this->configAuth('Basic', $this->request['uri']['user'], $this->request['uri']['pass']);
+ }
+ $this->_setAuth();
+ $this->request['auth'] = $this->_auth;
+
+ if (is_array($this->request['body'])) {
+ $this->request['body'] = http_build_query($this->request['body']);
+ }
+
+ if (!empty($this->request['body']) && !isset($this->request['header']['Content-Type'])) {
+ $this->request['header']['Content-Type'] = 'application/x-www-form-urlencoded';
+ }
+
+ if (!empty($this->request['body']) && !isset($this->request['header']['Content-Length'])) {
+ $this->request['header']['Content-Length'] = strlen($this->request['body']);
+ }
+
+ $connectionType = null;
+ if (isset($this->request['header']['Connection'])) {
+ $connectionType = $this->request['header']['Connection'];
+ }
+ $this->request['header'] = $this->_buildHeader($this->request['header']) . $cookies;
+
+ if (empty($this->request['line'])) {
+ $this->request['line'] = $this->_buildRequestLine($this->request);
+ }
+
+ if ($this->quirksMode === false && $this->request['line'] === false) {
+ return false;
+ }
+
+ $this->request['raw'] = '';
+ if ($this->request['line'] !== false) {
+ $this->request['raw'] = $this->request['line'];
+ }
+
+ if ($this->request['header'] !== false) {
+ $this->request['raw'] .= $this->request['header'];
+ }
+
+ $this->request['raw'] .= "\r\n";
+ $this->request['raw'] .= $this->request['body'];
+ $this->write($this->request['raw']);
+
+ $response = null;
+ $inHeader = true;
+ while ($data = $this->read()) {
+ if ($this->_contentResource) {
+ if ($inHeader) {
+ $response .= $data;
+ $pos = strpos($response, "\r\n\r\n");
+ if ($pos !== false) {
+ $pos += 4;
+ $data = substr($response, $pos);
+ fwrite($this->_contentResource, $data);
+
+ $response = substr($response, 0, $pos);
+ $inHeader = false;
+ }
+ } else {
+ fwrite($this->_contentResource, $data);
+ fflush($this->_contentResource);
+ }
+ } else {
+ $response .= $data;
+ }
+ }
+
+ if ($connectionType === 'close') {
+ $this->disconnect();
+ }
+
+ list($plugin, $responseClass) = pluginSplit($this->responseClass, true);
+ App::uses($responseClass, $plugin . 'Network/Http');
+ if (!class_exists($responseClass)) {
+ throw new SocketException(__d('cake_dev', 'Class %s not found.', $this->responseClass));
+ }
+ $this->response = new $responseClass($response);
+ if (!empty($this->response->cookies)) {
+ if (!isset($this->config['request']['cookies'][$Host])) {
+ $this->config['request']['cookies'][$Host] = array();
+ }
+ $this->config['request']['cookies'][$Host] = array_merge($this->config['request']['cookies'][$Host], $this->response->cookies);
+ }
+
+ if ($this->request['redirect'] && $this->response->isRedirect()) {
+ $request['uri'] = $this->response->getHeader('Location');
+ $request['redirect'] = is_int($this->request['redirect']) ? $this->request['redirect'] - 1 : $this->request['redirect'];
+ $this->response = $this->request($request);
+ }
+
+ return $this->response;
+ }
+
+/**
+ * Issues a GET request to the specified URI, query, and request.
+ *
+ * Using a string uri and an array of query string parameters:
+ *
+ * `$response = $http->get('http://google.com/search', array('q' => 'cakephp', 'client' => 'safari'));`
+ *
+ * Would do a GET request to `http://google.com/search?q=cakephp&client=safari`
+ *
+ * You could express the same thing using a uri array and query string parameters:
+ *
+ * {{{
+ * $response = $http->get(
+ * array('host' => 'google.com', 'path' => '/search'),
+ * array('q' => 'cakephp', 'client' => 'safari')
+ * );
+ * }}}
+ *
+ * @param string|array $uri URI to request. Either a string uri, or a uri array, see HttpSocket::_parseUri()
+ * @param array $query Querystring parameters to append to URI
+ * @param array $request An indexed array with indexes such as 'method' or uri
+ * @return mixed Result of request, either false on failure or the response to the request.
+ */
+ public function get($uri = null, $query = array(), $request = array()) {
+ if (!empty($query)) {
+ $uri = $this->_parseUri($uri, $this->config['request']['uri']);
+ if (isset($uri['query'])) {
+ $uri['query'] = array_merge($uri['query'], $query);
+ } else {
+ $uri['query'] = $query;
+ }
+ $uri = $this->_buildUri($uri);
+ }
+
+ $request = Hash::merge(array('method' => 'GET', 'uri' => $uri), $request);
+ return $this->request($request);
+ }
+
+/**
+ * Issues a POST request to the specified URI, query, and request.
+ *
+ * `post()` can be used to post simple data arrays to a url:
+ *
+ * {{{
+ * $response = $http->post('http://example.com', array(
+ * 'username' => 'batman',
+ * 'password' => 'bruce_w4yne'
+ * ));
+ * }}}
+ *
+ * @param string|array $uri URI to request. See HttpSocket::_parseUri()
+ * @param array $data Array of POST data keys and values.
+ * @param array $request An indexed array with indexes such as 'method' or uri
+ * @return mixed Result of request, either false on failure or the response to the request.
+ */
+ public function post($uri = null, $data = array(), $request = array()) {
+ $request = Hash::merge(array('method' => 'POST', 'uri' => $uri, 'body' => $data), $request);
+ return $this->request($request);
+ }
+
+/**
+ * Issues a PUT request to the specified URI, query, and request.
+ *
+ * @param string|array $uri URI to request, See HttpSocket::_parseUri()
+ * @param array $data Array of PUT data keys and values.
+ * @param array $request An indexed array with indexes such as 'method' or uri
+ * @return mixed Result of request
+ */
+ public function put($uri = null, $data = array(), $request = array()) {
+ $request = Hash::merge(array('method' => 'PUT', 'uri' => $uri, 'body' => $data), $request);
+ return $this->request($request);
+ }
+
+/**
+ * Issues a DELETE request to the specified URI, query, and request.
+ *
+ * @param string|array $uri URI to request (see {@link _parseUri()})
+ * @param array $data Query to append to URI
+ * @param array $request An indexed array with indexes such as 'method' or uri
+ * @return mixed Result of request
+ */
+ public function delete($uri = null, $data = array(), $request = array()) {
+ $request = Hash::merge(array('method' => 'DELETE', 'uri' => $uri, 'body' => $data), $request);
+ return $this->request($request);
+ }
+
+/**
+ * Normalizes urls into a $uriTemplate. If no template is provided
+ * a default one will be used. Will generate the url using the
+ * current config information.
+ *
+ * ### Usage:
+ *
+ * After configuring part of the request parameters, you can use url() to generate
+ * urls.
+ *
+ * {{{
+ * $http = new HttpSocket('http://www.cakephp.org');
+ * $url = $http->url('/search?q=bar');
+ * }}}
+ *
+ * Would return `http://www.cakephp.org/search?q=bar`
+ *
+ * url() can also be used with custom templates:
+ *
+ * `$url = $http->url('http://www.cakephp/search?q=socket', '/%path?%query');`
+ *
+ * Would return `/search?q=socket`.
+ *
+ * @param string|array Either a string or array of url options to create a url with.
+ * @param string $uriTemplate A template string to use for url formatting.
+ * @return mixed Either false on failure or a string containing the composed url.
+ */
+ public function url($url = null, $uriTemplate = null) {
+ if (is_null($url)) {
+ $url = '/';
+ }
+ if (is_string($url)) {
+ $scheme = $this->config['request']['uri']['scheme'];
+ if (is_array($scheme)) {
+ $scheme = $scheme[0];
+ }
+ $port = $this->config['request']['uri']['port'];
+ if (is_array($port)) {
+ $port = $port[0];
+ }
+ if ($url{0} == '/') {
+ $url = $this->config['request']['uri']['host'] . ':' . $port . $url;
+ }
+ if (!preg_match('/^.+:\/\/|\*|^\//', $url)) {
+ $url = $scheme . '://' . $url;
+ }
+ } elseif (!is_array($url) && !empty($url)) {
+ return false;
+ }
+
+ $base = array_merge($this->config['request']['uri'], array('scheme' => array('http', 'https'), 'port' => array(80, 443)));
+ $url = $this->_parseUri($url, $base);
+
+ if (empty($url)) {
+ $url = $this->config['request']['uri'];
+ }
+
+ if (!empty($uriTemplate)) {
+ return $this->_buildUri($url, $uriTemplate);
+ }
+ return $this->_buildUri($url);
+ }
+
+/**
+ * Set authentication in request
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _setAuth() {
+ if (empty($this->_auth)) {
+ return;
+ }
+ $method = key($this->_auth);
+ list($plugin, $authClass) = pluginSplit($method, true);
+ $authClass = Inflector::camelize($authClass) . 'Authentication';
+ App::uses($authClass, $plugin . 'Network/Http');
+
+ if (!class_exists($authClass)) {
+ throw new SocketException(__d('cake_dev', 'Unknown authentication method.'));
+ }
+ if (!method_exists($authClass, 'authentication')) {
+ throw new SocketException(sprintf(__d('cake_dev', 'The %s do not support authentication.'), $authClass));
+ }
+ call_user_func_array("$authClass::authentication", array($this, &$this->_auth[$method]));
+ }
+
+/**
+ * Set the proxy configuration and authentication
+ *
+ * @return void
+ * @throws SocketException
+ */
+ protected function _setProxy() {
+ if (empty($this->_proxy) || !isset($this->_proxy['host'], $this->_proxy['port'])) {
+ return;
+ }
+ $this->config['host'] = $this->_proxy['host'];
+ $this->config['port'] = $this->_proxy['port'];
+
+ if (empty($this->_proxy['method']) || !isset($this->_proxy['user'], $this->_proxy['pass'])) {
+ return;
+ }
+ list($plugin, $authClass) = pluginSplit($this->_proxy['method'], true);
+ $authClass = Inflector::camelize($authClass) . 'Authentication';
+ App::uses($authClass, $plugin . 'Network/Http');
+
+ if (!class_exists($authClass)) {
+ throw new SocketException(__d('cake_dev', 'Unknown authentication method for proxy.'));
+ }
+ if (!method_exists($authClass, 'proxyAuthentication')) {
+ throw new SocketException(sprintf(__d('cake_dev', 'The %s do not support proxy authentication.'), $authClass));
+ }
+ call_user_func_array("$authClass::proxyAuthentication", array($this, &$this->_proxy));
+ }
+
+/**
+ * Parses and sets the specified URI into current request configuration.
+ *
+ * @param string|array $uri URI, See HttpSocket::_parseUri()
+ * @return boolean If uri has merged in config
+ */
+ protected function _configUri($uri = null) {
+ if (empty($uri)) {
+ return false;
+ }
+
+ if (is_array($uri)) {
+ $uri = $this->_parseUri($uri);
+ } else {
+ $uri = $this->_parseUri($uri, true);
+ }
+
+ if (!isset($uri['host'])) {
+ return false;
+ }
+ $config = array(
+ 'request' => array(
+ 'uri' => array_intersect_key($uri, $this->config['request']['uri'])
+ )
+ );
+ $this->config = Hash::merge($this->config, $config);
+ $this->config = Hash::merge($this->config, array_intersect_key($this->config['request']['uri'], $this->config));
+ return true;
+ }
+
+/**
+ * Takes a $uri array and turns it into a fully qualified URL string
+ *
+ * @param string|array $uri Either A $uri array, or a request string. Will use $this->config if left empty.
+ * @param string $uriTemplate The Uri template/format to use.
+ * @return mixed A fully qualified URL formatted according to $uriTemplate, or false on failure
+ */
+ protected function _buildUri($uri = array(), $uriTemplate = '%scheme://%user:%pass@%host:%port/%path?%query#%fragment') {
+ if (is_string($uri)) {
+ $uri = array('host' => $uri);
+ }
+ $uri = $this->_parseUri($uri, true);
+
+ if (!is_array($uri) || empty($uri)) {
+ return false;
+ }
+
+ $uri['path'] = preg_replace('/^\//', null, $uri['path']);
+ $uri['query'] = http_build_query($uri['query']);
+ $uri['query'] = rtrim($uri['query'], '=');
+ $stripIfEmpty = array(
+ 'query' => '?%query',
+ 'fragment' => '#%fragment',
+ 'user' => '%user:%pass@',
+ 'host' => '%host:%port/'
+ );
+
+ foreach ($stripIfEmpty as $key => $strip) {
+ if (empty($uri[$key])) {
+ $uriTemplate = str_replace($strip, null, $uriTemplate);
+ }
+ }
+
+ $defaultPorts = array('http' => 80, 'https' => 443);
+ if (array_key_exists($uri['scheme'], $defaultPorts) && $defaultPorts[$uri['scheme']] == $uri['port']) {
+ $uriTemplate = str_replace(':%port', null, $uriTemplate);
+ }
+ foreach ($uri as $property => $value) {
+ $uriTemplate = str_replace('%' . $property, $value, $uriTemplate);
+ }
+
+ if ($uriTemplate === '/*') {
+ $uriTemplate = '*';
+ }
+ return $uriTemplate;
+ }
+
+/**
+ * Parses the given URI and breaks it down into pieces as an indexed array with elements
+ * such as 'scheme', 'port', 'query'.
+ *
+ * @param string|array $uri URI to parse
+ * @param boolean|array $base If true use default URI config, otherwise indexed array to set 'scheme', 'host', 'port', etc.
+ * @return array Parsed URI
+ */
+ protected function _parseUri($uri = null, $base = array()) {
+ $uriBase = array(
+ 'scheme' => array('http', 'https'),
+ 'host' => null,
+ 'port' => array(80, 443),
+ 'user' => null,
+ 'pass' => null,
+ 'path' => '/',
+ 'query' => null,
+ 'fragment' => null
+ );
+
+ if (is_string($uri)) {
+ $uri = parse_url($uri);
+ }
+ if (!is_array($uri) || empty($uri)) {
+ return false;
+ }
+ if ($base === true) {
+ $base = $uriBase;
+ }
+
+ if (isset($base['port'], $base['scheme']) && is_array($base['port']) && is_array($base['scheme'])) {
+ if (isset($uri['scheme']) && !isset($uri['port'])) {
+ $base['port'] = $base['port'][array_search($uri['scheme'], $base['scheme'])];
+ } elseif (isset($uri['port']) && !isset($uri['scheme'])) {
+ $base['scheme'] = $base['scheme'][array_search($uri['port'], $base['port'])];
+ }
+ }
+
+ if (is_array($base) && !empty($base)) {
+ $uri = array_merge($base, $uri);
+ }
+
+ if (isset($uri['scheme']) && is_array($uri['scheme'])) {
+ $uri['scheme'] = array_shift($uri['scheme']);
+ }
+ if (isset($uri['port']) && is_array($uri['port'])) {
+ $uri['port'] = array_shift($uri['port']);
+ }
+
+ if (array_key_exists('query', $uri)) {
+ $uri['query'] = $this->_parseQuery($uri['query']);
+ }
+
+ if (!array_intersect_key($uriBase, $uri)) {
+ return false;
+ }
+ return $uri;
+ }
+
+/**
+ * This function can be thought of as a reverse to PHP5's http_build_query(). It takes a given query string and turns it into an array and
+ * supports nesting by using the php bracket syntax. So this means you can parse queries like:
+ *
+ * - ?key[subKey]=value
+ * - ?key[]=value1&key[]=value2
+ *
+ * A leading '?' mark in $query is optional and does not effect the outcome of this function.
+ * For the complete capabilities of this implementation take a look at HttpSocketTest::testparseQuery()
+ *
+ * @param string|array $query A query string to parse into an array or an array to return directly "as is"
+ * @return array The $query parsed into a possibly multi-level array. If an empty $query is
+ * given, an empty array is returned.
+ */
+ protected function _parseQuery($query) {
+ if (is_array($query)) {
+ return $query;
+ }
+
+ $parsedQuery = array();
+
+ if (is_string($query) && !empty($query)) {
+ $query = preg_replace('/^\?/', '', $query);
+ $items = explode('&', $query);
+
+ foreach ($items as $item) {
+ if (strpos($item, '=') !== false) {
+ list($key, $value) = explode('=', $item, 2);
+ } else {
+ $key = $item;
+ $value = null;
+ }
+
+ $key = urldecode($key);
+ $value = urldecode($value);
+
+ if (preg_match_all('/\[([^\[\]]*)\]/iUs', $key, $matches)) {
+ $subKeys = $matches[1];
+ $rootKey = substr($key, 0, strpos($key, '['));
+ if (!empty($rootKey)) {
+ array_unshift($subKeys, $rootKey);
+ }
+ $queryNode =& $parsedQuery;
+
+ foreach ($subKeys as $subKey) {
+ if (!is_array($queryNode)) {
+ $queryNode = array();
+ }
+
+ if ($subKey === '') {
+ $queryNode[] = array();
+ end($queryNode);
+ $subKey = key($queryNode);
+ }
+ $queryNode =& $queryNode[$subKey];
+ }
+ $queryNode = $value;
+ continue;
+ }
+ if (!isset($parsedQuery[$key])) {
+ $parsedQuery[$key] = $value;
+ } else {
+ $parsedQuery[$key] = (array)$parsedQuery[$key];
+ $parsedQuery[$key][] = $value;
+ }
+ }
+ }
+ return $parsedQuery;
+ }
+
+/**
+ * Builds a request line according to HTTP/1.1 specs. Activate quirks mode to work outside specs.
+ *
+ * @param array $request Needs to contain a 'uri' key. Should also contain a 'method' key, otherwise defaults to GET.
+ * @param string $versionToken The version token to use, defaults to HTTP/1.1
+ * @return string Request line
+ * @throws SocketException
+ */
+ protected function _buildRequestLine($request = array(), $versionToken = 'HTTP/1.1') {
+ $asteriskMethods = array('OPTIONS');
+
+ if (is_string($request)) {
+ $isValid = preg_match("/(.+) (.+) (.+)\r\n/U", $request, $match);
+ if (!$this->quirksMode && (!$isValid || ($match[2] == '*' && !in_array($match[3], $asteriskMethods)))) {
+ throw new SocketException(__d('cake_dev', 'HttpSocket::_buildRequestLine - Passed an invalid request line string. Activate quirks mode to do this.'));
+ }
+ return $request;
+ } elseif (!is_array($request)) {
+ return false;
+ } elseif (!array_key_exists('uri', $request)) {
+ return false;
+ }
+
+ $request['uri'] = $this->_parseUri($request['uri']);
+ $request = array_merge(array('method' => 'GET'), $request);
+ if (!empty($this->_proxy['host'])) {
+ $request['uri'] = $this->_buildUri($request['uri'], '%scheme://%host:%port/%path?%query');
+ } else {
+ $request['uri'] = $this->_buildUri($request['uri'], '/%path?%query');
+ }
+
+ if (!$this->quirksMode && $request['uri'] === '*' && !in_array($request['method'], $asteriskMethods)) {
+ throw new SocketException(__d('cake_dev', 'HttpSocket::_buildRequestLine - The "*" asterisk character is only allowed for the following methods: %s. Activate quirks mode to work outside of HTTP/1.1 specs.', implode(',', $asteriskMethods)));
+ }
+ return $request['method'] . ' ' . $request['uri'] . ' ' . $versionToken . "\r\n";
+ }
+
+/**
+ * Builds the header.
+ *
+ * @param array $header Header to build
+ * @param string $mode
+ * @return string Header built from array
+ */
+ protected function _buildHeader($header, $mode = 'standard') {
+ if (is_string($header)) {
+ return $header;
+ } elseif (!is_array($header)) {
+ return false;
+ }
+
+ $fieldsInHeader = array();
+ foreach ($header as $key => $value) {
+ $lowKey = strtolower($key);
+ if (array_key_exists($lowKey, $fieldsInHeader)) {
+ $header[$fieldsInHeader[$lowKey]] = $value;
+ unset($header[$key]);
+ } else {
+ $fieldsInHeader[$lowKey] = $key;
+ }
+ }
+
+ $returnHeader = '';
+ foreach ($header as $field => $contents) {
+ if (is_array($contents) && $mode == 'standard') {
+ $contents = implode(',', $contents);
+ }
+ foreach ((array)$contents as $content) {
+ $contents = preg_replace("/\r\n(?![\t ])/", "\r\n ", $content);
+ $field = $this->_escapeToken($field);
+
+ $returnHeader .= $field . ': ' . $contents . "\r\n";
+ }
+ }
+ return $returnHeader;
+ }
+
+/**
+ * Builds cookie headers for a request.
+ *
+ * @param array $cookies Array of cookies to send with the request.
+ * @return string Cookie header string to be sent with the request.
+ * @todo Refactor token escape mechanism to be configurable
+ */
+ public function buildCookies($cookies) {
+ $header = array();
+ foreach ($cookies as $name => $cookie) {
+ $header[] = $name . '=' . $this->_escapeToken($cookie['value'], array(';'));
+ }
+ return $this->_buildHeader(array('Cookie' => implode('; ', $header)), 'pragmatic');
+ }
+
+/**
+ * Escapes a given $token according to RFC 2616 (HTTP 1.1 specs)
+ *
+ * @param string $token Token to escape
+ * @param array $chars
+ * @return string Escaped token
+ * @todo Test $chars parameter
+ */
+ protected function _escapeToken($token, $chars = null) {
+ $regex = '/([' . implode('', $this->_tokenEscapeChars(true, $chars)) . '])/';
+ $token = preg_replace($regex, '"\\1"', $token);
+ return $token;
+ }
+
+/**
+ * Gets escape chars according to RFC 2616 (HTTP 1.1 specs).
+ *
+ * @param boolean $hex true to get them as HEX values, false otherwise
+ * @param array $chars
+ * @return array Escape chars
+ * @todo Test $chars parameter
+ */
+ protected function _tokenEscapeChars($hex = true, $chars = null) {
+ if (!empty($chars)) {
+ $escape = $chars;
+ } else {
+ $escape = array('"', "(", ")", "<", ">", "@", ",", ";", ":", "\\", "/", "[", "]", "?", "=", "{", "}", " ");
+ for ($i = 0; $i <= 31; $i++) {
+ $escape[] = chr($i);
+ }
+ $escape[] = chr(127);
+ }
+
+ if ($hex == false) {
+ return $escape;
+ }
+ foreach ($escape as $key => $char) {
+ $escape[$key] = '\\x' . str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
+ }
+ return $escape;
+ }
+
+/**
+ * Resets the state of this HttpSocket instance to it's initial state (before Object::__construct got executed) or does
+ * the same thing partially for the request and the response property only.
+ *
+ * @param boolean $full If set to false only HttpSocket::response and HttpSocket::request are reseted
+ * @return boolean True on success
+ */
+ public function reset($full = true) {
+ static $initalState = array();
+ if (empty($initalState)) {
+ $initalState = get_class_vars(__CLASS__);
+ }
+ if (!$full) {
+ $this->request = $initalState['request'];
+ $this->response = $initalState['response'];
+ return true;
+ }
+ parent::reset($initalState);
+ return true;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Dispatcher.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Dispatcher.php
new file mode 100644
index 0000000..bf3e395
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Dispatcher.php
@@ -0,0 +1,281 @@
+<?php
+/**
+ * Dispatcher takes the URL information, parses it for parameters and
+ * tells the involved controllers what to do.
+ *
+ * This is the heart of Cake's operation.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Routing
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Router', 'Routing');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+App::uses('Controller', 'Controller');
+App::uses('Scaffold', 'Controller');
+App::uses('View', 'View');
+App::uses('Debugger', 'Utility');
+App::uses('CakeEvent', 'Event');
+App::uses('CakeEventManager', 'Event');
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * Dispatcher converts Requests into controller actions. It uses the dispatched Request
+ * to locate and load the correct controller. If found, the requested action is called on
+ * the controller.
+ *
+ * @package Cake.Routing
+ */
+class Dispatcher implements CakeEventListener {
+
+/**
+ * Event manager, used to handle dispatcher filters
+ *
+ * @var CakeEventManager
+ */
+ protected $_eventManager;
+
+/**
+ * Constructor.
+ *
+ * @param string $base The base directory for the application. Writes `App.base` to Configure.
+ */
+ public function __construct($base = false) {
+ if ($base !== false) {
+ Configure::write('App.base', $base);
+ }
+ }
+
+/**
+ * Returns the CakeEventManager instance or creates one if none was
+ * creted. Attaches the default listeners and filters
+ *
+ * @return CakeEventManager
+ */
+ public function getEventManager() {
+ if (!$this->_eventManager) {
+ $this->_eventManager = new CakeEventManager();
+ $this->_eventManager->attach($this);
+ $this->_attachFilters($this->_eventManager);
+ }
+ return $this->_eventManager;
+ }
+
+/**
+ * Returns the list of events this object listents to.
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array('Dispatcher.beforeDispatch' => 'parseParams');
+ }
+
+/**
+ * Attaches all event listeners for this dispatcher instance. Loads the
+ * dispatcher filters from the configured locations.
+ *
+ * @param CakeEventManager $manager
+ * @return void
+ * @throws MissingDispatcherFilterException
+ */
+ protected function _attachFilters($manager) {
+ $filters = Configure::read('Dispatcher.filters');
+ if (empty($filters)) {
+ return;
+ }
+
+ foreach ($filters as $filter) {
+ if (is_string($filter)) {
+ $filter = array('callable' => $filter);
+ }
+ if (is_string($filter['callable'])) {
+ list($plugin, $callable) = pluginSplit($filter['callable'], true);
+ App::uses($callable, $plugin . 'Routing/Filter');
+ if (!class_exists($callable)) {
+ throw new MissingDispatcherFilterException($callable);
+ }
+ $manager->attach(new $callable);
+ } else {
+ $on = strtolower($filter['on']);
+ $options = array();
+ if (isset($filter['priority'])) {
+ $options = array('priority' => $filter['priority']);
+ }
+ $manager->attach($filter['callable'], 'Dispatcher.' . $on . 'Dispatch', $options);
+ }
+ }
+ }
+
+/**
+ * Dispatches and invokes given Request, handing over control to the involved controller. If the controller is set
+ * to autoRender, via Controller::$autoRender, then Dispatcher will render the view.
+ *
+ * Actions in CakePHP can be any public method on a controller, that is not declared in Controller. If you
+ * want controller methods to be public and in-accessible by URL, then prefix them with a `_`.
+ * For example `public function _loadPosts() { }` would not be accessible via URL. Private and protected methods
+ * are also not accessible via URL.
+ *
+ * If no controller of given name can be found, invoke() will throw an exception.
+ * If the controller is found, and the action is not found an exception will be thrown.
+ *
+ * @param CakeRequest $request Request object to dispatch.
+ * @param CakeResponse $response Response object to put the results of the dispatch into.
+ * @param array $additionalParams Settings array ("bare", "return") which is melded with the GET and POST params
+ * @return string|void if `$request['return']` is set then it returns response body, null otherwise
+ * @throws MissingControllerException When the controller is missing.
+ */
+ public function dispatch(CakeRequest $request, CakeResponse $response, $additionalParams = array()) {
+ $beforeEvent = new CakeEvent('Dispatcher.beforeDispatch', $this, compact('request', 'response', 'additionalParams'));
+ $this->getEventManager()->dispatch($beforeEvent);
+
+ $request = $beforeEvent->data['request'];
+ if ($beforeEvent->result instanceof CakeResponse) {
+ if (isset($request->params['return'])) {
+ return $response->body();
+ }
+ $response->send();
+ return;
+ }
+
+ $controller = $this->_getController($request, $response);
+
+ if (!($controller instanceof Controller)) {
+ throw new MissingControllerException(array(
+ 'class' => Inflector::camelize($request->params['controller']) . 'Controller',
+ 'plugin' => empty($request->params['plugin']) ? null : Inflector::camelize($request->params['plugin'])
+ ));
+ }
+
+ $response = $this->_invoke($controller, $request, $response);
+ if (isset($request->params['return'])) {
+ return $response->body();
+ }
+
+ $afterEvent = new CakeEvent('Dispatcher.afterDispatch', $this, compact('request', 'response'));
+ $this->getEventManager()->dispatch($afterEvent);
+ $afterEvent->data['response']->send();
+ }
+
+/**
+ * Initializes the components and models a controller will be using.
+ * Triggers the controller action, and invokes the rendering if Controller::$autoRender is true and echo's the output.
+ * Otherwise the return value of the controller action are returned.
+ *
+ * @param Controller $controller Controller to invoke
+ * @param CakeRequest $request The request object to invoke the controller for.
+ * @param CakeResponse $response The response object to receive the output
+ * @return CakeResponse te resulting response object
+ */
+ protected function _invoke(Controller $controller, CakeRequest $request, CakeResponse $response) {
+ $controller->constructClasses();
+ $controller->startupProcess();
+
+ $render = true;
+ $result = $controller->invokeAction($request);
+ if ($result instanceof CakeResponse) {
+ $render = false;
+ $response = $result;
+ }
+
+ if ($render && $controller->autoRender) {
+ $response = $controller->render();
+ } elseif ($response->body() === null) {
+ $response->body($result);
+ }
+ $controller->shutdownProcess();
+
+ return $response;
+ }
+
+/**
+ * Applies Routing and additionalParameters to the request to be dispatched.
+ * If Routes have not been loaded they will be loaded, and app/Config/routes.php will be run.
+ *
+ * @param CakeEvent $event containing the request, response and additional params
+ * @return void
+ */
+ public function parseParams($event) {
+ $request = $event->data['request'];
+ Router::setRequestInfo($request);
+ if (count(Router::$routes) == 0) {
+ $namedExpressions = Router::getNamedExpressions();
+ extract($namedExpressions);
+ $this->_loadRoutes();
+ }
+
+ $params = Router::parse($request->url);
+ $request->addParams($params);
+
+ if (!empty($event->data['additionalParams'])) {
+ $request->addParams($event->data['additionalParams']);
+ }
+ }
+
+/**
+ * Get controller to use, either plugin controller or application controller
+ *
+ * @param CakeRequest $request Request object
+ * @param CakeResponse $response Response for the controller.
+ * @return mixed name of controller if not loaded, or object if loaded
+ */
+ protected function _getController($request, $response) {
+ $ctrlClass = $this->_loadController($request);
+ if (!$ctrlClass) {
+ return false;
+ }
+ $reflection = new ReflectionClass($ctrlClass);
+ if ($reflection->isAbstract() || $reflection->isInterface()) {
+ return false;
+ }
+ return $reflection->newInstance($request, $response);
+ }
+
+/**
+ * Load controller and return controller classname
+ *
+ * @param CakeRequest $request
+ * @return string|bool Name of controller class name
+ */
+ protected function _loadController($request) {
+ $pluginName = $pluginPath = $controller = null;
+ if (!empty($request->params['plugin'])) {
+ $pluginName = $controller = Inflector::camelize($request->params['plugin']);
+ $pluginPath = $pluginName . '.';
+ }
+ if (!empty($request->params['controller'])) {
+ $controller = Inflector::camelize($request->params['controller']);
+ }
+ if ($pluginPath . $controller) {
+ $class = $controller . 'Controller';
+ App::uses('AppController', 'Controller');
+ App::uses($pluginName . 'AppController', $pluginPath . 'Controller');
+ App::uses($class, $pluginPath . 'Controller');
+ if (class_exists($class)) {
+ return $class;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Loads route configuration
+ *
+ * @return void
+ */
+ protected function _loadRoutes() {
+ include APP . 'Config' . DS . 'routes.php';
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/DispatcherFilter.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/DispatcherFilter.php
new file mode 100644
index 0000000..cf6f4fa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/DispatcherFilter.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Routing
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * This abstract class represents a filter to be applied to a dispatcher cycle. It acts as as
+ * event listener with the ability to alter the request or response as needed before it is handled
+ * by a controller or after the response body has already been built.
+ *
+ * @package Cake.Routing
+ */
+abstract class DispatcherFilter implements CakeEventListener {
+
+/**
+ * Default priority for all methods in this filter
+ *
+ * @var int
+ **/
+ public $priority = 10;
+
+/**
+ * Returns the list of events this filter listens to.
+ * Dispatcher notifies 2 different events `Dispatcher.before` and `Dispatcher.after`.
+ * By default this class will attach `preDispatch` and `postDispatch` method respectively.
+ *
+ * Override this method at will to only listen to the events you are interested in.
+ *
+ * @return array
+ **/
+ public function implementedEvents() {
+ return array(
+ 'Dispatcher.beforeDispatch' => array('callable' => 'beforeDispatch', 'priority' => $this->priority),
+ 'Dispatcher.afterDispatch' => array('callable' => 'afterDispatch', 'priority' => $this->priority),
+ );
+ }
+
+/**
+ * Method called before the controller is instantiated and called to ser a request.
+ * If used with default priority, it will be called after the Router has parsed the
+ * url and set the routing params into the request object.
+ *
+ * If a CakeResponse object instance is returned, it will be served at the end of the
+ * event cycle, not calling any controller as a result. This will also have the effect of
+ * not calling the after event in the dispatcher.
+ *
+ * If false is returned, the event will be stopped and no more listeners will be notified.
+ * Alternatively you can call `$event->stopPropagation()` to acheive the same result.
+ *
+ * @param CakeEvent $event container object having the `request`, `response` and `additionalParams`
+ * keys in the data property.
+ * @return CakeResponse|boolean
+ **/
+ public function beforeDispatch($event) {
+ }
+
+/**
+ * Method called after the controller served a request and generated a response.
+ * It is posible to alter the response object at this point as it is not sent to the
+ * client yet.
+ *
+ * If false is returned, the event will be stopped and no more listeners will be notified.
+ * Alternatively you can call `$event->stopPropagation()` to acheive the same result.
+ *
+ * @param CakeEvent $event container object having the `request` and `response`
+ * keys in the data property.
+ * @return mixed boolean to stop the event dispatching or null to continue
+ **/
+ public function afterDispatch($event) {
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/AssetDispatcher.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/AssetDispatcher.php
new file mode 100644
index 0000000..11840ba
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/AssetDispatcher.php
@@ -0,0 +1,159 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Routing
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DispatcherFilter', 'Routing');
+
+/**
+ * Filters a request and tests whether it is a file in the webroot folder or not and
+ * serves the file to the client if appropriate.
+ *
+ * @package Cake.Routing.Filter
+ */
+class AssetDispatcher extends DispatcherFilter {
+
+/**
+ * Default priority for all methods in this filter
+ * This filter should run before the request gets parsed by router
+ *
+ * @var int
+ **/
+ public $priority = 9;
+
+/**
+ * Checks if a requested asset exists and sends it to the browser
+ *
+ * @param CakeEvent $event containing the request and response object
+ * @return CakeResponse if the client is requesting a recognized asset, null otherwise
+ */
+ public function beforeDispatch($event) {
+ $url = $event->data['request']->url;
+ $response = $event->data['response'];
+
+ if (strpos($url, '..') !== false || strpos($url, '.') === false) {
+ return;
+ }
+
+ if ($result = $this->_filterAsset($event)) {
+ $event->stopPropagation();
+ return $result;
+ }
+
+ $pathSegments = explode('.', $url);
+ $ext = array_pop($pathSegments);
+ $parts = explode('/', $url);
+ $assetFile = null;
+
+ if ($parts[0] === 'theme') {
+ $themeName = $parts[1];
+ unset($parts[0], $parts[1]);
+ $fileFragment = urldecode(implode(DS, $parts));
+ $path = App::themePath($themeName) . 'webroot' . DS;
+ if (file_exists($path . $fileFragment)) {
+ $assetFile = $path . $fileFragment;
+ }
+ } else {
+ $plugin = Inflector::camelize($parts[0]);
+ if (CakePlugin::loaded($plugin)) {
+ unset($parts[0]);
+ $fileFragment = urldecode(implode(DS, $parts));
+ $pluginWebroot = CakePlugin::path($plugin) . 'webroot' . DS;
+ if (file_exists($pluginWebroot . $fileFragment)) {
+ $assetFile = $pluginWebroot . $fileFragment;
+ }
+ }
+ }
+
+ if ($assetFile !== null) {
+ $event->stopPropagation();
+ $response->modified(filemtime($assetFile));
+ if (!$response->checkNotModified($event->data['request'])) {
+ $this->_deliverAsset($response, $assetFile, $ext);
+ }
+ return $response;
+ }
+ }
+
+/**
+ * Checks if the client is requeting a filtered asset and runs the corresponding
+ * filter if any is configured
+ *
+ * @param CakeEvent $event containing the request and response object
+ * @return CakeResponse if the client is requesting a recognized asset, null otherwise
+ */
+ protected function _filterAsset($event) {
+ $url = $event->data['request']->url;
+ $response = $event->data['response'];
+ $filters = Configure::read('Asset.filter');
+ $isCss = (
+ strpos($url, 'ccss/') === 0 ||
+ preg_match('#^(theme/([^/]+)/ccss/)|(([^/]+)(?<!css)/ccss)/#i', $url)
+ );
+ $isJs = (
+ strpos($url, 'cjs/') === 0 ||
+ preg_match('#^/((theme/[^/]+)/cjs/)|(([^/]+)(?<!js)/cjs)/#i', $url)
+ );
+
+ if (($isCss && empty($filters['css'])) || ($isJs && empty($filters['js']))) {
+ $response->statusCode(404);
+ return $response;
+ } elseif ($isCss) {
+ include WWW_ROOT . DS . $filters['css'];
+ return $response;
+ } elseif ($isJs) {
+ include WWW_ROOT . DS . $filters['js'];
+ return $response;
+ }
+ }
+
+/**
+ * Sends an asset file to the client
+ *
+ * @param CakeResponse $response The response object to use.
+ * @param string $assetFile Path to the asset file in the file system
+ * @param string $ext The extension of the file to determine its mime type
+ * @return void
+ */
+ protected function _deliverAsset(CakeResponse $response, $assetFile, $ext) {
+ ob_start();
+ $compressionEnabled = Configure::read('Asset.compress') && $response->compress();
+ if ($response->type($ext) == $ext) {
+ $contentType = 'application/octet-stream';
+ $agent = env('HTTP_USER_AGENT');
+ if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
+ $contentType = 'application/octetstream';
+ }
+ $response->type($contentType);
+ }
+ if (!$compressionEnabled) {
+ $response->header('Content-Length', filesize($assetFile));
+ }
+ $response->cache(filemtime($assetFile));
+ $response->send();
+ ob_clean();
+ if ($ext === 'css' || $ext === 'js') {
+ include $assetFile;
+ } else {
+ readfile($assetFile);
+ }
+
+ if ($compressionEnabled) {
+ ob_end_flush();
+ }
+ }
+
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/CacheDispatcher.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/CacheDispatcher.php
new file mode 100644
index 0000000..908d77a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Filter/CacheDispatcher.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DispatcherFilter', 'Routing');
+
+/**
+ * This filter will check wheter the response was previously cached in the file system
+ * and served it back to the client if appropriate.
+ *
+ * @package Cake.Routing.Filter
+ */
+class CacheDispatcher extends DispatcherFilter {
+
+/**
+ * Default priority for all methods in this filter
+ * This filter should run before the request gets parsed by router
+ *
+ * @var int
+ */
+ public $priority = 9;
+
+/**
+ * Checks whether the response was cached and set the body accordingly.
+ *
+ * @param CakeEvent $event containing the request and response object
+ * @return CakeResponse with cached content if found, null otherwise
+ */
+ public function beforeDispatch($event) {
+ if (Configure::read('Cache.check') !== true) {
+ return;
+ }
+
+ $path = $event->data['request']->here();
+ if ($path == '/') {
+ $path = 'home';
+ }
+ $path = strtolower(Inflector::slug($path));
+
+ $filename = CACHE . 'views' . DS . $path . '.php';
+
+ if (!file_exists($filename)) {
+ $filename = CACHE . 'views' . DS . $path . '_index.php';
+ }
+ if (file_exists($filename)) {
+ $controller = null;
+ $view = new View($controller);
+ $result = $view->renderCache($filename, microtime(true));
+ if ($result !== false) {
+ $event->stopPropagation();
+ $event->data['response']->body($result);
+ return $event->data['response'];
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/CakeRoute.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/CakeRoute.php
new file mode 100644
index 0000000..8fab212
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/CakeRoute.php
@@ -0,0 +1,532 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Set', 'Utility');
+
+/**
+ * A single Route used by the Router to connect requests to
+ * parameter maps.
+ *
+ * Not normally created as a standalone. Use Router::connect() to create
+ * Routes for your application.
+ *
+ * @package Cake.Routing.Route
+ */
+class CakeRoute {
+
+/**
+ * An array of named segments in a Route.
+ * `/:controller/:action/:id` has 3 key elements
+ *
+ * @var array
+ */
+ public $keys = array();
+
+/**
+ * An array of additional parameters for the Route.
+ *
+ * @var array
+ */
+ public $options = array();
+
+/**
+ * Default parameters for a Route
+ *
+ * @var array
+ */
+ public $defaults = array();
+
+/**
+ * The routes template string.
+ *
+ * @var string
+ */
+ public $template = null;
+
+/**
+ * Is this route a greedy route? Greedy routes have a `/*` in their
+ * template
+ *
+ * @var string
+ */
+ protected $_greedy = false;
+
+/**
+ * The compiled route regular expression
+ *
+ * @var string
+ */
+ protected $_compiledRoute = null;
+
+/**
+ * HTTP header shortcut map. Used for evaluating header-based route expressions.
+ *
+ * @var array
+ */
+ protected $_headerMap = array(
+ 'type' => 'content_type',
+ 'method' => 'request_method',
+ 'server' => 'server_name'
+ );
+
+/**
+ * Constructor for a Route
+ *
+ * @param string $template Template string with parameter placeholders
+ * @param array $defaults Array of defaults for the route.
+ * @param array $options Array of additional options for the Route
+ */
+ public function __construct($template, $defaults = array(), $options = array()) {
+ $this->template = $template;
+ $this->defaults = (array)$defaults;
+ $this->options = (array)$options;
+ }
+
+/**
+ * Check if a Route has been compiled into a regular expression.
+ *
+ * @return boolean
+ */
+ public function compiled() {
+ return !empty($this->_compiledRoute);
+ }
+
+/**
+ * Compiles the route's regular expression. Modifies defaults property so all necessary keys are set
+ * and populates $this->names with the named routing elements.
+ *
+ * @return array Returns a string regular expression of the compiled route.
+ */
+ public function compile() {
+ if ($this->compiled()) {
+ return $this->_compiledRoute;
+ }
+ $this->_writeRoute();
+ return $this->_compiledRoute;
+ }
+
+/**
+ * Builds a route regular expression. Uses the template, defaults and options
+ * properties to compile a regular expression that can be used to parse request strings.
+ *
+ * @return void
+ */
+ protected function _writeRoute() {
+ if (empty($this->template) || ($this->template === '/')) {
+ $this->_compiledRoute = '#^/*$#';
+ $this->keys = array();
+ return;
+ }
+ $route = $this->template;
+ $names = $routeParams = array();
+ $parsed = preg_quote($this->template, '#');
+
+ preg_match_all('#:([A-Za-z0-9_-]+[A-Z0-9a-z])#', $route, $namedElements);
+ foreach ($namedElements[1] as $i => $name) {
+ $search = '\\' . $namedElements[0][$i];
+ if (isset($this->options[$name])) {
+ $option = null;
+ if ($name !== 'plugin' && array_key_exists($name, $this->defaults)) {
+ $option = '?';
+ }
+ $slashParam = '/\\' . $namedElements[0][$i];
+ if (strpos($parsed, $slashParam) !== false) {
+ $routeParams[$slashParam] = '(?:/(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
+ } else {
+ $routeParams[$search] = '(?:(?P<' . $name . '>' . $this->options[$name] . ')' . $option . ')' . $option;
+ }
+ } else {
+ $routeParams[$search] = '(?:(?P<' . $name . '>[^/]+))';
+ }
+ $names[] = $name;
+ }
+ if (preg_match('#\/\*\*$#', $route)) {
+ $parsed = preg_replace('#/\\\\\*\\\\\*$#', '(?:/(?P<_trailing_>.*))?', $parsed);
+ $this->_greedy = true;
+ } elseif (preg_match('#\/\*$#', $route)) {
+ $parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed);
+ $this->_greedy = true;
+ }
+ krsort($routeParams);
+ $parsed = str_replace(array_keys($routeParams), array_values($routeParams), $parsed);
+ $this->_compiledRoute = '#^' . $parsed . '[/]*$#';
+ $this->keys = $names;
+
+ //remove defaults that are also keys. They can cause match failures
+ foreach ($this->keys as $key) {
+ unset($this->defaults[$key]);
+ }
+ }
+
+/**
+ * Checks to see if the given URL can be parsed by this route.
+ * If the route can be parsed an array of parameters will be returned; if not
+ * false will be returned. String urls are parsed if they match a routes regular expression.
+ *
+ * @param string $url The url to attempt to parse.
+ * @return mixed Boolean false on failure, otherwise an array or parameters
+ */
+ public function parse($url) {
+ if (!$this->compiled()) {
+ $this->compile();
+ }
+ if (!preg_match($this->_compiledRoute, $url, $route)) {
+ return false;
+ }
+ foreach ($this->defaults as $key => $val) {
+ $key = (string)$key;
+ if ($key[0] === '[' && preg_match('/^\[(\w+)\]$/', $key, $header)) {
+ if (isset($this->_headerMap[$header[1]])) {
+ $header = $this->_headerMap[$header[1]];
+ } else {
+ $header = 'http_' . $header[1];
+ }
+ $header = strtoupper($header);
+
+ $val = (array)$val;
+ $h = false;
+
+ foreach ($val as $v) {
+ if (env($header) === $v) {
+ $h = true;
+ }
+ }
+ if (!$h) {
+ return false;
+ }
+ }
+ }
+ array_shift($route);
+ $count = count($this->keys);
+ for ($i = 0; $i <= $count; $i++) {
+ unset($route[$i]);
+ }
+ $route['pass'] = $route['named'] = array();
+
+ // Assign defaults, set passed args to pass
+ foreach ($this->defaults as $key => $value) {
+ if (isset($route[$key])) {
+ continue;
+ }
+ if (is_integer($key)) {
+ $route['pass'][] = $value;
+ continue;
+ }
+ $route[$key] = $value;
+ }
+
+ foreach ($this->keys as $key) {
+ if (isset($route[$key])) {
+ $route[$key] = rawurldecode($route[$key]);
+ }
+ }
+
+ if (isset($route['_args_'])) {
+ list($pass, $named) = $this->_parseArgs($route['_args_'], $route);
+ $route['pass'] = array_merge($route['pass'], $pass);
+ $route['named'] = $named;
+ unset($route['_args_']);
+ }
+
+ if (isset($route['_trailing_'])) {
+ $route['pass'][] = rawurldecode($route['_trailing_']);
+ unset($route['_trailing_']);
+ }
+
+ // restructure 'pass' key route params
+ if (isset($this->options['pass'])) {
+ $j = count($this->options['pass']);
+ while ($j--) {
+ if (isset($route[$this->options['pass'][$j]])) {
+ array_unshift($route['pass'], $route[$this->options['pass'][$j]]);
+ }
+ }
+ }
+ return $route;
+ }
+
+/**
+ * Parse passed and Named parameters into a list of passed args, and a hash of named parameters.
+ * The local and global configuration for named parameters will be used.
+ *
+ * @param string $args A string with the passed & named params. eg. /1/page:2
+ * @param string $context The current route context, which should contain controller/action keys.
+ * @return array Array of ($pass, $named)
+ */
+ protected function _parseArgs($args, $context) {
+ $pass = $named = array();
+ $args = explode('/', $args);
+
+ $namedConfig = Router::namedConfig();
+ $greedy = $namedConfig['greedyNamed'];
+ $rules = $namedConfig['rules'];
+ if (!empty($this->options['named'])) {
+ $greedy = isset($this->options['greedyNamed']) && $this->options['greedyNamed'] === true;
+ foreach ((array)$this->options['named'] as $key => $val) {
+ if (is_numeric($key)) {
+ $rules[$val] = true;
+ continue;
+ }
+ $rules[$key] = $val;
+ }
+ }
+
+ foreach ($args as $param) {
+ if (empty($param) && $param !== '0' && $param !== 0) {
+ continue;
+ }
+
+ $separatorIsPresent = strpos($param, $namedConfig['separator']) !== false;
+ if ((!isset($this->options['named']) || !empty($this->options['named'])) && $separatorIsPresent) {
+ list($key, $val) = explode($namedConfig['separator'], $param, 2);
+ $key = rawurldecode($key);
+ $val = rawurldecode($val);
+ $hasRule = isset($rules[$key]);
+ $passIt = (!$hasRule && !$greedy) || ($hasRule && !$this->_matchNamed($val, $rules[$key], $context));
+ if ($passIt) {
+ $pass[] = rawurldecode($param);
+ } else {
+ if (preg_match_all('/\[([A-Za-z0-9_-]+)?\]/', $key, $matches, PREG_SET_ORDER)) {
+ $matches = array_reverse($matches);
+ $parts = explode('[', $key);
+ $key = array_shift($parts);
+ $arr = $val;
+ foreach ($matches as $match) {
+ if (empty($match[1])) {
+ $arr = array($arr);
+ } else {
+ $arr = array(
+ $match[1] => $arr
+ );
+ }
+ }
+ $val = $arr;
+ }
+ $named = array_merge_recursive($named, array($key => $val));
+ }
+ } else {
+ $pass[] = rawurldecode($param);
+ }
+ }
+ return array($pass, $named);
+ }
+
+/**
+ * Return true if a given named $param's $val matches a given $rule depending on $context. Currently implemented
+ * rule types are controller, action and match that can be combined with each other.
+ *
+ * @param string $val The value of the named parameter
+ * @param array $rule The rule(s) to apply, can also be a match string
+ * @param string $context An array with additional context information (controller / action)
+ * @return boolean
+ */
+ protected function _matchNamed($val, $rule, $context) {
+ if ($rule === true || $rule === false) {
+ return $rule;
+ }
+ if (is_string($rule)) {
+ $rule = array('match' => $rule);
+ }
+ if (!is_array($rule)) {
+ return false;
+ }
+
+ $controllerMatches = (
+ !isset($rule['controller'], $context['controller']) ||
+ in_array($context['controller'], (array)$rule['controller'])
+ );
+ if (!$controllerMatches) {
+ return false;
+ }
+ $actionMatches = (
+ !isset($rule['action'], $context['action']) ||
+ in_array($context['action'], (array)$rule['action'])
+ );
+ if (!$actionMatches) {
+ return false;
+ }
+ return (!isset($rule['match']) || preg_match('/' . $rule['match'] . '/', $val));
+ }
+
+/**
+ * Apply persistent parameters to a url array. Persistent parameters are a special
+ * key used during route creation to force route parameters to persist when omitted from
+ * a url array.
+ *
+ * @param array $url The array to apply persistent parameters to.
+ * @param array $params An array of persistent values to replace persistent ones.
+ * @return array An array with persistent parameters applied.
+ */
+ public function persistParams($url, $params) {
+ foreach ($this->options['persist'] as $persistKey) {
+ if (array_key_exists($persistKey, $params) && !isset($url[$persistKey])) {
+ $url[$persistKey] = $params[$persistKey];
+ }
+ }
+ return $url;
+ }
+
+/**
+ * Attempt to match a url array. If the url matches the route parameters and settings, then
+ * return a generated string url. If the url doesn't match the route parameters, false will be returned.
+ * This method handles the reverse routing or conversion of url arrays into string urls.
+ *
+ * @param array $url An array of parameters to check matching with.
+ * @return mixed Either a string url for the parameters if they match or false.
+ */
+ public function match($url) {
+ if (!$this->compiled()) {
+ $this->compile();
+ }
+ $defaults = $this->defaults;
+
+ if (isset($defaults['prefix'])) {
+ $url['prefix'] = $defaults['prefix'];
+ }
+
+ //check that all the key names are in the url
+ $keyNames = array_flip($this->keys);
+ if (array_intersect_key($keyNames, $url) !== $keyNames) {
+ return false;
+ }
+
+ // Missing defaults is a fail.
+ if (array_diff_key($defaults, $url) !== array()) {
+ return false;
+ }
+
+ $namedConfig = Router::namedConfig();
+ $prefixes = Router::prefixes();
+ $greedyNamed = $namedConfig['greedyNamed'];
+ $allowedNamedParams = $namedConfig['rules'];
+
+ $named = $pass = array();
+
+ foreach ($url as $key => $value) {
+
+ // keys that exist in the defaults and have different values is a match failure.
+ $defaultExists = array_key_exists($key, $defaults);
+ if ($defaultExists && $defaults[$key] != $value) {
+ return false;
+ } elseif ($defaultExists) {
+ continue;
+ }
+
+ // If the key is a routed key, its not different yet.
+ if (array_key_exists($key, $keyNames)) {
+ continue;
+ }
+
+ // pull out passed args
+ $numeric = is_numeric($key);
+ if ($numeric && isset($defaults[$key]) && $defaults[$key] == $value) {
+ continue;
+ } elseif ($numeric) {
+ $pass[] = $value;
+ unset($url[$key]);
+ continue;
+ }
+
+ // pull out named params if named params are greedy or a rule exists.
+ if (
+ ($greedyNamed || isset($allowedNamedParams[$key])) &&
+ ($value !== false && $value !== null) &&
+ (!in_array($key, $prefixes))
+ ) {
+ $named[$key] = $value;
+ continue;
+ }
+
+ // keys that don't exist are different.
+ if (!$defaultExists && !empty($value)) {
+ return false;
+ }
+ }
+
+ //if a not a greedy route, no extra params are allowed.
+ if (!$this->_greedy && (!empty($pass) || !empty($named))) {
+ return false;
+ }
+
+ //check patterns for routed params
+ if (!empty($this->options)) {
+ foreach ($this->options as $key => $pattern) {
+ if (array_key_exists($key, $url) && !preg_match('#^' . $pattern . '$#', $url[$key])) {
+ return false;
+ }
+ }
+ }
+ return $this->_writeUrl(array_merge($url, compact('pass', 'named')));
+ }
+
+/**
+ * Converts a matching route array into a url string. Composes the string url using the template
+ * used to create the route.
+ *
+ * @param array $params The params to convert to a string url.
+ * @return string Composed route string.
+ */
+ protected function _writeUrl($params) {
+ if (isset($params['prefix'])) {
+ $prefixed = $params['prefix'] . '_';
+ }
+ if (isset($prefixed, $params['action']) && strpos($params['action'], $prefixed) === 0) {
+ $params['action'] = substr($params['action'], strlen($prefixed) * -1);
+ unset($params['prefix']);
+ }
+
+ if (is_array($params['pass'])) {
+ $params['pass'] = implode('/', array_map('rawurlencode', $params['pass']));
+ }
+
+ $namedConfig = Router::namedConfig();
+ $separator = $namedConfig['separator'];
+
+ if (!empty($params['named']) && is_array($params['named'])) {
+ $named = array();
+ foreach ($params['named'] as $key => $value) {
+ if (is_array($value)) {
+ $flat = Hash::flatten($value, '%5D%5B');
+ foreach ($flat as $namedKey => $namedValue) {
+ $named[] = $key . "%5B{$namedKey}%5D" . $separator . rawurlencode($namedValue);
+ }
+ } else {
+ $named[] = $key . $separator . rawurlencode($value);
+ }
+ }
+ $params['pass'] = $params['pass'] . '/' . implode('/', $named);
+ }
+ $out = $this->template;
+
+ $search = $replace = array();
+ foreach ($this->keys as $key) {
+ $string = null;
+ if (isset($params[$key])) {
+ $string = $params[$key];
+ } elseif (strpos($out, $key) != strlen($out) - strlen($key)) {
+ $key .= '/';
+ }
+ $search[] = ':' . $key;
+ $replace[] = $string;
+ }
+ $out = str_replace($search, $replace, $out);
+
+ if (strpos($this->template, '*')) {
+ $out = str_replace('*', $params['pass'], $out);
+ }
+ $out = str_replace('//', '/', $out);
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/PluginShortRoute.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/PluginShortRoute.php
new file mode 100644
index 0000000..2edd944
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/PluginShortRoute.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeRoute', 'Routing/Route');
+
+/**
+ * Plugin short route, that copies the plugin param to the controller parameters
+ * It is used for supporting /:plugin routes.
+ *
+ * @package Cake.Routing.Route
+ */
+class PluginShortRoute extends CakeRoute {
+
+/**
+ * Parses a string url into an array. If a plugin key is found, it will be copied to the
+ * controller parameter
+ *
+ * @param string $url The url to parse
+ * @return mixed false on failure, or an array of request parameters
+ */
+ public function parse($url) {
+ $params = parent::parse($url);
+ if (!$params) {
+ return false;
+ }
+ $params['controller'] = $params['plugin'];
+ return $params;
+ }
+
+/**
+ * Reverse route plugin shortcut urls. If the plugin and controller
+ * are not the same the match is an auto fail.
+ *
+ * @param array $url Array of parameters to convert to a string.
+ * @return mixed either false or a string url.
+ */
+ public function match($url) {
+ if (isset($url['controller']) && isset($url['plugin']) && $url['plugin'] != $url['controller']) {
+ return false;
+ }
+ $this->defaults['controller'] = $url['controller'];
+ $result = parent::match($url);
+ unset($this->defaults['controller']);
+ return $result;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/RedirectRoute.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/RedirectRoute.php
new file mode 100644
index 0000000..bfb0f06
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Route/RedirectRoute.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Routing.Route
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeResponse', 'Network');
+App::uses('CakeRoute', 'Routing/Route');
+
+/**
+ * Redirect route will perform an immediate redirect. Redirect routes
+ * are useful when you want to have Routing layer redirects occur in your
+ * application, for when URLs move.
+ *
+ * @package Cake.Routing.Route
+ */
+class RedirectRoute extends CakeRoute {
+
+/**
+ * A CakeResponse object
+ *
+ * @var CakeResponse
+ */
+ public $response = null;
+
+/**
+ * The location to redirect to. Either a string or a cake array url.
+ *
+ * @var mixed
+ */
+ public $redirect;
+
+/**
+ * Flag for disabling exit() when this route parses a url.
+ *
+ * @var boolean
+ */
+ public $stop = true;
+
+/**
+ * Constructor
+ *
+ * @param string $template Template string with parameter placeholders
+ * @param array $defaults Array of defaults for the route.
+ * @param array $options Array of additional options for the Route
+ */
+ public function __construct($template, $defaults = array(), $options = array()) {
+ parent::__construct($template, $defaults, $options);
+ $this->redirect = (array)$defaults;
+ }
+
+/**
+ * Parses a string url into an array. Parsed urls will result in an automatic
+ * redirection
+ *
+ * @param string $url The url to parse
+ * @return boolean False on failure
+ */
+ public function parse($url) {
+ $params = parent::parse($url);
+ if (!$params) {
+ return false;
+ }
+ if (!$this->response) {
+ $this->response = new CakeResponse();
+ }
+ $redirect = $this->redirect;
+ if (count($this->redirect) == 1 && !isset($this->redirect['controller'])) {
+ $redirect = $this->redirect[0];
+ }
+ if (isset($this->options['persist']) && is_array($redirect)) {
+ $redirect += array('named' => $params['named'], 'pass' => $params['pass'], 'url' => array());
+ $redirect = Router::reverse($redirect);
+ }
+ $status = 301;
+ if (isset($this->options['status']) && ($this->options['status'] >= 300 && $this->options['status'] < 400)) {
+ $status = $this->options['status'];
+ }
+ $this->response->header(array('Location' => Router::url($redirect, true)));
+ $this->response->statusCode($status);
+ $this->response->send();
+ $this->_stop();
+ }
+
+/**
+ * There is no reverse routing redirection routes
+ *
+ * @param array $url Array of parameters to convert to a string.
+ * @return mixed either false or a string url.
+ */
+ public function match($url) {
+ return false;
+ }
+
+/**
+ * Stop execution of the current script. Wraps exit() making
+ * testing easier.
+ *
+ * @param integer|string $status see http://php.net/exit for values
+ * @return void
+ */
+ protected function _stop($code = 0) {
+ if ($this->stop) {
+ exit($code);
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Router.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Router.php
new file mode 100644
index 0000000..42a2937
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Routing/Router.php
@@ -0,0 +1,1141 @@
+<?php
+/**
+ * Parses the request URL into controller, action, and parameters.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Routing
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeRequest', 'Network');
+App::uses('CakeRoute', 'Routing/Route');
+
+/**
+ * Parses the request URL into controller, action, and parameters. Uses the connected routes
+ * to match the incoming url string to parameters that will allow the request to be dispatched. Also
+ * handles converting parameter lists into url strings, using the connected routes. Routing allows you to decouple
+ * the way the world interacts with your application (urls) and the implementation (controllers and actions).
+ *
+ * ### Connecting routes
+ *
+ * Connecting routes is done using Router::connect(). When parsing incoming requests or reverse matching
+ * parameters, routes are enumerated in the order they were connected. You can modify the order of connected
+ * routes using Router::promote(). For more information on routes and how to connect them see Router::connect().
+ *
+ * ### Named parameters
+ *
+ * Named parameters allow you to embed key:value pairs into path segments. This allows you create hash
+ * structures using urls. You can define how named parameters work in your application using Router::connectNamed()
+ *
+ * @package Cake.Routing
+ */
+class Router {
+
+/**
+ * Array of routes connected with Router::connect()
+ *
+ * @var array
+ */
+ public static $routes = array();
+
+/**
+ * List of action prefixes used in connected routes.
+ * Includes admin prefix
+ *
+ * @var array
+ */
+ protected static $_prefixes = array();
+
+/**
+ * Directive for Router to parse out file extensions for mapping to Content-types.
+ *
+ * @var boolean
+ */
+ protected static $_parseExtensions = false;
+
+/**
+ * List of valid extensions to parse from a URL. If null, any extension is allowed.
+ *
+ * @var array
+ */
+ protected static $_validExtensions = array();
+
+/**
+ * 'Constant' regular expression definitions for named route elements
+ *
+ */
+ const ACTION = 'index|show|add|create|edit|update|remove|del|delete|view|item';
+ const YEAR = '[12][0-9]{3}';
+ const MONTH = '0[1-9]|1[012]';
+ const DAY = '0[1-9]|[12][0-9]|3[01]';
+ const ID = '[0-9]+';
+ const UUID = '[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}';
+
+/**
+ * Named expressions
+ *
+ * @var array
+ */
+ protected static $_namedExpressions = array(
+ 'Action' => Router::ACTION,
+ 'Year' => Router::YEAR,
+ 'Month' => Router::MONTH,
+ 'Day' => Router::DAY,
+ 'ID' => Router::ID,
+ 'UUID' => Router::UUID
+ );
+
+/**
+ * Stores all information necessary to decide what named arguments are parsed under what conditions.
+ *
+ * @var string
+ */
+ protected static $_namedConfig = array(
+ 'default' => array('page', 'fields', 'order', 'limit', 'recursive', 'sort', 'direction', 'step'),
+ 'greedyNamed' => true,
+ 'separator' => ':',
+ 'rules' => false,
+ );
+
+/**
+ * The route matching the URL of the current request
+ *
+ * @var array
+ */
+ protected static $_currentRoute = array();
+
+/**
+ * Default HTTP request method => controller action map.
+ *
+ * @var array
+ */
+ protected static $_resourceMap = array(
+ array('action' => 'index', 'method' => 'GET', 'id' => false),
+ array('action' => 'view', 'method' => 'GET', 'id' => true),
+ array('action' => 'add', 'method' => 'POST', 'id' => false),
+ array('action' => 'edit', 'method' => 'PUT', 'id' => true),
+ array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
+ array('action' => 'edit', 'method' => 'POST', 'id' => true)
+ );
+
+/**
+ * List of resource-mapped controllers
+ *
+ * @var array
+ */
+ protected static $_resourceMapped = array();
+
+/**
+ * Maintains the request object stack for the current request.
+ * This will contain more than one request object when requestAction is used.
+ *
+ * @var array
+ */
+ protected static $_requests = array();
+
+/**
+ * Initial state is populated the first time reload() is called which is at the bottom
+ * of this file. This is a cheat as get_class_vars() returns the value of static vars even if they
+ * have changed.
+ *
+ * @var array
+ */
+ protected static $_initialState = array();
+
+/**
+ * Default route class to use
+ *
+ * @var string
+ */
+ protected static $_routeClass = 'CakeRoute';
+
+/**
+ * Set the default route class to use or return the current one
+ *
+ * @param string $routeClass to set as default
+ * @return mixed void|string
+ * @throws RouterException
+ */
+ public static function defaultRouteClass($routeClass = null) {
+ if (is_null($routeClass)) {
+ return self::$_routeClass;
+ }
+
+ self::$_routeClass = self::_validateRouteClass($routeClass);
+ }
+
+/**
+ * Validates that the passed route class exists and is a subclass of CakeRoute
+ *
+ * @param $routeClass
+ * @return string
+ * @throws RouterException
+ */
+ protected static function _validateRouteClass($routeClass) {
+ if (!class_exists($routeClass) || !is_subclass_of($routeClass, 'CakeRoute')) {
+ throw new RouterException(__d('cake_dev', 'Route classes must extend CakeRoute'));
+ }
+ return $routeClass;
+ }
+
+/**
+ * Sets the Routing prefixes.
+ *
+ * @return void
+ */
+ protected static function _setPrefixes() {
+ $routing = Configure::read('Routing');
+ if (!empty($routing['prefixes'])) {
+ self::$_prefixes = array_merge(self::$_prefixes, (array)$routing['prefixes']);
+ }
+ }
+
+/**
+ * Gets the named route elements for use in app/Config/routes.php
+ *
+ * @return array Named route elements
+ * @see Router::$_namedExpressions
+ */
+ public static function getNamedExpressions() {
+ return self::$_namedExpressions;
+ }
+
+/**
+ * Resource map getter & setter.
+ *
+ * @param array $resourceMap Resource map
+ * @return mixed
+ * @see Router::$_resourceMap
+ */
+ public static function resourceMap($resourceMap = null) {
+ if ($resourceMap === null) {
+ return self::$_resourceMap;
+ }
+ self::$_resourceMap = $resourceMap;
+ }
+
+/**
+ * Connects a new Route in the router.
+ *
+ * Routes are a way of connecting request urls to objects in your application. At their core routes
+ * are a set or regular expressions that are used to match requests to destinations.
+ *
+ * Examples:
+ *
+ * `Router::connect('/:controller/:action/*');`
+ *
+ * The first parameter will be used as a controller name while the second is used as the action name.
+ * the '/*' syntax makes this route greedy in that it will match requests like `/posts/index` as well as requests
+ * like `/posts/edit/1/foo/bar`.
+ *
+ * `Router::connect('/home-page', array('controller' => 'pages', 'action' => 'display', 'home'));`
+ *
+ * The above shows the use of route parameter defaults. And providing routing parameters for a static route.
+ *
+ * {{{
+ * Router::connect(
+ * '/:lang/:controller/:action/:id',
+ * array(),
+ * array('id' => '[0-9]+', 'lang' => '[a-z]{3}')
+ * );
+ * }}}
+ *
+ * Shows connecting a route with custom route parameters as well as providing patterns for those parameters.
+ * Patterns for routing parameters do not need capturing groups, as one will be added for each route params.
+ *
+ * $options offers four 'special' keys. `pass`, `named`, `persist` and `routeClass`
+ * have special meaning in the $options array.
+ *
+ * `pass` is used to define which of the routed parameters should be shifted into the pass array. Adding a
+ * parameter to pass will remove it from the regular route array. Ex. `'pass' => array('slug')`
+ *
+ * `persist` is used to define which route parameters should be automatically included when generating
+ * new urls. You can override persistent parameters by redefining them in a url or remove them by
+ * setting the parameter to `false`. Ex. `'persist' => array('lang')`
+ *
+ * `routeClass` is used to extend and change how individual routes parse requests and handle reverse routing,
+ * via a custom routing class. Ex. `'routeClass' => 'SlugRoute'`
+ *
+ * `named` is used to configure named parameters at the route level. This key uses the same options
+ * as Router::connectNamed()
+ *
+ * @param string $route A string describing the template of the route
+ * @param array $defaults An array describing the default route parameters. These parameters will be used by default
+ * and can supply routing parameters that are not dynamic. See above.
+ * @param array $options An array matching the named elements in the route to regular expressions which that
+ * element should match. Also contains additional parameters such as which routed parameters should be
+ * shifted into the passed arguments, supplying patterns for routing parameters and supplying the name of a
+ * custom routing class.
+ * @see routes
+ * @return array Array of routes
+ * @throws RouterException
+ */
+ public static function connect($route, $defaults = array(), $options = array()) {
+ foreach (self::$_prefixes as $prefix) {
+ if (isset($defaults[$prefix])) {
+ if ($defaults[$prefix]) {
+ $defaults['prefix'] = $prefix;
+ } else {
+ unset($defaults[$prefix]);
+ }
+ break;
+ }
+ }
+ if (isset($defaults['prefix'])) {
+ self::$_prefixes[] = $defaults['prefix'];
+ self::$_prefixes = array_keys(array_flip(self::$_prefixes));
+ }
+ $defaults += array('plugin' => null);
+ if (empty($options['action'])) {
+ $defaults += array('action' => 'index');
+ }
+ $routeClass = self::$_routeClass;
+ if (isset($options['routeClass'])) {
+ $routeClass = self::_validateRouteClass($options['routeClass']);
+ unset($options['routeClass']);
+ }
+ if ($routeClass == 'RedirectRoute' && isset($defaults['redirect'])) {
+ $defaults = $defaults['redirect'];
+ }
+ self::$routes[] = new $routeClass($route, $defaults, $options);
+ return self::$routes;
+ }
+
+/**
+ * Connects a new redirection Route in the router.
+ *
+ * Redirection routes are different from normal routes as they perform an actual
+ * header redirection if a match is found. The redirection can occur within your
+ * application or redirect to an outside location.
+ *
+ * Examples:
+ *
+ * `Router::redirect('/home/*', array('controller' => 'posts', 'action' => 'view', array('persist' => true)));`
+ *
+ * Redirects /home/* to /posts/view and passes the parameters to /posts/view. Using an array as the
+ * redirect destination allows you to use other routes to define where a url string should be redirected to.
+ *
+ * `Router::redirect('/posts/*', 'http://google.com', array('status' => 302));`
+ *
+ * Redirects /posts/* to http://google.com with a HTTP status of 302
+ *
+ * ### Options:
+ *
+ * - `status` Sets the HTTP status (default 301)
+ * - `persist` Passes the params to the redirected route, if it can. This is useful with greedy routes,
+ * routes that end in `*` are greedy. As you can remap urls and not loose any passed/named args.
+ *
+ * @param string $route A string describing the template of the route
+ * @param array $url A url to redirect to. Can be a string or a Cake array-based url
+ * @param array $options An array matching the named elements in the route to regular expressions which that
+ * element should match. Also contains additional parameters such as which routed parameters should be
+ * shifted into the passed arguments. As well as supplying patterns for routing parameters.
+ * @see routes
+ * @return array Array of routes
+ */
+ public static function redirect($route, $url, $options = array()) {
+ App::uses('RedirectRoute', 'Routing/Route');
+ $options['routeClass'] = 'RedirectRoute';
+ if (is_string($url)) {
+ $url = array('redirect' => $url);
+ }
+ return self::connect($route, $url, $options);
+ }
+
+/**
+ * Specifies what named parameters CakePHP should be parsing out of incoming urls. By default
+ * CakePHP will parse every named parameter out of incoming URLs. However, if you want to take more
+ * control over how named parameters are parsed you can use one of the following setups:
+ *
+ * Do not parse any named parameters:
+ *
+ * {{{ Router::connectNamed(false); }}}
+ *
+ * Parse only default parameters used for CakePHP's pagination:
+ *
+ * {{{ Router::connectNamed(false, array('default' => true)); }}}
+ *
+ * Parse only the page parameter if its value is a number:
+ *
+ * {{{ Router::connectNamed(array('page' => '[\d]+'), array('default' => false, 'greedy' => false)); }}}
+ *
+ * Parse only the page parameter no matter what.
+ *
+ * {{{ Router::connectNamed(array('page'), array('default' => false, 'greedy' => false)); }}}
+ *
+ * Parse only the page parameter if the current action is 'index'.
+ *
+ * {{{
+ * Router::connectNamed(
+ * array('page' => array('action' => 'index')),
+ * array('default' => false, 'greedy' => false)
+ * );
+ * }}}
+ *
+ * Parse only the page parameter if the current action is 'index' and the controller is 'pages'.
+ *
+ * {{{
+ * Router::connectNamed(
+ * array('page' => array('action' => 'index', 'controller' => 'pages')),
+ * array('default' => false, 'greedy' => false)
+ * );
+ * }}}
+ *
+ * ### Options
+ *
+ * - `greedy` Setting this to true will make Router parse all named params. Setting it to false will
+ * parse only the connected named params.
+ * - `default` Set this to true to merge in the default set of named parameters.
+ * - `reset` Set to true to clear existing rules and start fresh.
+ * - `separator` Change the string used to separate the key & value in a named parameter. Defaults to `:`
+ *
+ * @param array $named A list of named parameters. Key value pairs are accepted where values are
+ * either regex strings to match, or arrays as seen above.
+ * @param array $options Allows to control all settings: separator, greedy, reset, default
+ * @return array
+ */
+ public static function connectNamed($named, $options = array()) {
+ if (isset($options['separator'])) {
+ self::$_namedConfig['separator'] = $options['separator'];
+ unset($options['separator']);
+ }
+
+ if ($named === true || $named === false) {
+ $options = array_merge(array('default' => $named, 'reset' => true, 'greedy' => $named), $options);
+ $named = array();
+ } else {
+ $options = array_merge(array('default' => false, 'reset' => false, 'greedy' => true), $options);
+ }
+
+ if ($options['reset'] == true || self::$_namedConfig['rules'] === false) {
+ self::$_namedConfig['rules'] = array();
+ }
+
+ if ($options['default']) {
+ $named = array_merge($named, self::$_namedConfig['default']);
+ }
+
+ foreach ($named as $key => $val) {
+ if (is_numeric($key)) {
+ self::$_namedConfig['rules'][$val] = true;
+ } else {
+ self::$_namedConfig['rules'][$key] = $val;
+ }
+ }
+ self::$_namedConfig['greedyNamed'] = $options['greedy'];
+ return self::$_namedConfig;
+ }
+
+/**
+ * Gets the current named parameter configuration values.
+ *
+ * @return array
+ * @see Router::$_namedConfig
+ */
+ public static function namedConfig() {
+ return self::$_namedConfig;
+ }
+
+/**
+ * Creates REST resource routes for the given controller(s). When creating resource routes
+ * for a plugin, by default the prefix will be changed to the lower_underscore version of the plugin
+ * name. By providing a prefix you can override this behavior.
+ *
+ * ### Options:
+ *
+ * - 'id' - The regular expression fragment to use when matching IDs. By default, matches
+ * integer values and UUIDs.
+ * - 'prefix' - URL prefix to use for the generated routes. Defaults to '/'.
+ *
+ * @param string|array $controller A controller name or array of controller names (i.e. "Posts" or "ListItems")
+ * @param array $options Options to use when generating REST routes
+ * @return array Array of mapped resources
+ */
+ public static function mapResources($controller, $options = array()) {
+ $hasPrefix = isset($options['prefix']);
+ $options = array_merge(array(
+ 'prefix' => '/',
+ 'id' => self::ID . '|' . self::UUID
+ ), $options);
+
+ $prefix = $options['prefix'];
+
+ foreach ((array)$controller as $name) {
+ list($plugin, $name) = pluginSplit($name);
+ $urlName = Inflector::underscore($name);
+ $plugin = Inflector::underscore($plugin);
+ if ($plugin && !$hasPrefix) {
+ $prefix = '/' . $plugin . '/';
+ }
+
+ foreach (self::$_resourceMap as $params) {
+ $url = $prefix . $urlName . (($params['id']) ? '/:id' : '');
+
+ Router::connect($url,
+ array(
+ 'plugin' => $plugin,
+ 'controller' => $urlName,
+ 'action' => $params['action'],
+ '[method]' => $params['method']
+ ),
+ array('id' => $options['id'], 'pass' => array('id'))
+ );
+ }
+ self::$_resourceMapped[] = $urlName;
+ }
+ return self::$_resourceMapped;
+ }
+
+/**
+ * Returns the list of prefixes used in connected routes
+ *
+ * @return array A list of prefixes used in connected routes
+ */
+ public static function prefixes() {
+ return self::$_prefixes;
+ }
+
+/**
+ * Parses given URL string. Returns 'routing' parameters for that url.
+ *
+ * @param string $url URL to be parsed
+ * @return array Parsed elements from URL
+ */
+ public static function parse($url) {
+ $ext = null;
+ $out = array();
+
+ if ($url && strpos($url, '/') !== 0) {
+ $url = '/' . $url;
+ }
+ if (strpos($url, '?') !== false) {
+ $url = substr($url, 0, strpos($url, '?'));
+ }
+
+ extract(self::_parseExtension($url));
+
+ for ($i = 0, $len = count(self::$routes); $i < $len; $i++) {
+ $route =& self::$routes[$i];
+
+ if (($r = $route->parse($url)) !== false) {
+ self::$_currentRoute[] =& $route;
+ $out = $r;
+ break;
+ }
+ }
+ if (isset($out['prefix'])) {
+ $out['action'] = $out['prefix'] . '_' . $out['action'];
+ }
+
+ if (!empty($ext) && !isset($out['ext'])) {
+ $out['ext'] = $ext;
+ }
+ return $out;
+ }
+
+/**
+ * Parses a file extension out of a URL, if Router::parseExtensions() is enabled.
+ *
+ * @param string $url
+ * @return array Returns an array containing the altered URL and the parsed extension.
+ */
+ protected static function _parseExtension($url) {
+ $ext = null;
+
+ if (self::$_parseExtensions) {
+ if (preg_match('/\.[0-9a-zA-Z]*$/', $url, $match) === 1) {
+ $match = substr($match[0], 1);
+ if (empty(self::$_validExtensions)) {
+ $url = substr($url, 0, strpos($url, '.' . $match));
+ $ext = $match;
+ } else {
+ foreach (self::$_validExtensions as $name) {
+ if (strcasecmp($name, $match) === 0) {
+ $url = substr($url, 0, strpos($url, '.' . $name));
+ $ext = $match;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return compact('ext', 'url');
+ }
+
+/**
+ * Takes parameter and path information back from the Dispatcher, sets these
+ * parameters as the current request parameters that are merged with url arrays
+ * created later in the request.
+ *
+ * Nested requests will create a stack of requests. You can remove requests using
+ * Router::popRequest(). This is done automatically when using Object::requestAction().
+ *
+ * Will accept either a CakeRequest object or an array of arrays. Support for
+ * accepting arrays may be removed in the future.
+ *
+ * @param CakeRequest|array $request Parameters and path information or a CakeRequest object.
+ * @return void
+ */
+ public static function setRequestInfo($request) {
+ if ($request instanceof CakeRequest) {
+ self::$_requests[] = $request;
+ } else {
+ $requestObj = new CakeRequest();
+ $request += array(array(), array());
+ $request[0] += array('controller' => false, 'action' => false, 'plugin' => null);
+ $requestObj->addParams($request[0])->addPaths($request[1]);
+ self::$_requests[] = $requestObj;
+ }
+ }
+
+/**
+ * Pops a request off of the request stack. Used when doing requestAction
+ *
+ * @return CakeRequest The request removed from the stack.
+ * @see Router::setRequestInfo()
+ * @see Object::requestAction()
+ */
+ public static function popRequest() {
+ return array_pop(self::$_requests);
+ }
+
+/**
+ * Get the either the current request object, or the first one.
+ *
+ * @param boolean $current Whether you want the request from the top of the stack or the first one.
+ * @return CakeRequest or null.
+ */
+ public static function getRequest($current = false) {
+ if ($current) {
+ $i = count(self::$_requests) - 1;
+ return isset(self::$_requests[$i]) ? self::$_requests[$i] : null;
+ }
+ return isset(self::$_requests[0]) ? self::$_requests[0] : null;
+ }
+
+/**
+ * Gets parameter information
+ *
+ * @param boolean $current Get current request parameter, useful when using requestAction
+ * @return array Parameter information
+ */
+ public static function getParams($current = false) {
+ if ($current) {
+ return self::$_requests[count(self::$_requests) - 1]->params;
+ }
+ if (isset(self::$_requests[0])) {
+ return self::$_requests[0]->params;
+ }
+ return array();
+ }
+
+/**
+ * Gets URL parameter by name
+ *
+ * @param string $name Parameter name
+ * @param boolean $current Current parameter, useful when using requestAction
+ * @return string Parameter value
+ */
+ public static function getParam($name = 'controller', $current = false) {
+ $params = Router::getParams($current);
+ if (isset($params[$name])) {
+ return $params[$name];
+ }
+ return null;
+ }
+
+/**
+ * Gets path information
+ *
+ * @param boolean $current Current parameter, useful when using requestAction
+ * @return array
+ */
+ public static function getPaths($current = false) {
+ if ($current) {
+ return self::$_requests[count(self::$_requests) - 1];
+ }
+ if (!isset(self::$_requests[0])) {
+ return array('base' => null);
+ }
+ return array('base' => self::$_requests[0]->base);
+ }
+
+/**
+ * Reloads default Router settings. Resets all class variables and
+ * removes all connected routes.
+ *
+ * @return void
+ */
+ public static function reload() {
+ if (empty(self::$_initialState)) {
+ self::$_initialState = get_class_vars('Router');
+ self::_setPrefixes();
+ return;
+ }
+ foreach (self::$_initialState as $key => $val) {
+ if ($key != '_initialState') {
+ self::${$key} = $val;
+ }
+ }
+ self::_setPrefixes();
+ }
+
+/**
+ * Promote a route (by default, the last one added) to the beginning of the list
+ *
+ * @param integer $which A zero-based array index representing the route to move. For example,
+ * if 3 routes have been added, the last route would be 2.
+ * @return boolean Returns false if no route exists at the position specified by $which.
+ */
+ public static function promote($which = null) {
+ if ($which === null) {
+ $which = count(self::$routes) - 1;
+ }
+ if (!isset(self::$routes[$which])) {
+ return false;
+ }
+ $route =& self::$routes[$which];
+ unset(self::$routes[$which]);
+ array_unshift(self::$routes, $route);
+ return true;
+ }
+
+/**
+ * Finds URL for specified action.
+ *
+ * Returns an URL pointing to a combination of controller and action. Param
+ * $url can be:
+ *
+ * - Empty - the method will find address to actual controller/action.
+ * - '/' - the method will find base URL of application.
+ * - A combination of controller/action - the method will find url for it.
+ *
+ * There are a few 'special' parameters that can change the final URL string that is generated
+ *
+ * - `base` - Set to false to remove the base path from the generated url. If your application
+ * is not in the root directory, this can be used to generate urls that are 'cake relative'.
+ * cake relative urls are required when using requestAction.
+ * - `?` - Takes an array of query string parameters
+ * - `#` - Allows you to set url hash fragments.
+ * - `full_base` - If true the `FULL_BASE_URL` constant will be prepended to generated urls.
+ *
+ * @param string|array $url Cake-relative URL, like "/products/edit/92" or "/presidents/elect/4"
+ * or an array specifying any of the following: 'controller', 'action',
+ * and/or 'plugin', in addition to named arguments (keyed array elements),
+ * and standard URL arguments (indexed array elements)
+ * @param bool|array $full If (bool) true, the full base URL will be prepended to the result.
+ * If an array accepts the following keys
+ * - escape - used when making urls embedded in html escapes query string '&'
+ * - full - if true the full base URL will be prepended.
+ * @return string Full translated URL with base path.
+ */
+ public static function url($url = null, $full = false) {
+ $params = array('plugin' => null, 'controller' => null, 'action' => 'index');
+
+ if (is_bool($full)) {
+ $escape = false;
+ } else {
+ extract($full + array('escape' => false, 'full' => false));
+ }
+
+ $path = array('base' => null);
+ if (!empty(self::$_requests)) {
+ $request = self::$_requests[count(self::$_requests) - 1];
+ $params = $request->params;
+ $path = array('base' => $request->base, 'here' => $request->here);
+ }
+
+ $base = $path['base'];
+ $extension = $output = $q = $frag = null;
+
+ if (empty($url)) {
+ $output = isset($path['here']) ? $path['here'] : '/';
+ if ($full && defined('FULL_BASE_URL')) {
+ $output = FULL_BASE_URL . $output;
+ }
+ return $output;
+ } elseif (is_array($url)) {
+ if (isset($url['base']) && $url['base'] === false) {
+ $base = null;
+ unset($url['base']);
+ }
+ if (isset($url['full_base']) && $url['full_base'] === true) {
+ $full = true;
+ unset($url['full_base']);
+ }
+ if (isset($url['?'])) {
+ $q = $url['?'];
+ unset($url['?']);
+ }
+ if (isset($url['#'])) {
+ $frag = '#' . $url['#'];
+ unset($url['#']);
+ }
+ if (isset($url['ext'])) {
+ $extension = '.' . $url['ext'];
+ unset($url['ext']);
+ }
+ if (empty($url['action'])) {
+ if (empty($url['controller']) || $params['controller'] === $url['controller']) {
+ $url['action'] = $params['action'];
+ } else {
+ $url['action'] = 'index';
+ }
+ }
+
+ $prefixExists = (array_intersect_key($url, array_flip(self::$_prefixes)));
+ foreach (self::$_prefixes as $prefix) {
+ if (!empty($params[$prefix]) && !$prefixExists) {
+ $url[$prefix] = true;
+ } elseif (isset($url[$prefix]) && !$url[$prefix]) {
+ unset($url[$prefix]);
+ }
+ if (isset($url[$prefix]) && strpos($url['action'], $prefix . '_') === 0) {
+ $url['action'] = substr($url['action'], strlen($prefix) + 1);
+ }
+ }
+
+ $url += array('controller' => $params['controller'], 'plugin' => $params['plugin']);
+
+ $match = false;
+
+ for ($i = 0, $len = count(self::$routes); $i < $len; $i++) {
+ $originalUrl = $url;
+
+ if (isset(self::$routes[$i]->options['persist'], $params)) {
+ $url = self::$routes[$i]->persistParams($url, $params);
+ }
+
+ if ($match = self::$routes[$i]->match($url)) {
+ $output = trim($match, '/');
+ break;
+ }
+ $url = $originalUrl;
+ }
+ if ($match === false) {
+ $output = self::_handleNoRoute($url);
+ }
+ } else {
+ if (
+ (strpos($url, '://') !== false ||
+ (strpos($url, 'javascript:') === 0) ||
+ (strpos($url, 'mailto:') === 0)) ||
+ (!strncmp($url, '#', 1))
+ ) {
+ return $url;
+ }
+ if (substr($url, 0, 1) === '/') {
+ $output = substr($url, 1);
+ } else {
+ foreach (self::$_prefixes as $prefix) {
+ if (isset($params[$prefix])) {
+ $output .= $prefix . '/';
+ break;
+ }
+ }
+ if (!empty($params['plugin']) && $params['plugin'] !== $params['controller']) {
+ $output .= Inflector::underscore($params['plugin']) . '/';
+ }
+ $output .= Inflector::underscore($params['controller']) . '/' . $url;
+ }
+ }
+ $protocol = preg_match('#^[a-z][a-z0-9+-.]*\://#i', $output);
+ if ($protocol === 0) {
+ $output = str_replace('//', '/', $base . '/' . $output);
+
+ if ($full && defined('FULL_BASE_URL')) {
+ $output = FULL_BASE_URL . $output;
+ }
+ if (!empty($extension)) {
+ $output = rtrim($output, '/');
+ }
+ }
+ return $output . $extension . self::queryString($q, array(), $escape) . $frag;
+ }
+
+/**
+ * A special fallback method that handles url arrays that cannot match
+ * any defined routes.
+ *
+ * @param array $url A url that didn't match any routes
+ * @return string A generated url for the array
+ * @see Router::url()
+ */
+ protected static function _handleNoRoute($url) {
+ $named = $args = array();
+ $skip = array_merge(
+ array('bare', 'action', 'controller', 'plugin', 'prefix'),
+ self::$_prefixes
+ );
+
+ $keys = array_values(array_diff(array_keys($url), $skip));
+ $count = count($keys);
+
+ // Remove this once parsed URL parameters can be inserted into 'pass'
+ for ($i = 0; $i < $count; $i++) {
+ $key = $keys[$i];
+ if (is_numeric($keys[$i])) {
+ $args[] = $url[$key];
+ } else {
+ $named[$key] = $url[$key];
+ }
+ }
+
+ list($args, $named) = array(Hash::filter($args), Hash::filter($named));
+ foreach (self::$_prefixes as $prefix) {
+ $prefixed = $prefix . '_';
+ if (!empty($url[$prefix]) && strpos($url['action'], $prefixed) === 0) {
+ $url['action'] = substr($url['action'], strlen($prefixed) * -1);
+ break;
+ }
+ }
+
+ if (empty($named) && empty($args) && (!isset($url['action']) || $url['action'] === 'index')) {
+ $url['action'] = null;
+ }
+
+ $urlOut = array_filter(array($url['controller'], $url['action']));
+
+ if (isset($url['plugin'])) {
+ array_unshift($urlOut, $url['plugin']);
+ }
+
+ foreach (self::$_prefixes as $prefix) {
+ if (isset($url[$prefix])) {
+ array_unshift($urlOut, $prefix);
+ break;
+ }
+ }
+ $output = implode('/', $urlOut);
+
+ if (!empty($args)) {
+ $output .= '/' . implode('/', array_map('rawurlencode', $args));
+ }
+
+ if (!empty($named)) {
+ foreach ($named as $name => $value) {
+ if (is_array($value)) {
+ $flattend = Hash::flatten($value, '][');
+ foreach ($flattend as $namedKey => $namedValue) {
+ $output .= '/' . $name . "[$namedKey]" . self::$_namedConfig['separator'] . rawurlencode($namedValue);
+ }
+ } else {
+ $output .= '/' . $name . self::$_namedConfig['separator'] . rawurlencode($value);
+ }
+ }
+ }
+ return $output;
+ }
+
+/**
+ * Generates a well-formed querystring from $q
+ *
+ * @param string|array $q Query string Either a string of already compiled query string arguments or
+ * an array of arguments to convert into a query string.
+ * @param array $extra Extra querystring parameters.
+ * @param boolean $escape Whether or not to use escaped &
+ * @return array
+ */
+ public static function queryString($q, $extra = array(), $escape = false) {
+ if (empty($q) && empty($extra)) {
+ return null;
+ }
+ $join = '&';
+ if ($escape === true) {
+ $join = '&amp;';
+ }
+ $out = '';
+
+ if (is_array($q)) {
+ $q = array_merge($q, $extra);
+ } else {
+ $out = $q;
+ $q = $extra;
+ }
+ $addition = http_build_query($q, null, $join);
+
+ if ($out && $addition && substr($out, strlen($join) * -1, strlen($join)) != $join) {
+ $out .= $join;
+ }
+
+ $out .= $addition;
+
+ if (isset($out[0]) && $out[0] != '?') {
+ $out = '?' . $out;
+ }
+ return $out;
+ }
+
+/**
+ * Reverses a parsed parameter array into a string. Works similarly to Router::url(), but
+ * Since parsed URL's contain additional 'pass' and 'named' as well as 'url.url' keys.
+ * Those keys need to be specially handled in order to reverse a params array into a string url.
+ *
+ * This will strip out 'autoRender', 'bare', 'requested', and 'return' param names as those
+ * are used for CakePHP internals and should not normally be part of an output url.
+ *
+ * @param CakeRequest|array $params The params array or CakeRequest object that needs to be reversed.
+ * @param boolean $full Set to true to include the full url including the protocol when reversing
+ * the url.
+ * @return string The string that is the reversed result of the array
+ */
+ public static function reverse($params, $full = false) {
+ if ($params instanceof CakeRequest) {
+ $url = $params->query;
+ $params = $params->params;
+ } else {
+ $url = $params['url'];
+ }
+ $pass = isset($params['pass']) ? $params['pass'] : array();
+ $named = isset($params['named']) ? $params['named'] : array();
+
+ unset(
+ $params['pass'], $params['named'], $params['paging'], $params['models'], $params['url'], $url['url'],
+ $params['autoRender'], $params['bare'], $params['requested'], $params['return'],
+ $params['_Token']
+ );
+ $params = array_merge($params, $pass, $named);
+ if (!empty($url)) {
+ $params['?'] = $url;
+ }
+ return Router::url($params, $full);
+ }
+
+/**
+ * Normalizes a URL for purposes of comparison. Will strip the base path off
+ * and replace any double /'s. It will not unify the casing and underscoring
+ * of the input value.
+ *
+ * @param array|string $url URL to normalize Either an array or a string url.
+ * @return string Normalized URL
+ */
+ public static function normalize($url = '/') {
+ if (is_array($url)) {
+ $url = Router::url($url);
+ }
+ if (preg_match('/^[a-z\-]+:\/\//', $url)) {
+ return $url;
+ }
+ $request = Router::getRequest();
+
+ if (!empty($request->base) && stristr($url, $request->base)) {
+ $url = preg_replace('/^' . preg_quote($request->base, '/') . '/', '', $url, 1);
+ }
+ $url = '/' . $url;
+
+ while (strpos($url, '//') !== false) {
+ $url = str_replace('//', '/', $url);
+ }
+ $url = preg_replace('/(?:(\/$))/', '', $url);
+
+ if (empty($url)) {
+ return '/';
+ }
+ return $url;
+ }
+
+/**
+ * Returns the route matching the current request URL.
+ *
+ * @return CakeRoute Matching route object.
+ */
+ public static function &requestRoute() {
+ return self::$_currentRoute[0];
+ }
+
+/**
+ * Returns the route matching the current request (useful for requestAction traces)
+ *
+ * @return CakeRoute Matching route object.
+ */
+ public static function &currentRoute() {
+ return self::$_currentRoute[count(self::$_currentRoute) - 1];
+ }
+
+/**
+ * Removes the plugin name from the base URL.
+ *
+ * @param string $base Base URL
+ * @param string $plugin Plugin name
+ * @return string base url with plugin name removed if present
+ */
+ public static function stripPlugin($base, $plugin = null) {
+ if ($plugin != null) {
+ $base = preg_replace('/(?:' . $plugin . ')/', '', $base);
+ $base = str_replace('//', '', $base);
+ $pos1 = strrpos($base, '/');
+ $char = strlen($base) - 1;
+
+ if ($pos1 === $char) {
+ $base = substr($base, 0, $char);
+ }
+ }
+ return $base;
+ }
+
+/**
+ * Instructs the router to parse out file extensions from the URL. For example,
+ * http://example.com/posts.rss would yield an file extension of "rss".
+ * The file extension itself is made available in the controller as
+ * `$this->params['ext']`, and is used by the RequestHandler component to
+ * automatically switch to alternate layouts and templates, and load helpers
+ * corresponding to the given content, i.e. RssHelper. Switching layouts and helpers
+ * requires that the chosen extension has a defined mime type in `CakeResponse`
+ *
+ * A list of valid extension can be passed to this method, i.e. Router::parseExtensions('rss', 'xml');
+ * If no parameters are given, anything after the first . (dot) after the last / in the URL will be
+ * parsed, excluding querystring parameters (i.e. ?q=...).
+ *
+ * @return void
+ * @see RequestHandler::startup()
+ */
+ public static function parseExtensions() {
+ self::$_parseExtensions = true;
+ if (func_num_args() > 0) {
+ self::setExtensions(func_get_args(), false);
+ }
+ }
+
+/**
+ * Get the list of extensions that can be parsed by Router.
+ * To initially set extensions use `Router::parseExtensions()`
+ * To add more see `setExtensions()`
+ *
+ * @return array Array of extensions Router is configured to parse.
+ */
+ public static function extensions() {
+ return self::$_validExtensions;
+ }
+
+/**
+ * Set/add valid extensions.
+ * To have the extensions parsed you still need to call `Router::parseExtensions()`
+ *
+ * @param array $extensions List of extensions to be added as valid extension
+ * @param boolean $merge Default true will merge extensions. Set to false to override current extensions
+ * @return array
+ */
+ public static function setExtensions($extensions, $merge = true) {
+ if (!is_array($extensions)) {
+ return self::$_validExtensions;
+ }
+ if (!$merge) {
+ return self::$_validExtensions = $extensions;
+ }
+ return self::$_validExtensions = array_merge(self::$_validExtensions, $extensions);
+ }
+
+}
+
+//Save the initial state
+Router::reload();
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllBehaviorsTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllBehaviorsTest.php
new file mode 100644
index 0000000..c2f30af
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllBehaviorsTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * AllBehaviorsTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * AllBehaviorsTest class
+ *
+ * This test group will run all test in the Case/Model/Behavior directory
+ *
+ * @package Cake.Test.Case
+ */
+class AllBehaviorsTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * Suite define the tests for this suite
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('Model Behavior and all behaviors');
+
+ $path = CORE_TEST_CASES . DS . 'Model' . DS . 'Behavior' . DS;
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'BehaviorCollectionTest.php');
+
+ $suite->addTestDirectory($path);
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCacheTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCacheTest.php
new file mode 100644
index 0000000..e9c8a3e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCacheTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * AllCacheTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllCacheTest class
+ *
+ * This test group will run cache engine tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllCacheTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Cache related class tests');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Cache');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Cache' . DS . 'Engine');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllComponentsTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllComponentsTest.php
new file mode 100644
index 0000000..25cf170
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllComponentsTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * AllComponentsTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllComponentsTest class
+ *
+ * This test group will run component class tests
+ *
+ * @package Cake.Test.Case
+ */
+class AllComponentsTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All component class tests');
+
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentCollectionTest.php');
+ $suite->addTestDirectoryRecursive(CORE_TEST_CASES . DS . 'Controller' . DS . 'Component');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConfigureTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConfigureTest.php
new file mode 100644
index 0000000..ff56ee6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConfigureTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * AllConfigureTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllConfigureTest class
+ *
+ * This test group will run configure tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllConfigureTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Configure related tests');
+
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Configure');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConsoleTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConsoleTest.php
new file mode 100644
index 0000000..820d622
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllConsoleTest.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * AllConsoleTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllConsoleTest class
+ *
+ * This test group will run all console classes.
+ *
+ * @package Cake.Test.Case
+ */
+class AllConsoleTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All console classes');
+
+ $path = CORE_TEST_CASES . DS . 'Console' . DS;
+
+ $suite->addTestFile($path . 'AllConsoleLibsTest.php');
+ $suite->addTestFile($path . 'AllTasksTest.php');
+ $suite->addTestFile($path . 'AllShellsTest.php');
+ return $suite;
+ }
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllControllerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllControllerTest.php
new file mode 100644
index 0000000..0d3a316
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllControllerTest.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * AllControllersTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllControllersTest class
+ *
+ * This test group will run Controller related tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllControllersTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Controller related class tests');
+
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ControllerTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ScaffoldTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'PagesControllerTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ComponentTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Controller' . DS . 'ControllerMergeVarsTest.php');
+ return $suite;
+ }
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCoreTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCoreTest.php
new file mode 100644
index 0000000..7964fe1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllCoreTest.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * AllCoreTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllCoreTest class
+ *
+ * This test group will run all core class tests
+ *
+ * @package Cake.Test.Case
+ */
+class AllCoreTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Core class tests');
+
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Core');
+ return $suite;
+ }
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllDatabaseTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllDatabaseTest.php
new file mode 100644
index 0000000..6357ab9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllDatabaseTest.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * AllDatabaseTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllDatabaseTest class
+ *
+ * This test group will run database tests not in model or behavior group.
+ *
+ * @package Cake.Test.Case
+ */
+class AllDatabaseTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new PHPUnit_Framework_TestSuite('Datasources, Schema and DbAcl tests');
+
+ $path = CORE_TEST_CASES . DS . 'Model' . DS;
+ $tasks = array(
+ 'AclNode',
+ 'CakeSchema',
+ 'ConnectionManager',
+ 'Datasource' . DS . 'DboSource',
+ 'Datasource' . DS . 'Database' . DS . 'Mysql',
+ 'Datasource' . DS . 'Database' . DS . 'Postgres',
+ 'Datasource' . DS . 'Database' . DS . 'Sqlite',
+ 'Datasource' . DS . 'Database' . DS . 'Sqlserver',
+ 'Datasource' . DS . 'CakeSession',
+ 'Datasource' . DS . 'Session' . DS . 'CacheSession',
+ 'Datasource' . DS . 'Session' . DS . 'DatabaseSession',
+ );
+ foreach ($tasks as $task) {
+ $suite->addTestFile($path . $task . 'Test.php');
+ }
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllErrorTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllErrorTest.php
new file mode 100644
index 0000000..0777ed5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllErrorTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * AllErrorTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllErrorTest class
+ *
+ * This test group will run error handling related tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllErrorTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Error handling tests');
+
+ $libs = CORE_TEST_CASES . DS;
+
+ $suite->addTestDirectory($libs . 'Error');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllEventTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllEventTest.php
new file mode 100644
index 0000000..9f8ab29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllEventTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * AllEventTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllEventTest class
+ *
+ * This test group will run Event tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllEventTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Event related class tests');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Event');
+ return $suite;
+ }
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllHelpersTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllHelpersTest.php
new file mode 100644
index 0000000..9c40ad6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllHelpersTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * HelpersGroupTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * HelpersGroupTest class
+ *
+ * This test group will run all Helper related tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllHelpersTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite declares tests to run
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Helper tests');
+
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'View' . DS . 'HelperTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'View' . DS . 'HelperCollectionTest.php');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'View' . DS . 'Helper' . DS);
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllI18nTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllI18nTest.php
new file mode 100644
index 0000000..b4bfb8b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllI18nTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * AllLocalizationTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllLocalizationTest class
+ *
+ * This test group will run i18n/l10n tests
+ *
+ * @package Cake.Test.Case
+ */
+class AllLocalizationTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All localization class tests');
+
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'I18n');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllLogTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllLogTest.php
new file mode 100644
index 0000000..e6dca95
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllLogTest.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * AllLogTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllLogTest class
+ *
+ * This test group will run log tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllLogTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Logging related class tests');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Log');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Log' . DS . 'Engine');
+ return $suite;
+ }
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllNetworkTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllNetworkTest.php
new file mode 100644
index 0000000..22809e0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllNetworkTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * AllNetworkTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllNetworkTest class
+ *
+ * This test group will run socket class tests
+ *
+ * @package Cake.Test.Case
+ */
+class AllNetworkTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Network related class tests');
+
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network' . DS . 'Email');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network' . DS . 'Http');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllRoutingTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllRoutingTest.php
new file mode 100644
index 0000000..ebd6712
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllRoutingTest.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * AllRoutingTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllRoutingTest class
+ *
+ * This test group will routing related tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllRoutingTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Routing class tests');
+
+ $libs = CORE_TEST_CASES . DS;
+
+ $suite->addTestDirectory($libs . 'Routing');
+ $suite->addTestDirectory($libs . 'Routing' . DS . 'Route');
+ $suite->addTestDirectory($libs . 'Routing' . DS . 'Filter');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestSuiteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestSuiteTest.php
new file mode 100644
index 0000000..1ead825
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestSuiteTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * AllTestSuiteTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllTestSuiteTest class
+ *
+ * This test group will run all test suite tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllTestSuiteTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Test Suite classes tests');
+
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'TestSuite');
+ return $suite;
+ }
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestsTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestsTest.php
new file mode 100644
index 0000000..8990359
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllTestsTest.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * AllTests file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * AllTests class
+ *
+ * This test group will run all tests.
+ *
+ * @package Cake.Test.Case
+ */
+class AllTests extends PHPUnit_Framework_TestSuite {
+
+/**
+ * Suite define the tests for this suite
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new PHPUnit_Framework_TestSuite('All Tests');
+
+ $path = CORE_TEST_CASES . DS;
+
+ $suite->addTestFile($path . 'BasicsTest.php');
+ $suite->addTestFile($path . 'AllConsoleTest.php');
+ $suite->addTestFile($path . 'AllBehaviorsTest.php');
+ $suite->addTestFile($path . 'AllCacheTest.php');
+ $suite->addTestFile($path . 'AllComponentsTest.php');
+ $suite->addTestFile($path . 'AllConfigureTest.php');
+ $suite->addTestFile($path . 'AllCoreTest.php');
+ $suite->addTestFile($path . 'AllControllerTest.php');
+ $suite->addTestFile($path . 'AllDatabaseTest.php');
+ $suite->addTestFile($path . 'AllErrorTest.php');
+ $suite->addTestFile($path . 'AllEventTest.php');
+ $suite->addTestFile($path . 'AllHelpersTest.php');
+ $suite->addTestFile($path . 'AllLogTest.php');
+ $suite->addTestFile($path . 'Model' . DS . 'ModelTest.php');
+ $suite->addTestFile($path . 'AllRoutingTest.php');
+ $suite->addTestFile($path . 'AllNetworkTest.php');
+ $suite->addTestFile($path . 'AllTestSuiteTest.php');
+ $suite->addTestFile($path . 'AllUtilityTest.php');
+ $suite->addTestFile($path . 'AllViewTest.php');
+ $suite->addTestFile($path . 'AllI18nTest.php');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllUtilityTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllUtilityTest.php
new file mode 100644
index 0000000..8b41d8d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllUtilityTest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * AllUtilityTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllUtilityTest class
+ *
+ * This test group will run all non mvc related lib class tests
+ *
+ * @package Cake.Test.Case
+ */
+class AllUtilityTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Utility class tests');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Utility');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllViewTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllViewTest.php
new file mode 100644
index 0000000..3a9bcd3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/AllViewTest.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * AllViewTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllViewTest class
+ *
+ * This test group will run view class tests (view, theme)
+ *
+ * @package Cake.Test.Case
+ */
+class AllViewTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All View class tests');
+
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'View');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/BasicsTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/BasicsTest.php
new file mode 100644
index 0000000..c218f1a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/BasicsTest.php
@@ -0,0 +1,942 @@
+<?php
+/**
+ * BasicsTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+require_once CAKE . 'basics.php';
+App::uses('Folder', 'Utility');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * BasicsTest class
+ *
+ * @package Cake.Test.Case
+ */
+class BasicsTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
+ ));
+ }
+
+/**
+ * test the array_diff_key compatibility function.
+ *
+ * @return void
+ */
+ public function testArrayDiffKey() {
+ $one = array('one' => 1, 'two' => 2, 'three' => 3);
+ $two = array('one' => 'one', 'two' => 'two');
+ $result = array_diff_key($one, $two);
+ $expected = array('three' => 3);
+ $this->assertEquals($expected, $result);
+
+ $one = array('one' => array('value', 'value-two'), 'two' => 2, 'three' => 3);
+ $two = array('two' => 'two');
+ $result = array_diff_key($one, $two);
+ $expected = array('one' => array('value', 'value-two'), 'three' => 3);
+ $this->assertEquals($expected, $result);
+
+ $one = array('one' => null, 'two' => 2, 'three' => '', 'four' => 0);
+ $two = array('two' => 'two');
+ $result = array_diff_key($one, $two);
+ $expected = array('one' => null, 'three' => '', 'four' => 0);
+ $this->assertEquals($expected, $result);
+
+ $one = array('minYear' => null, 'maxYear' => null, 'separator' => '-', 'interval' => 1, 'monthNames' => true);
+ $two = array('minYear' => null, 'maxYear' => null, 'separator' => '-', 'interval' => 1, 'monthNames' => true);
+ $result = array_diff_key($one, $two);
+ $this->assertEquals(array(), $result);
+ }
+
+/**
+ * testHttpBase method
+ *
+ * @return void
+ */
+ public function testEnv() {
+ $this->skipIf(!function_exists('ini_get') || ini_get('safe_mode') === '1', 'Safe mode is on.');
+
+ $server = $_SERVER;
+ $env = $_ENV;
+
+ $_SERVER['HTTP_HOST'] = 'localhost';
+ $this->assertEquals(env('HTTP_BASE'), '.localhost');
+
+ $_SERVER['HTTP_HOST'] = 'com.ar';
+ $this->assertEquals(env('HTTP_BASE'), '.com.ar');
+
+ $_SERVER['HTTP_HOST'] = 'example.ar';
+ $this->assertEquals(env('HTTP_BASE'), '.example.ar');
+
+ $_SERVER['HTTP_HOST'] = 'example.com';
+ $this->assertEquals(env('HTTP_BASE'), '.example.com');
+
+ $_SERVER['HTTP_HOST'] = 'www.example.com';
+ $this->assertEquals(env('HTTP_BASE'), '.example.com');
+
+ $_SERVER['HTTP_HOST'] = 'subdomain.example.com';
+ $this->assertEquals(env('HTTP_BASE'), '.example.com');
+
+ $_SERVER['HTTP_HOST'] = 'example.com.ar';
+ $this->assertEquals(env('HTTP_BASE'), '.example.com.ar');
+
+ $_SERVER['HTTP_HOST'] = 'www.example.com.ar';
+ $this->assertEquals(env('HTTP_BASE'), '.example.com.ar');
+
+ $_SERVER['HTTP_HOST'] = 'subdomain.example.com.ar';
+ $this->assertEquals(env('HTTP_BASE'), '.example.com.ar');
+
+ $_SERVER['HTTP_HOST'] = 'double.subdomain.example.com';
+ $this->assertEquals(env('HTTP_BASE'), '.subdomain.example.com');
+
+ $_SERVER['HTTP_HOST'] = 'double.subdomain.example.com.ar';
+ $this->assertEquals(env('HTTP_BASE'), '.subdomain.example.com.ar');
+
+ $_SERVER = $_ENV = array();
+
+ $_SERVER['SCRIPT_NAME'] = '/a/test/test.php';
+ $this->assertEquals(env('SCRIPT_NAME'), '/a/test/test.php');
+
+ $_SERVER = $_ENV = array();
+
+ $_ENV['CGI_MODE'] = 'BINARY';
+ $_ENV['SCRIPT_URL'] = '/a/test/test.php';
+ $this->assertEquals(env('SCRIPT_NAME'), '/a/test/test.php');
+
+ $_SERVER = $_ENV = array();
+
+ $this->assertFalse(env('HTTPS'));
+
+ $_SERVER['HTTPS'] = 'on';
+ $this->assertTrue(env('HTTPS'));
+
+ $_SERVER['HTTPS'] = '1';
+ $this->assertTrue(env('HTTPS'));
+
+ $_SERVER['HTTPS'] = 'I am not empty';
+ $this->assertTrue(env('HTTPS'));
+
+ $_SERVER['HTTPS'] = 1;
+ $this->assertTrue(env('HTTPS'));
+
+ $_SERVER['HTTPS'] = 'off';
+ $this->assertFalse(env('HTTPS'));
+
+ $_SERVER['HTTPS'] = false;
+ $this->assertFalse(env('HTTPS'));
+
+ $_SERVER['HTTPS'] = '';
+ $this->assertFalse(env('HTTPS'));
+
+ $_SERVER = array();
+
+ $_ENV['SCRIPT_URI'] = 'https://domain.test/a/test.php';
+ $this->assertTrue(env('HTTPS'));
+
+ $_ENV['SCRIPT_URI'] = 'http://domain.test/a/test.php';
+ $this->assertFalse(env('HTTPS'));
+
+ $_SERVER = $_ENV = array();
+
+ $this->assertNull(env('TEST_ME'));
+
+ $_ENV['TEST_ME'] = 'a';
+ $this->assertEquals(env('TEST_ME'), 'a');
+
+ $_SERVER['TEST_ME'] = 'b';
+ $this->assertEquals(env('TEST_ME'), 'b');
+
+ unset($_ENV['TEST_ME']);
+ $this->assertEquals(env('TEST_ME'), 'b');
+
+ $_SERVER = $server;
+ $_ENV = $env;
+ }
+
+/**
+ * Test h()
+ *
+ * @return void
+ */
+ public function testH() {
+ $string = '<foo>';
+ $result = h($string);
+ $this->assertEquals('&lt;foo&gt;', $result);
+
+ $in = array('this & that', '<p>Which one</p>');
+ $result = h($in);
+ $expected = array('this &amp; that', '&lt;p&gt;Which one&lt;/p&gt;');
+ $this->assertEquals($expected, $result);
+
+ $string = '<foo> & &nbsp;';
+ $result = h($string);
+ $this->assertEquals('&lt;foo&gt; &amp; &amp;nbsp;', $result);
+
+ $string = '<foo> & &nbsp;';
+ $result = h($string, false);
+ $this->assertEquals('&lt;foo&gt; &amp; &nbsp;', $result);
+
+ $string = '<foo> & &nbsp;';
+ $result = h($string, 'UTF-8');
+ $this->assertEquals('&lt;foo&gt; &amp; &amp;nbsp;', $result);
+
+ $arr = array('<foo>', '&nbsp;');
+ $result = h($arr);
+ $expected = array(
+ '&lt;foo&gt;',
+ '&amp;nbsp;'
+ );
+ $this->assertEquals($expected, $result);
+
+ $arr = array('<foo>', '&nbsp;');
+ $result = h($arr, false);
+ $expected = array(
+ '&lt;foo&gt;',
+ '&nbsp;'
+ );
+ $this->assertEquals($expected, $result);
+
+ $arr = array('f' => '<foo>', 'n' => '&nbsp;');
+ $result = h($arr, false);
+ $expected = array(
+ 'f' => '&lt;foo&gt;',
+ 'n' => '&nbsp;'
+ );
+ $this->assertEquals($expected, $result);
+
+ $obj = new stdClass();
+ $result = h($obj);
+ $this->assertEquals('(object)stdClass', $result);
+
+ $obj = new CakeResponse(array('body' => 'Body content'));
+ $result = h($obj);
+ $this->assertEquals('Body content', $result);
+ }
+
+/**
+ * Test am()
+ *
+ * @return void
+ */
+ public function testAm() {
+ $result = am(array('one', 'two'), 2, 3, 4);
+ $expected = array('one', 'two', 2, 3, 4);
+ $this->assertEquals($expected, $result);
+
+ $result = am(array('one' => array(2, 3), 'two' => array('foo')), array('one' => array(4, 5)));
+ $expected = array('one' => array(4, 5), 'two' => array('foo'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test cache()
+ *
+ * @return void
+ */
+ public function testCache() {
+ $_cacheDisable = Configure::read('Cache.disable');
+ $this->skipIf($_cacheDisable, 'Cache is disabled, skipping cache() tests.');
+
+ Configure::write('Cache.disable', true);
+ $result = cache('basics_test', 'simple cache write');
+ $this->assertNull($result);
+
+ $result = cache('basics_test');
+ $this->assertNull($result);
+
+ Configure::write('Cache.disable', false);
+ $result = cache('basics_test', 'simple cache write');
+ $this->assertTrue((boolean)$result);
+ $this->assertTrue(file_exists(CACHE . 'basics_test'));
+
+ $result = cache('basics_test');
+ $this->assertEquals('simple cache write', $result);
+ @unlink(CACHE . 'basics_test');
+
+ cache('basics_test', 'expired', '+1 second');
+ sleep(2);
+ $result = cache('basics_test', null, '+1 second');
+ $this->assertNull($result);
+
+ Configure::write('Cache.disable', $_cacheDisable);
+ }
+
+/**
+ * test clearCache()
+ *
+ * @return void
+ */
+ public function testClearCache() {
+ $cacheOff = Configure::read('Cache.disable');
+ $this->skipIf($cacheOff, 'Cache is disabled, skipping clearCache() tests.');
+
+ cache('views' . DS . 'basics_test.cache', 'simple cache write');
+ $this->assertTrue(file_exists(CACHE . 'views' . DS . 'basics_test.cache'));
+
+ cache('views' . DS . 'basics_test_2.cache', 'simple cache write 2');
+ $this->assertTrue(file_exists(CACHE . 'views' . DS . 'basics_test_2.cache'));
+
+ cache('views' . DS . 'basics_test_3.cache', 'simple cache write 3');
+ $this->assertTrue(file_exists(CACHE . 'views' . DS . 'basics_test_3.cache'));
+
+ $result = clearCache(array('basics_test', 'basics_test_2'), 'views', '.cache');
+ $this->assertTrue($result);
+ $this->assertFalse(file_exists(CACHE . 'views' . DS . 'basics_test.cache'));
+ $this->assertFalse(file_exists(CACHE . 'views' . DS . 'basics_test.cache'));
+ $this->assertTrue(file_exists(CACHE . 'views' . DS . 'basics_test_3.cache'));
+
+ $result = clearCache(null, 'views', '.cache');
+ $this->assertTrue($result);
+ $this->assertFalse(file_exists(CACHE . 'views' . DS . 'basics_test_3.cache'));
+
+ // Different path from views and with prefix
+ cache('models' . DS . 'basics_test.cache', 'simple cache write');
+ $this->assertTrue(file_exists(CACHE . 'models' . DS . 'basics_test.cache'));
+
+ cache('models' . DS . 'basics_test_2.cache', 'simple cache write 2');
+ $this->assertTrue(file_exists(CACHE . 'models' . DS . 'basics_test_2.cache'));
+
+ cache('models' . DS . 'basics_test_3.cache', 'simple cache write 3');
+ $this->assertTrue(file_exists(CACHE . 'models' . DS . 'basics_test_3.cache'));
+
+ $result = clearCache('basics', 'models', '.cache');
+ $this->assertTrue($result);
+ $this->assertFalse(file_exists(CACHE . 'models' . DS . 'basics_test.cache'));
+ $this->assertFalse(file_exists(CACHE . 'models' . DS . 'basics_test_2.cache'));
+ $this->assertFalse(file_exists(CACHE . 'models' . DS . 'basics_test_3.cache'));
+
+ // checking if empty files were not removed
+ $emptyExists = file_exists(CACHE . 'views' . DS . 'empty');
+ if (!$emptyExists) {
+ cache('views' . DS . 'empty', '');
+ }
+ cache('views' . DS . 'basics_test.php', 'simple cache write');
+ $this->assertTrue(file_exists(CACHE . 'views' . DS . 'basics_test.php'));
+ $this->assertTrue(file_exists(CACHE . 'views' . DS . 'empty'));
+
+ $result = clearCache();
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists(CACHE . 'views' . DS . 'empty'));
+ $this->assertFalse(file_exists(CACHE . 'views' . DS . 'basics_test.php'));
+ if (!$emptyExists) {
+ unlink(CACHE . 'views' . DS . 'empty');
+ }
+ }
+
+/**
+ * test __()
+ *
+ * @return void
+ */
+ public function testTranslate() {
+ Configure::write('Config.language', 'rule_1_po');
+
+ $result = __('Plural Rule 1');
+ $expected = 'Plural Rule 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __('Plural Rule 1 (from core)');
+ $expected = 'Plural Rule 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __('Some string with %s', 'arguments');
+ $expected = 'Some string with arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __('Some string with %s %s', 'multiple', 'arguments');
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __('Some string with %s %s', array('multiple', 'arguments'));
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __('Testing %2$s %1$s', 'order', 'different');
+ $expected = 'Testing different order';
+ $this->assertEquals($expected, $result);
+
+ $result = __('Testing %2$s %1$s', array('order', 'different'));
+ $expected = 'Testing different order';
+ $this->assertEquals($expected, $result);
+
+ $result = __('Testing %.2f number', 1.2345);
+ $expected = 'Testing 1.23 number';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test __n()
+ *
+ * @return void
+ */
+ public function testTranslatePlural() {
+ Configure::write('Config.language', 'rule_1_po');
+
+ $result = __n('%d = 1', '%d = 0 or > 1', 0);
+ $expected = '%d = 0 or > 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __n('%d = 1', '%d = 0 or > 1', 1);
+ $expected = '%d = 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __n('%d = 1 (from core)', '%d = 0 or > 1 (from core)', 2);
+ $expected = '%d = 0 or > 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __n('%d item.', '%d items.', 1, 1);
+ $expected = '1 item.';
+ $this->assertEquals($expected, $result);
+
+ $result = __n('%d item for id %s', '%d items for id %s', 2, 2, '1234');
+ $expected = '2 items for id 1234';
+ $this->assertEquals($expected, $result);
+
+ $result = __n('%d item for id %s', '%d items for id %s', 2, array(2, '1234'));
+ $expected = '2 items for id 1234';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test __d()
+ *
+ * @return void
+ */
+ public function testTranslateDomain() {
+ Configure::write('Config.language', 'rule_1_po');
+
+ $result = __d('default', 'Plural Rule 1');
+ $expected = 'Plural Rule 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __d('core', 'Plural Rule 1');
+ $expected = 'Plural Rule 1';
+ $this->assertEquals($expected, $result);
+
+ $result = __d('core', 'Plural Rule 1 (from core)');
+ $expected = 'Plural Rule 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __d('core', 'Some string with %s', 'arguments');
+ $expected = 'Some string with arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __d('core', 'Some string with %s %s', 'multiple', 'arguments');
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __d('core', 'Some string with %s %s', array('multiple', 'arguments'));
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test __dn()
+ *
+ * @return void
+ */
+ public function testTranslateDomainPlural() {
+ Configure::write('Config.language', 'rule_1_po');
+
+ $result = __dn('default', '%d = 1', '%d = 0 or > 1', 0);
+ $expected = '%d = 0 or > 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dn('core', '%d = 1', '%d = 0 or > 1', 0);
+ $expected = '%d = 0 or > 1';
+ $this->assertEquals($expected, $result);
+
+ $result = __dn('core', '%d = 1 (from core)', '%d = 0 or > 1 (from core)', 0);
+ $expected = '%d = 0 or > 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dn('default', '%d = 1', '%d = 0 or > 1', 1);
+ $expected = '%d = 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dn('core', '%d item.', '%d items.', 1, 1);
+ $expected = '1 item.';
+ $this->assertEquals($expected, $result);
+
+ $result = __dn('core', '%d item for id %s', '%d items for id %s', 2, 2, '1234');
+ $expected = '2 items for id 1234';
+ $this->assertEquals($expected, $result);
+
+ $result = __dn('core', '%d item for id %s', '%d items for id %s', 2, array(2, '1234'));
+ $expected = '2 items for id 1234';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test __c()
+ *
+ * @return void
+ */
+ public function testTranslateCategory() {
+ Configure::write('Config.language', 'rule_1_po');
+
+ $result = __c('Plural Rule 1', 6);
+ $expected = 'Plural Rule 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __c('Plural Rule 1 (from core)', 6);
+ $expected = 'Plural Rule 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __c('Some string with %s', 6, 'arguments');
+ $expected = 'Some string with arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __c('Some string with %s %s', 6, 'multiple', 'arguments');
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __c('Some string with %s %s', 6, array('multiple', 'arguments'));
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test __dc()
+ *
+ * @return void
+ */
+ public function testTranslateDomainCategory() {
+ Configure::write('Config.language', 'rule_1_po');
+
+ $result = __dc('default', 'Plural Rule 1', 6);
+ $expected = 'Plural Rule 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dc('default', 'Plural Rule 1 (from core)', 6);
+ $expected = 'Plural Rule 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dc('core', 'Plural Rule 1', 6);
+ $expected = 'Plural Rule 1';
+ $this->assertEquals($expected, $result);
+
+ $result = __dc('core', 'Plural Rule 1 (from core)', 6);
+ $expected = 'Plural Rule 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dc('core', 'Some string with %s', 6, 'arguments');
+ $expected = 'Some string with arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __dc('core', 'Some string with %s %s', 6, 'multiple', 'arguments');
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+
+ $result = __dc('core', 'Some string with %s %s', 6, array('multiple', 'arguments'));
+ $expected = 'Some string with multiple arguments';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test __dcn()
+ *
+ * @return void
+ */
+ public function testTranslateDomainCategoryPlural() {
+ Configure::write('Config.language', 'rule_1_po');
+
+ $result = __dcn('default', '%d = 1', '%d = 0 or > 1', 0, 6);
+ $expected = '%d = 0 or > 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dcn('default', '%d = 1 (from core)', '%d = 0 or > 1 (from core)', 1, 6);
+ $expected = '%d = 1 (from core translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __dcn('core', '%d = 1', '%d = 0 or > 1', 0, 6);
+ $expected = '%d = 0 or > 1';
+ $this->assertEquals($expected, $result);
+
+ $result = __dcn('core', '%d item.', '%d items.', 1, 6, 1);
+ $expected = '1 item.';
+ $this->assertEquals($expected, $result);
+
+ $result = __dcn('core', '%d item for id %s', '%d items for id %s', 2, 6, 2, '1234');
+ $expected = '2 items for id 1234';
+ $this->assertEquals($expected, $result);
+
+ $result = __dcn('core', '%d item for id %s', '%d items for id %s', 2, 6, array(2, '1234'));
+ $expected = '2 items for id 1234';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test LogError()
+ *
+ * @return void
+ */
+ public function testLogError() {
+ @unlink(LOGS . 'error.log');
+
+ // disable stderr output for this test
+ if (CakeLog::stream('stderr')) {
+ CakeLog::disable('stderr');
+ }
+
+ LogError('Testing LogError() basic function');
+ LogError("Testing with\nmulti-line\nstring");
+
+ if (CakeLog::stream('stderr')) {
+ CakeLog::enable('stderr');
+ }
+
+ $result = file_get_contents(LOGS . 'error.log');
+ $this->assertRegExp('/Error: Testing LogError\(\) basic function/', $result);
+ $this->assertNotRegExp("/Error: Testing with\nmulti-line\nstring/", $result);
+ $this->assertRegExp('/Error: Testing with multi-line string/', $result);
+ }
+
+/**
+ * test fileExistsInPath()
+ *
+ * @return void
+ */
+ public function testFileExistsInPath() {
+ if (!function_exists('ini_set')) {
+ $this->markTestSkipped('%s ini_set function not available');
+ }
+
+ $_includePath = ini_get('include_path');
+
+ $path = TMP . 'basics_test';
+ $folder1 = $path . DS . 'folder1';
+ $folder2 = $path . DS . 'folder2';
+ $file1 = $path . DS . 'file1.php';
+ $file2 = $folder1 . DS . 'file2.php';
+ $file3 = $folder1 . DS . 'file3.php';
+ $file4 = $folder2 . DS . 'file4.php';
+
+ new Folder($path, true);
+ new Folder($folder1, true);
+ new Folder($folder2, true);
+ touch($file1);
+ touch($file2);
+ touch($file3);
+ touch($file4);
+
+ ini_set('include_path', $path . PATH_SEPARATOR . $folder1);
+
+ $this->assertEquals(fileExistsInPath('file1.php'), $file1);
+ $this->assertEquals(fileExistsInPath('file2.php'), $file2);
+ $this->assertEquals(fileExistsInPath('folder1' . DS . 'file2.php'), $file2);
+ $this->assertEquals(fileExistsInPath($file2), $file2);
+ $this->assertEquals(fileExistsInPath('file3.php'), $file3);
+ $this->assertEquals(fileExistsInPath($file4), $file4);
+
+ $this->assertFalse(fileExistsInPath('file1'));
+ $this->assertFalse(fileExistsInPath('file4.php'));
+
+ $Folder = new Folder($path);
+ $Folder->delete();
+
+ ini_set('include_path', $_includePath);
+ }
+
+/**
+ * test convertSlash()
+ *
+ * @return void
+ */
+ public function testConvertSlash() {
+ $result = convertSlash('\path\to\location\\');
+ $expected = '\path\to\location\\';
+ $this->assertEquals($expected, $result);
+
+ $result = convertSlash('/path/to/location/');
+ $expected = 'path_to_location';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test debug()
+ *
+ * @return void
+ */
+ public function testDebug() {
+ ob_start();
+ debug('this-is-a-test', false);
+ $result = ob_get_clean();
+ $expectedText = <<<EXPECTED
+%s (line %d)
+########## DEBUG ##########
+'this-is-a-test'
+###########################
+EXPECTED;
+ $expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
+
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', true);
+ $result = ob_get_clean();
+ $expectedHtml = <<<EXPECTED
+<div class="cake-debug-output">
+<span><strong>%s</strong> (line <strong>%d</strong>)</span>
+<pre class="cake-debug">
+&#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
+</pre>
+</div>
+EXPECTED;
+ $expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 10);
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', true, true);
+ $result = ob_get_clean();
+ $expected = <<<EXPECTED
+<div class="cake-debug-output">
+<span><strong>%s</strong> (line <strong>%d</strong>)</span>
+<pre class="cake-debug">
+&#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
+</pre>
+</div>
+EXPECTED;
+ $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 10);
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', true, false);
+ $result = ob_get_clean();
+ $expected = <<<EXPECTED
+<div class="cake-debug-output">
+
+<pre class="cake-debug">
+&#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
+</pre>
+</div>
+EXPECTED;
+ $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 10);
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', null);
+ $result = ob_get_clean();
+ $expectedHtml = <<<EXPECTED
+<div class="cake-debug-output">
+<span><strong>%s</strong> (line <strong>%d</strong>)</span>
+<pre class="cake-debug">
+&#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
+</pre>
+</div>
+EXPECTED;
+ $expectedText = <<<EXPECTED
+%s (line %d)
+########## DEBUG ##########
+'<div>this-is-a-test</div>'
+###########################
+EXPECTED;
+ if (php_sapi_name() == 'cli') {
+ $expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 17);
+ } else {
+ $expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 19);
+ }
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', null, false);
+ $result = ob_get_clean();
+ $expectedHtml = <<<EXPECTED
+<div class="cake-debug-output">
+
+<pre class="cake-debug">
+&#039;&lt;div&gt;this-is-a-test&lt;/div&gt;&#039;
+</pre>
+</div>
+EXPECTED;
+ $expectedText = <<<EXPECTED
+
+########## DEBUG ##########
+'<div>this-is-a-test</div>'
+###########################
+EXPECTED;
+ if (php_sapi_name() == 'cli') {
+ $expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 17);
+ } else {
+ $expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 19);
+ }
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', false);
+ $result = ob_get_clean();
+ $expected = <<<EXPECTED
+%s (line %d)
+########## DEBUG ##########
+'<div>this-is-a-test</div>'
+###########################
+EXPECTED;
+ $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', false, true);
+ $result = ob_get_clean();
+ $expected = <<<EXPECTED
+%s (line %d)
+########## DEBUG ##########
+'<div>this-is-a-test</div>'
+###########################
+EXPECTED;
+ $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ debug('<div>this-is-a-test</div>', false, false);
+ $result = ob_get_clean();
+ $expected = <<<EXPECTED
+
+########## DEBUG ##########
+'<div>this-is-a-test</div>'
+###########################
+EXPECTED;
+ $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test pr()
+ *
+ * @return void
+ */
+ public function testPr() {
+ ob_start();
+ pr('this is a test');
+ $result = ob_get_clean();
+ $expected = "<pre>this is a test</pre>";
+ $this->assertEquals($expected, $result);
+
+ ob_start();
+ pr(array('this' => 'is', 'a' => 'test'));
+ $result = ob_get_clean();
+ $expected = "<pre>Array\n(\n [this] => is\n [a] => test\n)\n</pre>";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test stripslashes_deep()
+ *
+ * @return void
+ */
+ public function testStripslashesDeep() {
+ $this->skipIf(ini_get('magic_quotes_sybase') === '1', 'magic_quotes_sybase is on.');
+
+ $this->assertEquals(stripslashes_deep("tes\'t"), "tes't");
+ $this->assertEquals(stripslashes_deep('tes\\' . chr(0) . 't'), 'tes' . chr(0) . 't');
+ $this->assertEquals(stripslashes_deep('tes\"t'), 'tes"t');
+ $this->assertEquals(stripslashes_deep("tes\'t"), "tes't");
+ $this->assertEquals(stripslashes_deep('te\\st'), 'test');
+
+ $nested = array(
+ 'a' => "tes\'t",
+ 'b' => 'tes\\' . chr(0) . 't',
+ 'c' => array(
+ 'd' => 'tes\"t',
+ 'e' => "te\'s\'t",
+ array('f' => "tes\'t")
+ ),
+ 'g' => 'te\\st'
+ );
+ $expected = array(
+ 'a' => "tes't",
+ 'b' => 'tes' . chr(0) . 't',
+ 'c' => array(
+ 'd' => 'tes"t',
+ 'e' => "te's't",
+ array('f' => "tes't")
+ ),
+ 'g' => 'test'
+ );
+ $this->assertEquals($expected, stripslashes_deep($nested));
+ }
+
+/**
+ * test stripslashes_deep() with magic_quotes_sybase on
+ *
+ * @return void
+ */
+ public function testStripslashesDeepSybase() {
+ if (!(ini_get('magic_quotes_sybase') === '1')) {
+ $this->markTestSkipped('magic_quotes_sybase is off');
+ }
+
+ $this->assertEquals(stripslashes_deep("tes\'t"), "tes\'t");
+
+ $nested = array(
+ 'a' => "tes't",
+ 'b' => "tes''t",
+ 'c' => array(
+ 'd' => "tes'''t",
+ 'e' => "tes''''t",
+ array('f' => "tes''t")
+ ),
+ 'g' => "te'''''st"
+ );
+ $expected = array(
+ 'a' => "tes't",
+ 'b' => "tes't",
+ 'c' => array(
+ 'd' => "tes''t",
+ 'e' => "tes''t",
+ array('f' => "tes't")
+ ),
+ 'g' => "te'''st"
+ );
+ $this->assertEquals($expected, stripslashes_deep($nested));
+ }
+
+/**
+ * test pluginSplit
+ *
+ * @return void
+ */
+ public function testPluginSplit() {
+ $result = pluginSplit('Something.else');
+ $this->assertEquals(array('Something', 'else'), $result);
+
+ $result = pluginSplit('Something.else.more.dots');
+ $this->assertEquals(array('Something', 'else.more.dots'), $result);
+
+ $result = pluginSplit('Somethingelse');
+ $this->assertEquals(array(null, 'Somethingelse'), $result);
+
+ $result = pluginSplit('Something.else', true);
+ $this->assertEquals(array('Something.', 'else'), $result);
+
+ $result = pluginSplit('Something.else.more.dots', true);
+ $this->assertEquals(array('Something.', 'else.more.dots'), $result);
+
+ $result = pluginSplit('Post', false, 'Blog');
+ $this->assertEquals(array('Blog', 'Post'), $result);
+
+ $result = pluginSplit('Blog.Post', false, 'Ultimate');
+ $this->assertEquals(array('Blog', 'Post'), $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/CacheTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/CacheTest.php
new file mode 100644
index 0000000..b4cb358
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/CacheTest.php
@@ -0,0 +1,412 @@
+<?php
+/**
+ * CacheTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Cache
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+
+/**
+ * CacheTest class
+ *
+ * @package Cake.Test.Case.Cache
+ */
+class CacheTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->_cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', false);
+
+ $this->_defaultCacheConfig = Cache::config('default');
+ Cache::config('default', array('engine' => 'File', 'path' => TMP . 'tests'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('Cache.disable', $this->_cacheDisable);
+ Cache::config('default', $this->_defaultCacheConfig['settings']);
+ }
+
+/**
+ * testConfig method
+ *
+ * @return void
+ */
+ public function testConfig() {
+ $settings = array('engine' => 'File', 'path' => TMP . 'tests', 'prefix' => 'cake_test_');
+ $results = Cache::config('new', $settings);
+ $this->assertEquals(Cache::config('new'), $results);
+ $this->assertTrue(isset($results['engine']));
+ $this->assertTrue(isset($results['settings']));
+ }
+
+/**
+ * Check that no fatal errors are issued doing normal things when Cache.disable is true.
+ *
+ * @return void
+ */
+ public function testNonFatalErrorsWithCachedisable() {
+ Configure::write('Cache.disable', true);
+ Cache::config('test', array('engine' => 'File', 'path' => TMP, 'prefix' => 'error_test_'));
+
+ Cache::write('no_save', 'Noooo!', 'test');
+ Cache::read('no_save', 'test');
+ Cache::delete('no_save', 'test');
+ Cache::set('duration', '+10 minutes');
+
+ Configure::write('Cache.disable', false);
+ }
+
+/**
+ * test configuring CacheEngines in App/libs
+ *
+ * @return void
+ */
+ public function testConfigWithLibAndPluginEngines() {
+ App::build(array(
+ 'Lib' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+
+ $settings = array('engine' => 'TestAppCache', 'path' => TMP, 'prefix' => 'cake_test_');
+ $result = Cache::config('libEngine', $settings);
+ $this->assertEquals(Cache::config('libEngine'), $result);
+
+ $settings = array('engine' => 'TestPlugin.TestPluginCache', 'path' => TMP, 'prefix' => 'cake_test_');
+ $result = Cache::config('pluginLibEngine', $settings);
+ $this->assertEquals(Cache::config('pluginLibEngine'), $result);
+
+ Cache::drop('libEngine');
+ Cache::drop('pluginLibEngine');
+
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * testInvalidConfig method
+ *
+ * Test that the cache class doesn't cause fatal errors with a partial path
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testInvalidConfig() {
+ Cache::config('invalid', array(
+ 'engine' => 'File',
+ 'duration' => '+1 year',
+ 'prefix' => 'testing_invalid_',
+ 'path' => 'data/',
+ 'serialize' => true,
+ 'random' => 'wii'
+ ));
+ $read = Cache::read('Test', 'invalid');
+ }
+
+/**
+ * Test reading from a config that is undefined.
+ *
+ * @return void
+ */
+ public function testReadNonExistingConfig() {
+ $this->assertFalse(Cache::read('key', 'totally fake'));
+ $this->assertFalse(Cache::write('key', 'value', 'totally fake'));
+ $this->assertFalse(Cache::increment('key', 1, 'totally fake'));
+ $this->assertFalse(Cache::decrement('key', 1, 'totally fake'));
+ }
+
+/**
+ * test that trying to configure classes that don't extend CacheEngine fail.
+ *
+ * @expectedException CacheException
+ * @return void
+ */
+ public function testAttemptingToConfigureANonCacheEngineClass() {
+ $this->getMock('StdClass', array(), array(), 'RubbishEngine');
+ Cache::config('Garbage', array(
+ 'engine' => 'Rubbish'
+ ));
+ }
+
+/**
+ * testConfigChange method
+ *
+ * @return void
+ */
+ public function testConfigChange() {
+ $_cacheConfigSessions = Cache::config('sessions');
+ $_cacheConfigTests = Cache::config('tests');
+
+ $result = Cache::config('sessions', array('engine' => 'File', 'path' => TMP . 'sessions'));
+ $this->assertEquals(Cache::settings('sessions'), $result['settings']);
+
+ $result = Cache::config('tests', array('engine' => 'File', 'path' => TMP . 'tests'));
+ $this->assertEquals(Cache::settings('tests'), $result['settings']);
+
+ Cache::config('sessions', $_cacheConfigSessions['settings']);
+ Cache::config('tests', $_cacheConfigTests['settings']);
+ }
+
+/**
+ * test that calling config() sets the 'default' configuration up.
+ *
+ * @return void
+ */
+ public function testConfigSettingDefaultConfigKey() {
+ Cache::config('test_name', array('engine' => 'File', 'prefix' => 'test_name_'));
+
+ Cache::write('value_one', 'I am cached', 'test_name');
+ $result = Cache::read('value_one', 'test_name');
+ $this->assertEquals('I am cached', $result);
+
+ $result = Cache::read('value_one');
+ $this->assertEquals(null, $result);
+
+ Cache::write('value_one', 'I am in default config!');
+ $result = Cache::read('value_one');
+ $this->assertEquals('I am in default config!', $result);
+
+ $result = Cache::read('value_one', 'test_name');
+ $this->assertEquals('I am cached', $result);
+
+ Cache::delete('value_one', 'test_name');
+ Cache::delete('value_one', 'default');
+ }
+
+/**
+ * testWritingWithConfig method
+ *
+ * @return void
+ */
+ public function testWritingWithConfig() {
+ $_cacheConfigSessions = Cache::config('sessions');
+
+ Cache::write('test_something', 'this is the test data', 'tests');
+
+ $expected = array(
+ 'path' => TMP . 'sessions' . DS,
+ 'prefix' => 'cake_',
+ 'lock' => true,
+ 'serialize' => true,
+ 'duration' => 3600,
+ 'probability' => 100,
+ 'engine' => 'File',
+ 'isWindows' => DIRECTORY_SEPARATOR == '\\',
+ 'mask' => 0664,
+ 'groups' => array()
+ );
+ $this->assertEquals($expected, Cache::settings('sessions'));
+
+ Cache::config('sessions', $_cacheConfigSessions['settings']);
+ }
+
+/**
+ * test that configured returns an array of the currently configured cache
+ * settings
+ *
+ * @return void
+ */
+ public function testConfigured() {
+ $result = Cache::configured();
+ $this->assertTrue(in_array('_cake_core_', $result));
+ $this->assertTrue(in_array('default', $result));
+ }
+
+/**
+ * testInitSettings method
+ *
+ * @return void
+ */
+ public function testInitSettings() {
+ $initial = Cache::settings();
+ $override = array('engine' => 'File', 'path' => TMP . 'tests');
+ Cache::config('for_test', $override);
+
+ $settings = Cache::settings();
+ $expecting = $override + $initial;
+ $this->assertEquals($settings, $expecting);
+ }
+
+/**
+ * test that drop removes cache configs, and that further attempts to use that config
+ * do not work.
+ *
+ * @return void
+ */
+ public function testDrop() {
+ App::build(array(
+ 'Lib' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+
+ $result = Cache::drop('some_config_that_does_not_exist');
+ $this->assertFalse($result);
+
+ $_testsConfig = Cache::config('tests');
+ $result = Cache::drop('tests');
+ $this->assertTrue($result);
+
+ Cache::config('unconfigTest', array(
+ 'engine' => 'TestAppCache'
+ ));
+ $this->assertTrue(Cache::isInitialized('unconfigTest'));
+
+ $this->assertTrue(Cache::drop('unconfigTest'));
+ $this->assertFalse(Cache::isInitialized('TestAppCache'));
+
+ Cache::config('tests', $_testsConfig);
+ App::build();
+ }
+
+/**
+ * testWriteEmptyValues method
+ *
+ * @return void
+ */
+ public function testWriteEmptyValues() {
+ Cache::write('App.falseTest', false);
+ $this->assertSame(Cache::read('App.falseTest'), false);
+
+ Cache::write('App.trueTest', true);
+ $this->assertSame(Cache::read('App.trueTest'), true);
+
+ Cache::write('App.nullTest', null);
+ $this->assertSame(Cache::read('App.nullTest'), null);
+
+ Cache::write('App.zeroTest', 0);
+ $this->assertSame(Cache::read('App.zeroTest'), 0);
+
+ Cache::write('App.zeroTest2', '0');
+ $this->assertSame(Cache::read('App.zeroTest2'), '0');
+ }
+
+/**
+ * Test that failed writes cause errors to be triggered.
+ *
+ * @return void
+ */
+ public function testWriteTriggerError() {
+ App::build(array(
+ 'Lib' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+
+ Cache::config('test_trigger', array('engine' => 'TestAppCache', 'prefix' => ''));
+ try {
+ Cache::write('fail', 'value', 'test_trigger');
+ $this->fail('No exception thrown');
+ } catch (PHPUnit_Framework_Error $e) {
+ $this->assertTrue(true);
+ }
+ Cache::drop('test_trigger');
+ App::build();
+ }
+
+/**
+ * testCacheDisable method
+ *
+ * Check that the "Cache.disable" configuration and a change to it
+ * (even after a cache config has been setup) is taken into account.
+ *
+ * @return void
+ */
+ public function testCacheDisable() {
+ Configure::write('Cache.disable', false);
+ Cache::config('test_cache_disable_1', array('engine' => 'File', 'path' => TMP . 'tests'));
+
+ $this->assertTrue(Cache::write('key_1', 'hello', 'test_cache_disable_1'));
+ $this->assertSame(Cache::read('key_1', 'test_cache_disable_1'), 'hello');
+
+ Configure::write('Cache.disable', true);
+
+ $this->assertFalse(Cache::write('key_2', 'hello', 'test_cache_disable_1'));
+ $this->assertFalse(Cache::read('key_2', 'test_cache_disable_1'));
+
+ Configure::write('Cache.disable', false);
+
+ $this->assertTrue(Cache::write('key_3', 'hello', 'test_cache_disable_1'));
+ $this->assertSame(Cache::read('key_3', 'test_cache_disable_1'), 'hello');
+
+ Configure::write('Cache.disable', true);
+ Cache::config('test_cache_disable_2', array('engine' => 'File', 'path' => TMP . 'tests'));
+
+ $this->assertFalse(Cache::write('key_4', 'hello', 'test_cache_disable_2'));
+ $this->assertFalse(Cache::read('key_4', 'test_cache_disable_2'));
+
+ Configure::write('Cache.disable', false);
+
+ $this->assertTrue(Cache::write('key_5', 'hello', 'test_cache_disable_2'));
+ $this->assertSame(Cache::read('key_5', 'test_cache_disable_2'), 'hello');
+
+ Configure::write('Cache.disable', true);
+
+ $this->assertFalse(Cache::write('key_6', 'hello', 'test_cache_disable_2'));
+ $this->assertFalse(Cache::read('key_6', 'test_cache_disable_2'));
+ }
+
+/**
+ * testSet method
+ *
+ * @return void
+ */
+ public function testSet() {
+ $_cacheSet = Cache::set();
+
+ Cache::set(array('duration' => '+1 year'));
+ $data = Cache::read('test_cache');
+ $this->assertFalse($data);
+
+ $data = 'this is just a simple test of the cache system';
+ $write = Cache::write('test_cache', $data);
+ $this->assertTrue($write);
+
+ Cache::set(array('duration' => '+1 year'));
+ $data = Cache::read('test_cache');
+ $this->assertEquals('this is just a simple test of the cache system', $data);
+
+ Cache::delete('test_cache');
+
+ $global = Cache::settings();
+
+ Cache::set($_cacheSet);
+ }
+
+/**
+ * test set() parameter handling for user cache configs.
+ *
+ * @return void
+ */
+ public function testSetOnAlternateConfigs() {
+ Cache::config('file_config', array('engine' => 'File', 'prefix' => 'test_file_'));
+ Cache::set(array('duration' => '+1 year'), 'file_config');
+ $settings = Cache::settings('file_config');
+
+ $this->assertEquals('test_file_', $settings['prefix']);
+ $this->assertEquals(strtotime('+1 year') - time(), $settings['duration']);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php
new file mode 100644
index 0000000..d1e7605
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/ApcEngineTest.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * ApcEngineTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.5434
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+
+/**
+ * ApcEngineTest class
+ *
+ * @package Cake.Test.Case.Cache.Engine
+ */
+class ApcEngineTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->skipIf(!function_exists('apc_store'), 'Apc is not installed or configured properly.');
+
+ $this->_cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', false);
+ Cache::config('apc', array('engine' => 'Apc', 'prefix' => 'cake_'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('Cache.disable', $this->_cacheDisable);
+ Cache::drop('apc');
+ Cache::drop('apc_groups');
+ Cache::config('default');
+ }
+
+/**
+ * testReadAndWriteCache method
+ *
+ * @return void
+ */
+ public function testReadAndWriteCache() {
+ Cache::set(array('duration' => 1), 'apc');
+
+ $result = Cache::read('test', 'apc');
+ $expecting = '';
+ $this->assertEquals($expecting, $result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('test', $data, 'apc');
+ $this->assertTrue($result);
+
+ $result = Cache::read('test', 'apc');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ Cache::delete('test', 'apc');
+ }
+
+/**
+ * Writing cache entries with duration = 0 (forever) should work.
+ *
+ * @return void
+ */
+ public function testReadWriteDurationZero() {
+ Cache::config('apc', array('engine' => 'Apc', 'duration' => 0, 'prefix' => 'cake_'));
+ Cache::write('zero', 'Should save', 'apc');
+ sleep(1);
+
+ $result = Cache::read('zero', 'apc');
+ $this->assertEquals('Should save', $result);
+ }
+
+/**
+ * testExpiry method
+ *
+ * @return void
+ */
+ public function testExpiry() {
+ Cache::set(array('duration' => 1), 'apc');
+
+ $result = Cache::read('test', 'apc');
+ $this->assertFalse($result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'apc');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'apc');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => 1), 'apc');
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'apc');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'apc');
+ $this->assertFalse($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'apc');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testDeleteCache method
+ *
+ * @return void
+ */
+ public function testDeleteCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('delete_test', $data, 'apc');
+ $this->assertTrue($result);
+
+ $result = Cache::delete('delete_test', 'apc');
+ $this->assertTrue($result);
+ }
+
+/**
+ * testDecrement method
+ *
+ * @return void
+ */
+ public function testDecrement() {
+ $this->skipIf(!function_exists('apc_dec'), 'No apc_dec() function, cannot test decrement().');
+
+ $result = Cache::write('test_decrement', 5, 'apc');
+ $this->assertTrue($result);
+
+ $result = Cache::decrement('test_decrement', 1, 'apc');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::read('test_decrement', 'apc');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::decrement('test_decrement', 2, 'apc');
+ $this->assertEquals(2, $result);
+
+ $result = Cache::read('test_decrement', 'apc');
+ $this->assertEquals(2, $result);
+ }
+
+/**
+ * testIncrement method
+ *
+ * @return void
+ */
+ public function testIncrement() {
+ $this->skipIf(!function_exists('apc_inc'), 'No apc_inc() function, cannot test increment().');
+
+ $result = Cache::write('test_increment', 5, 'apc');
+ $this->assertTrue($result);
+
+ $result = Cache::increment('test_increment', 1, 'apc');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::read('test_increment', 'apc');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::increment('test_increment', 2, 'apc');
+ $this->assertEquals(8, $result);
+
+ $result = Cache::read('test_increment', 'apc');
+ $this->assertEquals(8, $result);
+ }
+
+/**
+ * test the clearing of cache keys
+ *
+ * @return void
+ */
+ public function testClear() {
+ apc_store('not_cake', 'survive');
+ Cache::write('some_value', 'value', 'apc');
+
+ $result = Cache::clear(false, 'apc');
+ $this->assertTrue($result);
+ $this->assertFalse(Cache::read('some_value', 'apc'));
+ $this->assertEquals('survive', apc_fetch('not_cake'));
+ apc_delete('not_cake');
+ }
+
+/**
+ * Tests that configuring groups for stored keys return the correct values when read/written
+ * Shows that altering the group value is equivalent to deleting all keys under the same
+ * group
+ *
+ * @return void
+ */
+ public function testGroupsReadWrite() {
+ Cache::config('apc_groups', array(
+ 'engine' => 'Apc',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'apc_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'apc_groups'));
+
+ apc_inc('test_group_a');
+ $this->assertFalse(Cache::read('test_groups', 'apc_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'apc_groups'));
+ $this->assertEquals('value2', Cache::read('test_groups', 'apc_groups'));
+
+ apc_inc('test_group_b');
+ $this->assertFalse(Cache::read('test_groups', 'apc_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value3', 'apc_groups'));
+ $this->assertEquals('value3', Cache::read('test_groups', 'apc_groups'));
+ }
+
+/**
+ * Tests that deleteing from a groups-enabled config is possible
+ *
+ * @return void
+ */
+ public function testGroupDelete() {
+ Cache::config('apc_groups', array(
+ 'engine' => 'Apc',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'apc_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'apc_groups'));
+ $this->assertTrue(Cache::delete('test_groups', 'apc_groups'));
+
+ $this->assertFalse(Cache::read('test_groups', 'apc_groups'));
+ }
+
+/**
+ * Test clearing a cache group
+ *
+ * @return void
+ **/
+ public function testGroupClear() {
+ Cache::config('apc_groups', array(
+ 'engine' => 'Apc',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+
+ $this->assertTrue(Cache::write('test_groups', 'value', 'apc_groups'));
+ $this->assertTrue(Cache::clearGroup('group_a', 'apc_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'apc_groups'));
+
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'apc_groups'));
+ $this->assertTrue(Cache::clearGroup('group_b', 'apc_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'apc_groups'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php
new file mode 100644
index 0000000..a091fbd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/FileEngineTest.php
@@ -0,0 +1,455 @@
+<?php
+/**
+ * FileEngineTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.5434
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+
+/**
+ * FileEngineTest class
+ *
+ * @package Cake.Test.Case.Cache.Engine
+ */
+class FileEngineTest extends CakeTestCase {
+
+/**
+ * config property
+ *
+ * @var array
+ */
+ public $config = array();
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Cache.disable', false);
+ Cache::config('file_test', array('engine' => 'File', 'path' => CACHE));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Cache::clear(false, 'file_test');
+ Cache::drop('file_test');
+ Cache::drop('file_groups');
+ Cache::drop('file_groups2');
+ Cache::drop('file_groups3');
+ }
+
+/**
+ * testCacheDirChange method
+ *
+ * @return void
+ */
+ public function testCacheDirChange() {
+ $result = Cache::config('sessions', array('engine' => 'File', 'path' => TMP . 'sessions'));
+ $this->assertEquals(Cache::settings('sessions'), $result['settings']);
+
+ $result = Cache::config('sessions', array('engine' => 'File', 'path' => TMP . 'tests'));
+ $this->assertEquals(Cache::settings('sessions'), $result['settings']);
+ $this->assertNotEquals(Cache::settings('default'), $result['settings']);
+ }
+
+/**
+ * testReadAndWriteCache method
+ *
+ * @return void
+ */
+ public function testReadAndWriteCache() {
+ Cache::config('default');
+
+ $result = Cache::write(null, 'here', 'file_test');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => 1), 'file_test');
+
+ $result = Cache::read('test', 'file_test');
+ $expecting = '';
+ $this->assertEquals($expecting, $result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('test', $data, 'file_test');
+ $this->assertTrue(file_exists(CACHE . 'cake_test'));
+
+ $result = Cache::read('test', 'file_test');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ Cache::delete('test', 'file_test');
+ }
+
+/**
+ * Test read/write on the same cache key. Ensures file handles are re-wound.
+ *
+ * @return void
+ */
+ public function testConsecutiveReadWrite() {
+ Cache::write('rw', 'first write', 'file_test');
+ $result = Cache::read('rw', 'file_test');
+
+ Cache::write('rw', 'second write', 'file_test');
+ $resultB = Cache::read('rw', 'file_test');
+
+ Cache::delete('rw', 'file_test');
+ $this->assertEquals('first write', $result);
+ $this->assertEquals('second write', $resultB);
+ }
+
+/**
+ * testExpiry method
+ *
+ * @return void
+ */
+ public function testExpiry() {
+ Cache::set(array('duration' => 1), 'file_test');
+
+ $result = Cache::read('test', 'file_test');
+ $this->assertFalse($result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'file_test');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'file_test');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => "+1 second"), 'file_test');
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'file_test');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'file_test');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testDeleteCache method
+ *
+ * @return void
+ */
+ public function testDeleteCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('delete_test', $data, 'file_test');
+ $this->assertTrue($result);
+
+ $result = Cache::delete('delete_test', 'file_test');
+ $this->assertTrue($result);
+ $this->assertFalse(file_exists(TMP . 'tests' . DS . 'delete_test'));
+
+ $result = Cache::delete('delete_test', 'file_test');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testSerialize method
+ *
+ * @return void
+ */
+ public function testSerialize() {
+ Cache::config('file_test', array('engine' => 'File', 'serialize' => true));
+ $data = 'this is a test of the emergency broadcasting system';
+ $write = Cache::write('serialize_test', $data, 'file_test');
+ $this->assertTrue($write);
+
+ Cache::config('file_test', array('serialize' => false));
+ $read = Cache::read('serialize_test', 'file_test');
+
+ $newread = Cache::read('serialize_test', 'file_test');
+
+ $delete = Cache::delete('serialize_test', 'file_test');
+
+ $this->assertSame($read, serialize($data));
+
+ $this->assertSame(unserialize($newread), $data);
+ }
+
+/**
+ * testClear method
+ *
+ * @return void
+ */
+ public function testClear() {
+ Cache::config('file_test', array('engine' => 'File', 'duration' => 1));
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $write = Cache::write('serialize_test1', $data, 'file_test');
+ $write = Cache::write('serialize_test2', $data, 'file_test');
+ $write = Cache::write('serialize_test3', $data, 'file_test');
+ $this->assertTrue(file_exists(CACHE . 'cake_serialize_test1'));
+ $this->assertTrue(file_exists(CACHE . 'cake_serialize_test2'));
+ $this->assertTrue(file_exists(CACHE . 'cake_serialize_test3'));
+ sleep(2);
+ $result = Cache::clear(true, 'file_test');
+ $this->assertTrue($result);
+ $this->assertFalse(file_exists(CACHE . 'cake_serialize_test1'));
+ $this->assertFalse(file_exists(CACHE . 'cake_serialize_test2'));
+ $this->assertFalse(file_exists(CACHE . 'cake_serialize_test3'));
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $write = Cache::write('serialize_test1', $data, 'file_test');
+ $write = Cache::write('serialize_test2', $data, 'file_test');
+ $write = Cache::write('serialize_test3', $data, 'file_test');
+ $this->assertTrue(file_exists(CACHE . 'cake_serialize_test1'));
+ $this->assertTrue(file_exists(CACHE . 'cake_serialize_test2'));
+ $this->assertTrue(file_exists(CACHE . 'cake_serialize_test3'));
+
+ $result = Cache::clear(false, 'file_test');
+ $this->assertTrue($result);
+ $this->assertFalse(file_exists(CACHE . 'cake_serialize_test1'));
+ $this->assertFalse(file_exists(CACHE . 'cake_serialize_test2'));
+ $this->assertFalse(file_exists(CACHE . 'cake_serialize_test3'));
+ }
+
+/**
+ * test that clear() doesn't wipe files not in the current engine's prefix.
+ *
+ * @return void
+ */
+ public function testClearWithPrefixes() {
+ $FileOne = new FileEngine();
+ $FileOne->init(array(
+ 'prefix' => 'prefix_one_',
+ 'duration' => DAY
+ ));
+ $FileTwo = new FileEngine();
+ $FileTwo->init(array(
+ 'prefix' => 'prefix_two_',
+ 'duration' => DAY
+ ));
+
+ $dataOne = $dataTwo = $expected = 'content to cache';
+ $FileOne->write('prefix_one_key_one', $dataOne, DAY);
+ $FileTwo->write('prefix_two_key_two', $dataTwo, DAY);
+
+ $this->assertEquals($expected, $FileOne->read('prefix_one_key_one'));
+ $this->assertEquals($expected, $FileTwo->read('prefix_two_key_two'));
+
+ $FileOne->clear(false);
+ $this->assertEquals($expected, $FileTwo->read('prefix_two_key_two'), 'secondary config was cleared by accident.');
+ $FileTwo->clear(false);
+ }
+
+/**
+ * testKeyPath method
+ *
+ * @return void
+ */
+ public function testKeyPath() {
+ $result = Cache::write('views.countries.something', 'here', 'file_test');
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists(CACHE . 'cake_views_countries_something'));
+
+ $result = Cache::read('views.countries.something', 'file_test');
+ $this->assertEquals('here', $result);
+
+ $result = Cache::clear(false, 'file_test');
+ $this->assertTrue($result);
+ }
+
+/**
+ * testRemoveWindowsSlashesFromCache method
+ *
+ * @return void
+ */
+ public function testRemoveWindowsSlashesFromCache() {
+ Cache::config('windows_test', array('engine' => 'File', 'isWindows' => true, 'prefix' => null, 'path' => TMP));
+
+ $expected = array(
+ 'C:\dev\prj2\sites\cake\libs' => array(
+ 0 => 'C:\dev\prj2\sites\cake\libs', 1 => 'C:\dev\prj2\sites\cake\libs\view',
+ 2 => 'C:\dev\prj2\sites\cake\libs\view\scaffolds', 3 => 'C:\dev\prj2\sites\cake\libs\view\pages',
+ 4 => 'C:\dev\prj2\sites\cake\libs\view\layouts', 5 => 'C:\dev\prj2\sites\cake\libs\view\layouts\xml',
+ 6 => 'C:\dev\prj2\sites\cake\libs\view\layouts\rss', 7 => 'C:\dev\prj2\sites\cake\libs\view\layouts\js',
+ 8 => 'C:\dev\prj2\sites\cake\libs\view\layouts\email', 9 => 'C:\dev\prj2\sites\cake\libs\view\layouts\email\text',
+ 10 => 'C:\dev\prj2\sites\cake\libs\view\layouts\email\html', 11 => 'C:\dev\prj2\sites\cake\libs\view\helpers',
+ 12 => 'C:\dev\prj2\sites\cake\libs\view\errors', 13 => 'C:\dev\prj2\sites\cake\libs\view\elements',
+ 14 => 'C:\dev\prj2\sites\cake\libs\view\elements\email', 15 => 'C:\dev\prj2\sites\cake\libs\view\elements\email\text',
+ 16 => 'C:\dev\prj2\sites\cake\libs\view\elements\email\html', 17 => 'C:\dev\prj2\sites\cake\libs\model',
+ 18 => 'C:\dev\prj2\sites\cake\libs\model\datasources', 19 => 'C:\dev\prj2\sites\cake\libs\model\datasources\dbo',
+ 20 => 'C:\dev\prj2\sites\cake\libs\model\behaviors', 21 => 'C:\dev\prj2\sites\cake\libs\controller',
+ 22 => 'C:\dev\prj2\sites\cake\libs\controller\components', 23 => 'C:\dev\prj2\sites\cake\libs\cache'),
+ 'C:\dev\prj2\sites\main_site\vendors' => array(
+ 0 => 'C:\dev\prj2\sites\main_site\vendors', 1 => 'C:\dev\prj2\sites\main_site\vendors\shells',
+ 2 => 'C:\dev\prj2\sites\main_site\vendors\shells\templates', 3 => 'C:\dev\prj2\sites\main_site\vendors\shells\templates\cdc_project',
+ 4 => 'C:\dev\prj2\sites\main_site\vendors\shells\tasks', 5 => 'C:\dev\prj2\sites\main_site\vendors\js',
+ 6 => 'C:\dev\prj2\sites\main_site\vendors\css'),
+ 'C:\dev\prj2\sites\vendors' => array(
+ 0 => 'C:\dev\prj2\sites\vendors', 1 => 'C:\dev\prj2\sites\vendors\simpletest',
+ 2 => 'C:\dev\prj2\sites\vendors\simpletest\test', 3 => 'C:\dev\prj2\sites\vendors\simpletest\test\support',
+ 4 => 'C:\dev\prj2\sites\vendors\simpletest\test\support\collector', 5 => 'C:\dev\prj2\sites\vendors\simpletest\extensions',
+ 6 => 'C:\dev\prj2\sites\vendors\simpletest\extensions\testdox', 7 => 'C:\dev\prj2\sites\vendors\simpletest\docs',
+ 8 => 'C:\dev\prj2\sites\vendors\simpletest\docs\fr', 9 => 'C:\dev\prj2\sites\vendors\simpletest\docs\en'),
+ 'C:\dev\prj2\sites\main_site\views\helpers' => array(
+ 0 => 'C:\dev\prj2\sites\main_site\views\helpers')
+ );
+
+ Cache::write('test_dir_map', $expected, 'windows_test');
+ $data = Cache::read('test_dir_map', 'windows_test');
+ Cache::delete('test_dir_map', 'windows_test');
+ $this->assertEquals($expected, $data);
+
+ Cache::drop('windows_test');
+ }
+
+/**
+ * testWriteQuotedString method
+ *
+ * @return void
+ */
+ public function testWriteQuotedString() {
+ Cache::config('file_test', array('engine' => 'File', 'path' => TMP . 'tests'));
+ Cache::write('App.doubleQuoteTest', '"this is a quoted string"', 'file_test');
+ $this->assertSame(Cache::read('App.doubleQuoteTest', 'file_test'), '"this is a quoted string"');
+ Cache::write('App.singleQuoteTest', "'this is a quoted string'", 'file_test');
+ $this->assertSame(Cache::read('App.singleQuoteTest', 'file_test'), "'this is a quoted string'");
+
+ Cache::config('file_test', array('isWindows' => true, 'path' => TMP . 'tests'));
+ $this->assertSame(Cache::read('App.doubleQuoteTest', 'file_test'), '"this is a quoted string"');
+ Cache::write('App.singleQuoteTest', "'this is a quoted string'", 'file_test');
+ $this->assertSame(Cache::read('App.singleQuoteTest', 'file_test'), "'this is a quoted string'");
+ Cache::delete('App.singleQuoteTest', 'file_test');
+ Cache::delete('App.doubleQuoteTest', 'file_test');
+ }
+
+/**
+ * check that FileEngine generates an error when a configured Path does not exist.
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testErrorWhenPathDoesNotExist() {
+ $this->skipIf(is_dir(TMP . 'tests' . DS . 'file_failure'), 'Cannot run test directory exists.');
+
+ Cache::config('failure', array(
+ 'engine' => 'File',
+ 'path' => TMP . 'tests' . DS . 'file_failure'
+ ));
+
+ Cache::drop('failure');
+ }
+
+/**
+ * Testing the mask setting in FileEngine
+ *
+ * @return void
+ */
+ public function testMaskSetting() {
+ if (DS === '\\') {
+ $this->markTestSkipped('File permission testing does not work on Windows.');
+ }
+ Cache::config('mask_test', array('engine' => 'File', 'path' => TMP . 'tests'));
+ $data = 'This is some test content';
+ $write = Cache::write('masking_test', $data, 'mask_test');
+ $result = substr(sprintf('%o',fileperms(TMP . 'tests' . DS . 'cake_masking_test')), -4);
+ $expected = '0664';
+ $this->assertEquals($expected, $result);
+ Cache::delete('masking_test', 'mask_test');
+ Cache::drop('mask_test');
+
+ Cache::config('mask_test', array('engine' => 'File', 'mask' => 0666, 'path' => TMP . 'tests'));
+ $write = Cache::write('masking_test', $data, 'mask_test');
+ $result = substr(sprintf('%o',fileperms(TMP . 'tests' . DS . 'cake_masking_test')), -4);
+ $expected = '0666';
+ $this->assertEquals($expected, $result);
+ Cache::delete('masking_test', 'mask_test');
+ Cache::drop('mask_test');
+
+ Cache::config('mask_test', array('engine' => 'File', 'mask' => 0644, 'path' => TMP . 'tests'));
+ $write = Cache::write('masking_test', $data, 'mask_test');
+ $result = substr(sprintf('%o',fileperms(TMP . 'tests' . DS . 'cake_masking_test')), -4);
+ $expected = '0644';
+ $this->assertEquals($expected, $result);
+ Cache::delete('masking_test', 'mask_test');
+ Cache::drop('mask_test');
+
+ Cache::config('mask_test', array('engine' => 'File', 'mask' => 0640, 'path' => TMP . 'tests'));
+ $write = Cache::write('masking_test', $data, 'mask_test');
+ $result = substr(sprintf('%o',fileperms(TMP . 'tests' . DS . 'cake_masking_test')), -4);
+ $expected = '0640';
+ $this->assertEquals($expected, $result);
+ Cache::delete('masking_test', 'mask_test');
+ Cache::drop('mask_test');
+ }
+
+/**
+ * Tests that configuring groups for stored keys return the correct values when read/written
+ *
+ * @return void
+ */
+ public function testGroupsReadWrite() {
+ Cache::config('file_groups', array('engine' => 'File', 'duration' => 3600, 'groups' => array('group_a', 'group_b')));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'file_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'file_groups'));
+
+ $this->assertTrue(Cache::write('test_groups2', 'value2', 'file_groups'));
+ $this->assertTrue(Cache::write('test_groups3', 'value3', 'file_groups'));
+ }
+
+/**
+ * Tests that deleteing from a groups-enabled config is possible
+ *
+ * @return void
+ */
+ public function testGroupDelete() {
+ Cache::config('file_groups', array('engine' => 'File', 'duration' => 3600, 'groups' => array('group_a', 'group_b')));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'file_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'file_groups'));
+ $this->assertTrue(Cache::delete('test_groups', 'file_groups'));
+
+ $this->assertFalse(Cache::read('test_groups', 'file_groups'));
+ }
+
+/**
+ * Test clearing a cache group
+ *
+ * @return void
+ **/
+ public function testGroupClear() {
+ Cache::config('file_groups', array('engine' => 'File', 'duration' => 3600, 'groups' => array('group_a', 'group_b')));
+ Cache::config('file_groups2', array('engine' => 'File', 'duration' => 3600, 'groups' => array('group_b')));
+ Cache::config('file_groups3', array('engine' => 'File', 'duration' => 3600, 'groups' => array('group_a')));
+
+ $this->assertTrue(Cache::write('test_groups', 'value', 'file_groups'));
+ $this->assertTrue(Cache::write('test_groups2', 'value', 'file_groups2'));
+ $this->assertTrue(Cache::write('test_groups3', 'value', 'file_groups3'));
+
+ $this->assertTrue(Cache::clearGroup('group_a', 'file_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'file_groups'));
+ $this->assertEquals('value', Cache::read('test_groups2', 'file_groups2'));
+ $this->assertFalse(Cache::read('test_groups3', 'file_groups3'));
+
+ $this->assertTrue(Cache::write('test_groups4', 'value', 'file_groups'));
+ $this->assertTrue(Cache::write('test_groups5', 'value', 'file_groups2'));
+ $this->assertTrue(Cache::write('test_groups6', 'value', 'file_groups3'));
+
+ $this->assertTrue(Cache::clearGroup('group_b', 'file_groups'));
+ $this->assertFalse(Cache::read('test_groups4', 'file_groups'));
+ $this->assertFalse(Cache::read('test_groups5', 'file_groups2'));
+ $this->assertEquals('value', Cache::read('test_groups6', 'file_groups3'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php
new file mode 100644
index 0000000..a1c2abd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php
@@ -0,0 +1,479 @@
+<?php
+/**
+ * MemcacheEngineTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.5434
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+App::uses('MemcacheEngine', 'Cache/Engine');
+
+class TestMemcacheEngine extends MemcacheEngine {
+
+/**
+ * public accessor to _parseServerString
+ *
+ * @param string $server
+ * @return array
+ */
+ public function parseServerString($server) {
+ return $this->_parseServerString($server);
+ }
+
+ public function setMemcache($memcache) {
+ $this->_Memcache = $memcache;
+ }
+
+}
+
+/**
+ * MemcacheEngineTest class
+ *
+ * @package Cake.Test.Case.Cache.Engine
+ */
+class MemcacheEngineTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->skipIf(!class_exists('Memcache'), 'Memcache is not installed or configured properly.');
+
+ $this->_cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', false);
+ Cache::config('memcache', array(
+ 'engine' => 'Memcache',
+ 'prefix' => 'cake_',
+ 'duration' => 3600
+ ));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('Cache.disable', $this->_cacheDisable);
+ Cache::drop('memcache');
+ Cache::drop('memcache_groups');
+ Cache::drop('memcache_helper');
+ Cache::config('default');
+ }
+
+/**
+ * testSettings method
+ *
+ * @return void
+ */
+ public function testSettings() {
+ $settings = Cache::settings('memcache');
+ unset($settings['serialize'], $settings['path']);
+ $expecting = array(
+ 'prefix' => 'cake_',
+ 'duration' => 3600,
+ 'probability' => 100,
+ 'servers' => array('127.0.0.1'),
+ 'persistent' => true,
+ 'compress' => false,
+ 'engine' => 'Memcache',
+ 'persistent' => true,
+ 'groups' => array()
+ );
+ $this->assertEquals($expecting, $settings);
+ }
+
+/**
+ * testSettings method
+ *
+ * @return void
+ */
+ public function testMultipleServers() {
+ $servers = array('127.0.0.1:11211', '127.0.0.1:11222');
+ $available = true;
+ $Memcache = new Memcache();
+
+ foreach ($servers as $server) {
+ list($host, $port) = explode(':', $server);
+ if (!@$Memcache->connect($host, $port)) {
+ $available = false;
+ }
+ }
+
+ $this->skipIf(!$available, 'Need memcache servers at ' . implode(', ', $servers) . ' to run this test.');
+
+ $Memcache = new MemcacheEngine();
+ $Memcache->init(array('engine' => 'Memcache', 'servers' => $servers));
+
+ $servers = array_keys($Memcache->__Memcache->getExtendedStats());
+ $settings = $Memcache->settings();
+ $this->assertEquals($settings['servers'], $servers);
+ Cache::drop('dual_server');
+ }
+
+/**
+ * testConnect method
+ *
+ * @return void
+ */
+ public function testConnect() {
+ $Memcache = new MemcacheEngine();
+ $Memcache->init(Cache::settings('memcache'));
+ $result = $Memcache->connect('127.0.0.1');
+ $this->assertTrue($result);
+ }
+
+/**
+ * test connecting to an ipv6 server.
+ *
+ * @return void
+ */
+ public function testConnectIpv6() {
+ $Memcache = new MemcacheEngine();
+ $result = $Memcache->init(array(
+ 'prefix' => 'cake_',
+ 'duration' => 200,
+ 'engine' => 'Memcache',
+ 'servers' => array(
+ '[::1]:11211'
+ )
+ ));
+ $this->assertTrue($result);
+ }
+
+/**
+ * test non latin domains.
+ *
+ * @return void
+ */
+ public function testParseServerStringNonLatin() {
+ $Memcache = new TestMemcacheEngine();
+ $result = $Memcache->parseServerString('schülervz.net:13211');
+ $this->assertEquals(array('schülervz.net', '13211'), $result);
+
+ $result = $Memcache->parseServerString('sülül:1111');
+ $this->assertEquals(array('sülül', '1111'), $result);
+ }
+
+/**
+ * test unix sockets.
+ *
+ * @return void
+ */
+ public function testParseServerStringUnix() {
+ $Memcache = new TestMemcacheEngine();
+ $result = $Memcache->parseServerString('unix:///path/to/memcached.sock');
+ $this->assertEquals(array('unix:///path/to/memcached.sock', 0), $result);
+ }
+
+/**
+ * testReadAndWriteCache method
+ *
+ * @return void
+ */
+ public function testReadAndWriteCache() {
+ Cache::set(array('duration' => 1), null, 'memcache');
+
+ $result = Cache::read('test', 'memcache');
+ $expecting = '';
+ $this->assertEquals($expecting, $result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('test', $data, 'memcache');
+ $this->assertTrue($result);
+
+ $result = Cache::read('test', 'memcache');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ Cache::delete('test', 'memcache');
+ }
+
+/**
+ * testExpiry method
+ *
+ * @return void
+ */
+ public function testExpiry() {
+ Cache::set(array('duration' => 1), 'memcache');
+
+ $result = Cache::read('test', 'memcache');
+ $this->assertFalse($result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'memcache');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'memcache');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => "+1 second"), 'memcache');
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'memcache');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'memcache');
+ $this->assertFalse($result);
+
+ Cache::config('memcache', array('duration' => '+1 second'));
+ sleep(2);
+
+ $result = Cache::read('other_test', 'memcache');
+ $this->assertFalse($result);
+
+ Cache::config('memcache', array('duration' => '+29 days'));
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('long_expiry_test', $data, 'memcache');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('long_expiry_test', 'memcache');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ Cache::config('memcache', array('duration' => 3600));
+ }
+
+/**
+ * testDeleteCache method
+ *
+ * @return void
+ */
+ public function testDeleteCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('delete_test', $data, 'memcache');
+ $this->assertTrue($result);
+
+ $result = Cache::delete('delete_test', 'memcache');
+ $this->assertTrue($result);
+ }
+
+/**
+ * testDecrement method
+ *
+ * @return void
+ */
+ public function testDecrement() {
+ $result = Cache::write('test_decrement', 5, 'memcache');
+ $this->assertTrue($result);
+
+ $result = Cache::decrement('test_decrement', 1, 'memcache');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::read('test_decrement', 'memcache');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::decrement('test_decrement', 2, 'memcache');
+ $this->assertEquals(2, $result);
+
+ $result = Cache::read('test_decrement', 'memcache');
+ $this->assertEquals(2, $result);
+ }
+
+/**
+ * testIncrement method
+ *
+ * @return void
+ */
+ public function testIncrement() {
+ $result = Cache::write('test_increment', 5, 'memcache');
+ $this->assertTrue($result);
+
+ $result = Cache::increment('test_increment', 1, 'memcache');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::read('test_increment', 'memcache');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::increment('test_increment', 2, 'memcache');
+ $this->assertEquals(8, $result);
+
+ $result = Cache::read('test_increment', 'memcache');
+ $this->assertEquals(8, $result);
+ }
+
+/**
+ * test that configurations don't conflict, when a file engine is declared after a memcache one.
+ *
+ * @return void
+ */
+ public function testConfigurationConflict() {
+ Cache::config('long_memcache', array(
+ 'engine' => 'Memcache',
+ 'duration' => '+2 seconds',
+ 'servers' => array('127.0.0.1:11211'),
+ ));
+ Cache::config('short_memcache', array(
+ 'engine' => 'Memcache',
+ 'duration' => '+1 seconds',
+ 'servers' => array('127.0.0.1:11211'),
+ ));
+ Cache::config('some_file', array('engine' => 'File'));
+
+ $this->assertTrue(Cache::write('duration_test', 'yay', 'long_memcache'));
+ $this->assertTrue(Cache::write('short_duration_test', 'boo', 'short_memcache'));
+
+ $this->assertEquals('yay', Cache::read('duration_test', 'long_memcache'), 'Value was not read %s');
+ $this->assertEquals('boo', Cache::read('short_duration_test', 'short_memcache'), 'Value was not read %s');
+
+ sleep(1);
+ $this->assertEquals('yay', Cache::read('duration_test', 'long_memcache'), 'Value was not read %s');
+
+ sleep(2);
+ $this->assertFalse(Cache::read('short_duration_test', 'short_memcache'), 'Cache was not invalidated %s');
+ $this->assertFalse(Cache::read('duration_test', 'long_memcache'), 'Value did not expire %s');
+
+ Cache::delete('duration_test', 'long_memcache');
+ Cache::delete('short_duration_test', 'short_memcache');
+ }
+
+/**
+ * test clearing memcache.
+ *
+ * @return void
+ */
+ public function testClear() {
+ Cache::config('memcache2', array(
+ 'engine' => 'Memcache',
+ 'prefix' => 'cake2_',
+ 'duration' => 3600
+ ));
+
+ Cache::write('some_value', 'cache1', 'memcache');
+ $result = Cache::clear(true, 'memcache');
+ $this->assertTrue($result);
+ $this->assertEquals('cache1', Cache::read('some_value', 'memcache'));
+
+ Cache::write('some_value', 'cache2', 'memcache2');
+ $result = Cache::clear(false, 'memcache');
+ $this->assertTrue($result);
+ $this->assertFalse(Cache::read('some_value', 'memcache'));
+ $this->assertEquals('cache2', Cache::read('some_value', 'memcache2'));
+
+ Cache::clear(false, 'memcache2');
+ }
+
+/**
+ * test that a 0 duration can successfully write.
+ *
+ * @return void
+ */
+ public function testZeroDuration() {
+ Cache::config('memcache', array('duration' => 0));
+ $result = Cache::write('test_key', 'written!', 'memcache');
+
+ $this->assertTrue($result);
+ $result = Cache::read('test_key', 'memcache');
+ $this->assertEquals('written!', $result);
+ }
+
+/**
+ * test that durations greater than 30 days never expire
+ *
+ * @return void
+ */
+ public function testLongDurationEqualToZero() {
+ $memcache = new TestMemcacheEngine();
+ $memcache->settings['compress'] = false;
+
+ $mock = $this->getMock('Memcache');
+ $memcache->setMemcache($mock);
+ $mock->expects($this->once())
+ ->method('set')
+ ->with('key', 'value', false, 0);
+
+ $value = 'value';
+ $memcache->write('key', $value, 50 * DAY);
+ }
+
+/**
+ * Tests that configuring groups for stored keys return the correct values when read/written
+ * Shows that altering the group value is equivalent to deleting all keys under the same
+ * group
+ *
+ * @return void
+ */
+ public function testGroupReadWrite() {
+ Cache::config('memcache_groups', array(
+ 'engine' => 'Memcache',
+ 'duration' => 3600,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ Cache::config('memcache_helper', array(
+ 'engine' => 'Memcache',
+ 'duration' => 3600,
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'memcache_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'memcache_groups'));
+
+ Cache::increment('group_a', 1, 'memcache_helper');
+ $this->assertFalse(Cache::read('test_groups', 'memcache_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'memcache_groups'));
+ $this->assertEquals('value2', Cache::read('test_groups', 'memcache_groups'));
+
+ Cache::increment('group_b', 1, 'memcache_helper');
+ $this->assertFalse(Cache::read('test_groups', 'memcache_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value3', 'memcache_groups'));
+ $this->assertEquals('value3', Cache::read('test_groups', 'memcache_groups'));
+ }
+
+/**
+ * Tests that deleteing from a groups-enabled config is possible
+ *
+ * @return void
+ */
+ public function testGroupDelete() {
+ Cache::config('memcache_groups', array(
+ 'engine' => 'Memcache',
+ 'duration' => 3600,
+ 'groups' => array('group_a', 'group_b')
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'memcache_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'memcache_groups'));
+ $this->assertTrue(Cache::delete('test_groups', 'memcache_groups'));
+
+ $this->assertFalse(Cache::read('test_groups', 'memcache_groups'));
+ }
+
+/**
+ * Test clearing a cache group
+ *
+ * @return void
+ **/
+ public function testGroupClear() {
+ Cache::config('memcache_groups', array(
+ 'engine' => 'Memcache',
+ 'duration' => 3600,
+ 'groups' => array('group_a', 'group_b')
+ ));
+
+ $this->assertTrue(Cache::write('test_groups', 'value', 'memcache_groups'));
+ $this->assertTrue(Cache::clearGroup('group_a', 'memcache_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'memcache_groups'));
+
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'memcache_groups'));
+ $this->assertTrue(Cache::clearGroup('group_b', 'memcache_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'memcache_groups'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php
new file mode 100644
index 0000000..de4c50d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/RedisEngineTest.php
@@ -0,0 +1,335 @@
+<?php
+/**
+ * RedisEngineTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package Cake.Test.Case.Cache.Engine
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+App::uses('RedisEngine', 'Cache/Engine');
+
+/**
+ * RedisEngineTest class
+ *
+ * @package Cake.Test.Case.Cache.Engine
+ */
+class RegisEngineTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ $this->skipIf(!class_exists('Redis'), 'Redis is not installed or configured properly.');
+
+ $this->_cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', false);
+ Cache::config('redis', array(
+ 'engine' => 'Redis',
+ 'prefix' => 'cake_',
+ 'duration' => 3600
+ ));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ Configure::write('Cache.disable', $this->_cacheDisable);
+ Cache::drop('');
+ Cache::drop('redis_groups');
+ Cache::drop('redis_helper');
+ Cache::config('default');
+ }
+
+/**
+ * testSettings method
+ *
+ * @return void
+ */
+ public function testSettings() {
+ $settings = Cache::settings('redis');
+ $expecting = array(
+ 'prefix' => 'cake_',
+ 'duration' => 3600,
+ 'probability' => 100,
+ 'groups' => array(),
+ 'engine' => 'Redis',
+ 'server' => '127.0.0.1',
+ 'port' => 6379,
+ 'timeout' => 0,
+ 'persistent' => true
+ );
+ $this->assertEquals($expecting, $settings);
+ }
+
+/**
+ * testConnect method
+ *
+ * @return void
+ */
+ public function testConnect() {
+ $Redis = new RedisEngine();
+ $this->assertTrue($Redis->init(Cache::settings('redis')));
+ }
+
+/**
+ * testReadAndWriteCache method
+ *
+ * @return void
+ */
+ public function testReadAndWriteCache() {
+ Cache::set(array('duration' => 1), null, 'redis');
+
+ $result = Cache::read('test', 'redis');
+ $expecting = '';
+ $this->assertEquals($expecting, $result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('test', $data, 'redis');
+ $this->assertTrue($result);
+
+ $result = Cache::read('test', 'redis');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ $data = array(1, 2, 3);
+ $this->assertTrue(Cache::write('array_data', $data, 'redis'));
+ $this->assertEquals($data, Cache::read('array_data', 'redis'));
+
+ Cache::delete('test', 'redis');
+ }
+
+/**
+ * testExpiry method
+ *
+ * @return void
+ */
+ public function testExpiry() {
+ Cache::set(array('duration' => 1), 'redis');
+
+ $result = Cache::read('test', 'redis');
+ $this->assertFalse($result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'redis');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'redis');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => "+1 second"), 'redis');
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'redis');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'redis');
+ $this->assertFalse($result);
+
+ Cache::config('redis', array('duration' => '+1 second'));
+ sleep(2);
+
+ $result = Cache::read('other_test', 'redis');
+ $this->assertFalse($result);
+
+ Cache::config('redis', array('duration' => '+29 days'));
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('long_expiry_test', $data, 'redis');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('long_expiry_test', 'redis');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ Cache::config('redis', array('duration' => 3600));
+ }
+
+/**
+ * testDeleteCache method
+ *
+ * @return void
+ */
+ public function testDeleteCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('delete_test', $data, 'redis');
+ $this->assertTrue($result);
+
+ $result = Cache::delete('delete_test', 'redis');
+ $this->assertTrue($result);
+ }
+
+/**
+ * testDecrement method
+ *
+ * @return void
+ */
+ public function testDecrement() {
+ Cache::delete('test_decrement', 'redis');
+ $result = Cache::write('test_decrement', 5, 'redis');
+ $this->assertTrue($result);
+
+ $result = Cache::decrement('test_decrement', 1, 'redis');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::read('test_decrement', 'redis');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::decrement('test_decrement', 2, 'redis');
+ $this->assertEquals(2, $result);
+
+ $result = Cache::read('test_decrement', 'redis');
+ $this->assertEquals(2, $result);
+ }
+
+/**
+ * testIncrement method
+ *
+ * @return void
+ */
+ public function testIncrement() {
+ Cache::delete('test_increment', 'redis');
+ $result = Cache::increment('test_increment', 1, 'redis');
+ $this->assertEquals(1, $result);
+
+ $result = Cache::read('test_increment', 'redis');
+ $this->assertEquals(1, $result);
+
+ $result = Cache::increment('test_increment', 2, 'redis');
+ $this->assertEquals(3, $result);
+
+ $result = Cache::read('test_increment', 'redis');
+ $this->assertEquals(3, $result);
+ }
+
+/**
+ * test clearing redis.
+ *
+ * @return void
+ */
+ public function testClear() {
+ Cache::config('redis2', array(
+ 'engine' => 'Redis',
+ 'prefix' => 'cake2_',
+ 'duration' => 3600
+ ));
+
+ Cache::write('some_value', 'cache1', 'redis');
+ $result = Cache::clear(true, 'redis');
+ $this->assertTrue($result);
+ $this->assertEquals('cache1', Cache::read('some_value', 'redis'));
+
+ Cache::write('some_value', 'cache2', 'redis2');
+ $result = Cache::clear(false, 'redis');
+ $this->assertTrue($result);
+ $this->assertFalse(Cache::read('some_value', 'redis'));
+ $this->assertEquals('cache2', Cache::read('some_value', 'redis2'));
+
+ Cache::clear(false, 'redis2');
+ }
+
+/**
+ * test that a 0 duration can successfully write.
+ *
+ * @return void
+ */
+ public function testZeroDuration() {
+ Cache::config('redis', array('duration' => 0));
+ $result = Cache::write('test_key', 'written!', 'redis');
+
+ $this->assertTrue($result);
+ $result = Cache::read('test_key', 'redis');
+ $this->assertEquals('written!', $result);
+ }
+
+/**
+ * Tests that configuring groups for stored keys return the correct values when read/written
+ * Shows that altering the group value is equivalent to deleting all keys under the same
+ * group
+ *
+ * @return void
+ */
+ public function testGroupReadWrite() {
+ Cache::config('redis_groups', array(
+ 'engine' => 'Redis',
+ 'duration' => 3600,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ Cache::config('redis_helper', array(
+ 'engine' => 'Redis',
+ 'duration' => 3600,
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'redis_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'redis_groups'));
+
+ Cache::increment('group_a', 1, 'redis_helper');
+ $this->assertFalse(Cache::read('test_groups', 'redis_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'redis_groups'));
+ $this->assertEquals('value2', Cache::read('test_groups', 'redis_groups'));
+
+ Cache::increment('group_b', 1, 'redis_helper');
+ $this->assertFalse(Cache::read('test_groups', 'redis_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value3', 'redis_groups'));
+ $this->assertEquals('value3', Cache::read('test_groups', 'redis_groups'));
+ }
+
+/**
+ * Tests that deleteing from a groups-enabled config is possible
+ *
+ * @return void
+ */
+ public function testGroupDelete() {
+ Cache::config('redis_groups', array(
+ 'engine' => 'Redis',
+ 'duration' => 3600,
+ 'groups' => array('group_a', 'group_b')
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'redis_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'redis_groups'));
+ $this->assertTrue(Cache::delete('test_groups', 'redis_groups'));
+
+ $this->assertFalse(Cache::read('test_groups', 'redis_groups'));
+ }
+
+/**
+ * Test clearing a cache group
+ *
+ * @return void
+ **/
+ public function testGroupClear() {
+ Cache::config('redis_groups', array(
+ 'engine' => 'Redis',
+ 'duration' => 3600,
+ 'groups' => array('group_a', 'group_b')
+ ));
+
+ $this->assertTrue(Cache::write('test_groups', 'value', 'redis_groups'));
+ $this->assertTrue(Cache::clearGroup('group_a', 'redis_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'redis_groups'));
+
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'redis_groups'));
+ $this->assertTrue(Cache::clearGroup('group_b', 'redis_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'redis_groups'));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php
new file mode 100644
index 0000000..12eed53
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php
@@ -0,0 +1,263 @@
+<?php
+/**
+ * WincacheEngineTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.5434
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+
+/**
+ * WincacheEngineTest class
+ *
+ * @package Cake.Test.Case.Cache.Engine
+ */
+class WincacheEngineTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->skipIf(!function_exists('wincache_ucache_set'), 'Wincache is not installed or configured properly.');
+ $this->_cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', false);
+ Cache::config('wincache', array('engine' => 'Wincache', 'prefix' => 'cake_'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('Cache.disable', $this->_cacheDisable);
+ Cache::drop('wincache');
+ Cache::drop('wincache_groups');
+ Cache::config('default');
+ }
+
+/**
+ * testReadAndWriteCache method
+ *
+ * @return void
+ */
+ public function testReadAndWriteCache() {
+ Cache::set(array('duration' => 1), 'wincache');
+
+ $result = Cache::read('test', 'wincache');
+ $expecting = '';
+ $this->assertEquals($expecting, $result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('test', $data, 'wincache');
+ $this->assertTrue($result);
+
+ $result = Cache::read('test', 'wincache');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ Cache::delete('test', 'wincache');
+ }
+
+/**
+ * testExpiry method
+ *
+ * @return void
+ */
+ public function testExpiry() {
+ Cache::set(array('duration' => 1), 'wincache');
+
+ $result = Cache::read('test', 'wincache');
+ $this->assertFalse($result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'wincache');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'wincache');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => 1), 'wincache');
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'wincache');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'wincache');
+ $this->assertFalse($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'wincache');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testDeleteCache method
+ *
+ * @return void
+ */
+ public function testDeleteCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('delete_test', $data, 'wincache');
+ $this->assertTrue($result);
+
+ $result = Cache::delete('delete_test', 'wincache');
+ $this->assertTrue($result);
+ }
+
+/**
+ * testDecrement method
+ *
+ * @return void
+ */
+ public function testDecrement() {
+ $this->skipIf(
+ !function_exists('wincache_ucache_dec'),
+ 'No wincache_ucache_dec() function, cannot test decrement().'
+ );
+
+ $result = Cache::write('test_decrement', 5, 'wincache');
+ $this->assertTrue($result);
+
+ $result = Cache::decrement('test_decrement', 1, 'wincache');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::read('test_decrement', 'wincache');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::decrement('test_decrement', 2, 'wincache');
+ $this->assertEquals(2, $result);
+
+ $result = Cache::read('test_decrement', 'wincache');
+ $this->assertEquals(2, $result);
+ }
+
+/**
+ * testIncrement method
+ *
+ * @return void
+ */
+ public function testIncrement() {
+ $this->skipIf(
+ !function_exists('wincache_ucache_inc'),
+ 'No wincache_inc() function, cannot test increment().'
+ );
+
+ $result = Cache::write('test_increment', 5, 'wincache');
+ $this->assertTrue($result);
+
+ $result = Cache::increment('test_increment', 1, 'wincache');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::read('test_increment', 'wincache');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::increment('test_increment', 2, 'wincache');
+ $this->assertEquals(8, $result);
+
+ $result = Cache::read('test_increment', 'wincache');
+ $this->assertEquals(8, $result);
+ }
+
+/**
+ * test the clearing of cache keys
+ *
+ * @return void
+ */
+ public function testClear() {
+ wincache_ucache_set('not_cake', 'safe');
+ Cache::write('some_value', 'value', 'wincache');
+
+ $result = Cache::clear(false, 'wincache');
+ $this->assertTrue($result);
+ $this->assertFalse(Cache::read('some_value', 'wincache'));
+ $this->assertEquals('safe', wincache_ucache_get('not_cake'));
+ }
+
+/**
+ * Tests that configuring groups for stored keys return the correct values when read/written
+ * Shows that altering the group value is equivalent to deleting all keys under the same
+ * group
+ *
+ * @return void
+ */
+ public function testGroupsReadWrite() {
+ Cache::config('wincache_groups', array(
+ 'engine' => 'Wincache',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'wincache_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'wincache_groups'));
+
+ wincache_ucache_inc('test_group_a');
+ $this->assertFalse(Cache::read('test_groups', 'wincache_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'wincache_groups'));
+ $this->assertEquals('value2', Cache::read('test_groups', 'wincache_groups'));
+
+ wincache_ucache_inc('test_group_b');
+ $this->assertFalse(Cache::read('test_groups', 'wincache_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value3', 'wincache_groups'));
+ $this->assertEquals('value3', Cache::read('test_groups', 'wincache_groups'));
+ }
+
+/**
+ * Tests that deleteing from a groups-enabled config is possible
+ *
+ * @return void
+ */
+ public function testGroupDelete() {
+ Cache::config('wincache_groups', array(
+ 'engine' => 'Wincache',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'wincache_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'wincache_groups'));
+ $this->assertTrue(Cache::delete('test_groups', 'wincache_groups'));
+
+ $this->assertFalse(Cache::read('test_groups', 'wincache_groups'));
+ }
+
+/**
+ * Test clearing a cache group
+ *
+ * @return void
+ **/
+ public function testGroupClear() {
+ Cache::config('wincache_groups', array(
+ 'engine' => 'Wincache',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+
+ $this->assertTrue(Cache::write('test_groups', 'value', 'wincache_groups'));
+ $this->assertTrue(Cache::clearGroup('group_a', 'wincache_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'wincache_groups'));
+
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'wincache_groups'));
+ $this->assertTrue(Cache::clearGroup('group_b', 'wincache_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'wincache_groups'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php
new file mode 100644
index 0000000..985977e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Cache/Engine/XcacheEngineTest.php
@@ -0,0 +1,272 @@
+<?php
+/**
+ * XcacheEngineTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Cache.Engine
+ * @since CakePHP(tm) v 1.2.0.5434
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+
+/**
+ * XcacheEngineTest class
+ *
+ * @package Cake.Test.Case.Cache.Engine
+ */
+class XcacheEngineTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ if (!function_exists('xcache_set')) {
+ $this->markTestSkipped('Xcache is not installed or configured properly');
+ }
+ $this->_cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', false);
+ Cache::config('xcache', array('engine' => 'Xcache', 'prefix' => 'cake_'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('Cache.disable', $this->_cacheDisable);
+ Cache::drop('xcache');
+ Cache::drop('xcache_groups');
+ Cache::config('default');
+ }
+
+/**
+ * testSettings method
+ *
+ * @return void
+ */
+ public function testSettings() {
+ $settings = Cache::settings();
+ $expecting = array(
+ 'prefix' => 'cake_',
+ 'duration' => 3600,
+ 'probability' => 100,
+ 'engine' => 'Xcache',
+ );
+ $this->assertTrue(isset($settings['PHP_AUTH_USER']));
+ $this->assertTrue(isset($settings['PHP_AUTH_PW']));
+
+ unset($settings['PHP_AUTH_USER'], $settings['PHP_AUTH_PW']);
+ $this->assertEquals($settings, $expecting);
+ }
+
+/**
+ * testReadAndWriteCache method
+ *
+ * @return void
+ */
+ public function testReadAndWriteCache() {
+ Cache::set(array('duration' => 1));
+
+ $result = Cache::read('test');
+ $expecting = '';
+ $this->assertEquals($expecting, $result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('test', $data);
+ $this->assertTrue($result);
+
+ $result = Cache::read('test');
+ $expecting = $data;
+ $this->assertEquals($expecting, $result);
+
+ Cache::delete('test');
+ }
+
+/**
+ * testExpiry method
+ *
+ * @return void
+ */
+ public function testExpiry() {
+ Cache::set(array('duration' => 1));
+ $result = Cache::read('test');
+ $this->assertFalse($result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data);
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => "+1 second"));
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data);
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testDeleteCache method
+ *
+ * @return void
+ */
+ public function testDeleteCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('delete_test', $data);
+ $this->assertTrue($result);
+
+ $result = Cache::delete('delete_test');
+ $this->assertTrue($result);
+ }
+
+/**
+ * testClearCache method
+ *
+ * @return void
+ */
+ public function testClearCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('clear_test_1', $data);
+ $this->assertTrue($result);
+
+ $result = Cache::write('clear_test_2', $data);
+ $this->assertTrue($result);
+
+ $result = Cache::clear();
+ $this->assertTrue($result);
+ }
+
+/**
+ * testDecrement method
+ *
+ * @return void
+ */
+ public function testDecrement() {
+ $result = Cache::write('test_decrement', 5);
+ $this->assertTrue($result);
+
+ $result = Cache::decrement('test_decrement');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::read('test_decrement');
+ $this->assertEquals(4, $result);
+
+ $result = Cache::decrement('test_decrement', 2);
+ $this->assertEquals(2, $result);
+
+ $result = Cache::read('test_decrement');
+ $this->assertEquals(2, $result);
+ }
+
+/**
+ * testIncrement method
+ *
+ * @return void
+ */
+ public function testIncrement() {
+ $result = Cache::write('test_increment', 5);
+ $this->assertTrue($result);
+
+ $result = Cache::increment('test_increment');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::read('test_increment');
+ $this->assertEquals(6, $result);
+
+ $result = Cache::increment('test_increment', 2);
+ $this->assertEquals(8, $result);
+
+ $result = Cache::read('test_increment');
+ $this->assertEquals(8, $result);
+ }
+
+/**
+ * Tests that configuring groups for stored keys return the correct values when read/written
+ * Shows that altering the group value is equivalent to deleting all keys under the same
+ * group
+ *
+ * @return void
+ */
+ public function testGroupsReadWrite() {
+ Cache::config('xcache_groups', array(
+ 'engine' => 'Xcache',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'xcache_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'xcache_groups'));
+
+ xcache_inc('test_group_a', 1);
+ $this->assertFalse(Cache::read('test_groups', 'xcache_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'xcache_groups'));
+ $this->assertEquals('value2', Cache::read('test_groups', 'xcache_groups'));
+
+ xcache_inc('test_group_b', 1);
+ $this->assertFalse(Cache::read('test_groups', 'xcache_groups'));
+ $this->assertTrue(Cache::write('test_groups', 'value3', 'xcache_groups'));
+ $this->assertEquals('value3', Cache::read('test_groups', 'xcache_groups'));
+ }
+
+/**
+ * Tests that deleteing from a groups-enabled config is possible
+ *
+ * @return void
+ */
+ public function testGroupDelete() {
+ Cache::config('xcache_groups', array(
+ 'engine' => 'Xcache',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+ $this->assertTrue(Cache::write('test_groups', 'value', 'xcache_groups'));
+ $this->assertEquals('value', Cache::read('test_groups', 'xcache_groups'));
+ $this->assertTrue(Cache::delete('test_groups', 'xcache_groups'));
+
+ $this->assertFalse(Cache::read('test_groups', 'xcache_groups'));
+ }
+
+/**
+ * Test clearing a cache group
+ *
+ * @return void
+ **/
+ public function testGroupClear() {
+ Cache::config('xcache_groups', array(
+ 'engine' => 'Xcache',
+ 'duration' => 0,
+ 'groups' => array('group_a', 'group_b'),
+ 'prefix' => 'test_'
+ ));
+
+ $this->assertTrue(Cache::write('test_groups', 'value', 'xcache_groups'));
+ $this->assertTrue(Cache::clearGroup('group_a', 'xcache_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'xcache_groups'));
+
+ $this->assertTrue(Cache::write('test_groups', 'value2', 'xcache_groups'));
+ $this->assertTrue(Cache::clearGroup('group_b', 'xcache_groups'));
+ $this->assertFalse(Cache::read('test_groups', 'xcache_groups'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/IniReaderTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/IniReaderTest.php
new file mode 100644
index 0000000..e4b4634
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/IniReaderTest.php
@@ -0,0 +1,188 @@
+<?php
+/**
+ * IniReaderTest
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Configure
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('IniReader', 'Configure');
+
+class IniReaderTest extends CakeTestCase {
+
+/**
+ * Test data to serialize and unserialize.
+ *
+ * @var array
+ */
+ public $testData = array(
+ 'One' => array(
+ 'two' => 'value',
+ 'three' => array(
+ 'four' => 'value four'
+ ),
+ 'is_null' => null,
+ 'bool_false' => false,
+ 'bool_true' => true,
+ ),
+ 'Asset' => array(
+ 'timestamp' => 'force'
+ ),
+ );
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->path = CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS;
+ }
+
+/**
+ * test construct
+ *
+ * @return void
+ */
+ public function testConstruct() {
+ $reader = new IniReader($this->path);
+ $config = $reader->read('acl.ini.php');
+
+ $this->assertTrue(isset($config['admin']));
+ $this->assertTrue(isset($config['paul']['groups']));
+ $this->assertEquals('ads', $config['admin']['deny']);
+ }
+
+/**
+ * no other sections should exist.
+ *
+ * @return void
+ */
+ public function testReadingOnlyOneSection() {
+ $reader = new IniReader($this->path, 'admin');
+ $config = $reader->read('acl.ini.php');
+
+ $this->assertTrue(isset($config['groups']));
+ $this->assertEquals('administrators', $config['groups']);
+ }
+
+/**
+ * test without section
+ *
+ * @return void
+ */
+ public function testReadingWithoutSection() {
+ $reader = new IniReader($this->path);
+ $config = $reader->read('no_section.ini');
+
+ $expected = array(
+ 'some_key' => 'some_value',
+ 'bool_key' => true
+ );
+ $this->assertEquals($expected, $config);
+ }
+
+/**
+ * test that names with .'s get exploded into arrays.
+ *
+ * @return void
+ */
+ public function testReadingValuesWithDots() {
+ $reader = new IniReader($this->path);
+ $config = $reader->read('nested.ini');
+
+ $this->assertTrue(isset($config['database']['db']['username']));
+ $this->assertEquals('mark', $config['database']['db']['username']);
+ $this->assertEquals(3, $config['nesting']['one']['two']['three']);
+ $this->assertFalse(isset($config['database.db.username']));
+ $this->assertFalse(isset($config['database']['db.username']));
+ }
+
+/**
+ * test boolean reading
+ *
+ * @return void
+ */
+ public function testBooleanReading() {
+ $reader = new IniReader($this->path);
+ $config = $reader->read('nested.ini');
+
+ $this->assertTrue($config['bools']['test_on']);
+ $this->assertFalse($config['bools']['test_off']);
+
+ $this->assertTrue($config['bools']['test_yes']);
+ $this->assertFalse($config['bools']['test_no']);
+
+ $this->assertTrue($config['bools']['test_true']);
+ $this->assertFalse($config['bools']['test_false']);
+
+ $this->assertFalse($config['bools']['test_null']);
+ }
+
+/**
+ * test read file without extension
+ *
+ * @return void
+ */
+ public function testReadingWithoutExtension() {
+ $reader = new IniReader($this->path);
+ $config = $reader->read('nested');
+ $this->assertTrue($config['bools']['test_on']);
+ }
+
+/**
+ * test dump method.
+ *
+ * @return void
+ */
+ public function testDump() {
+ $reader = new IniReader(TMP);
+ $result = $reader->dump('test.ini', $this->testData);
+ $this->assertTrue($result > 0);
+
+ $expected = <<<INI
+[One]
+two = value
+three.four = value four
+is_null = null
+bool_false = false
+bool_true = true
+[Asset]
+timestamp = force
+INI;
+ $file = TMP . 'test.ini';
+ $result = file_get_contents($file);
+ unlink($file);
+
+ $this->assertTextEquals($expected, $result);
+ }
+
+/**
+ * Test that dump() makes files read() can read.
+ *
+ * @return void
+ */
+ public function testDumpRead() {
+ $reader = new IniReader(TMP);
+ $reader->dump('test.ini', $this->testData);
+ $result = $reader->read('test.ini');
+ unlink(TMP . 'test.ini');
+
+ $expected = $this->testData;
+ $expected['One']['is_null'] = false;
+
+ $this->assertEquals($expected, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/PhpReaderTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/PhpReaderTest.php
new file mode 100644
index 0000000..08982cb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Configure/PhpReaderTest.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * PhpConfigReaderTest
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Configure
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('PhpReader', 'Configure');
+
+class PhpReaderTest extends CakeTestCase {
+
+/**
+ * Test data to serialize and unserialize.
+ *
+ * @var array
+ */
+ public $testData = array(
+ 'One' => array(
+ 'two' => 'value',
+ 'three' => array(
+ 'four' => 'value four'
+ ),
+ 'is_null' => null,
+ 'bool_false' => false,
+ 'bool_true' => true,
+ ),
+ 'Asset' => array(
+ 'timestamp' => 'force'
+ ),
+ );
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->path = CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS;
+ }
+
+/**
+ * test reading files
+ *
+ * @return void
+ */
+ public function testRead() {
+ $reader = new PhpReader($this->path);
+ $values = $reader->read('var_test');
+ $this->assertEquals('value', $values['Read']);
+ $this->assertEquals('buried', $values['Deep']['Deeper']['Deepest']);
+
+ $values = $reader->read('var_test.php');
+ $this->assertEquals('value', $values['Read']);
+ }
+
+/**
+ * Test an exception is thrown by reading files that don't exist.
+ *
+ * @expectedException ConfigureException
+ * @return void
+ */
+ public function testReadWithNonExistantFile() {
+ $reader = new PhpReader($this->path);
+ $reader->read('fake_values');
+ }
+
+/**
+ * test reading an empty file.
+ *
+ * @expectedException RuntimeException
+ * @return void
+ */
+ public function testReadEmptyFile() {
+ $reader = new PhpReader($this->path);
+ $reader->read('empty');
+ }
+
+/**
+ * test reading keys with ../ doesn't work
+ *
+ * @expectedException ConfigureException
+ * @return void
+ */
+ public function testReadWithDots() {
+ $reader = new PhpReader($this->path);
+ $reader->read('../empty');
+ }
+
+/**
+ * test reading from plugins
+ *
+ * @return void
+ */
+ public function testReadPluginValue() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+ $reader = new PhpReader($this->path);
+ $result = $reader->read('TestPlugin.load');
+ $this->assertTrue(isset($result['plugin_load']));
+
+ $result = $reader->read('TestPlugin.load.php');
+ $this->assertTrue(isset($result['plugin_load']));
+ CakePlugin::unload();
+ }
+
+/**
+ * Test dumping data to PHP format.
+ *
+ * @return void
+ */
+ public function testDump() {
+ $reader = new PhpReader(TMP);
+ $result = $reader->dump('test.php', $this->testData);
+ $this->assertTrue($result > 0);
+ $expected = <<<PHP
+<?php
+\$config = array (
+ 'One' =>
+ array (
+ 'two' => 'value',
+ 'three' =>
+ array (
+ 'four' => 'value four',
+ ),
+ 'is_null' => NULL,
+ 'bool_false' => false,
+ 'bool_true' => true,
+ ),
+ 'Asset' =>
+ array (
+ 'timestamp' => 'force',
+ ),
+);
+PHP;
+ $file = TMP . 'test.php';
+ $contents = file_get_contents($file);
+
+ unlink($file);
+ $this->assertTextEquals($expected, $contents);
+ }
+
+/**
+ * Test that dump() makes files read() can read.
+ *
+ * @return void
+ */
+ public function testDumpRead() {
+ $reader = new PhpReader(TMP);
+ $reader->dump('test.php', $this->testData);
+ $result = $reader->read('test.php');
+ unlink(TMP . 'test.php');
+
+ $this->assertEquals($this->testData, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleLibsTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleLibsTest.php
new file mode 100644
index 0000000..5a6846b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleLibsTest.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * AllConsoleLibsTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllConsoleLibsTest class
+ *
+ * This test group will run all console lib classes.
+ *
+ * @package Cake.Test.Case.Console
+ */
+class AllConsoleLibsTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All console lib classes');
+
+ foreach (new DirectoryIterator(dirname(__FILE__)) as $file) {
+ if (!$file->isFile() || strpos($file, 'All') === 0) {
+ continue;
+ }
+ $fileName = $file->getRealPath();
+ if (substr($fileName, -4) === '.php') {
+ $suite->addTestFile($file->getRealPath());
+ }
+ }
+ return $suite;
+ }
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleTest.php
new file mode 100644
index 0000000..e284479
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllConsoleTest.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * AllConsoleTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllConsoleTest class
+ *
+ * This test group will run all console classes.
+ *
+ * @package Cake.Test.Case.Console
+ */
+class AllConsoleTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All console classes');
+
+ $path = CORE_TEST_CASES . DS . 'Console' . DS;
+
+ $suite->addTestFile($path . 'AllConsoleLibsTest.php');
+ $suite->addTestFile($path . 'AllTasksTest.php');
+ $suite->addTestFile($path . 'AllShellsTest.php');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllShellsTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllShellsTest.php
new file mode 100644
index 0000000..8842d61
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllShellsTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * AllShellsTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllShellsTest class
+ *
+ * This test group will run all top level shell classes.
+ *
+ * @package Cake.Test.Case.Console
+ */
+class AllShellsTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All shell classes');
+
+ $path = CORE_TEST_CASES . DS . 'Console' . DS . 'Command' . DS;
+
+ $suite->addTestDirectory($path);
+ return $suite;
+ }
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllTasksTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllTasksTest.php
new file mode 100644
index 0000000..dcdce73
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/AllTasksTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * AllTasksTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AllTasksTest class
+ *
+ * This test group will run all the task tests.
+ *
+ * @package Cake.Test.Case.Console
+ */
+class AllTasksTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('All Tasks tests');
+
+ $path = CORE_TEST_CASES . DS . 'Console' . DS . 'Command' . DS . 'Task' . DS;
+ $suite->addTestDirectory($path);
+ return $suite;
+ }
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/AclShellTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/AclShellTest.php
new file mode 100644
index 0000000..7dfbbc0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/AclShellTest.php
@@ -0,0 +1,311 @@
+<?php
+/**
+ * AclShell Test file
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('AclShell', 'Console/Command');
+App::uses('ComponentCollection', 'Controller');
+
+/**
+ * AclShellTest class
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class AclShellTest extends CakeTestCase {
+
+/**
+ * Fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array('core.aco', 'core.aro', 'core.aros_aco');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Acl.database', 'test');
+ Configure::write('Acl.classname', 'DbAcl');
+
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock(
+ 'AclShell',
+ array('in', 'out', 'hr', 'createFile', 'error', 'err', 'clear', 'dispatchShell'),
+ array($out, $out, $in)
+ );
+ $collection = new ComponentCollection();
+ $this->Task->Acl = new AclComponent($collection);
+ $this->Task->params['datasource'] = 'test';
+ }
+
+/**
+ * test that model.foreign_key output works when looking at acl rows
+ *
+ * @return void
+ */
+ public function testViewWithModelForeignKeyOutput() {
+ $this->Task->command = 'view';
+ $this->Task->startup();
+ $data = array(
+ 'parent_id' => null,
+ 'model' => 'MyModel',
+ 'foreign_key' => 2,
+ );
+ $this->Task->Acl->Aro->create($data);
+ $this->Task->Acl->Aro->save();
+ $this->Task->args[0] = 'aro';
+
+ $this->Task->expects($this->at(0))->method('out')->with('Aro tree:');
+ $this->Task->expects($this->at(2))->method('out')
+ ->with($this->stringContains('[1] ROOT'));
+
+ $this->Task->expects($this->at(4))->method('out')
+ ->with($this->stringContains('[3] Gandalf'));
+
+ $this->Task->expects($this->at(6))->method('out')
+ ->with($this->stringContains('[5] MyModel.2'));
+
+ $this->Task->view();
+ }
+
+/**
+ * test view with an argument
+ *
+ * @return void
+ */
+ public function testViewWithArgument() {
+ $this->Task->args = array('aro', 'admins');
+
+ $this->Task->expects($this->at(0))->method('out')->with('Aro tree:');
+ $this->Task->expects($this->at(2))->method('out')->with(' [2] admins');
+ $this->Task->expects($this->at(3))->method('out')->with(' [3] Gandalf');
+ $this->Task->expects($this->at(4))->method('out')->with(' [4] Elrond');
+
+ $this->Task->view();
+ }
+
+/**
+ * test the method that splits model.foreign key. and that it returns an array.
+ *
+ * @return void
+ */
+ public function testParsingModelAndForeignKey() {
+ $result = $this->Task->parseIdentifier('Model.foreignKey');
+ $expected = array('model' => 'Model', 'foreign_key' => 'foreignKey');
+
+ $result = $this->Task->parseIdentifier('mySuperUser');
+ $this->assertEquals('mySuperUser', $result);
+
+ $result = $this->Task->parseIdentifier('111234');
+ $this->assertEquals('111234', $result);
+ }
+
+/**
+ * test creating aro/aco nodes
+ *
+ * @return void
+ */
+ public function testCreate() {
+ $this->Task->args = array('aro', 'root', 'User.1');
+ $this->Task->expects($this->at(0))->method('out')->with("<success>New Aro</success> 'User.1' created.", 2);
+ $this->Task->expects($this->at(1))->method('out')->with("<success>New Aro</success> 'User.3' created.", 2);
+ $this->Task->expects($this->at(2))->method('out')->with("<success>New Aro</success> 'somealias' created.", 2);
+
+ $this->Task->create();
+
+ $Aro = ClassRegistry::init('Aro');
+ $Aro->cacheQueries = false;
+ $result = $Aro->read();
+ $this->assertEquals('User', $result['Aro']['model']);
+ $this->assertEquals(1, $result['Aro']['foreign_key']);
+ $this->assertEquals(null, $result['Aro']['parent_id']);
+ $id = $result['Aro']['id'];
+
+ $this->Task->args = array('aro', 'User.1', 'User.3');
+ $this->Task->create();
+
+ $Aro = ClassRegistry::init('Aro');
+ $result = $Aro->read();
+ $this->assertEquals('User', $result['Aro']['model']);
+ $this->assertEquals(3, $result['Aro']['foreign_key']);
+ $this->assertEquals($id, $result['Aro']['parent_id']);
+
+ $this->Task->args = array('aro', 'root', 'somealias');
+ $this->Task->create();
+
+ $Aro = ClassRegistry::init('Aro');
+ $result = $Aro->read();
+ $this->assertEquals('somealias', $result['Aro']['alias']);
+ $this->assertEquals(null, $result['Aro']['model']);
+ $this->assertEquals(null, $result['Aro']['foreign_key']);
+ $this->assertEquals(null, $result['Aro']['parent_id']);
+ }
+
+/**
+ * test the delete method with different node types.
+ *
+ * @return void
+ */
+ public function testDelete() {
+ $this->Task->args = array('aro', 'AuthUser.1');
+ $this->Task->expects($this->at(0))->method('out')
+ ->with("<success>Aro deleted.</success>", 2);
+ $this->Task->delete();
+
+ $Aro = ClassRegistry::init('Aro');
+ $result = $Aro->findById(3);
+ $this->assertFalse($result);
+ }
+
+/**
+ * test setParent method.
+ *
+ * @return void
+ */
+ public function testSetParent() {
+ $this->Task->args = array('aro', 'AuthUser.2', 'root');
+ $this->Task->setParent();
+
+ $Aro = ClassRegistry::init('Aro');
+ $result = $Aro->read(null, 4);
+ $this->assertEquals(null, $result['Aro']['parent_id']);
+ }
+
+/**
+ * test grant
+ *
+ * @return void
+ */
+ public function testGrant() {
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'create');
+ $this->Task->expects($this->at(0))->method('out')
+ ->with($this->matchesRegularExpression('/granted/'), true);
+ $this->Task->grant();
+ $node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
+ $node = $this->Task->Acl->Aro->read(null, $node[0]['Aro']['id']);
+
+ $this->assertFalse(empty($node['Aco'][0]));
+ $this->assertEquals(1, $node['Aco'][0]['Permission']['_create']);
+ }
+
+/**
+ * test deny
+ *
+ * @return void
+ */
+ public function testDeny() {
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'create');
+ $this->Task->expects($this->at(0))->method('out')
+ ->with($this->stringContains('Permission denied'), true);
+
+ $this->Task->deny();
+
+ $node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
+ $node = $this->Task->Acl->Aro->read(null, $node[0]['Aro']['id']);
+ $this->assertFalse(empty($node['Aco'][0]));
+ $this->assertEquals(-1, $node['Aco'][0]['Permission']['_create']);
+ }
+
+/**
+ * test checking allowed and denied perms
+ *
+ * @return void
+ */
+ public function testCheck() {
+ $this->Task->expects($this->at(0))->method('out')
+ ->with($this->matchesRegularExpression('/not allowed/'), true);
+ $this->Task->expects($this->at(1))->method('out')
+ ->with($this->matchesRegularExpression('/granted/'), true);
+ $this->Task->expects($this->at(2))->method('out')
+ ->with($this->matchesRegularExpression('/is.*allowed/'), true);
+ $this->Task->expects($this->at(3))->method('out')
+ ->with($this->matchesRegularExpression('/not.*allowed/'), true);
+
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', '*');
+ $this->Task->check();
+
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'create');
+ $this->Task->grant();
+
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'create');
+ $this->Task->check();
+
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', '*');
+ $this->Task->check();
+ }
+
+/**
+ * test inherit and that it 0's the permission fields.
+ *
+ * @return void
+ */
+ public function testInherit() {
+ $this->Task->expects($this->at(0))->method('out')
+ ->with($this->matchesRegularExpression('/Permission .*granted/'), true);
+ $this->Task->expects($this->at(1))->method('out')
+ ->with($this->matchesRegularExpression('/Permission .*inherited/'), true);
+
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'create');
+ $this->Task->grant();
+
+ $this->Task->args = array('AuthUser.2', 'ROOT/Controller1', 'all');
+ $this->Task->inherit();
+
+ $node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
+ $node = $this->Task->Acl->Aro->read(null, $node[0]['Aro']['id']);
+ $this->assertFalse(empty($node['Aco'][0]));
+ $this->assertEquals(0, $node['Aco'][0]['Permission']['_create']);
+ }
+
+/**
+ * test getting the path for an aro/aco
+ *
+ * @return void
+ */
+ public function testGetPath() {
+ $this->Task->args = array('aro', 'AuthUser.2');
+ $node = $this->Task->Acl->Aro->node(array('model' => 'AuthUser', 'foreign_key' => 2));
+ $first = $node[0]['Aro']['id'];
+ $second = $node[1]['Aro']['id'];
+ $last = $node[2]['Aro']['id'];
+ $this->Task->expects($this->at(2))->method('out')->with('[' . $last . '] ROOT');
+ $this->Task->expects($this->at(3))->method('out')->with(' [' . $second . '] admins');
+ $this->Task->expects($this->at(4))->method('out')->with(' [' . $first . '] Elrond');
+ $this->Task->getPath();
+ }
+
+/**
+ * test that initdb makes the correct call.
+ *
+ * @return void
+ */
+ public function testInitDb() {
+ $this->Task->expects($this->once())->method('dispatchShell')
+ ->with('schema create DbAcl');
+
+ $this->Task->initdb();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/ApiShellTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/ApiShellTest.php
new file mode 100644
index 0000000..f5d2fbe
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/ApiShellTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * ApiShellTest file
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('ApiShell', 'Console/Command');
+
+/**
+ * ApiShellTest class
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class ApiShellTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Shell = $this->getMock(
+ 'ApiShell',
+ array('in', 'out', 'createFile', 'hr', '_stop'),
+ array( $out, $out, $in)
+ );
+ }
+
+/**
+ * Test that method names are detected properly including those with no arguments.
+ *
+ * @return void
+ */
+ public function testMethodNameDetection() {
+ $this->Shell->expects($this->any())->method('in')->will($this->returnValue('q'));
+ $this->Shell->expects($this->at(0))->method('out')->with('Controller');
+
+ $expected = array(
+ '1. afterFilter()',
+ '2. afterScaffoldSave($method)',
+ '3. afterScaffoldSaveError($method)',
+ '4. beforeFilter()',
+ '5. beforeRedirect($url, $status = NULL, $exit = true)',
+ '6. beforeRender()',
+ '7. beforeScaffold($method)',
+ '8. constructClasses()',
+ '9. disableCache()',
+ '10. flash($message, $url, $pause = 1, $layout = \'flash\')',
+ '11. getEventManager()',
+ '12. header($status)',
+ '13. httpCodes($code = NULL)',
+ '14. implementedEvents()',
+ '15. invokeAction($request)',
+ '16. loadModel($modelClass = NULL, $id = NULL)',
+ '17. paginate($object = NULL, $scope = array (), $whitelist = array ())',
+ '18. postConditions($data = array (), $op = NULL, $bool = \'AND\', $exclusive = false)',
+ '19. redirect($url, $status = NULL, $exit = true)',
+ '20. referer($default = NULL, $local = false)',
+ '21. render($view = NULL, $layout = NULL)',
+ '22. scaffoldError($method)',
+ '23. set($one, $two = NULL)',
+ '24. setAction($action)',
+ '25. setRequest($request)',
+ '26. shutdownProcess()',
+ '27. startupProcess()',
+ '28. validate()',
+ '29. validateErrors()'
+ );
+ $this->Shell->expects($this->at(2))->method('out')->with($expected);
+
+ $this->Shell->args = array('controller');
+ $this->Shell->paths['controller'] = CAKE . 'Controller' . DS;
+ $this->Shell->main();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/BakeShellTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/BakeShellTest.php
new file mode 100644
index 0000000..8991674
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/BakeShellTest.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * BakeShell Test Case
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('BakeShell', 'Console/Command');
+App::uses('ModelTask', 'Console/Command/Task');
+App::uses('ControllerTask', 'Console/Command/Task');
+App::uses('DbConfigTask', 'Console/Command/Task');
+App::uses('Controller', 'Controller');
+
+if (!class_exists('UsersController')) {
+ class UsersController extends Controller {
+
+ public $name = 'Users';
+
+ }
+}
+
+class BakeShellTest extends CakeTestCase {
+
+/**
+ * fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array('core.user');
+
+/**
+ * setup test
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Shell = $this->getMock(
+ 'BakeShell',
+ array('in', 'out', 'hr', 'err', 'createFile', '_stop', '_checkUnitTest'),
+ array($out, $out, $in)
+ );
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Dispatch, $this->Shell);
+ }
+
+/**
+ * test bake all
+ *
+ * @return void
+ */
+ public function testAllWithModelName() {
+ App::uses('User', 'Model');
+ $userExists = class_exists('User');
+ $this->skipIf($userExists, 'User class exists, cannot test `bake all [param]`.');
+
+ $this->Shell->Model = $this->getMock('ModelTask', array(), array(&$this->Dispatcher));
+ $this->Shell->Controller = $this->getMock('ControllerTask', array(), array(&$this->Dispatcher));
+ $this->Shell->View = $this->getMock('ModelTask', array(), array(&$this->Dispatcher));
+ $this->Shell->DbConfig = $this->getMock('DbConfigTask', array(), array(&$this->Dispatcher));
+
+ $this->Shell->DbConfig->expects($this->once())
+ ->method('getConfig')
+ ->will($this->returnValue('test'));
+
+ $this->Shell->Model->expects($this->never())
+ ->method('getName');
+
+ $this->Shell->Model->expects($this->once())
+ ->method('bake')
+ ->will($this->returnValue(true));
+
+ $this->Shell->Controller->expects($this->once())
+ ->method('bake')
+ ->will($this->returnValue(true));
+
+ $this->Shell->View->expects($this->once())
+ ->method('execute');
+
+ $this->Shell->expects($this->once())->method('_stop');
+ $this->Shell->expects($this->at(0))
+ ->method('out')
+ ->with('Bake All');
+
+ $this->Shell->expects($this->at(5))
+ ->method('out')
+ ->with('<success>Bake All complete</success>');
+
+ $this->Shell->connection = '';
+ $this->Shell->params = array();
+ $this->Shell->args = array('User');
+ $this->Shell->all();
+
+ $this->assertEquals('User', $this->Shell->View->args[0]);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php
new file mode 100644
index 0000000..22eed19
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/CommandListShellTest.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * CommandListShellTest file
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CommandListShell', 'Console/Command');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+
+
+class TestStringOutput extends ConsoleOutput {
+
+ public $output = '';
+
+ protected function _write($message) {
+ $this->output .= $message;
+ }
+
+}
+
+class CommandListShellTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'Plugin' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ ),
+ 'Console/Command' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS . 'Command' . DS
+ )
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ $out = new TestStringOutput();
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Shell = $this->getMock(
+ 'CommandListShell',
+ array('in', '_stop', 'clear'),
+ array($out, $out, $in)
+ );
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Shell);
+ CakePlugin::unload();
+ }
+
+/**
+ * test that main finds core shells.
+ *
+ * @return void
+ */
+ public function testMain() {
+ $this->Shell->main();
+ $output = $this->Shell->stdout->output;
+
+ $expected = "/\[.*TestPlugin.*\] example/";
+ $this->assertRegExp($expected, $output);
+
+ $expected = "/\[.*TestPluginTwo.*\] example, welcome/";
+ $this->assertRegExp($expected, $output);
+
+ $expected = "/\[.*CORE.*\] acl, api, bake, command_list, console, i18n, schema, test, testsuite, upgrade/";
+ $this->assertRegExp($expected, $output);
+
+ $expected = "/\[.*app.*\] sample/";
+ $this->assertRegExp($expected, $output);
+ }
+
+/**
+ * test xml output.
+ *
+ * @return void
+ */
+ public function testMainXml() {
+ $this->Shell->params['xml'] = true;
+ $this->Shell->main();
+
+ $output = $this->Shell->stdout->output;
+
+ $find = '<shell name="sample" call_as="sample" provider="app" help="sample -h"/>';
+ $this->assertContains($find, $output);
+
+ $find = '<shell name="bake" call_as="bake" provider="CORE" help="bake -h"/>';
+ $this->assertContains($find, $output);
+
+ $find = '<shell name="welcome" call_as="TestPluginTwo.welcome" provider="TestPluginTwo" help="TestPluginTwo.welcome -h"/>';
+ $this->assertContains($find, $output);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php
new file mode 100644
index 0000000..7d21753
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/SchemaShellTest.php
@@ -0,0 +1,492 @@
+<?php
+/**
+ * SchemaShellTest Test file
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+App::uses('CakeSchema', 'Model');
+App::uses('SchemaShell', 'Console/Command');
+
+/**
+ * Test for Schema database management
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class SchemaShellTestSchema extends CakeSchema {
+
+/**
+ * name property
+ *
+ * @var string 'MyApp'
+ */
+ public $name = 'SchemaShellTest';
+
+/**
+ * connection property
+ *
+ * @var string 'test'
+ */
+ public $connection = 'test';
+
+/**
+ * comments property
+ *
+ * @var array
+ */
+ public $comments = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false, 'length' => 100),
+ 'comment' => array('type' => 'text', 'null' => false, 'default' => null),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ );
+
+/**
+ * posts property
+ *
+ * @var array
+ */
+ public $articles = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'user_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
+ 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
+ 'body' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'summary' => array('type' => 'text', 'null' => true),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ );
+}
+
+/**
+ * SchemaShellTest class
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class SchemaShellTest extends CakeTestCase {
+
+/**
+ * Fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array('core.article', 'core.user', 'core.post', 'core.auth_user', 'core.author',
+ 'core.comment', 'core.test_plugin_comment'
+ );
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Shell = $this->getMock(
+ 'SchemaShell',
+ array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop'),
+ array($out, $out, $in)
+ );
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ if (!empty($this->file) && $this->file instanceof File) {
+ $this->file->delete();
+ unset($this->file);
+ }
+ }
+
+/**
+ * test startup method
+ *
+ * @return void
+ */
+ public function testStartup() {
+ $this->Shell->startup();
+ $this->assertTrue(isset($this->Shell->Schema));
+ $this->assertTrue(is_a($this->Shell->Schema, 'CakeSchema'));
+ $this->assertEquals(Inflector::camelize(Inflector::slug(APP_DIR)), $this->Shell->Schema->name);
+ $this->assertEquals('schema.php', $this->Shell->Schema->file);
+
+ $this->Shell->Schema = null;
+ $this->Shell->params = array(
+ 'name' => 'TestSchema'
+ );
+ $this->Shell->startup();
+ $this->assertEquals('TestSchema', $this->Shell->Schema->name);
+ $this->assertEquals('test_schema.php', $this->Shell->Schema->file);
+ $this->assertEquals('default', $this->Shell->Schema->connection);
+ $this->assertEquals(APP . 'Config' . DS . 'Schema', $this->Shell->Schema->path);
+
+ $this->Shell->Schema = null;
+ $this->Shell->params = array(
+ 'file' => 'other_file.php',
+ 'connection' => 'test',
+ 'path' => '/test/path'
+ );
+ $this->Shell->startup();
+ $this->assertEquals(Inflector::camelize(Inflector::slug(APP_DIR)), $this->Shell->Schema->name);
+ $this->assertEquals('other_file.php', $this->Shell->Schema->file);
+ $this->assertEquals('test', $this->Shell->Schema->connection);
+ $this->assertEquals('/test/path', $this->Shell->Schema->path);
+ }
+
+/**
+ * Test View - and that it dumps the schema file to stdout
+ *
+ * @return void
+ */
+ public function testView() {
+ $this->Shell->startup();
+ $this->Shell->Schema->path = APP . 'Config' . DS . 'Schema';
+ $this->Shell->params['file'] = 'i18n.php';
+ $this->Shell->expects($this->once())->method('_stop');
+ $this->Shell->expects($this->once())->method('out');
+ $this->Shell->view();
+ }
+
+/**
+ * test that view() can find plugin schema files.
+ *
+ * @return void
+ */
+ public function testViewWithPlugins() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $this->Shell->args = array('TestPlugin.schema');
+ $this->Shell->startup();
+ $this->Shell->expects($this->exactly(2))->method('_stop');
+ $this->Shell->expects($this->atLeastOnce())->method('out');
+ $this->Shell->view();
+
+ $this->Shell->args = array();
+ $this->Shell->params = array('plugin' => 'TestPlugin');
+ $this->Shell->startup();
+ $this->Shell->view();
+
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * test dump() with sql file generation
+ *
+ * @return void
+ */
+ public function testDumpWithFileWriting() {
+ $this->Shell->params = array(
+ 'name' => 'i18n',
+ 'connection' => 'test',
+ 'write' => TMP . 'tests' . DS . 'i18n.sql'
+ );
+ $this->Shell->expects($this->once())->method('_stop');
+ $this->Shell->startup();
+ $this->Shell->dump();
+
+ $this->file = new File(TMP . 'tests' . DS . 'i18n.sql');
+ $contents = $this->file->read();
+ $this->assertRegExp('/DROP TABLE/', $contents);
+ $this->assertRegExp('/CREATE TABLE.*?i18n/', $contents);
+ $this->assertRegExp('/id/', $contents);
+ $this->assertRegExp('/model/', $contents);
+ $this->assertRegExp('/field/', $contents);
+ $this->assertRegExp('/locale/', $contents);
+ $this->assertRegExp('/foreign_key/', $contents);
+ $this->assertRegExp('/content/', $contents);
+ }
+
+/**
+ * test that dump() can find and work with plugin schema files.
+ *
+ * @return void
+ */
+ public function testDumpFileWritingWithPlugins() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $this->Shell->args = array('TestPlugin.TestPluginApp');
+ $this->Shell->params = array(
+ 'connection' => 'test',
+ 'write' => TMP . 'tests' . DS . 'dump_test.sql'
+ );
+ $this->Shell->startup();
+ $this->Shell->expects($this->once())->method('_stop');
+ $this->Shell->dump();
+
+ $this->file = new File(TMP . 'tests' . DS . 'dump_test.sql');
+ $contents = $this->file->read();
+
+ $this->assertRegExp('/CREATE TABLE.*?test_plugin_acos/', $contents);
+ $this->assertRegExp('/id/', $contents);
+ $this->assertRegExp('/model/', $contents);
+
+ $this->file->delete();
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * test generate with snapshot generation
+ *
+ * @return void
+ */
+ public function testGenerateSnapshot() {
+ $this->Shell->path = TMP;
+ $this->Shell->params['file'] = 'schema.php';
+ $this->Shell->params['force'] = false;
+ $this->Shell->args = array('snapshot');
+ $this->Shell->Schema = $this->getMock('CakeSchema');
+ $this->Shell->Schema->expects($this->at(0))->method('read')->will($this->returnValue(array('schema data')));
+ $this->Shell->Schema->expects($this->at(0))->method('write')->will($this->returnValue(true));
+
+ $this->Shell->Schema->expects($this->at(1))->method('read');
+ $this->Shell->Schema->expects($this->at(1))->method('write')->with(array('schema data', 'file' => 'schema_0.php'));
+
+ $this->Shell->generate();
+ }
+
+/**
+ * test generate without a snapshot.
+ *
+ * @return void
+ */
+ public function testGenerateNoOverwrite() {
+ touch(TMP . 'schema.php');
+ $this->Shell->params['file'] = 'schema.php';
+ $this->Shell->params['force'] = false;
+ $this->Shell->args = array();
+
+ $this->Shell->expects($this->once())->method('in')->will($this->returnValue('q'));
+ $this->Shell->Schema = $this->getMock('CakeSchema');
+ $this->Shell->Schema->path = TMP;
+ $this->Shell->Schema->expects($this->never())->method('read');
+
+ $result = $this->Shell->generate();
+ unlink(TMP . 'schema.php');
+ }
+
+/**
+ * test generate with overwriting of the schema files.
+ *
+ * @return void
+ */
+ public function testGenerateOverwrite() {
+ touch(TMP . 'schema.php');
+ $this->Shell->params['file'] = 'schema.php';
+ $this->Shell->params['force'] = false;
+ $this->Shell->args = array();
+
+ $this->Shell->expects($this->once())->method('in')->will($this->returnValue('o'));
+
+ $this->Shell->expects($this->at(2))->method('out')
+ ->with(new PHPUnit_Framework_Constraint_PCREMatch('/Schema file:\s[a-z\.]+\sgenerated/'));
+
+ $this->Shell->Schema = $this->getMock('CakeSchema');
+ $this->Shell->Schema->path = TMP;
+ $this->Shell->Schema->expects($this->once())->method('read')->will($this->returnValue(array('schema data')));
+ $this->Shell->Schema->expects($this->once())->method('write')->will($this->returnValue(true));
+
+ $this->Shell->Schema->expects($this->once())->method('read');
+ $this->Shell->Schema->expects($this->once())->method('write')
+ ->with(array('schema data', 'file' => 'schema.php'));
+
+ $this->Shell->generate();
+ unlink(TMP . 'schema.php');
+ }
+
+/**
+ * test that generate() can read plugin dirs and generate schema files for the models
+ * in a plugin.
+ *
+ * @return void
+ */
+ public function testGenerateWithPlugins() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+
+ $this->db->cacheSources = false;
+ $this->Shell->params = array(
+ 'plugin' => 'TestPlugin',
+ 'connection' => 'test',
+ 'force' => false
+ );
+ $this->Shell->startup();
+ $this->Shell->Schema->path = TMP . 'tests' . DS;
+
+ $this->Shell->generate();
+ $this->file = new File(TMP . 'tests' . DS . 'schema.php');
+ $contents = $this->file->read();
+
+ $this->assertRegExp('/class TestPluginSchema/', $contents);
+ $this->assertRegExp('/public \$posts/', $contents);
+ $this->assertRegExp('/public \$auth_users/', $contents);
+ $this->assertRegExp('/public \$authors/', $contents);
+ $this->assertRegExp('/public \$test_plugin_comments/', $contents);
+ $this->assertNotRegExp('/public \$users/', $contents);
+ $this->assertNotRegExp('/public \$articles/', $contents);
+ CakePlugin::unload();
+ }
+
+/**
+ * Test schema run create with no table args.
+ *
+ * @return void
+ */
+ public function testCreateNoArgs() {
+ $this->Shell->params = array(
+ 'connection' => 'test'
+ );
+ $this->Shell->args = array('i18n');
+ $this->Shell->startup();
+ $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y'));
+ $this->Shell->create();
+
+ $db = ConnectionManager::getDataSource('test');
+
+ $db->cacheSources = false;
+ $sources = $db->listSources();
+ $this->assertTrue(in_array($db->config['prefix'] . 'i18n', $sources));
+
+ $schema = new i18nSchema();
+ $db->execute($db->dropSchema($schema));
+ }
+
+/**
+ * Test schema run create with no table args.
+ *
+ * @return void
+ */
+ public function testCreateWithTableArgs() {
+ $db = ConnectionManager::getDataSource('test');
+ $sources = $db->listSources();
+ if (in_array('acos', $sources)) {
+ $this->markTestSkipped('acos table already exists, cannot try to create it again.');
+ }
+ $this->Shell->params = array(
+ 'connection' => 'test',
+ 'name' => 'DbAcl',
+ 'path' => APP . 'Config' . DS . 'Schema'
+ );
+ $this->Shell->args = array('DbAcl', 'acos');
+ $this->Shell->startup();
+ $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y'));
+ $this->Shell->create();
+
+ $db = ConnectionManager::getDataSource('test');
+ $db->cacheSources = false;
+ $sources = $db->listSources();
+ $this->assertTrue(in_array($db->config['prefix'] . 'acos', $sources), 'acos should be present.');
+ $this->assertFalse(in_array($db->config['prefix'] . 'aros', $sources), 'aros should not be found.');
+ $this->assertFalse(in_array('aros_acos', $sources), 'aros_acos should not be found.');
+
+ $schema = new DbAclSchema();
+ $db->execute($db->dropSchema($schema, 'acos'));
+ }
+
+/**
+ * test run update with a table arg.
+ *
+ * @return void
+ */
+ public function testUpdateWithTable() {
+ $this->Shell = $this->getMock(
+ 'SchemaShell',
+ array('in', 'out', 'hr', 'createFile', 'error', 'err', '_stop', '_run'),
+ array(&$this->Dispatcher)
+ );
+
+ $this->Shell->params = array(
+ 'connection' => 'test',
+ 'force' => true
+ );
+ $this->Shell->args = array('SchemaShellTest', 'articles');
+ $this->Shell->startup();
+ $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y'));
+ $this->Shell->expects($this->once())->method('_run')
+ ->with($this->arrayHasKey('articles'), 'update', $this->isInstanceOf('CakeSchema'));
+
+ $this->Shell->update();
+ }
+
+/**
+ * test that the plugin param creates the correct path in the schema object.
+ *
+ * @return void
+ */
+ public function testPluginParam() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $this->Shell->params = array(
+ 'plugin' => 'TestPlugin',
+ 'connection' => 'test'
+ );
+ $this->Shell->startup();
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'Config' . DS . 'Schema';
+ $this->assertEquals($expected, $this->Shell->Schema->path);
+ CakePlugin::unload();
+ }
+
+/**
+ * test that using Plugin.name with write.
+ *
+ * @return void
+ */
+ public function testPluginDotSyntaxWithCreate() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $this->Shell->params = array(
+ 'connection' => 'test'
+ );
+ $this->Shell->args = array('TestPlugin.TestPluginApp');
+ $this->Shell->startup();
+ $this->Shell->expects($this->any())->method('in')->will($this->returnValue('y'));
+ $this->Shell->create();
+
+ $db = ConnectionManager::getDataSource('test');
+ $sources = $db->listSources();
+ $this->assertTrue(in_array($db->config['prefix'] . 'test_plugin_acos', $sources));
+
+ $schema = new TestPluginAppSchema();
+ $db->execute($db->dropSchema($schema, 'test_plugin_acos'));
+ CakePlugin::unload();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php
new file mode 100644
index 0000000..b17c862
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ControllerTaskTest.php
@@ -0,0 +1,652 @@
+<?php
+/**
+ * ControllerTask Test Case
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('CakeSchema', 'Model');
+App::uses('ClassRegistry', 'Utility');
+App::uses('Helper', 'View/Helper');
+App::uses('ProjectTask', 'Console/Command/Task');
+App::uses('ControllerTask', 'Console/Command/Task');
+App::uses('ModelTask', 'Console/Command/Task');
+App::uses('TemplateTask', 'Console/Command/Task');
+App::uses('TestTask', 'Console/Command/Task');
+App::uses('Model', 'Model');
+
+App::uses('BakeArticle', 'Model');
+App::uses('BakeComment', 'Model');
+App::uses('BakeTags', 'Model');
+$imported = class_exists('BakeArticle') || class_exists('BakeComment') || class_exists('BakeTag');
+
+if (!$imported) {
+ define('ARTICLE_MODEL_CREATED', true);
+
+ class BakeArticle extends Model {
+
+ public $name = 'BakeArticle';
+
+ public $hasMany = array('BakeComment');
+
+ public $hasAndBelongsToMany = array('BakeTag');
+
+ }
+}
+
+/**
+ * ControllerTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ControllerTaskTest extends CakeTestCase {
+
+/**
+ * fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array('core.bake_article', 'core.bake_articles_bake_tag', 'core.bake_comment', 'core.bake_tag');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ControllerTask',
+ array('in', 'out', 'err', 'hr', 'createFile', '_stop', '_checkUnitTest'),
+ array($out, $out, $in)
+ );
+ $this->Task->name = 'Controller';
+ $this->Task->Template = new TemplateTask($out, $out, $in);
+ $this->Task->Template->params['theme'] = 'default';
+
+ $this->Task->Model = $this->getMock('ModelTask',
+ array('in', 'out', 'err', 'createFile', '_stop', '_checkUnitTest'),
+ array($out, $out, $in)
+ );
+ $this->Task->Project = $this->getMock('ProjectTask',
+ array('in', 'out', 'err', 'createFile', '_stop', '_checkUnitTest', 'getPrefix'),
+ array($out, $out, $in)
+ );
+ $this->Task->Test = $this->getMock('TestTask', array(), array($out, $out, $in));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->Task);
+ ClassRegistry::flush();
+ App::build();
+ parent::tearDown();
+ }
+
+/**
+ * test ListAll
+ *
+ * @return void
+ */
+ public function testListAll() {
+ $count = count($this->Task->listAll('test'));
+ if ($count != count($this->fixtures)) {
+ $this->markTestSkipped('Additional tables detected.');
+ }
+
+ $this->Task->connection = 'test';
+ $this->Task->interactive = true;
+ $this->Task->expects($this->at(1))->method('out')->with('1. BakeArticles');
+ $this->Task->expects($this->at(2))->method('out')->with('2. BakeArticlesBakeTags');
+ $this->Task->expects($this->at(3))->method('out')->with('3. BakeComments');
+ $this->Task->expects($this->at(4))->method('out')->with('4. BakeTags');
+
+ $expected = array('BakeArticles', 'BakeArticlesBakeTags', 'BakeComments', 'BakeTags');
+ $result = $this->Task->listAll('test');
+ $this->assertEquals($expected, $result);
+
+ $this->Task->interactive = false;
+ $result = $this->Task->listAll();
+
+ $expected = array('bake_articles', 'bake_articles_bake_tags', 'bake_comments', 'bake_tags');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that getName interacts with the user and returns the controller name.
+ *
+ * @return void
+ */
+ public function testGetNameValidIndex() {
+ $count = count($this->Task->listAll('test'));
+ if ($count != count($this->fixtures)) {
+ $this->markTestSkipped('Additional tables detected.');
+ }
+ $this->Task->interactive = true;
+ $this->Task->expects($this->any())->method('in')->will(
+ $this->onConsecutiveCalls(3, 1)
+ );
+
+ $result = $this->Task->getName('test');
+ $expected = 'BakeComments';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->getName('test');
+ $expected = 'BakeArticles';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test getting invalid indexes.
+ *
+ * @return void
+ */
+ public function testGetNameInvalidIndex() {
+ $this->Task->interactive = true;
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls(50, 'q'));
+
+ $this->Task->expects($this->once())->method('err');
+ $this->Task->expects($this->once())->method('_stop');
+
+ $this->Task->getName('test');
+ }
+
+/**
+ * test helper interactions
+ *
+ * @return void
+ */
+ public function testDoHelpersNo() {
+ $this->Task->expects($this->any())->method('in')->will($this->returnValue('n'));
+ $result = $this->Task->doHelpers();
+ $this->assertEquals(array(), $result);
+ }
+
+/**
+ * test getting helper values
+ *
+ * @return void
+ */
+ public function testDoHelpersTrailingSpace() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' Javascript, Ajax, CustomOne '));
+ $result = $this->Task->doHelpers();
+ $expected = array('Javascript', 'Ajax', 'CustomOne');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test doHelpers with extra commas
+ *
+ * @return void
+ */
+ public function testDoHelpersTrailingCommas() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' Javascript, Ajax, CustomOne, , '));
+ $result = $this->Task->doHelpers();
+ $expected = array('Javascript', 'Ajax', 'CustomOne');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test component interactions
+ *
+ * @return void
+ */
+ public function testDoComponentsNo() {
+ $this->Task->expects($this->any())->method('in')->will($this->returnValue('n'));
+ $result = $this->Task->doComponents();
+ $this->assertEquals(array(), $result);
+ }
+
+/**
+ * test components with spaces
+ *
+ * @return void
+ */
+ public function testDoComponentsTrailingSpaces() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' RequestHandler, Security '));
+
+ $result = $this->Task->doComponents();
+ $expected = array('RequestHandler', 'Security');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test components with commas
+ *
+ * @return void
+ */
+ public function testDoComponentsTrailingCommas() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue(' RequestHandler, Security, , '));
+
+ $result = $this->Task->doComponents();
+ $expected = array('RequestHandler', 'Security');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Confirming controller user interaction
+ *
+ * @return void
+ */
+ public function testConfirmController() {
+ $controller = 'Posts';
+ $scaffold = false;
+ $helpers = array('Ajax', 'Time');
+ $components = array('Acl', 'Auth');
+
+ $this->Task->expects($this->at(4))->method('out')->with("Controller Name:\n\t$controller");
+ $this->Task->expects($this->at(5))->method('out')->with("Helpers:\n\tAjax, Time");
+ $this->Task->expects($this->at(6))->method('out')->with("Components:\n\tAcl, Auth");
+ $this->Task->confirmController($controller, $scaffold, $helpers, $components);
+ }
+
+/**
+ * test the bake method
+ *
+ * @return void
+ */
+ public function testBake() {
+ $helpers = array('Ajax', 'Time');
+ $components = array('Acl', 'Auth');
+ $this->Task->expects($this->any())->method('createFile')->will($this->returnValue(true));
+
+ $result = $this->Task->bake('Articles', '--actions--', $helpers, $components);
+ $this->assertContains(' * @property Article $Article', $result);
+ $this->assertContains(' * @property AclComponent $Acl', $result);
+ $this->assertContains(' * @property AuthComponent $Auth', $result);
+ $this->assertContains('class ArticlesController extends AppController', $result);
+ $this->assertContains("public \$components = array('Acl', 'Auth')", $result);
+ $this->assertContains("public \$helpers = array('Ajax', 'Time')", $result);
+ $this->assertContains("--actions--", $result);
+
+ $result = $this->Task->bake('Articles', 'scaffold', $helpers, $components);
+ $this->assertContains("class ArticlesController extends AppController", $result);
+ $this->assertContains("public \$scaffold", $result);
+ $this->assertNotContains('@property', $result);
+ $this->assertNotContains('helpers', $result);
+ $this->assertNotContains('components', $result);
+
+ $result = $this->Task->bake('Articles', '--actions--', array(), array());
+ $this->assertContains('class ArticlesController extends AppController', $result);
+ $this->assertSame(substr_count($result, '@property'), 1);
+ $this->assertNotContains('components', $result);
+ $this->assertNotContains('helpers', $result);
+ $this->assertContains('--actions--', $result);
+ }
+
+/**
+ * test bake() with a -plugin param
+ *
+ * @return void
+ */
+ public function testBakeWithPlugin() {
+ $this->Task->plugin = 'ControllerTest';
+
+ //fake plugin path
+ CakePlugin::load('ControllerTest', array('path' => APP . 'Plugin' . DS . 'ControllerTest' . DS));
+ $path = APP . 'Plugin' . DS . 'ControllerTest' . DS . 'Controller' . DS . 'ArticlesController.php';
+
+ $this->Task->expects($this->at(1))->method('createFile')->with(
+ $path,
+ new PHPUnit_Framework_Constraint_IsAnything()
+ );
+ $this->Task->expects($this->at(3))->method('createFile')->with(
+ $path,
+ $this->stringContains('ArticlesController extends ControllerTestAppController')
+ )->will($this->returnValue(true));
+
+ $this->Task->bake('Articles', '--actions--', array(), array(), array());
+
+ $this->Task->plugin = 'ControllerTest';
+ $path = APP . 'Plugin' . DS . 'ControllerTest' . DS . 'Controller' . DS . 'ArticlesController.php';
+ $result = $this->Task->bake('Articles', '--actions--', array(), array(), array());
+
+ $this->assertContains("App::uses('ControllerTestAppController', 'ControllerTest.Controller');", $result);
+ $this->assertEquals('ControllerTest', $this->Task->Template->templateVars['plugin']);
+ $this->assertEquals('ControllerTest.', $this->Task->Template->templateVars['pluginPath']);
+
+ CakePlugin::unload();
+ }
+
+/**
+ * test that bakeActions is creating the correct controller Code. (Using sessions)
+ *
+ * @return void
+ */
+ public function testBakeActionsUsingSessions() {
+ $this->skipIf(!defined('ARTICLE_MODEL_CREATED'), 'Testing bakeActions requires Article, Comment & Tag Model to be undefined.');
+
+ $result = $this->Task->bakeActions('BakeArticles', null, true);
+
+ $this->assertContains('function index() {', $result);
+ $this->assertContains('$this->BakeArticle->recursive = 0;', $result);
+ $this->assertContains("\$this->set('bakeArticles', \$this->paginate());", $result);
+
+ $this->assertContains('function view($id = null)', $result);
+ $this->assertContains("throw new NotFoundException(__('Invalid bake article'));", $result);
+ $this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result);
+
+ $this->assertContains('function add()', $result);
+ $this->assertContains("if (\$this->request->is('post'))", $result);
+ $this->assertContains('if ($this->BakeArticle->save($this->request->data))', $result);
+ $this->assertContains("\$this->Session->setFlash(__('The bake article has been saved'));", $result);
+
+ $this->assertContains('function edit($id = null)', $result);
+ $this->assertContains("\$this->Session->setFlash(__('The bake article could not be saved. Please, try again.'));", $result);
+
+ $this->assertContains('function delete($id = null)', $result);
+ $this->assertContains('if ($this->BakeArticle->delete())', $result);
+ $this->assertContains("\$this->Session->setFlash(__('Bake article deleted'));", $result);
+
+ $result = $this->Task->bakeActions('BakeArticles', 'admin_', true);
+
+ $this->assertContains('function admin_index() {', $result);
+ $this->assertContains('function admin_add()', $result);
+ $this->assertContains('function admin_view($id = null)', $result);
+ $this->assertContains('function admin_edit($id = null)', $result);
+ $this->assertContains('function admin_delete($id = null)', $result);
+ }
+
+/**
+ * Test baking with Controller::flash() or no sessions.
+ *
+ * @return void
+ */
+ public function testBakeActionsWithNoSessions() {
+ $this->skipIf(!defined('ARTICLE_MODEL_CREATED'), 'Testing bakeActions requires Article, Tag, Comment Models to be undefined.');
+
+ $result = $this->Task->bakeActions('BakeArticles', null, false);
+
+ $this->assertContains('function index() {', $result);
+ $this->assertContains('$this->BakeArticle->recursive = 0;', $result);
+ $this->assertContains("\$this->set('bakeArticles', \$this->paginate());", $result);
+
+ $this->assertContains('function view($id = null)', $result);
+ $this->assertContains("throw new NotFoundException(__('Invalid bake article'));", $result);
+ $this->assertContains("\$this->set('bakeArticle', \$this->BakeArticle->read(null, \$id)", $result);
+
+ $this->assertContains('function add()', $result);
+ $this->assertContains("if (\$this->request->is('post'))", $result);
+ $this->assertContains('if ($this->BakeArticle->save($this->request->data))', $result);
+
+ $this->assertContains("\$this->flash(__('The bake article has been saved.'), array('action' => 'index'))", $result);
+
+ $this->assertContains('function edit($id = null)', $result);
+ $this->assertContains("\$this->BakeArticle->BakeTag->find('list')", $result);
+ $this->assertContains("\$this->set(compact('bakeTags'))", $result);
+
+ $this->assertContains('function delete($id = null)', $result);
+ $this->assertContains('if ($this->BakeArticle->delete())', $result);
+ $this->assertContains("\$this->flash(__('Bake article deleted'), array('action' => 'index'))", $result);
+ }
+
+/**
+ * test baking a test
+ *
+ * @return void
+ */
+ public function testBakeTest() {
+ $this->Task->plugin = 'ControllerTest';
+ $this->Task->connection = 'test';
+ $this->Task->interactive = false;
+
+ $this->Task->Test->expects($this->once())->method('bake')->with('Controller', 'BakeArticles');
+ $this->Task->bakeTest('BakeArticles');
+
+ $this->assertEquals($this->Task->plugin, $this->Task->Test->plugin);
+ $this->assertEquals($this->Task->connection, $this->Task->Test->connection);
+ $this->assertEquals($this->Task->interactive, $this->Task->Test->interactive);
+ }
+
+/**
+ * test Interactive mode.
+ *
+ * @return void
+ */
+ public function testInteractive() {
+ $count = count($this->Task->listAll('test'));
+ if ($count != count($this->fixtures)) {
+ $this->markTestSkipped('Additional tables detected.');
+ }
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls(
+ '1',
+ 'y', // build interactive
+ 'n', // build no scaffolds
+ 'y', // build normal methods
+ 'n', // build admin methods
+ 'n', // helpers?
+ 'n', // components?
+ 'y', // sessions ?
+ 'y' // looks good?
+ ));
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename,
+ $this->stringContains('class BakeArticlesController')
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test Interactive mode.
+ *
+ * @return void
+ */
+ public function testInteractiveAdminMethodsNotInteractive() {
+ $count = count($this->Task->listAll('test'));
+ if ($count != count($this->fixtures)) {
+ $this->markTestSkipped('Additional tables detected.');
+ }
+
+ $this->Task->connection = 'test';
+ $this->Task->interactive = true;
+ $this->Task->path = '/my/path/';
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls(
+ '1',
+ 'y', // build interactive
+ 'n', // build no scaffolds
+ 'y', // build normal methods
+ 'y', // build admin methods
+ 'n', // helpers?
+ 'n', // components?
+ 'y', // sessions ?
+ 'y' // looks good?
+ ));
+
+ $this->Task->Project->expects($this->any())
+ ->method('getPrefix')
+ ->will($this->returnValue('admin_'));
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename,
+ $this->stringContains('class BakeArticlesController')
+ )->will($this->returnValue(true));
+
+ $result = $this->Task->execute();
+ $this->assertRegExp('/admin_index/', $result);
+ }
+
+/**
+ * test that execute runs all when the first arg == all
+ *
+ * @return void
+ */
+ public function testExecuteIntoAll() {
+ $count = count($this->Task->listAll('test'));
+ if ($count != count($this->fixtures)) {
+ $this->markTestSkipped('Additional tables detected.');
+ }
+ if (!defined('ARTICLE_MODEL_CREATED')) {
+ $this->markTestSkipped('Execute into all could not be run as an Article, Tag or Comment model was already loaded.');
+ }
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('all');
+
+ $this->Task->expects($this->any())->method('_checkUnitTest')->will($this->returnValue(true));
+ $this->Task->Test->expects($this->once())->method('bake');
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename,
+ $this->stringContains('class BakeArticlesController')
+ )->will($this->returnValue(true));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test that `cake bake controller foos` works.
+ *
+ * @return void
+ */
+ public function testExecuteWithController() {
+ if (!defined('ARTICLE_MODEL_CREATED')) {
+ $this->markTestSkipped('Execute with scaffold param requires no Article, Tag or Comment model to be defined');
+ }
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeArticles');
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename,
+ $this->stringContains('$scaffold')
+ );
+
+ $this->Task->execute();
+ }
+
+/**
+ * data provider for testExecuteWithControllerNameVariations
+ *
+ * @return void
+ */
+ public static function nameVariations() {
+ return array(
+ array('BakeArticles'), array('BakeArticle'), array('bake_article'), array('bake_articles')
+ );
+ }
+
+/**
+ * test that both plural and singular forms work for controller baking.
+ *
+ * @dataProvider nameVariations
+ * @return void
+ */
+ public function testExecuteWithControllerNameVariations($name) {
+ if (!defined('ARTICLE_MODEL_CREATED')) {
+ $this->markTestSkipped('Execute with scaffold param requires no Article, Tag or Comment model to be defined.');
+ }
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array($name);
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename, $this->stringContains('$scaffold')
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test that `cake bake controller foo scaffold` works.
+ *
+ * @return void
+ */
+ public function testExecuteWithPublicParam() {
+ if (!defined('ARTICLE_MODEL_CREATED')) {
+ $this->markTestSkipped('Execute with public param requires no Article, Tag or Comment model to be defined.');
+ }
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeArticles');
+ $this->Task->params = array('public' => true);
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $expected = new PHPUnit_Framework_Constraint_Not($this->stringContains('$scaffold'));
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename, $expected
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test that `cake bake controller foos both` works.
+ *
+ * @return void
+ */
+ public function testExecuteWithControllerAndBoth() {
+ if (!defined('ARTICLE_MODEL_CREATED')) {
+ $this->markTestSkipped('Execute with controller and both requires no Article, Tag or Comment model to be defined.');
+ }
+ $this->Task->Project->expects($this->any())->method('getPrefix')->will($this->returnValue('admin_'));
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeArticles');
+ $this->Task->params = array('public' => true, 'admin' => true);
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename, $this->stringContains('admin_index')
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test that `cake bake controller foos admin` works.
+ *
+ * @return void
+ */
+ public function testExecuteWithControllerAndAdmin() {
+ if (!defined('ARTICLE_MODEL_CREATED')) {
+ $this->markTestSkipped('Execute with controller and admin requires no Article, Tag or Comment model to be defined.');
+ }
+ $this->Task->Project->expects($this->any())->method('getPrefix')->will($this->returnValue('admin_'));
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeArticles');
+ $this->Task->params = array('admin' => true);
+
+ $filename = '/my/path/BakeArticlesController.php';
+ $this->Task->expects($this->once())->method('createFile')->with(
+ $filename, $this->stringContains('admin_index')
+ );
+ $this->Task->execute();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php
new file mode 100644
index 0000000..b831c95
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/DbConfigTaskTest.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * DBConfigTask Test Case
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+App::uses('DbConfigTask', 'Console/Command/Task');
+
+/**
+ * DbConfigTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class DbConfigTaskTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('DbConfigTask',
+ array('in', 'out', 'err', 'hr', 'createFile', '_stop', '_checkUnitTest', '_verify'),
+ array($out, $out, $in)
+ );
+
+ $this->Task->path = APP . 'Config' . DS;
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Task);
+ }
+
+/**
+ * Test the getConfig method.
+ *
+ * @return void
+ */
+ public function testGetConfig() {
+ $this->Task->expects($this->any())
+ ->method('in')
+ ->will($this->returnValue('test'));
+
+ $result = $this->Task->getConfig();
+ $this->assertEquals('test', $result);
+ }
+
+/**
+ * test that initialize sets the path up.
+ *
+ * @return void
+ */
+ public function testInitialize() {
+ $this->Task->initialize();
+ $this->assertFalse(empty($this->Task->path));
+ $this->assertEquals(APP . 'Config' . DS, $this->Task->path);
+ }
+
+/**
+ * test execute and by extension _interactive
+ *
+ * @return void
+ */
+ public function testExecuteIntoInteractive() {
+ $this->Task->initialize();
+
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock(
+ 'DbConfigTask',
+ array('in', '_stop', 'createFile', 'bake'), array($out, $out, $in)
+ );
+
+ $this->Task->expects($this->once())->method('_stop');
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('default')); //name
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue('mysql')); //db type
+ $this->Task->expects($this->at(2))->method('in')->will($this->returnValue('n')); //persistant
+ $this->Task->expects($this->at(3))->method('in')->will($this->returnValue('localhost')); //server
+ $this->Task->expects($this->at(4))->method('in')->will($this->returnValue('n')); //port
+ $this->Task->expects($this->at(5))->method('in')->will($this->returnValue('root')); //user
+ $this->Task->expects($this->at(6))->method('in')->will($this->returnValue('password')); //password
+ $this->Task->expects($this->at(10))->method('in')->will($this->returnValue('cake_test')); //db
+ $this->Task->expects($this->at(11))->method('in')->will($this->returnValue('n')); //prefix
+ $this->Task->expects($this->at(12))->method('in')->will($this->returnValue('n')); //encoding
+ $this->Task->expects($this->at(13))->method('in')->will($this->returnValue('y')); //looks good
+ $this->Task->expects($this->at(14))->method('in')->will($this->returnValue('n')); //another
+ $this->Task->expects($this->at(15))->method('bake')
+ ->with(array(
+ array(
+ 'name' => 'default',
+ 'datasource' => 'mysql',
+ 'persistent' => 'false',
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => 'password',
+ 'database' => 'cake_test',
+ 'prefix' => null,
+ 'encoding' => null,
+ 'port' => '',
+ 'schema' => null
+ )
+ ));
+
+ $result = $this->Task->execute();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php
new file mode 100644
index 0000000..66bc9c2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ExtractTaskTest.php
@@ -0,0 +1,462 @@
+<?php
+/**
+ * ExtractTaskTest file
+ *
+ * Test Case for i18n extraction shell task
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Folder', 'Utility');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('ExtractTask', 'Console/Command/Task');
+
+/**
+ * ExtractTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ExtractTaskTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock(
+ 'ExtractTask',
+ array('in', 'out', 'err', '_stop'),
+ array($out, $out, $in)
+ );
+ $this->path = TMP . 'tests' . DS . 'extract_task_test';
+ $Folder = new Folder($this->path . DS . 'locale', true);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Task);
+
+ $Folder = new Folder($this->path);
+ $Folder->delete();
+ CakePlugin::unload();
+ }
+
+/**
+ * testExecute method
+ *
+ * @return void
+ */
+ public function testExecute() {
+ $this->Task->interactive = false;
+
+ $this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages';
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['extract-core'] = 'no';
+ $this->Task->expects($this->never())->method('err');
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->returnValue('y'));
+ $this->Task->expects($this->never())->method('_stop');
+
+ $this->Task->execute();
+ $this->assertTrue(file_exists($this->path . DS . 'default.pot'));
+ $result = file_get_contents($this->path . DS . 'default.pot');
+
+ $this->assertFalse(file_exists($this->path . DS . 'cake.pot'));
+
+ $pattern = '/"Content-Type\: text\/plain; charset\=utf-8/';
+ $this->assertRegExp($pattern, $result);
+ $pattern = '/"Content-Transfer-Encoding\: 8bit/';
+ $this->assertRegExp($pattern, $result);
+ $pattern = '/"Plural-Forms\: nplurals\=INTEGER; plural\=EXPRESSION;/';
+ $this->assertRegExp($pattern, $result);
+
+ // home.ctp
+ $pattern = '/msgid "Your tmp directory is writable."\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Your tmp directory is NOT writable."\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "The %s is being used for caching. To change the config edit ';
+ $pattern .= 'APP\/config\/core.php "\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Your cache is NOT working. Please check ';
+ $pattern .= 'the settings in APP\/config\/core.php"\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Your database configuration file is present."\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Your database configuration file is NOT present."\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Rename config\/database.php.default to ';
+ $pattern .= 'config\/database.php"\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Cake is able to connect to the database."\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Cake is NOT able to connect to the database."\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "Editing this Page"\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "To change the content of this page, create: APP\/views\/pages\/home\.ctp/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/To change its layout, create: APP\/views\/layouts\/default\.ctp\./s';
+ $this->assertRegExp($pattern, $result);
+
+ // extract.ctp
+ $pattern = '/\#: (\\\\|\/)extract\.ctp:15;6\n';
+ $pattern .= 'msgid "You have %d new message."\nmsgid_plural "You have %d new messages."/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/msgid "You have %d new message."\nmsgstr ""/';
+ $this->assertNotRegExp($pattern, $result, 'No duplicate msgid');
+
+ $pattern = '/\#: (\\\\|\/)extract\.ctp:7\n';
+ $pattern .= 'msgid "You deleted %d message."\nmsgid_plural "You deleted %d messages."/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/\#: (\\\\|\/)extract\.ctp:14\n';
+ $pattern .= '\#: (\\\\|\/)home\.ctp:99\n';
+ $pattern .= 'msgid "Editing this Page"\nmsgstr ""/';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '/\#: (\\\\|\/)extract\.ctp:18\nmsgid "';
+ $pattern .= 'Hot features!';
+ $pattern .= '\\\n - No Configuration: Set-up the database and let the magic begin';
+ $pattern .= '\\\n - Extremely Simple: Just look at the name...It\'s Cake';
+ $pattern .= '\\\n - Active, Friendly Community: Join us #cakephp on IRC. We\'d love to help you get started';
+ $pattern .= '"\nmsgstr ""/';
+ $this->assertRegExp($pattern, $result);
+
+ // extract.ctp - reading the domain.pot
+ $result = file_get_contents($this->path . DS . 'domain.pot');
+
+ $pattern = '/msgid "You have %d new message."\nmsgid_plural "You have %d new messages."/';
+ $this->assertNotRegExp($pattern, $result);
+ $pattern = '/msgid "You deleted %d message."\nmsgid_plural "You deleted %d messages."/';
+ $this->assertNotRegExp($pattern, $result);
+
+ $pattern = '/msgid "You have %d new message \(domain\)."\nmsgid_plural "You have %d new messages \(domain\)."/';
+ $this->assertRegExp($pattern, $result);
+ $pattern = '/msgid "You deleted %d message \(domain\)."\nmsgid_plural "You deleted %d messages \(domain\)."/';
+ $this->assertRegExp($pattern, $result);
+ }
+
+/**
+ * test exclusions
+ *
+ * @return void
+ */
+ public function testExtractWithExclude() {
+ $this->Task->interactive = false;
+
+ $this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS . 'View';
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['exclude'] = 'Pages,Layouts';
+ $this->Task->params['extract-core'] = 'no';
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->returnValue('y'));
+
+ $this->Task->execute();
+ $this->assertTrue(file_exists($this->path . DS . 'default.pot'));
+ $result = file_get_contents($this->path . DS . 'default.pot');
+
+ $pattern = '/\#: .*extract\.ctp:6\n/';
+ $this->assertNotRegExp($pattern, $result);
+
+ $pattern = '/\#: .*default\.ctp:26\n/';
+ $this->assertNotRegExp($pattern, $result);
+ }
+
+/**
+ * test extract can read more than one path.
+ *
+ * @return void
+ */
+ public function testExtractMultiplePaths() {
+ $this->Task->interactive = false;
+
+ $this->Task->params['paths'] =
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages,' .
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Posts';
+
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['extract-core'] = 'no';
+ $this->Task->expects($this->never())->method('err');
+ $this->Task->expects($this->never())->method('_stop');
+ $this->Task->execute();
+
+ $result = file_get_contents($this->path . DS . 'default.pot');
+
+ $pattern = '/msgid "Add User"/';
+ $this->assertRegExp($pattern, $result);
+ }
+
+/**
+ * Tests that it is possible to exclude plugin paths by enabling the param option for the ExtractTask
+ *
+ * @return void
+ */
+ public function testExtractExcludePlugins() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ $this->out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $this->in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ExtractTask',
+ array('_isExtractingApp', '_extractValidationMessages', 'in', 'out', 'err', 'clear', '_stop'),
+ array($this->out, $this->out, $this->in)
+ );
+ $this->Task->expects($this->exactly(2))->method('_isExtractingApp')->will($this->returnValue(true));
+
+ $this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS;
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['exclude-plugins'] = true;
+
+ $this->Task->execute();
+ $result = file_get_contents($this->path . DS . 'default.pot');
+ $this->assertNotRegExp('#TestPlugin#', $result);
+ }
+
+/**
+ * Test that is possible to extract messages form a single plugin
+ *
+ * @return void
+ */
+ public function testExtractPlugin() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+
+ $this->out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $this->in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ExtractTask',
+ array('_isExtractingApp', '_extractValidationMessages', 'in', 'out', 'err', 'clear', '_stop'),
+ array($this->out, $this->out, $this->in)
+ );
+
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['plugin'] = 'TestPlugin';
+
+ $this->Task->execute();
+ $result = file_get_contents($this->path . DS . 'default.pot');
+ $this->assertNotRegExp('#Pages#', $result);
+ $this->assertContains('translate.ctp:1', $result);
+ $this->assertContains('This is a translatable string', $result);
+ }
+
+/**
+ * Tests that the task will inspect application models and extract the validation messages from them
+ *
+ * @return void
+ */
+ public function testExtractModelValidation() {
+ App::build(array(
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ $this->out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $this->in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ExtractTask',
+ array('_isExtractingApp', 'in', 'out', 'err', 'clear', '_stop'),
+ array($this->out, $this->out, $this->in)
+ );
+ $this->Task->expects($this->exactly(2))->method('_isExtractingApp')->will($this->returnValue(true));
+
+ $this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS;
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['extract-core'] = 'no';
+ $this->Task->params['exclude-plugins'] = true;
+ $this->Task->params['ignore-model-validation'] = false;
+
+ $this->Task->execute();
+ $result = file_get_contents($this->path . DS . 'default.pot');
+
+ $pattern = preg_quote('#Model' . DS . 'PersisterOne.php:validation for field title#', '\\');
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = preg_quote('#Model' . DS . 'PersisterOne.php:validation for field body#', '\\');
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post title is required"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "You may enter up to %s chars \(minimum is %s chars\)"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post body is required"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post body is super required"#';
+ $this->assertRegExp($pattern, $result);
+ }
+
+/**
+ * Tests that the task will inspect application models and extract the validation messages from them
+ * while using a custom validation domain for the messages set on the model itself
+ *
+ * @return void
+ */
+ public function testExtractModelValidationWithDomainInModel() {
+ App::build(array(
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'Model' . DS)
+ ));
+ $this->out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $this->in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ExtractTask',
+ array('_isExtractingApp', 'in', 'out', 'err', 'clear', '_stop'),
+ array($this->out, $this->out, $this->in)
+ );
+ $this->Task->expects($this->exactly(2))->method('_isExtractingApp')->will($this->returnValue(true));
+
+ $this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS;
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['extract-core'] = 'no';
+ $this->Task->params['exclude-plugins'] = true;
+ $this->Task->params['ignore-model-validation'] = false;
+
+ $this->Task->execute();
+ $result = file_get_contents($this->path . DS . 'test_plugin.pot');
+
+ $pattern = preg_quote('#Plugin' . DS . 'TestPlugin' . DS . 'Model' . DS . 'TestPluginPost.php:validation for field title#', '\\');
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = preg_quote('#Plugin' . DS . 'TestPlugin' . DS . 'Model' . DS . 'TestPluginPost.php:validation for field body#', '\\');
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post title is required"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post body is required"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post body is super required"#';
+ $this->assertRegExp($pattern, $result);
+ }
+
+/**
+ * Test that the extract shell can obtain validation messages from models inside a specific plugin
+ *
+ * @return void
+ */
+ public function testExtractModelValidationInPlugin() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ $this->out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $this->in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ExtractTask',
+ array('_isExtractingApp', 'in', 'out', 'err', 'clear', '_stop'),
+ array($this->out, $this->out, $this->in)
+ );
+
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['ignore-model-validation'] = false;
+ $this->Task->params['plugin'] = 'TestPlugin';
+
+ $this->Task->execute();
+ $result = file_get_contents($this->path . DS . 'test_plugin.pot');
+
+ $pattern = preg_quote('#Model' . DS . 'TestPluginPost.php:validation for field title#', '\\');
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = preg_quote('#Model' . DS . 'TestPluginPost.php:validation for field body#', '\\');
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post title is required"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post body is required"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#msgid "Post body is super required"#';
+ $this->assertRegExp($pattern, $result);
+
+ $pattern = '#Plugin/TestPlugin/Model/TestPluginPost.php:validation for field title#';
+ $this->assertNotRegExp($pattern, $result);
+ }
+
+/**
+ * Test that the extract shell overwrites existing files with the overwrite parameter
+ *
+ * @return void
+ */
+ public function testExtractOverwrite() {
+ $this->Task->interactive = false;
+
+ $this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS;
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['extract-core'] = 'no';
+ $this->Task->params['overwrite'] = true;
+
+ file_put_contents($this->path . DS . 'default.pot', 'will be overwritten');
+ $this->assertTrue(file_exists($this->path . DS . 'default.pot'));
+ $original = file_get_contents($this->path . DS . 'default.pot');
+
+ $this->Task->execute();
+ $result = file_get_contents($this->path . DS . 'default.pot');
+ $this->assertNotEquals($original, $result);
+ }
+
+/**
+ * Test that the extract shell scans the core libs
+ *
+ * @return void
+ */
+ public function testExtractCore() {
+ $this->Task->interactive = false;
+
+ $this->Task->params['paths'] = CAKE . 'Test' . DS . 'test_app' . DS;
+ $this->Task->params['output'] = $this->path . DS;
+ $this->Task->params['extract-core'] = 'yes';
+
+ $this->Task->execute();
+ $this->assertTrue(file_exists($this->path . DS . 'cake.pot'));
+ $result = file_get_contents($this->path . DS . 'cake.pot');
+
+ $pattern = '/msgid "Yesterday, %s"\nmsgstr ""\n/';
+ $this->assertRegExp($pattern, $result);
+
+ $this->assertTrue(file_exists($this->path . DS . 'cake_dev.pot'));
+ $result = file_get_contents($this->path . DS . 'cake_dev.pot');
+
+ $pattern = '/#: Console\/Templates\//';
+ $this->assertNotRegExp($pattern, $result);
+
+ $pattern = '/#: Test\//';
+ $this->assertNotRegExp($pattern, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php
new file mode 100644
index 0000000..9f2cbd0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/FixtureTaskTest.php
@@ -0,0 +1,388 @@
+<?php
+/**
+ * FixtureTask Test case
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('ModelTask', 'Console/Command/Task');
+App::uses('FixtureTask', 'Console/Command/Task');
+App::uses('TemplateTask', 'Console/Command/Task');
+App::uses('DbConfigTask', 'Console/Command/Task');
+
+/**
+ * FixtureTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class FixtureTaskTest extends CakeTestCase {
+
+/**
+ * fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array('core.article', 'core.comment', 'core.datatype', 'core.binary_test', 'core.user');
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ */
+ public $backupGlobals = false;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('FixtureTask',
+ array('in', 'err', 'createFile', '_stop', 'clear'),
+ array($out, $out, $in)
+ );
+ $this->Task->Model = $this->getMock('ModelTask',
+ array('in', 'out', 'err', 'createFile', 'getName', 'getTable', 'listAll'),
+ array($out, $out, $in)
+ );
+ $this->Task->Template = new TemplateTask($out, $out, $in);
+ $this->Task->DbConfig = $this->getMock('DbConfigTask', array(), array($out, $out, $in));
+ $this->Task->Template->initialize();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Task);
+ }
+
+/**
+ * test that initialize sets the path
+ *
+ * @return void
+ */
+ public function testConstruct() {
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $Task = new FixtureTask($out, $out, $in);
+ $this->assertEquals(APP . 'Test' . DS . 'Fixture' . DS, $Task->path);
+ }
+
+/**
+ * test import option array generation
+ *
+ * @return void
+ */
+ public function testImportOptionsSchemaRecords() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue('y'));
+
+ $result = $this->Task->importOptions('Article');
+ $expected = array('schema' => 'Article', 'records' => true);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test importOptions choosing nothing.
+ *
+ * @return void
+ */
+ public function testImportOptionsNothing() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue('n'));
+ $this->Task->expects($this->at(2))->method('in')->will($this->returnValue('n'));
+
+ $result = $this->Task->importOptions('Article');
+ $expected = array();
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test importOptions choosing from Table.
+ *
+ * @return void
+ */
+ public function testImportOptionsTable() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue('n'));
+ $this->Task->expects($this->at(2))->method('in')->will($this->returnValue('y'));
+ $result = $this->Task->importOptions('Article');
+ $expected = array('fromTable' => true);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test generating a fixture with database conditions.
+ *
+ * @return void
+ */
+ public function testImportRecordsFromDatabaseWithConditionsPoo() {
+ $this->Task->interactive = true;
+ $this->Task->expects($this->at(0))->method('in')
+ ->will($this->returnValue('WHERE 1=1'));
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+
+ $result = $this->Task->bake('Article', false, array(
+ 'fromTable' => true, 'schema' => 'Article', 'records' => false
+ ));
+
+ $this->assertContains('class ArticleFixture extends CakeTestFixture', $result);
+ $this->assertContains('public $records', $result);
+ $this->assertContains('public $import', $result);
+ $this->assertContains("'title' => 'First Article'", $result, 'Missing import data %s');
+ $this->assertContains('Second Article', $result, 'Missing import data %s');
+ $this->assertContains('Third Article', $result, 'Missing import data %s');
+ }
+
+/**
+ * test that connection gets set to the import options when a different connection is used.
+ *
+ * @return void
+ */
+ public function testImportOptionsAlternateConnection() {
+ $this->Task->connection = 'test';
+ $result = $this->Task->bake('Article', false, array('schema' => 'Article'));
+ $this->assertContains("'connection' => 'test'", $result);
+ }
+
+/**
+ * Ensure that fixture data doesn't get overly escaped.
+ *
+ * @return void
+ */
+ public function testImportRecordsNoEscaping() {
+ $db = ConnectionManager::getDataSource('test');
+ if ($db instanceof Sqlserver) {
+ $this->markTestSkipped('This test does not run on SQLServer');
+ }
+
+ $Article = ClassRegistry::init('Article');
+ $Article->updateAll(array('body' => "'Body \"value\"'"));
+
+ $this->Task->interactive = true;
+ $this->Task->expects($this->at(0))
+ ->method('in')
+ ->will($this->returnValue('WHERE 1=1 LIMIT 10'));
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $result = $this->Task->bake('Article', false, array(
+ 'fromTable' => true,
+ 'schema' => 'Article',
+ 'records' => false
+ ));
+ $this->assertContains("'body' => 'Body \"value\"'", $result, 'Data has bad escaping');
+ }
+
+/**
+ * test that execute passes runs bake depending with named model.
+ *
+ *
+ * @return void
+ */
+ public function testExecuteWithNamedModel() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('article');
+ $filename = '/my/path/ArticleFixture.php';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with($filename, $this->stringContains('class ArticleFixture'));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test that execute runs all() when args[0] = all
+ *
+ * @return void
+ */
+ public function testExecuteIntoAll() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('all');
+ $this->Task->Model->expects($this->any())
+ ->method('listAll')
+ ->will($this->returnValue(array('articles', 'comments')));
+
+ $filename = '/my/path/ArticleFixture.php';
+ $this->Task->expects($this->at(0))
+ ->method('createFile')
+ ->with($filename, $this->stringContains('class ArticleFixture'));
+
+ $filename = '/my/path/CommentFixture.php';
+ $this->Task->expects($this->at(1))
+ ->method('createFile')
+ ->with($filename, $this->stringContains('class CommentFixture'));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test using all() with -count and -records
+ *
+ * @return void
+ */
+ public function testAllWithCountAndRecordsFlags() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('all');
+ $this->Task->params = array('count' => 10, 'records' => true);
+
+ $this->Task->Model->expects($this->any())->method('listAll')
+ ->will($this->returnValue(array('Articles', 'comments')));
+
+ $filename = '/my/path/ArticleFixture.php';
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with($filename, $this->stringContains("'title' => 'Third Article'"));
+
+ $filename = '/my/path/CommentFixture.php';
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with($filename, $this->stringContains("'comment' => 'First Comment for First Article'"));
+ $this->Task->expects($this->exactly(2))->method('createFile');
+
+ $this->Task->all();
+ }
+
+/**
+ * test interactive mode of execute
+ *
+ * @return void
+ */
+ public function testExecuteInteractive() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+
+ $this->Task->expects($this->any())->method('in')->will($this->returnValue('y'));
+ $this->Task->Model->expects($this->any())->method('getName')->will($this->returnValue('Article'));
+ $this->Task->Model->expects($this->any())->method('getTable')
+ ->with('Article')
+ ->will($this->returnValue('articles'));
+
+ $filename = '/my/path/ArticleFixture.php';
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($filename, $this->stringContains('class ArticleFixture'));
+
+ $this->Task->execute();
+ }
+
+/**
+ * Test that bake works
+ *
+ * @return void
+ */
+ public function testBake() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+
+ $result = $this->Task->bake('Article');
+ $this->assertContains('class ArticleFixture extends CakeTestFixture', $result);
+ $this->assertContains('public $fields', $result);
+ $this->assertContains('public $records', $result);
+ $this->assertNotContains('public $import', $result);
+
+ $result = $this->Task->bake('Article', 'comments');
+ $this->assertContains('class ArticleFixture extends CakeTestFixture', $result);
+ $this->assertContains('public $table = \'comments\';', $result);
+ $this->assertContains('public $fields = array(', $result);
+
+ $result = $this->Task->bake('Article', 'comments', array('records' => true));
+ $this->assertContains("public \$import = array('records' => true, 'connection' => 'test');", $result);
+ $this->assertNotContains('public $records', $result);
+
+ $result = $this->Task->bake('Article', 'comments', array('schema' => 'Article'));
+ $this->assertContains("public \$import = array('model' => 'Article', 'connection' => 'test');", $result);
+ $this->assertNotContains('public $fields', $result);
+
+ $result = $this->Task->bake('Article', 'comments', array('schema' => 'Article', 'records' => true));
+ $this->assertContains("public \$import = array('model' => 'Article', 'records' => true, 'connection' => 'test');", $result);
+ $this->assertNotContains('public $fields', $result);
+ $this->assertNotContains('public $records', $result);
+ }
+
+/**
+ * test record generation with float and binary types
+ *
+ * @return void
+ */
+ public function testRecordGenerationForBinaryAndFloat() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+
+ $result = $this->Task->bake('Article', 'datatypes');
+ $this->assertContains("'float_field' => 1", $result);
+ $this->assertContains("'bool' => 1", $result);
+
+ $result = $this->Task->bake('Article', 'binary_tests');
+ $this->assertContains("'data' => 'Lorem ipsum dolor sit amet'", $result);
+ }
+
+/**
+ * Test that file generation includes headers and correct path for plugins.
+ *
+ * @return void
+ */
+ public function testGenerateFixtureFile() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $filename = '/my/path/ArticleFixture.php';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with($filename, $this->stringContains('ArticleFixture'));
+
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with($filename, $this->stringContains('<?php'));
+
+ $result = $this->Task->generateFixtureFile('Article', array());
+
+ $result = $this->Task->generateFixtureFile('Article', array());
+ }
+
+/**
+ * test generating files into plugins.
+ *
+ * @return void
+ */
+ public function testGeneratePluginFixtureFile() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->plugin = 'TestFixture';
+ $filename = APP . 'Plugin' . DS . 'TestFixture' . DS . 'Test' . DS . 'Fixture' . DS . 'ArticleFixture.php';
+
+ //fake plugin path
+ CakePlugin::load('TestFixture', array('path' => APP . 'Plugin' . DS . 'TestFixture' . DS));
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with($filename, $this->stringContains('class Article'));
+
+ $result = $this->Task->generateFixtureFile('Article', array());
+ CakePlugin::unload();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php
new file mode 100644
index 0000000..2e3c5d9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ModelTaskTest.php
@@ -0,0 +1,1189 @@
+<?php
+/**
+ * ModelTaskTest file
+ *
+ * Test Case for test generation shell task
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP v 1.2.6
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('FixtureTask', 'Console/Command/Task');
+App::uses('TemplateTask', 'Console/Command/Task');
+App::uses('ModelTask', 'Console/Command/Task');
+
+/**
+ * ModelTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ModelTaskTest extends CakeTestCase {
+
+/**
+ * fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.bake_article', 'core.bake_comment', 'core.bake_articles_bake_tag',
+ 'core.bake_tag', 'core.category_thread'
+ );
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'err', 'createFile', '_stop', '_checkUnitTest'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+ }
+
+/**
+ * Setup a mock that has out mocked. Normally this is not used as it makes $this->at() really tricky.
+ *
+ * @return void
+ */
+ protected function _useMockedOut() {
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'out', 'err', 'hr', 'createFile', '_stop', '_checkUnitTest'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+ }
+
+/**
+ * sets up the rest of the dependencies for Model Task
+ *
+ * @return void
+ */
+ protected function _setupOtherMocks() {
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task->Fixture = $this->getMock('FixtureTask', array(), array($out, $out, $in));
+ $this->Task->Test = $this->getMock('FixtureTask', array(), array($out, $out, $in));
+ $this->Task->Template = new TemplateTask($out, $out, $in);
+
+ $this->Task->name = 'Model';
+ $this->Task->interactive = true;
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Task);
+ }
+
+/**
+ * Test that listAll scans the database connection and lists all the tables in it.s
+ *
+ * @return void
+ */
+ public function testListAllArgument() {
+ $this->_useMockedOut();
+
+ $result = $this->Task->listAll('test');
+ $this->assertContains('bake_articles', $result);
+ $this->assertContains('bake_articles_bake_tags', $result);
+ $this->assertContains('bake_tags', $result);
+ $this->assertContains('bake_comments', $result);
+ $this->assertContains('category_threads', $result);
+ }
+
+/**
+ * Test that listAll uses the connection property
+ *
+ * @return void
+ */
+ public function testListAllConnection() {
+ $this->_useMockedOut();
+
+ $this->Task->connection = 'test';
+ $result = $this->Task->listAll();
+ $this->assertContains('bake_articles', $result);
+ $this->assertContains('bake_articles_bake_tags', $result);
+ $this->assertContains('bake_tags', $result);
+ $this->assertContains('bake_comments', $result);
+ $this->assertContains('category_threads', $result);
+ }
+
+/**
+ * Test that getName interacts with the user and returns the model name.
+ *
+ * @return void
+ */
+ public function testGetNameQuit() {
+ $this->Task->expects($this->once())->method('in')->will($this->returnValue('q'));
+ $this->Task->expects($this->once())->method('_stop');
+ $this->Task->getName('test');
+ }
+
+/**
+ * test getName with a valid option.
+ *
+ * @return void
+ */
+ public function testGetNameValidOption() {
+ $listing = $this->Task->listAll('test');
+ $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls(1, 4));
+
+ $result = $this->Task->getName('test');
+ $this->assertEquals(Inflector::classify($listing[0]), $result);
+
+ $result = $this->Task->getName('test');
+ $this->assertEquals(Inflector::classify($listing[3]), $result);
+ }
+
+/**
+ * test that an out of bounds option causes an error.
+ *
+ * @return void
+ */
+ public function testGetNameWithOutOfBoundsOption() {
+ $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls(99, 1));
+ $this->Task->expects($this->once())->method('err');
+
+ $result = $this->Task->getName('test');
+ }
+
+/**
+ * Test table name interactions
+ *
+ * @return void
+ */
+ public function testGetTableName() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $result = $this->Task->getTable('BakeArticle', 'test');
+ $expected = 'bake_articles';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test gettting a custom table name.
+ *
+ * @return void
+ */
+ public function testGetTableNameCustom() {
+ $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls('n', 'my_table'));
+ $result = $this->Task->getTable('BakeArticle', 'test');
+ $expected = 'my_table';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test getTable with non-conventional tablenames
+ *
+ * @return void
+ */
+ public function testGetTableOddTableInteractive() {
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->interactive = true;
+
+ $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls(
+ 2 // bake_odd
+ ));
+
+ $result = $this->Task->getName();
+ $expected = 'BakeOdd';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->getTable($result);
+ $expected = 'bake_odd';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test getTable with non-conventional tablenames
+ *
+ * @return void
+ */
+ public function testGetTableOddTable() {
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->interactive = false;
+ $this->Task->args = array('BakeOdd');
+
+ $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
+
+ $this->Task->listAll();
+
+ $result = $this->Task->getTable('BakeOdd');
+ $expected = 'bake_odd';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that initializing the validations works.
+ *
+ * @return void
+ */
+ public function testInitValidations() {
+ $result = $this->Task->initValidations();
+ $this->assertTrue(in_array('notempty', $result));
+ }
+
+/**
+ * test that individual field validation works, with interactive = false
+ * tests the guessing features of validation
+ *
+ * @return void
+ */
+ public function testFieldValidationGuessing() {
+ $this->Task->interactive = false;
+ $this->Task->initValidations();
+
+ $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
+ $expected = array('notempty' => 'notempty');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->fieldValidation('text', array('type' => 'date', 'length' => 10, 'null' => false));
+ $expected = array('date' => 'date');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->fieldValidation('text', array('type' => 'time', 'length' => 10, 'null' => false));
+ $expected = array('time' => 'time');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->fieldValidation('email', array('type' => 'string', 'length' => 10, 'null' => false));
+ $expected = array('email' => 'email');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->fieldValidation('test', array('type' => 'integer', 'length' => 10, 'null' => false));
+ $expected = array('numeric' => 'numeric');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->fieldValidation('test', array('type' => 'boolean', 'length' => 10, 'null' => false));
+ $expected = array('boolean' => 'boolean');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that interactive field validation works and returns multiple validators.
+ *
+ * @return void
+ */
+ public function testInteractiveFieldValidation() {
+ $this->Task->initValidations();
+ $this->Task->interactive = true;
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('23', 'y', '17', 'n'));
+
+ $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
+ $expected = array('notempty' => 'notempty', 'maxlength' => 'maxlength');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that a bogus response doesn't cause errors to bubble up.
+ *
+ * @return void
+ */
+ public function testInteractiveFieldValidationWithBogusResponse() {
+ $this->_useMockedOut();
+ $this->Task->initValidations();
+ $this->Task->interactive = true;
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('999999', '23', 'n'));
+
+ $this->Task->expects($this->at(10))->method('out')
+ ->with($this->stringContains('make a valid'));
+
+ $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
+ $expected = array('notempty' => 'notempty');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that a regular expression can be used for validation.
+ *
+ * @return void
+ */
+ public function testInteractiveFieldValidationWithRegexp() {
+ $this->Task->initValidations();
+ $this->Task->interactive = true;
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('/^[a-z]{0,9}$/', 'n'));
+
+ $result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
+ $expected = array('a_z_0_9' => '/^[a-z]{0,9}$/');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test the validation Generation routine
+ *
+ * @return void
+ */
+ public function testNonInteractiveDoValidation() {
+ $Model = $this->getMock('Model');
+ $Model->primaryKey = 'id';
+ $Model->expects($this->any())->method('schema')->will($this->returnValue(array(
+ 'id' => array(
+ 'type' => 'integer',
+ 'length' => 11,
+ 'null' => false,
+ 'key' => 'primary',
+ ),
+ 'name' => array(
+ 'type' => 'string',
+ 'length' => 20,
+ 'null' => false,
+ ),
+ 'email' => array(
+ 'type' => 'string',
+ 'length' => 255,
+ 'null' => false,
+ ),
+ 'some_date' => array(
+ 'type' => 'date',
+ 'length' => '',
+ 'null' => false,
+ ),
+ 'some_time' => array(
+ 'type' => 'time',
+ 'length' => '',
+ 'null' => false,
+ ),
+ 'created' => array(
+ 'type' => 'datetime',
+ 'length' => '',
+ 'null' => false,
+ )
+ )));
+ $this->Task->interactive = false;
+
+ $result = $this->Task->doValidation($Model);
+ $expected = array(
+ 'name' => array(
+ 'notempty' => 'notempty'
+ ),
+ 'email' => array(
+ 'email' => 'email',
+ ),
+ 'some_date' => array(
+ 'date' => 'date'
+ ),
+ 'some_time' => array(
+ 'time' => 'time'
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that finding primary key works
+ *
+ * @return void
+ */
+ public function testFindPrimaryKey() {
+ $fields = array(
+ 'one' => array(),
+ 'two' => array(),
+ 'key' => array('key' => 'primary')
+ );
+ $anything = new PHPUnit_Framework_Constraint_IsAnything();
+ $this->Task->expects($this->once())->method('in')
+ ->with($anything, null, 'key')
+ ->will($this->returnValue('my_field'));
+
+ $result = $this->Task->findPrimaryKey($fields);
+ $expected = 'my_field';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test finding Display field
+ *
+ * @return void
+ */
+ public function testFindDisplayFieldNone() {
+ $fields = array(
+ 'id' => array(), 'tagname' => array(), 'body' => array(),
+ 'created' => array(), 'modified' => array()
+ );
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
+ $result = $this->Task->findDisplayField($fields);
+ $this->assertFalse($result);
+ }
+
+/**
+ * Test finding a displayname from user input
+ *
+ * @return void
+ */
+ public function testFindDisplayName() {
+ $fields = array(
+ 'id' => array(), 'tagname' => array(), 'body' => array(),
+ 'created' => array(), 'modified' => array()
+ );
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('y', 2));
+
+ $result = $this->Task->findDisplayField($fields);
+ $this->assertEquals('tagname', $result);
+ }
+
+/**
+ * test that belongsTo generation works.
+ *
+ * @return void
+ */
+ public function testBelongsToGeneration() {
+ $model = new Model(array('ds' => 'test', 'name' => 'BakeComment'));
+ $result = $this->Task->findBelongsTo($model, array());
+ $expected = array(
+ 'belongsTo' => array(
+ array(
+ 'alias' => 'BakeArticle',
+ 'className' => 'BakeArticle',
+ 'foreignKey' => 'bake_article_id',
+ ),
+ array(
+ 'alias' => 'BakeUser',
+ 'className' => 'BakeUser',
+ 'foreignKey' => 'bake_user_id',
+ ),
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $model = new Model(array('ds' => 'test', 'name' => 'CategoryThread'));
+ $result = $this->Task->findBelongsTo($model, array());
+ $expected = array(
+ 'belongsTo' => array(
+ array(
+ 'alias' => 'ParentCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that hasOne and/or hasMany relations are generated properly.
+ *
+ * @return void
+ */
+ public function testHasManyHasOneGeneration() {
+ $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle'));
+ $this->Task->connection = 'test';
+ $this->Task->listAll();
+ $result = $this->Task->findHasOneAndMany($model, array());
+ $expected = array(
+ 'hasMany' => array(
+ array(
+ 'alias' => 'BakeComment',
+ 'className' => 'BakeComment',
+ 'foreignKey' => 'bake_article_id',
+ ),
+ ),
+ 'hasOne' => array(
+ array(
+ 'alias' => 'BakeComment',
+ 'className' => 'BakeComment',
+ 'foreignKey' => 'bake_article_id',
+ ),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ $model = new Model(array('ds' => 'test', 'name' => 'CategoryThread'));
+ $result = $this->Task->findHasOneAndMany($model, array());
+ $expected = array(
+ 'hasOne' => array(
+ array(
+ 'alias' => 'ChildCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ ),
+ 'hasMany' => array(
+ array(
+ 'alias' => 'ChildCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that HABTM generation works
+ *
+ * @return void
+ */
+ public function testHasAndBelongsToManyGeneration() {
+ $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle'));
+ $this->Task->connection = 'test';
+ $this->Task->listAll();
+ $result = $this->Task->findHasAndBelongsToMany($model, array());
+ $expected = array(
+ 'hasAndBelongsToMany' => array(
+ array(
+ 'alias' => 'BakeTag',
+ 'className' => 'BakeTag',
+ 'foreignKey' => 'bake_article_id',
+ 'joinTable' => 'bake_articles_bake_tags',
+ 'associationForeignKey' => 'bake_tag_id',
+ ),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test non interactive doAssociations
+ *
+ * @return void
+ */
+ public function testDoAssociationsNonInteractive() {
+ $this->Task->connection = 'test';
+ $this->Task->interactive = false;
+ $model = new Model(array('ds' => 'test', 'name' => 'BakeArticle'));
+ $result = $this->Task->doAssociations($model);
+ $expected = array(
+ 'belongsTo' => array(
+ array(
+ 'alias' => 'BakeUser',
+ 'className' => 'BakeUser',
+ 'foreignKey' => 'bake_user_id',
+ ),
+ ),
+ 'hasMany' => array(
+ array(
+ 'alias' => 'BakeComment',
+ 'className' => 'BakeComment',
+ 'foreignKey' => 'bake_article_id',
+ ),
+ ),
+ 'hasAndBelongsToMany' => array(
+ array(
+ 'alias' => 'BakeTag',
+ 'className' => 'BakeTag',
+ 'foreignKey' => 'bake_article_id',
+ 'joinTable' => 'bake_articles_bake_tags',
+ 'associationForeignKey' => 'bake_tag_id',
+ ),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Ensure that the fixture object is correctly called.
+ *
+ * @return void
+ */
+ public function testBakeFixture() {
+ $this->Task->plugin = 'TestPlugin';
+ $this->Task->interactive = true;
+ $this->Task->Fixture->expects($this->at(0))->method('bake')->with('BakeArticle', 'bake_articles');
+ $this->Task->bakeFixture('BakeArticle', 'bake_articles');
+
+ $this->assertEquals($this->Task->plugin, $this->Task->Fixture->plugin);
+ $this->assertEquals($this->Task->connection, $this->Task->Fixture->connection);
+ $this->assertEquals($this->Task->interactive, $this->Task->Fixture->interactive);
+ }
+
+/**
+ * Ensure that the test object is correctly called.
+ *
+ * @return void
+ */
+ public function testBakeTest() {
+ $this->Task->plugin = 'TestPlugin';
+ $this->Task->interactive = true;
+ $this->Task->Test->expects($this->at(0))->method('bake')->with('Model', 'BakeArticle');
+ $this->Task->bakeTest('BakeArticle');
+
+ $this->assertEquals($this->Task->plugin, $this->Task->Test->plugin);
+ $this->assertEquals($this->Task->connection, $this->Task->Test->connection);
+ $this->assertEquals($this->Task->interactive, $this->Task->Test->interactive);
+ }
+
+/**
+ * test confirming of associations, and that when an association is hasMany
+ * a question for the hasOne is also not asked.
+ *
+ * @return void
+ */
+ public function testConfirmAssociations() {
+ $associations = array(
+ 'hasOne' => array(
+ array(
+ 'alias' => 'ChildCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ ),
+ 'hasMany' => array(
+ array(
+ 'alias' => 'ChildCategoryThread',
+ 'className' => 'CategoryThread',
+ 'foreignKey' => 'parent_id',
+ ),
+ ),
+ 'belongsTo' => array(
+ array(
+ 'alias' => 'User',
+ 'className' => 'User',
+ 'foreignKey' => 'user_id',
+ ),
+ )
+ );
+ $model = new Model(array('ds' => 'test', 'name' => 'CategoryThread'));
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('n', 'y', 'n', 'n', 'n'));
+
+ $result = $this->Task->confirmAssociations($model, $associations);
+ $this->assertTrue(empty($result['hasOne']));
+
+ $result = $this->Task->confirmAssociations($model, $associations);
+ $this->assertTrue(empty($result['hasMany']));
+ $this->assertTrue(empty($result['hasOne']));
+ }
+
+/**
+ * test that inOptions generates questions and only accepts a valid answer
+ *
+ * @return void
+ */
+ public function testInOptions() {
+ $this->_useMockedOut();
+
+ $options = array('one', 'two', 'three');
+ $this->Task->expects($this->at(0))->method('out')->with('1. one');
+ $this->Task->expects($this->at(1))->method('out')->with('2. two');
+ $this->Task->expects($this->at(2))->method('out')->with('3. three');
+ $this->Task->expects($this->at(3))->method('in')->will($this->returnValue(10));
+
+ $this->Task->expects($this->at(4))->method('out')->with('1. one');
+ $this->Task->expects($this->at(5))->method('out')->with('2. two');
+ $this->Task->expects($this->at(6))->method('out')->with('3. three');
+ $this->Task->expects($this->at(7))->method('in')->will($this->returnValue(2));
+ $result = $this->Task->inOptions($options, 'Pick a number');
+ $this->assertEquals(1, $result);
+ }
+
+/**
+ * test baking validation
+ *
+ * @return void
+ */
+ public function testBakeValidation() {
+ $validate = array(
+ 'name' => array(
+ 'notempty' => 'notempty'
+ ),
+ 'email' => array(
+ 'email' => 'email',
+ ),
+ 'some_date' => array(
+ 'date' => 'date'
+ ),
+ 'some_time' => array(
+ 'time' => 'time'
+ )
+ );
+ $result = $this->Task->bake('BakeArticle', compact('validate'));
+ $this->assertRegExp('/class BakeArticle extends AppModel \{/', $result);
+ $this->assertRegExp('/\$validate \= array\(/', $result);
+ $expected = <<< STRINGEND
+array(
+ 'notempty' => array(
+ 'rule' => array('notempty'),
+ //'message' => 'Your custom message here',
+ //'allowEmpty' => false,
+ //'required' => false,
+ //'last' => false, // Stop validation after this rule
+ //'on' => 'create', // Limit validation to 'create' or 'update' operations
+ ),
+STRINGEND;
+ $this->assertRegExp('/' . preg_quote(str_replace("\r\n", "\n", $expected), '/') . '/', $result);
+ }
+
+/**
+ * test baking relations
+ *
+ * @return void
+ */
+ public function testBakeRelations() {
+ $associations = array(
+ 'belongsTo' => array(
+ array(
+ 'alias' => 'SomethingElse',
+ 'className' => 'SomethingElse',
+ 'foreignKey' => 'something_else_id',
+ ),
+ array(
+ 'alias' => 'BakeUser',
+ 'className' => 'BakeUser',
+ 'foreignKey' => 'bake_user_id',
+ ),
+ ),
+ 'hasOne' => array(
+ array(
+ 'alias' => 'OtherModel',
+ 'className' => 'OtherModel',
+ 'foreignKey' => 'other_model_id',
+ ),
+ ),
+ 'hasMany' => array(
+ array(
+ 'alias' => 'BakeComment',
+ 'className' => 'BakeComment',
+ 'foreignKey' => 'parent_id',
+ ),
+ ),
+ 'hasAndBelongsToMany' => array(
+ array(
+ 'alias' => 'BakeTag',
+ 'className' => 'BakeTag',
+ 'foreignKey' => 'bake_article_id',
+ 'joinTable' => 'bake_articles_bake_tags',
+ 'associationForeignKey' => 'bake_tag_id',
+ ),
+ )
+ );
+ $result = $this->Task->bake('BakeArticle', compact('associations'));
+ $this->assertContains(' * @property BakeUser $BakeUser', $result);
+ $this->assertContains(' * @property OtherModel $OtherModel', $result);
+ $this->assertContains(' * @property BakeComment $BakeComment', $result);
+ $this->assertContains(' * @property BakeTag $BakeTag', $result);
+ $this->assertRegExp('/\$hasAndBelongsToMany \= array\(/', $result);
+ $this->assertRegExp('/\$hasMany \= array\(/', $result);
+ $this->assertRegExp('/\$belongsTo \= array\(/', $result);
+ $this->assertRegExp('/\$hasOne \= array\(/', $result);
+ $this->assertRegExp('/BakeTag/', $result);
+ $this->assertRegExp('/OtherModel/', $result);
+ $this->assertRegExp('/SomethingElse/', $result);
+ $this->assertRegExp('/BakeComment/', $result);
+ }
+
+/**
+ * test bake() with a -plugin param
+ *
+ * @return void
+ */
+ public function testBakeWithPlugin() {
+ $this->Task->plugin = 'ControllerTest';
+
+ //fake plugin path
+ CakePlugin::load('ControllerTest', array('path' => APP . 'Plugin' . DS . 'ControllerTest' . DS));
+ $path = APP . 'Plugin' . DS . 'ControllerTest' . DS . 'Model' . DS . 'BakeArticle.php';
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($path, $this->stringContains('BakeArticle extends ControllerTestAppModel'));
+
+ $result = $this->Task->bake('BakeArticle', array(), array());
+ $this->assertContains("App::uses('ControllerTestAppModel', 'ControllerTest.Model');", $result);
+
+ $this->assertEquals(count(ClassRegistry::keys()), 0);
+ $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
+ }
+
+/**
+ * test that execute passes runs bake depending with named model.
+ *
+ * @return void
+ */
+ public function testExecuteWithNamedModel() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeArticle');
+ $filename = '/my/path/BakeArticle.php';
+
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1));
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($filename, $this->stringContains('class BakeArticle extends AppModel'));
+
+ $this->Task->execute();
+
+ $this->assertEquals(count(ClassRegistry::keys()), 0);
+ $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
+ }
+
+/**
+ * data provider for testExecuteWithNamedModelVariations
+ *
+ * @return void
+ */
+ public static function nameVariations() {
+ return array(
+ array('BakeArticles'), array('BakeArticle'), array('bake_article'), array('bake_articles')
+ );
+ }
+
+/**
+ * test that execute passes with different inflections of the same name.
+ *
+ * @dataProvider nameVariations
+ * @return void
+ */
+ public function testExecuteWithNamedModelVariations($name) {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1));
+
+ $this->Task->args = array($name);
+ $filename = '/my/path/BakeArticle.php';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeArticle extends AppModel'));
+ $this->Task->execute();
+ }
+
+/**
+ * test that execute with a model name picks up hasMany associations.
+ *
+ * @return void
+ */
+ public function testExecuteWithNamedModelHasManyCreated() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeArticle');
+ $filename = '/my/path/BakeArticle.php';
+
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(1));
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with($filename, $this->stringContains("'BakeComment' => array("));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test that execute runs all() when args[0] = all
+ *
+ * @return void
+ */
+ public function testExecuteIntoAll() {
+ $count = count($this->Task->listAll('test'));
+ if ($count != count($this->fixtures)) {
+ $this->markTestSkipped('Additional tables detected.');
+ }
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('all');
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
+
+ $this->Task->Fixture->expects($this->exactly(5))->method('bake');
+ $this->Task->Test->expects($this->exactly(5))->method('bake');
+
+ $filename = '/my/path/BakeArticle.php';
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeArticle'));
+
+ $filename = '/my/path/BakeArticlesBakeTag.php';
+ $this->Task->expects($this->at(2))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeArticlesBakeTag'));
+
+ $filename = '/my/path/BakeComment.php';
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeComment'));
+
+ $filename = '/my/path/BakeComment.php';
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with($filename, $this->stringContains('public $primaryKey = \'otherid\';'));
+
+ $filename = '/my/path/BakeTag.php';
+ $this->Task->expects($this->at(4))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeTag'));
+
+ $filename = '/my/path/BakeTag.php';
+ $this->Task->expects($this->at(4))->method('createFile')
+ ->with($filename, $this->logicalNot($this->stringContains('public $primaryKey')));
+
+ $filename = '/my/path/CategoryThread.php';
+ $this->Task->expects($this->at(5))->method('createFile')
+ ->with($filename, $this->stringContains('class CategoryThread'));
+
+ $this->Task->execute();
+
+ $this->assertEquals(count(ClassRegistry::keys()), 0);
+ $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
+ }
+
+/**
+ * test that odd tablenames arent inflected back from modelname
+ *
+ * @return void
+ */
+ public function testExecuteIntoAllOddTables() {
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'bake', 'bakeFixture'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('all');
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('bake_odd')));
+ $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
+ $this->Task->expects($this->once())->method('_getModelObject')->with('BakeOdd', 'bake_odd')->will($this->returnValue($object));
+ $this->Task->expects($this->at(3))->method('bake')->with($object, false)->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('bakeFixture')->with('BakeOdd', 'bake_odd');
+
+ $this->Task->execute();
+
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'doAssociations', 'doValidation', 'createFile'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('all');
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('bake_odd')));
+ $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
+ $this->Task->expects($this->once())->method('_getModelObject')->will($this->returnValue($object));
+ $this->Task->expects($this->once())->method('doAssociations')->will($this->returnValue(array()));
+ $this->Task->expects($this->once())->method('doValidation')->will($this->returnValue(array()));
+
+ $filename = '/my/path/BakeOdd.php';
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($filename, $this->stringContains('class BakeOdd'));
+
+ $filename = '/my/path/BakeOdd.php';
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($filename, $this->stringContains('public $useTable = \'bake_odd\''));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test that odd tablenames arent inflected back from modelname
+ *
+ * @return void
+ */
+ public function testExecuteIntoBakeOddTables() {
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'bake', 'bakeFixture'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeOdd');
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
+ $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
+ $this->Task->expects($this->once())->method('_getModelObject')->with('BakeOdd', 'bake_odd')->will($this->returnValue($object));
+ $this->Task->expects($this->once())->method('bake')->with($object, false)->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('bakeFixture')->with('BakeOdd', 'bake_odd');
+
+ $this->Task->execute();
+
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Task = $this->getMock('ModelTask',
+ array('in', 'err', '_stop', '_checkUnitTest', 'getAllTables', '_getModelObject', 'doAssociations', 'doValidation', 'createFile'),
+ array($out, $out, $in)
+ );
+ $this->_setupOtherMocks();
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('BakeOdd');
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('getAllTables')->will($this->returnValue(array('articles', 'bake_odd')));
+ $object = new Model(array('name' => 'BakeOdd', 'table' => 'bake_odd', 'ds' => 'test'));
+ $this->Task->expects($this->once())->method('_getModelObject')->will($this->returnValue($object));
+ $this->Task->expects($this->once())->method('doAssociations')->will($this->returnValue(array()));
+ $this->Task->expects($this->once())->method('doValidation')->will($this->returnValue(array()));
+
+ $filename = '/my/path/BakeOdd.php';
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($filename, $this->stringContains('class BakeOdd'));
+
+ $filename = '/my/path/BakeOdd.php';
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($filename, $this->stringContains('public $useTable = \'bake_odd\''));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test that skipTables changes how all() works.
+ *
+ * @return void
+ */
+ public function testSkipTablesAndAll() {
+ $count = count($this->Task->listAll('test'));
+ if ($count != count($this->fixtures)) {
+ $this->markTestSkipped('Additional tables detected.');
+ }
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->args = array('all');
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
+ $this->Task->skipTables = array('bake_tags');
+
+ $this->Task->Fixture->expects($this->exactly(4))->method('bake');
+ $this->Task->Test->expects($this->exactly(4))->method('bake');
+
+ $filename = '/my/path/BakeArticle.php';
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeArticle'));
+
+ $filename = '/my/path/BakeArticlesBakeTag.php';
+ $this->Task->expects($this->at(2))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeArticlesBakeTag'));
+
+ $filename = '/my/path/BakeComment.php';
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with($filename, $this->stringContains('class BakeComment'));
+
+ $filename = '/my/path/CategoryThread.php';
+ $this->Task->expects($this->at(4))->method('createFile')
+ ->with($filename, $this->stringContains('class CategoryThread'));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test the interactive side of bake.
+ *
+ * @return void
+ */
+ public function testExecuteIntoInteractive() {
+ $tables = $this->Task->listAll('test');
+ $article = array_search('bake_articles', $tables) + 1;
+
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+ $this->Task->interactive = true;
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls(
+ $article, // article
+ 'n', // no validation
+ 'y', // associations
+ 'y', // comment relation
+ 'y', // user relation
+ 'y', // tag relation
+ 'n', // additional assocs
+ 'y' // looks good?
+ ));
+ $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true));
+
+ $this->Task->Test->expects($this->once())->method('bake');
+ $this->Task->Fixture->expects($this->once())->method('bake');
+
+ $filename = '/my/path/BakeArticle.php';
+
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($filename, $this->stringContains('class BakeArticle'));
+
+ $this->Task->execute();
+
+ $this->assertEquals(count(ClassRegistry::keys()), 0);
+ $this->assertEquals(count(ClassRegistry::mapKeys()), 0);
+ }
+
+/**
+ * test using bake interactively with a table that does not exist.
+ *
+ * @return void
+ */
+ public function testExecuteWithNonExistantTableName() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls(
+ 'Foobar', // Or type in the name of the model
+ 'y', // Do you want to use this table
+ 'n' // Doesn't exist, continue anyway?
+ ));
+
+ $this->Task->execute();
+ }
+
+/**
+ * test using bake interactively with a table that does not exist.
+ *
+ * @return void
+ */
+ public function testForcedExecuteWithNonExistantTableName() {
+ $this->Task->connection = 'test';
+ $this->Task->path = '/my/path/';
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls(
+ 'Foobar', // Or type in the name of the model
+ 'y', // Do you want to use this table
+ 'y', // Doesn't exist, continue anyway?
+ 'id', // Primary key
+ 'y' // Looks good?
+ ));
+
+ $this->Task->execute();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php
new file mode 100644
index 0000000..28f06cc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/PluginTaskTest.php
@@ -0,0 +1,207 @@
+<?php
+/**
+ * PluginTask Test file
+ *
+ * Test Case for plugin generation shell task
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP v 1.3.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+App::uses('PluginTask', 'Console/Command/Task');
+App::uses('ModelTask', 'Console/Command/Task');
+App::uses('Folder', 'Utility');
+App::uses('File', 'Utility');
+
+/**
+ * PluginTaskPlugin class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class PluginTaskTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $this->in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('PluginTask',
+ array('in', 'err', 'createFile', '_stop', 'clear'),
+ array($this->out, $this->out, $this->in)
+ );
+ $this->Task->path = TMP . 'tests' . DS;
+ $this->Task->bootstrap = TMP . 'tests' . DS . 'bootstrap.php';
+ touch($this->Task->bootstrap);
+
+ $this->_paths = $paths = App::path('plugins');
+ foreach ($paths as $i => $p) {
+ if (!is_dir($p)) {
+ array_splice($paths, $i, 1);
+ }
+ }
+ $this->_testPath = array_push($paths, TMP . 'tests' . DS);
+ App::build(array('plugins' => $paths));
+ }
+
+/**
+ * tearDown()
+ *
+ * @return void
+ */
+ public function tearDown() {
+ if (file_exists($this->Task->bootstrap)) {
+ unlink($this->Task->bootstrap);
+ }
+ parent::tearDown();
+ }
+
+/**
+ * test bake()
+ *
+ * @return void
+ */
+ public function testBakeFoldersAndFiles() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue($this->_testPath));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue('y'));
+
+ $path = $this->Task->path . 'BakeTestPlugin';
+
+ $file = $path . DS . 'Controller' . DS . 'BakeTestPluginAppController.php';
+ $this->Task->expects($this->at(2))->method('createFile')
+ ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
+
+ $file = $path . DS . 'Model' . DS . 'BakeTestPluginAppModel.php';
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
+
+ $this->Task->bake('BakeTestPlugin');
+
+ $path = $this->Task->path . 'BakeTestPlugin';
+ $this->assertTrue(is_dir($path), 'No plugin dir %s');
+
+ $directories = array(
+ 'Config' . DS . 'Schema',
+ 'Model' . DS . 'Behavior',
+ 'Model' . DS . 'Datasource',
+ 'Console' . DS . 'Command' . DS . 'Task',
+ 'Controller' . DS . 'Component',
+ 'Lib',
+ 'View' . DS . 'Helper',
+ 'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component',
+ 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper',
+ 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior',
+ 'Test' . DS . 'Fixture',
+ 'Vendor',
+ 'webroot'
+ );
+ foreach ($directories as $dir) {
+ $this->assertTrue(is_dir($path . DS . $dir), 'Missing directory for ' . $dir);
+ }
+
+ $Folder = new Folder($this->Task->path . 'BakeTestPlugin');
+ $Folder->delete();
+ }
+
+/**
+ * test execute with no args, flowing into interactive,
+ *
+ * @return void
+ */
+ public function testExecuteWithNoArgs() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('TestPlugin'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue($this->_testPath));
+ $this->Task->expects($this->at(2))->method('in')->will($this->returnValue('y'));
+
+ $path = $this->Task->path . 'TestPlugin';
+ $file = $path . DS . 'Controller' . DS . 'TestPluginAppController.php';
+
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
+
+ $file = $path . DS . 'Model' . DS . 'TestPluginAppModel.php';
+ $this->Task->expects($this->at(4))->method('createFile')
+ ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
+
+ $this->Task->args = array();
+ $this->Task->execute();
+
+ $Folder = new Folder($path);
+ $Folder->delete();
+ }
+
+/**
+ * Test Execute
+ *
+ * @return void
+ */
+ public function testExecuteWithOneArg() {
+ $this->Task->expects($this->at(0))->method('in')
+ ->will($this->returnValue($this->_testPath));
+ $this->Task->expects($this->at(1))->method('in')
+ ->will($this->returnValue('y'));
+
+ $path = $this->Task->path . 'BakeTestPlugin';
+ $file = $path . DS . 'Controller' . DS . 'BakeTestPluginAppController.php';
+ $this->Task->expects($this->at(2))->method('createFile')
+ ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
+
+ $path = $this->Task->path . 'BakeTestPlugin';
+ $file = $path . DS . 'Model' . DS . 'BakeTestPluginAppModel.php';
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with($file, new PHPUnit_Framework_Constraint_IsAnything());
+
+ $this->Task->args = array('BakeTestPlugin');
+
+ $this->Task->execute();
+
+ $Folder = new Folder($this->Task->path . 'BakeTestPlugin');
+ $Folder->delete();
+ }
+
+/**
+ * Test that findPath ignores paths that don't exist.
+ *
+ * @return void
+ */
+ public function testFindPathNonExistant() {
+ $paths = App::path('plugins');
+ $last = count($paths);
+ $paths[] = '/fake/path';
+
+ $this->Task = $this->getMock('PluginTask',
+ array('in', 'out', 'err', 'createFile', '_stop'),
+ array($this->out, $this->out, $this->in)
+ );
+ $this->Task->path = TMP . 'tests' . DS;
+
+ // Make sure the added path is filtered out.
+ $this->Task->expects($this->exactly($last))
+ ->method('out');
+
+ $this->Task->expects($this->once())
+ ->method('in')
+ ->will($this->returnValue($last));
+
+ $this->Task->findPath($paths);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php
new file mode 100644
index 0000000..8fd1b33
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ProjectTaskTest.php
@@ -0,0 +1,369 @@
+<?php
+/**
+ * ProjectTask Test file
+ *
+ * Test Case for project generation shell task
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP v 1.3.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+App::uses('ProjectTask', 'Console/Command/Task');
+App::uses('Folder', 'Utility');
+App::uses('File', 'Utility');
+
+/**
+ * ProjectTask Test class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ProjectTaskTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('ProjectTask',
+ array('in', 'err', 'createFile', '_stop'),
+ array($out, $out, $in)
+ );
+ $this->Task->path = TMP . 'tests' . DS;
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+
+ $Folder = new Folder($this->Task->path . 'bake_test_app');
+ $Folder->delete();
+ unset($this->Task);
+ }
+
+/**
+ * creates a test project that is used for testing project task.
+ *
+ * @return void
+ */
+ protected function _setupTestProject() {
+ $skel = CAKE . 'Console' . DS . 'Templates' . DS . 'skel';
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->bake($this->Task->path . 'bake_test_app', $skel);
+ }
+
+/**
+ * test bake() method and directory creation.
+ *
+ * @return void
+ */
+ public function testBake() {
+ $this->_setupTestProject();
+ $path = $this->Task->path . 'bake_test_app';
+
+ $this->assertTrue(is_dir($path), 'No project dir %s');
+ $dirs = array(
+ 'Config',
+ 'Config' . DS . 'Schema',
+ 'Console',
+ 'Console' . DS . 'Command',
+ 'Console' . DS . 'Templates',
+ 'Console' . DS . 'Command' . DS . 'Task',
+ 'Controller',
+ 'Controller' . DS . 'Component',
+ 'Locale',
+ 'Model',
+ 'Model' . DS . 'Behavior',
+ 'Model' . DS . 'Datasource',
+ 'Plugin',
+ 'Test',
+ 'Test' . DS . 'Case',
+ 'Test' . DS . 'Case' . DS . 'Controller',
+ 'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component',
+ 'Test' . DS . 'Case' . DS . 'Model',
+ 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior',
+ 'Test' . DS . 'Fixture',
+ 'Vendor',
+ 'View',
+ 'View' . DS . 'Helper',
+ 'tmp',
+ 'tmp' . DS . 'cache',
+ 'tmp' . DS . 'cache' . DS . 'models',
+ 'tmp' . DS . 'cache' . DS . 'persistent',
+ 'tmp' . DS . 'cache' . DS . 'views',
+ 'tmp' . DS . 'logs',
+ 'tmp' . DS . 'sessions',
+ 'tmp' . DS . 'tests',
+ 'webroot',
+ 'webroot' . DS . 'css',
+ 'webroot' . DS . 'files',
+ 'webroot' . DS . 'img',
+ 'webroot' . DS . 'js',
+
+ );
+ foreach ($dirs as $dir) {
+ $this->assertTrue(is_dir($path . DS . $dir), 'Missing ' . $dir);
+ }
+ }
+
+/**
+ * test bake with an absolute path.
+ *
+ * @return void
+ */
+ public function testExecuteWithAbsolutePath() {
+ $path = $this->Task->args[0] = TMP . 'tests' . DS . 'bake_test_app';
+ $this->Task->params['skel'] = CAKE . 'Console' . DS . 'Templates' . DS . 'skel';
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->execute();
+
+ $this->assertTrue(is_dir($this->Task->args[0]), 'No project dir');
+ $File = new File($path . DS . 'webroot' . DS . 'index.php');
+ $contents = $File->read();
+ $this->assertRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents);
+ $File = new File($path . DS . 'webroot' . DS . 'test.php');
+ $contents = $File->read();
+ $this->assertRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents);
+ }
+
+/**
+ * test bake with CakePHP on the include path. The constants should remain commented out.
+ *
+ * @return void
+ */
+ public function testExecuteWithCakeOnIncludePath() {
+ if (!function_exists('ini_set')) {
+ $this->markTestAsSkipped('Not access to ini_set, cannot proceed.');
+ }
+ $restore = ini_get('include_path');
+ ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . $restore);
+
+ $path = $this->Task->args[0] = TMP . 'tests' . DS . 'bake_test_app';
+ $this->Task->params['skel'] = CAKE . 'Console' . DS . 'Templates' . DS . 'skel';
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->execute();
+
+ $this->assertTrue(is_dir($this->Task->args[0]), 'No project dir');
+ $contents = file_get_contents($path . DS . 'webroot' . DS . 'index.php');
+ $this->assertRegExp('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents);
+
+ $contents = file_get_contents($path . DS . 'webroot' . DS . 'test.php');
+ $this->assertRegExp('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents);
+
+ ini_set('include_path', $restore);
+ }
+
+/**
+ * test bake() method with -empty flag, directory creation and empty files.
+ *
+ * @return void
+ */
+ public function testBakeEmptyFlag() {
+ $this->Task->params['empty'] = true;
+ $this->_setupTestProject();
+ $path = $this->Task->path . 'bake_test_app';
+
+ $empty = array(
+ 'Console' . DS . 'Command' . DS . 'Task' => 'empty',
+ 'Controller' . DS . 'Component' => 'empty',
+ 'Lib' => 'empty',
+ 'Model' . DS . 'Behavior' => 'empty',
+ 'Model' . DS . 'Datasource' => 'empty',
+ 'Plugin' => 'empty',
+ 'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior' => 'empty',
+ 'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component' => 'empty',
+ 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper' => 'empty',
+ 'Test' . DS . 'Fixture' => 'empty',
+ 'Vendor' => 'empty',
+ 'View' . DS . 'Elements' => 'empty',
+ 'View' . DS . 'Scaffolds' => 'empty',
+ 'tmp' . DS . 'cache' . DS . 'models' => 'empty',
+ 'tmp' . DS . 'cache' . DS . 'persistent' => 'empty',
+ 'tmp' . DS . 'cache' . DS . 'views' => 'empty',
+ 'tmp' . DS . 'logs' => 'empty',
+ 'tmp' . DS . 'sessions' => 'empty',
+ 'tmp' . DS . 'tests' => 'empty',
+ 'webroot' . DS . 'js' => 'empty',
+ 'webroot' . DS . 'files' => 'empty'
+ );
+
+ foreach ($empty as $dir => $file) {
+ $this->assertTrue(is_file($path . DS . $dir . DS . $file), sprintf('Missing %s file in %s', $file, $dir));
+ }
+ }
+
+/**
+ * test generation of Security.salt
+ *
+ * @return void
+ */
+ public function testSecuritySaltGeneration() {
+ $this->_setupTestProject();
+
+ $path = $this->Task->path . 'bake_test_app' . DS;
+ $result = $this->Task->securitySalt($path);
+ $this->assertTrue($result);
+
+ $File = new File($path . 'Config' . DS . 'core.php');
+ $contents = $File->read();
+ $this->assertNotRegExp('/DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi/', $contents, 'Default Salt left behind. %s');
+ }
+
+/**
+ * test generation of Security.cipherSeed
+ *
+ * @return void
+ */
+ public function testSecurityCipherSeedGeneration() {
+ $this->_setupTestProject();
+
+ $path = $this->Task->path . 'bake_test_app' . DS;
+ $result = $this->Task->securityCipherSeed($path);
+ $this->assertTrue($result);
+
+ $File = new File($path . 'Config' . DS . 'core.php');
+ $contents = $File->read();
+ $this->assertNotRegExp('/76859309657453542496749683645/', $contents, 'Default CipherSeed left behind. %s');
+ }
+
+/**
+ * Test that index.php is generated correctly.
+ *
+ * @return void
+ */
+ public function testIndexPhpGeneration() {
+ $this->_setupTestProject();
+
+ $path = $this->Task->path . 'bake_test_app' . DS;
+ $this->Task->corePath($path);
+
+ $File = new File($path . 'webroot' . DS . 'index.php');
+ $contents = $File->read();
+ $this->assertNotRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents);
+ $File = new File($path . 'webroot' . DS . 'test.php');
+ $contents = $File->read();
+ $this->assertNotRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents);
+ }
+
+/**
+ * test getPrefix method, and that it returns Routing.prefix or writes to config file.
+ *
+ * @return void
+ */
+ public function testGetPrefix() {
+ Configure::write('Routing.prefixes', array('admin'));
+ $result = $this->Task->getPrefix();
+ $this->assertEquals('admin_', $result);
+
+ Configure::write('Routing.prefixes', null);
+ $this->_setupTestProject();
+ $this->Task->configPath = $this->Task->path . 'bake_test_app' . DS . 'Config' . DS;
+ $this->Task->expects($this->once())->method('in')->will($this->returnValue('super_duper_admin'));
+
+ $result = $this->Task->getPrefix();
+ $this->assertEquals('super_duper_admin_', $result);
+
+ $File = new File($this->Task->configPath . 'core.php');
+ $File->delete();
+ }
+
+/**
+ * test cakeAdmin() writing core.php
+ *
+ * @return void
+ */
+ public function testCakeAdmin() {
+ $File = new File(APP . 'Config' . DS . 'core.php');
+ $contents = $File->read();
+ $File = new File(TMP . 'tests' . DS . 'core.php');
+ $File->write($contents);
+
+ Configure::write('Routing.prefixes', null);
+ $this->Task->configPath = TMP . 'tests' . DS;
+ $result = $this->Task->cakeAdmin('my_prefix');
+ $this->assertTrue($result);
+
+ $this->assertEquals(Configure::read('Routing.prefixes'), array('my_prefix'));
+ $File->delete();
+ }
+
+/**
+ * test getting the prefix with more than one prefix setup
+ *
+ * @return void
+ */
+ public function testGetPrefixWithMultiplePrefixes() {
+ Configure::write('Routing.prefixes', array('admin', 'ninja', 'shinobi'));
+ $this->_setupTestProject();
+ $this->Task->configPath = $this->Task->path . 'bake_test_app' . DS . 'Config' . DS;
+ $this->Task->expects($this->once())->method('in')->will($this->returnValue(2));
+
+ $result = $this->Task->getPrefix();
+ $this->assertEquals('ninja_', $result);
+ }
+
+/**
+ * Test execute method with one param to destination folder.
+ *
+ * @return void
+ */
+ public function testExecute() {
+ $this->Task->params['skel'] = CAKE . 'Console' . DS . 'Templates' . DS . 'skel';
+ $this->Task->params['working'] = TMP . 'tests' . DS;
+
+ $path = $this->Task->path . 'bake_test_app';
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue($path));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue('y'));
+
+ $this->Task->execute();
+ $this->assertTrue(is_dir($path), 'No project dir');
+ $this->assertTrue(is_dir($path . DS . 'Controller'), 'No controllers dir ');
+ $this->assertTrue(is_dir($path . DS . 'Controller' . DS . 'Component'), 'No components dir ');
+ $this->assertTrue(is_dir($path . DS . 'Model'), 'No models dir');
+ $this->assertTrue(is_dir($path . DS . 'View'), 'No views dir');
+ $this->assertTrue(is_dir($path . DS . 'View' . DS . 'Helper'), 'No helpers dir');
+ $this->assertTrue(is_dir($path . DS . 'Test'), 'No tests dir');
+ $this->assertTrue(is_dir($path . DS . 'Test' . DS . 'Case'), 'No cases dir');
+ $this->assertTrue(is_dir($path . DS . 'Test' . DS . 'Fixture'), 'No fixtures dir');
+ }
+
+/**
+ * test console path
+ *
+ * @return void
+ */
+ public function testConsolePath() {
+ $this->_setupTestProject();
+
+ $path = $this->Task->path . 'bake_test_app' . DS;
+ $result = $this->Task->consolePath($path);
+ $this->assertTrue($result);
+
+ $File = new File($path . 'Console' . DS . 'cake.php');
+ $contents = $File->read();
+ $this->assertNotRegExp('/__CAKE_PATH__/', $contents, 'Console path placeholder left behind.');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php
new file mode 100644
index 0000000..d2df394
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TemplateTaskTest.php
@@ -0,0 +1,165 @@
+<?php
+/**
+ * TemplateTask file
+ *
+ * Test Case for TemplateTask generation shell task
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ShellDispatcher', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+App::uses('TemplateTask', 'Console/Command/Task');
+
+/**
+ * TemplateTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class TemplateTaskTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('TemplateTask',
+ array('in', 'err', 'createFile', '_stop', 'clear'),
+ array($out, $out, $in)
+ );
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Task);
+ }
+
+/**
+ * test that set sets variables
+ *
+ * @return void
+ */
+ public function testSet() {
+ $this->Task->set('one', 'two');
+ $this->assertTrue(isset($this->Task->templateVars['one']));
+ $this->assertEquals('two', $this->Task->templateVars['one']);
+
+ $this->Task->set(array('one' => 'three', 'four' => 'five'));
+ $this->assertTrue(isset($this->Task->templateVars['one']));
+ $this->assertEquals('three', $this->Task->templateVars['one']);
+ $this->assertTrue(isset($this->Task->templateVars['four']));
+ $this->assertEquals('five', $this->Task->templateVars['four']);
+
+ $this->Task->templateVars = array();
+ $this->Task->set(array(3 => 'three', 4 => 'four'));
+ $this->Task->set(array(1 => 'one', 2 => 'two'));
+ $expected = array(3 => 'three', 4 => 'four', 1 => 'one', 2 => 'two');
+ $this->assertEquals($expected, $this->Task->templateVars);
+ }
+
+/**
+ * test finding themes installed in
+ *
+ * @return void
+ */
+ public function testFindingInstalledThemesForBake() {
+ $consoleLibs = CAKE . 'Console' . DS;
+ $this->Task->initialize();
+ $this->assertEquals($this->Task->templatePaths['default'], $consoleLibs . 'Templates' . DS . 'default' . DS);
+ }
+
+/**
+ * test getting the correct theme name. Ensure that with only one theme, or a theme param
+ * that the user is not bugged. If there are more, find and return the correct theme name
+ *
+ * @return void
+ */
+ public function testGetThemePath() {
+ $defaultTheme = CAKE . 'Console' . DS . 'Templates' . DS . 'default' . DS;
+ $this->Task->templatePaths = array('default' => $defaultTheme);
+
+ $this->Task->expects($this->exactly(1))->method('in')->will($this->returnValue('1'));
+
+ $result = $this->Task->getThemePath();
+ $this->assertEquals($defaultTheme, $result);
+
+ $this->Task->templatePaths = array('other' => '/some/path', 'default' => $defaultTheme);
+ $this->Task->params['theme'] = 'other';
+ $result = $this->Task->getThemePath();
+ $this->assertEquals('/some/path', $result);
+
+ $this->Task->params = array();
+ $result = $this->Task->getThemePath();
+ $this->assertEquals('/some/path', $result);
+ $this->assertEquals('other', $this->Task->params['theme']);
+ }
+
+/**
+ * test generate
+ *
+ * @return void
+ */
+ public function testGenerate() {
+ App::build(array(
+ 'Console' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS
+ )
+ ));
+ $this->Task->initialize();
+ $this->Task->expects($this->any())->method('in')->will($this->returnValue(1));
+
+ $result = $this->Task->generate('classes', 'test_object', array('test' => 'foo'));
+ $expected = "I got rendered\nfoo";
+ $this->assertTextEquals($expected, $result);
+ }
+
+/**
+ * test generate with a missing template in the chosen theme.
+ * ensure fallback to default works.
+ *
+ * @return void
+ */
+ public function testGenerateWithTemplateFallbacks() {
+ App::build(array(
+ 'Console' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS,
+ CAKE_CORE_INCLUDE_PATH . DS . 'console' . DS
+ )
+ ));
+ $this->Task->initialize();
+ $this->Task->params['theme'] = 'test';
+ $this->Task->set(array(
+ 'model' => 'Article',
+ 'table' => 'articles',
+ 'import' => false,
+ 'records' => false,
+ 'schema' => ''
+ ));
+ $result = $this->Task->generate('classes', 'fixture');
+ $this->assertRegExp('/ArticleFixture extends CakeTestFixture/', $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php
new file mode 100644
index 0000000..6806af8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/TestTaskTest.php
@@ -0,0 +1,783 @@
+<?php
+/**
+ * TestTaskTest file
+ *
+ * Test Case for test generation shell task
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+App::uses('TestTask', 'Console/Command/Task');
+App::uses('TemplateTask', 'Console/Command/Task');
+App::uses('Controller', 'Controller');
+App::uses('Model', 'Model');
+
+/**
+ * Test Article model
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class TestTaskArticle extends Model {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'TestTaskArticle';
+
+/**
+ * Table name to use
+ *
+ * @var string
+ */
+ public $useTable = 'articles';
+
+/**
+ * HasMany Associations
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Comment' => array(
+ 'className' => 'TestTask.TestTaskComment',
+ 'foreignKey' => 'article_id',
+ )
+ );
+
+/**
+ * Has and Belongs To Many Associations
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array(
+ 'Tag' => array(
+ 'className' => 'TestTaskTag',
+ 'joinTable' => 'articles_tags',
+ 'foreignKey' => 'article_id',
+ 'associationForeignKey' => 'tag_id'
+ )
+ );
+
+/**
+ * Example public method
+ *
+ * @return void
+ */
+ public function doSomething() {
+ }
+
+/**
+ * Example Secondary public method
+ *
+ * @return void
+ */
+ public function doSomethingElse() {
+ }
+
+/**
+ * Example protected method
+ *
+ * @return void
+ */
+ protected function _innerMethod() {
+ }
+
+}
+
+/**
+ * Tag Testing Model
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class TestTaskTag extends Model {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'TestTaskTag';
+
+/**
+ * Table name
+ *
+ * @var string
+ */
+ public $useTable = 'tags';
+
+/**
+ * Has and Belongs To Many Associations
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array(
+ 'Article' => array(
+ 'className' => 'TestTaskArticle',
+ 'joinTable' => 'articles_tags',
+ 'foreignKey' => 'tag_id',
+ 'associationForeignKey' => 'article_id'
+ )
+ );
+}
+
+/**
+ * Simulated plugin
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class TestTaskAppModel extends Model {
+}
+
+/**
+ * Testing AppMode (TaskComment)
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class TestTaskComment extends TestTaskAppModel {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'TestTaskComment';
+
+/**
+ * Table name
+ *
+ * @var string
+ */
+ public $useTable = 'comments';
+
+/**
+ * Belongs To Associations
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Article' => array(
+ 'className' => 'TestTaskArticle',
+ 'foreignKey' => 'article_id',
+ )
+ );
+}
+
+/**
+ * Test Task Comments Controller
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class TestTaskCommentsController extends Controller {
+
+/**
+ * Controller Name
+ *
+ * @var string
+ */
+ public $name = 'TestTaskComments';
+
+/**
+ * Models to use
+ *
+ * @var array
+ */
+ public $uses = array('TestTaskComment', 'TestTaskTag');
+}
+
+/**
+ * TestTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class TestTaskTest extends CakeTestCase {
+
+/**
+ * Fixtures
+ *
+ * @var string
+ */
+ public $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('TestTask',
+ array('in', 'err', 'createFile', '_stop', 'isLoadableClass'),
+ array($out, $out, $in)
+ );
+ $this->Task->name = 'Test';
+ $this->Task->Template = new TemplateTask($out, $out, $in);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Task);
+ CakePlugin::unload();
+ }
+
+/**
+ * Test that file path generation doesn't continuously append paths.
+ *
+ * @return void
+ */
+ public function testFilePathGenerationModelRepeated() {
+ $this->Task->expects($this->never())->method('err');
+ $this->Task->expects($this->never())->method('_stop');
+
+ $file = TESTS . 'Case' . DS . 'Model' . DS . 'MyClassTest.php';
+
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with($file, $this->anything());
+
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with($file, $this->anything());
+
+ $file = TESTS . 'Case' . DS . 'Controller' . DS . 'CommentsControllerTest.php';
+ $this->Task->expects($this->at(5))->method('createFile')
+ ->with($file, $this->anything());
+
+ $this->Task->bake('Model', 'MyClass');
+ $this->Task->bake('Model', 'MyClass');
+ $this->Task->bake('Controller', 'Comments');
+ }
+
+/**
+ * Test that method introspection pulls all relevant non parent class
+ * methods into the test case.
+ *
+ * @return void
+ */
+ public function testMethodIntrospection() {
+ $result = $this->Task->getTestableMethods('TestTaskArticle');
+ $expected = array('dosomething', 'dosomethingelse');
+ $this->assertEquals($expected, array_map('strtolower', $result));
+ }
+
+/**
+ * test that the generation of fixtures works correctly.
+ *
+ * @return void
+ */
+ public function testFixtureArrayGenerationFromModel() {
+ $subject = ClassRegistry::init('TestTaskArticle');
+ $result = $this->Task->generateFixtureList($subject);
+ $expected = array('plugin.test_task.test_task_comment', 'app.articles_tags',
+ 'app.test_task_article', 'app.test_task_tag');
+
+ $this->assertEquals(sort($expected), sort($result));
+ }
+
+/**
+ * test that the generation of fixtures works correctly.
+ *
+ * @return void
+ */
+ public function testFixtureArrayGenerationFromController() {
+ $subject = new TestTaskCommentsController();
+ $result = $this->Task->generateFixtureList($subject);
+ $expected = array('plugin.test_task.test_task_comment', 'app.articles_tags',
+ 'app.test_task_article', 'app.test_task_tag');
+
+ $this->assertEquals(sort($expected), sort($result));
+ }
+
+/**
+ * test user interaction to get object type
+ *
+ * @return void
+ */
+ public function testGetObjectType() {
+ $this->Task->expects($this->once())->method('_stop');
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('q'));
+ $this->Task->expects($this->at(2))->method('in')->will($this->returnValue(2));
+
+ $this->Task->getObjectType();
+
+ $result = $this->Task->getObjectType();
+ $this->assertEquals($this->Task->classTypes['Controller'], $result);
+ }
+
+/**
+ * creating test subjects should clear the registry so the registry is always fresh
+ *
+ * @return void
+ */
+ public function testRegistryClearWhenBuildingTestObjects() {
+ ClassRegistry::flush();
+ $model = ClassRegistry::init('TestTaskComment');
+ $model->bindModel(array(
+ 'belongsTo' => array(
+ 'Random' => array(
+ 'className' => 'TestTaskArticle',
+ 'foreignKey' => 'article_id',
+ )
+ )
+ ));
+ $keys = ClassRegistry::keys();
+ $this->assertTrue(in_array('test_task_comment', $keys));
+ $object = $this->Task->buildTestSubject('Model', 'TestTaskComment');
+
+ $keys = ClassRegistry::keys();
+ $this->assertFalse(in_array('random', $keys));
+ }
+
+/**
+ * test that getClassName returns the user choice as a classname.
+ *
+ * @return void
+ */
+ public function testGetClassName() {
+ $objects = App::objects('model');
+ $this->skipIf(empty($objects), 'No models in app.');
+
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('MyCustomClass'));
+ $this->Task->expects($this->at(1))->method('in')->will($this->returnValue(1));
+
+ $result = $this->Task->getClassName('Model');
+ $this->assertEquals('MyCustomClass', $result);
+
+ $result = $this->Task->getClassName('Model');
+ $options = App::objects('model');
+ $this->assertEquals($options[0], $result);
+ }
+
+/**
+ * Test the user interaction for defining additional fixtures.
+ *
+ * @return void
+ */
+ public function testGetUserFixtures() {
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
+ $this->Task->expects($this->at(1))->method('in')
+ ->will($this->returnValue('app.pizza, app.topping, app.side_dish'));
+
+ $result = $this->Task->getUserFixtures();
+ $expected = array('app.pizza', 'app.topping', 'app.side_dish');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that resolving classnames works
+ *
+ * @return void
+ */
+ public function testGetRealClassname() {
+ $result = $this->Task->getRealClassname('Model', 'Post');
+ $this->assertEquals('Post', $result);
+
+ $result = $this->Task->getRealClassname('Controller', 'Posts');
+ $this->assertEquals('PostsController', $result);
+
+ $result = $this->Task->getRealClassname('Controller', 'PostsController');
+ $this->assertEquals('PostsController', $result);
+
+ $result = $this->Task->getRealClassname('Controller', 'AlertTypes');
+ $this->assertEquals('AlertTypesController', $result);
+
+ $result = $this->Task->getRealClassname('Helper', 'Form');
+ $this->assertEquals('FormHelper', $result);
+
+ $result = $this->Task->getRealClassname('Helper', 'FormHelper');
+ $this->assertEquals('FormHelper', $result);
+
+ $result = $this->Task->getRealClassname('Behavior', 'Containable');
+ $this->assertEquals('ContainableBehavior', $result);
+
+ $result = $this->Task->getRealClassname('Behavior', 'ContainableBehavior');
+ $this->assertEquals('ContainableBehavior', $result);
+
+ $result = $this->Task->getRealClassname('Component', 'Auth');
+ $this->assertEquals('AuthComponent', $result);
+ }
+
+/**
+ * test baking files. The conditionally run tests are known to fail in PHP4
+ * as PHP4 classnames are all lower case, breaking the plugin path inflection.
+ *
+ * @return void
+ */
+ public function testBakeModelTest() {
+ $this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('isLoadableClass')->will($this->returnValue(true));
+
+ $result = $this->Task->bake('Model', 'TestTaskArticle');
+
+ $this->assertContains("App::uses('TestTaskArticle', 'Model')", $result);
+ $this->assertContains('class TestTaskArticleTest extends CakeTestCase', $result);
+
+ $this->assertContains('function setUp()', $result);
+ $this->assertContains("\$this->TestTaskArticle = ClassRegistry::init('TestTaskArticle')", $result);
+
+ $this->assertContains('function tearDown()', $result);
+ $this->assertContains('unset($this->TestTaskArticle)', $result);
+
+ $this->assertContains('function testDoSomething()', $result);
+ $this->assertContains('function testDoSomethingElse()', $result);
+
+ $this->assertContains("'app.test_task_article'", $result);
+ $this->assertContains("'app.test_task_comment'", $result);
+ $this->assertContains("'app.test_task_tag'", $result);
+ $this->assertContains("'app.articles_tag'", $result);
+ }
+
+/**
+ * test baking controller test files
+ *
+ * @return void
+ */
+ public function testBakeControllerTest() {
+ $this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('isLoadableClass')->will($this->returnValue(true));
+
+ $result = $this->Task->bake('Controller', 'TestTaskComments');
+
+ $this->assertContains("App::uses('TestTaskCommentsController', 'Controller')", $result);
+ $this->assertContains('class TestTaskCommentsControllerTest extends ControllerTestCase', $result);
+
+ $this->assertNotContains('function setUp()', $result);
+ $this->assertNotContains("\$this->TestTaskComments = new TestTaskCommentsController()", $result);
+ $this->assertNotContains("\$this->TestTaskComments->constructClasses()", $result);
+
+ $this->assertNotContains('function tearDown()', $result);
+ $this->assertNotContains('unset($this->TestTaskComments)', $result);
+
+ $this->assertContains("'app.test_task_article'", $result);
+ $this->assertContains("'app.test_task_comment'", $result);
+ $this->assertContains("'app.test_task_tag'", $result);
+ $this->assertContains("'app.articles_tag'", $result);
+ }
+
+/**
+ * test baking component test files,
+ *
+ * @return void
+ */
+ public function testBakeComponentTest() {
+ $this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
+
+ $result = $this->Task->bake('Component', 'Example');
+
+ $this->assertContains("App::uses('ExampleComponent', 'Controller/Component')", $result);
+ $this->assertContains('class ExampleComponentTest extends CakeTestCase', $result);
+
+ $this->assertContains('function setUp()', $result);
+ $this->assertContains("\$Collection = new ComponentCollection()", $result);
+ $this->assertContains("\$this->Example = new ExampleComponent(\$Collection)", $result);
+
+ $this->assertContains('function tearDown()', $result);
+ $this->assertContains('unset($this->Example)', $result);
+ }
+
+/**
+ * test baking behavior test files,
+ *
+ * @return void
+ */
+ public function testBakeBehaviorTest() {
+ $this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
+
+ $result = $this->Task->bake('Behavior', 'Example');
+
+ $this->assertContains("App::uses('ExampleBehavior', 'Model/Behavior')", $result);
+ $this->assertContains('class ExampleBehaviorTest extends CakeTestCase', $result);
+
+ $this->assertContains('function setUp()', $result);
+ $this->assertContains("\$this->Example = new ExampleBehavior()", $result);
+
+ $this->assertContains('function tearDown()', $result);
+ $this->assertContains('unset($this->Example)', $result);
+ }
+
+/**
+ * test baking helper test files,
+ *
+ * @return void
+ */
+ public function testBakeHelperTest() {
+ $this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
+
+ $result = $this->Task->bake('Helper', 'Example');
+
+ $this->assertContains("App::uses('ExampleHelper', 'View/Helper')", $result);
+ $this->assertContains('class ExampleHelperTest extends CakeTestCase', $result);
+
+ $this->assertContains('function setUp()', $result);
+ $this->assertContains("\$View = new View()", $result);
+ $this->assertContains("\$this->Example = new ExampleHelper(\$View)", $result);
+
+ $this->assertContains('function tearDown()', $result);
+ $this->assertContains('unset($this->Example)', $result);
+ }
+
+/**
+ * test Constructor generation ensure that constructClasses is called for controllers
+ *
+ * @return void
+ */
+ public function testGenerateConstructor() {
+ $result = $this->Task->generateConstructor('controller', 'PostsController', null);
+ $expected = array('', '', '');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->generateConstructor('model', 'Post', null);
+ $expected = array('', "ClassRegistry::init('Post');\n", '');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->generateConstructor('helper', 'FormHelper', null);
+ $expected = array("\$View = new View();\n", "new FormHelper(\$View);\n", '');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test generateUses()
+ */
+ public function testGenerateUses() {
+ $result = $this->Task->generateUses('model', 'Model', 'Post');
+ $expected = array(
+ array('Post', 'Model')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->generateUses('controller', 'Controller', 'PostsController');
+ $expected = array(
+ array('PostsController', 'Controller')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->generateUses('helper', 'View/Helper', 'FormHelper');
+ $expected = array(
+ array('View', 'View'),
+ array('Helper', 'View'),
+ array('FormHelper', 'View/Helper'),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Task->generateUses('component', 'Controller/Component', 'AuthComponent');
+ $expected = array(
+ array('ComponentCollection', 'Controller'),
+ array('Component', 'Controller'),
+ array('AuthComponent', 'Controller/Component')
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that mock class generation works for the appropriate classes
+ *
+ * @return void
+ */
+ public function testMockClassGeneration() {
+ $result = $this->Task->hasMockClass('controller');
+ $this->assertTrue($result);
+ }
+
+/**
+ * test bake() with a -plugin param
+ *
+ * @return void
+ */
+ public function testBakeWithPlugin() {
+ $this->Task->plugin = 'TestTest';
+
+ //fake plugin path
+ CakePlugin::load('TestTest', array('path' => APP . 'Plugin' . DS . 'TestTest' . DS));
+ $path = APP . 'Plugin' . DS . 'TestTest' . DS . 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper' . DS . 'FormHelperTest.php';
+ $this->Task->expects($this->once())->method('createFile')
+ ->with($path, $this->anything());
+
+ $this->Task->bake('Helper', 'Form');
+ CakePlugin::unload();
+ }
+
+/**
+ * test interactive with plugins lists from the plugin
+ *
+ * @return void
+ */
+ public function testInteractiveWithPlugin() {
+ $testApp = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS;
+ App::build(array(
+ 'Plugin' => array($testApp)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+
+ $this->Task->plugin = 'TestPlugin';
+ $path = $testApp . 'TestPlugin' . DS . 'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper' . DS . 'OtherHelperTest.php';
+ $this->Task->expects($this->any())
+ ->method('in')
+ ->will($this->onConsecutiveCalls(
+ 5, //helper
+ 1 //OtherHelper
+ ));
+
+ $this->Task->expects($this->once())
+ ->method('createFile')
+ ->with($path, $this->anything());
+
+ $this->Task->stdout->expects($this->at(21))
+ ->method('write')
+ ->with('1. OtherHelperHelper');
+
+ $this->Task->execute();
+ }
+
+ public static function caseFileNameProvider() {
+ return array(
+ array('Model', 'Post', 'Case' . DS . 'Model' . DS . 'PostTest.php'),
+ array('Helper', 'Form', 'Case' . DS . 'View' . DS . 'Helper' . DS . 'FormHelperTest.php'),
+ array('Controller', 'Posts', 'Case' . DS . 'Controller' . DS . 'PostsControllerTest.php'),
+ array('Behavior', 'Containable', 'Case' . DS . 'Model' . DS . 'Behavior' . DS . 'ContainableBehaviorTest.php'),
+ array('Component', 'Auth', 'Case' . DS . 'Controller' . DS . 'Component' . DS . 'AuthComponentTest.php'),
+ array('model', 'Post', 'Case' . DS . 'Model' . DS . 'PostTest.php'),
+ array('helper', 'Form', 'Case' . DS . 'View' . DS . 'Helper' . DS . 'FormHelperTest.php'),
+ array('controller', 'Posts', 'Case' . DS . 'Controller' . DS . 'PostsControllerTest.php'),
+ array('behavior', 'Containable', 'Case' . DS . 'Model' . DS . 'Behavior' . DS . 'ContainableBehaviorTest.php'),
+ array('component', 'Auth', 'Case' . DS . 'Controller' . DS . 'Component' . DS . 'AuthComponentTest.php'),
+ );
+ }
+
+/**
+ * Test filename generation for each type + plugins
+ *
+ * @dataProvider caseFileNameProvider
+ * @return void
+ */
+ public function testTestCaseFileName($type, $class, $expected) {
+ $this->Task->path = DS . 'my' . DS . 'path' . DS . 'tests' . DS;
+
+ $result = $this->Task->testCaseFileName($type, $class);
+ $expected = $this->Task->path . $expected;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test filename generation for plugins.
+ *
+ * @return void
+ */
+ public function testTestCaseFileNamePlugin() {
+ $this->Task->path = DS . 'my' . DS . 'path' . DS . 'tests' . DS;
+
+ CakePlugin::load('TestTest', array('path' => APP . 'Plugin' . DS . 'TestTest' . DS ));
+ $this->Task->plugin = 'TestTest';
+ $result = $this->Task->testCaseFileName('Model', 'Post');
+ $expected = APP . 'Plugin' . DS . 'TestTest' . DS . 'Test' . DS . 'Case' . DS . 'Model' . DS . 'PostTest.php';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test execute with a type defined
+ *
+ * @return void
+ */
+ public function testExecuteWithOneArg() {
+ $this->Task->args[0] = 'Model';
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('TestTaskTag'));
+ $this->Task->expects($this->once())->method('isLoadableClass')->will($this->returnValue(true));
+ $this->Task->expects($this->once())->method('createFile')
+ ->with(
+ $this->anything(),
+ $this->stringContains('class TestTaskTagTest extends CakeTestCase')
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test execute with type and class name defined
+ *
+ * @return void
+ */
+ public function testExecuteWithTwoArgs() {
+ $this->Task->args = array('Model', 'TestTaskTag');
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('TestTaskTag'));
+ $this->Task->expects($this->once())->method('createFile')
+ ->with(
+ $this->anything(),
+ $this->stringContains('class TestTaskTagTest extends CakeTestCase')
+ );
+ $this->Task->expects($this->any())->method('isLoadableClass')->will($this->returnValue(true));
+ $this->Task->execute();
+ }
+
+/**
+ * test execute with type and class name defined and lower case.
+ *
+ * @return void
+ */
+ public function testExecuteWithTwoArgsLowerCase() {
+ $this->Task->args = array('model', 'TestTaskTag');
+ $this->Task->expects($this->at(0))->method('in')->will($this->returnValue('TestTaskTag'));
+ $this->Task->expects($this->once())->method('createFile')
+ ->with(
+ $this->anything(),
+ $this->stringContains('class TestTaskTagTest extends CakeTestCase')
+ );
+ $this->Task->expects($this->any())->method('isLoadableClass')->will($this->returnValue(true));
+ $this->Task->execute();
+ }
+
+/**
+ * Data provider for mapType() tests.
+ *
+ * @return array
+ */
+ public static function mapTypeProvider() {
+ return array(
+ array('controller', null, 'Controller'),
+ array('Controller', null, 'Controller'),
+ array('component', null, 'Controller/Component'),
+ array('Component', null, 'Controller/Component'),
+ array('model', null, 'Model'),
+ array('Model', null, 'Model'),
+ array('behavior', null, 'Model/Behavior'),
+ array('Behavior', null, 'Model/Behavior'),
+ array('helper', null, 'View/Helper'),
+ array('Helper', null, 'View/Helper'),
+ array('Helper', 'DebugKit', 'DebugKit.View/Helper'),
+ );
+ }
+
+/**
+ * Test that mapType returns the correct package names.
+ *
+ * @dataProvider mapTypeProvider
+ * @return void
+ */
+ public function testMapType($original, $plugin, $expected) {
+ $this->assertEquals($expected, $this->Task->mapType($original, $plugin));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php
new file mode 100644
index 0000000..4865443
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/Task/ViewTaskTest.php
@@ -0,0 +1,731 @@
+<?php
+/**
+ * ViewTask Test file
+ *
+ * Test Case for view generation shell task
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command.Task
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('ConsoleOutput', 'Console');
+App::uses('ConsoleInput', 'Console');
+App::uses('Shell', 'Console');
+App::uses('ViewTask', 'Console/Command/Task');
+App::uses('ControllerTask', 'Console/Command/Task');
+App::uses('TemplateTask', 'Console/Command/Task');
+App::uses('ProjectTask', 'Console/Command/Task');
+App::uses('DbConfigTask', 'Console/Command/Task');
+App::uses('Model', 'Model');
+App::uses('Controller', 'Controller');
+
+/**
+ * Test View Task Comment Model
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ViewTaskComment extends Model {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'ViewTaskComment';
+
+/**
+ * Table name
+ *
+ * @var string
+ */
+ public $useTable = 'comments';
+
+/**
+ * Belongs To Associations
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Article' => array(
+ 'className' => 'TestTest.ViewTaskArticle',
+ 'foreignKey' => 'article_id'
+ )
+ );
+}
+
+/**
+ * Test View Task Article Model
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ViewTaskArticle extends Model {
+
+/**
+ * Model name
+ *
+ * @var string
+ */
+ public $name = 'ViewTaskArticle';
+
+/**
+ * Table name
+ *
+ * @var string
+ */
+ public $useTable = 'articles';
+}
+
+/**
+ * Test View Task Comments Controller
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ViewTaskCommentsController extends Controller {
+
+/**
+ * Controller name
+ *
+ * @var string
+ */
+ public $name = 'ViewTaskComments';
+
+/**
+ * Testing public controller action
+ *
+ * @return void
+ */
+ public function index() {
+ }
+
+/**
+ * Testing public controller action
+ *
+ * @return void
+ */
+ public function add() {
+ }
+
+}
+
+/**
+ * Test View Task Articles Controller
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ViewTaskArticlesController extends Controller {
+
+/**
+ * Controller name
+ *
+ * @var string
+ */
+ public $name = 'ViewTaskArticles';
+
+/**
+ * Test public controller action
+ *
+ * @return void
+ */
+ public function index() {
+ }
+
+/**
+ * Test public controller action
+ *
+ * @return void
+ */
+ public function add() {
+ }
+
+/**
+ * Test admin prefixed controller action
+ *
+ * @return void
+ */
+ public function admin_index() {
+ }
+
+/**
+ * Test admin prefixed controller action
+ *
+ * @return void
+ */
+ public function admin_add() {
+ }
+
+/**
+ * Test admin prefixed controller action
+ *
+ * @return void
+ */
+ public function admin_view() {
+ }
+
+/**
+ * Test admin prefixed controller action
+ *
+ * @return void
+ */
+ public function admin_edit() {
+ }
+
+/**
+ * Test admin prefixed controller action
+ *
+ * @return void
+ */
+ public function admin_delete() {
+ }
+
+}
+
+/**
+ * ViewTaskTest class
+ *
+ * @package Cake.Test.Case.Console.Command.Task
+ */
+class ViewTaskTest extends CakeTestCase {
+
+/**
+ * Fixtures
+ *
+ * @var array
+ */
+ public $fixtures = array('core.article', 'core.comment', 'core.articles_tag', 'core.tag');
+
+/**
+ * setUp method
+ *
+ * Ensure that the default theme is used
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Task = $this->getMock('ViewTask',
+ array('in', 'err', 'createFile', '_stop'),
+ array($out, $out, $in)
+ );
+ $this->Task->Template = new TemplateTask($out, $out, $in);
+ $this->Task->Controller = $this->getMock('ControllerTask', array(), array($out, $out, $in));
+ $this->Task->Project = $this->getMock('ProjectTask', array(), array($out, $out, $in));
+ $this->Task->DbConfig = $this->getMock('DbConfigTask', array(), array($out, $out, $in));
+
+ $this->Task->path = TMP;
+ $this->Task->Template->params['theme'] = 'default';
+ $this->Task->Template->templatePaths = array('default' => CAKE . 'Console' . DS . 'Templates' . DS . 'default' . DS);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Task, $this->Dispatch);
+ }
+
+/**
+ * Test getContent and parsing of Templates.
+ *
+ * @return void
+ */
+ public function testGetContent() {
+ $vars = array(
+ 'modelClass' => 'TestViewModel',
+ 'schema' => array(),
+ 'primaryKey' => 'id',
+ 'displayField' => 'name',
+ 'singularVar' => 'testViewModel',
+ 'pluralVar' => 'testViewModels',
+ 'singularHumanName' => 'Test View Model',
+ 'pluralHumanName' => 'Test View Models',
+ 'fields' => array('id', 'name', 'body'),
+ 'associations' => array()
+ );
+ $result = $this->Task->getContent('view', $vars);
+
+ $this->assertRegExp('/Delete Test View Model/', $result);
+ $this->assertRegExp('/Edit Test View Model/', $result);
+ $this->assertRegExp('/List Test View Models/', $result);
+ $this->assertRegExp('/New Test View Model/', $result);
+
+ $this->assertRegExp('/testViewModel\[\'TestViewModel\'\]\[\'id\'\]/', $result);
+ $this->assertRegExp('/testViewModel\[\'TestViewModel\'\]\[\'name\'\]/', $result);
+ $this->assertRegExp('/testViewModel\[\'TestViewModel\'\]\[\'body\'\]/', $result);
+ }
+
+/**
+ * test getContent() using an admin_prefixed action.
+ *
+ * @return void
+ */
+ public function testGetContentWithAdminAction() {
+ $_back = Configure::read('Routing');
+ Configure::write('Routing.prefixes', array('admin'));
+ $vars = array(
+ 'modelClass' => 'TestViewModel',
+ 'schema' => array(),
+ 'primaryKey' => 'id',
+ 'displayField' => 'name',
+ 'singularVar' => 'testViewModel',
+ 'pluralVar' => 'testViewModels',
+ 'singularHumanName' => 'Test View Model',
+ 'pluralHumanName' => 'Test View Models',
+ 'fields' => array('id', 'name', 'body'),
+ 'associations' => array()
+ );
+ $result = $this->Task->getContent('admin_view', $vars);
+
+ $this->assertRegExp('/Delete Test View Model/', $result);
+ $this->assertRegExp('/Edit Test View Model/', $result);
+ $this->assertRegExp('/List Test View Models/', $result);
+ $this->assertRegExp('/New Test View Model/', $result);
+
+ $this->assertRegExp('/testViewModel\[\'TestViewModel\'\]\[\'id\'\]/', $result);
+ $this->assertRegExp('/testViewModel\[\'TestViewModel\'\]\[\'name\'\]/', $result);
+ $this->assertRegExp('/testViewModel\[\'TestViewModel\'\]\[\'body\'\]/', $result);
+
+ $result = $this->Task->getContent('admin_add', $vars);
+ $this->assertRegExp("/input\('name'\)/", $result);
+ $this->assertRegExp("/input\('body'\)/", $result);
+ $this->assertRegExp('/List Test View Models/', $result);
+
+ Configure::write('Routing', $_back);
+ }
+
+/**
+ * test Bake method
+ *
+ * @return void
+ */
+ public function testBakeView() {
+ $this->Task->controllerName = 'ViewTaskComments';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'view.ctp',
+ $this->stringContains('View Task Articles')
+ );
+
+ $this->Task->bake('view', true);
+ }
+
+/**
+ * test baking an edit file
+ *
+ * @return void
+ */
+ public function testBakeEdit() {
+ $this->Task->controllerName = 'ViewTaskComments';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'edit.ctp',
+ new PHPUnit_Framework_Constraint_IsAnything()
+ );
+ $this->Task->bake('edit', true);
+ }
+
+/**
+ * test baking an index
+ *
+ * @return void
+ */
+ public function testBakeIndex() {
+ $this->Task->controllerName = 'ViewTaskComments';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'index.ctp',
+ $this->stringContains("\$viewTaskComment['Article']['title']")
+ );
+ $this->Task->bake('index', true);
+ }
+
+/**
+ * test that baking a view with no template doesn't make a file.
+ *
+ * @return void
+ */
+ public function testBakeWithNoTemplate() {
+ $this->Task->controllerName = 'ViewTaskComments';
+
+ $this->Task->expects($this->never())->method('createFile');
+ $this->Task->bake('delete', true);
+ }
+
+/**
+ * test bake() with a -plugin param
+ *
+ * @return void
+ */
+ public function testBakeWithPlugin() {
+ $this->Task->controllerName = 'ViewTaskComments';
+ $this->Task->plugin = 'TestTest';
+ $this->Task->name = 'View';
+
+ //fake plugin path
+ CakePlugin::load('TestTest', array('path' => APP . 'Plugin' . DS . 'TestTest' . DS));
+ $path = APP . 'Plugin' . DS . 'TestTest' . DS . 'View' . DS . 'ViewTaskComments' . DS . 'view.ctp';
+
+ $result = $this->Task->getContent('index');
+ $this->assertNotContains('List Test Test.view Task Articles', $result);
+
+ $this->Task->expects($this->once())
+ ->method('createFile')
+ ->with($path, $this->anything());
+
+ $this->Task->bake('view', true);
+ CakePlugin::unload();
+ }
+
+/**
+ * test bake actions baking multiple actions.
+ *
+ * @return void
+ */
+ public function testBakeActions() {
+ $this->Task->controllerName = 'ViewTaskComments';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'view.ctp',
+ $this->stringContains('View Task Comments')
+ );
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'edit.ctp',
+ $this->stringContains('Edit View Task Comment')
+ );
+ $this->Task->expects($this->at(2))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'index.ctp',
+ $this->stringContains('ViewTaskComment')
+ );
+
+ $this->Task->bakeActions(array('view', 'edit', 'index'), array());
+ }
+
+/**
+ * test baking a customAction (non crud)
+ *
+ * @return void
+ */
+ public function testCustomAction() {
+ $this->Task->controllerName = 'ViewTaskComments';
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('', 'my_action', 'y'));
+
+ $this->Task->expects($this->once())->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'my_action.ctp',
+ $this->anything()
+ );
+
+ $this->Task->customAction();
+ }
+
+/**
+ * Test all()
+ *
+ * @return void
+ */
+ public function testExecuteIntoAll() {
+ $this->Task->args[0] = 'all';
+
+ $this->Task->Controller->expects($this->once())->method('listAll')
+ ->will($this->returnValue(array('view_task_comments')));
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'index.ctp',
+ $this->anything()
+ );
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'add.ctp',
+ $this->anything()
+ );
+ $this->Task->expects($this->exactly(2))->method('createFile');
+
+ $this->Task->execute();
+ }
+
+/**
+ * Test all() with action parameter
+ *
+ * @return void
+ */
+ public function testExecuteIntoAllWithActionName() {
+ $this->Task->args = array('all', 'index');
+
+ $this->Task->Controller->expects($this->once())->method('listAll')
+ ->will($this->returnValue(array('view_task_comments')));
+
+ $this->Task->expects($this->once())->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'index.ctp',
+ $this->anything()
+ );
+
+ $this->Task->execute();
+ }
+
+/**
+ * test `cake bake view $controller view`
+ *
+ * @return void
+ */
+ public function testExecuteWithActionParam() {
+ $this->Task->args[0] = 'ViewTaskComments';
+ $this->Task->args[1] = 'view';
+
+ $this->Task->expects($this->once())->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'view.ctp',
+ $this->anything()
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test `cake bake view $controller`
+ * Ensure that views are only baked for actions that exist in the controller.
+ *
+ * @return void
+ */
+ public function testExecuteWithController() {
+ $this->Task->args[0] = 'ViewTaskComments';
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'index.ctp',
+ $this->anything()
+ );
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'add.ctp',
+ $this->anything()
+ );
+ $this->Task->expects($this->exactly(2))->method('createFile');
+
+ $this->Task->execute();
+ }
+
+/**
+ * static dataprovider for test cases
+ *
+ * @return void
+ */
+ public static function nameVariations() {
+ return array(array('ViewTaskComments'), array('ViewTaskComment'), array('view_task_comment'));
+ }
+
+/**
+ * test that both plural and singular forms can be used for baking views.
+ *
+ * @dataProvider nameVariations
+ * @return void
+ */
+ public function testExecuteWithControllerVariations($name) {
+ $this->Task->args = array($name);
+
+ $this->Task->expects($this->at(0))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'index.ctp',
+ $this->anything()
+ );
+ $this->Task->expects($this->at(1))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'add.ctp',
+ $this->anything()
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test `cake bake view $controller --admin`
+ * Which only bakes admin methods, not non-admin methods.
+ *
+ * @return void
+ */
+ public function testExecuteWithControllerAndAdminFlag() {
+ $_back = Configure::read('Routing');
+ Configure::write('Routing.prefixes', array('admin'));
+ $this->Task->args[0] = 'ViewTaskArticles';
+ $this->Task->params['admin'] = 1;
+
+ $this->Task->Project->expects($this->any())->method('getPrefix')->will($this->returnValue('admin_'));
+
+ $this->Task->expects($this->exactly(4))->method('createFile');
+
+ $views = array('admin_index.ctp', 'admin_add.ctp', 'admin_view.ctp', 'admin_edit.ctp');
+ foreach ($views as $i => $view) {
+ $this->Task->expects($this->at($i))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskArticles' . DS . $view,
+ $this->anything()
+ );
+ }
+ $this->Task->execute();
+ Configure::write('Routing', $_back);
+ }
+
+/**
+ * test execute into interactive.
+ *
+ * @return void
+ */
+ public function testExecuteInteractive() {
+ $this->Task->connection = 'test';
+ $this->Task->args = array();
+ $this->Task->params = array();
+
+ $this->Task->Controller->expects($this->once())->method('getName')
+ ->will($this->returnValue('ViewTaskComments'));
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('y', 'y', 'n'));
+
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'index.ctp',
+ $this->stringContains('ViewTaskComment')
+ );
+
+ $this->Task->expects($this->at(4))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'view.ctp',
+ $this->stringContains('ViewTaskComment')
+ );
+
+ $this->Task->expects($this->at(5))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'add.ctp',
+ $this->stringContains('Add View Task Comment')
+ );
+
+ $this->Task->expects($this->at(6))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'edit.ctp',
+ $this->stringContains('Edit View Task Comment')
+ );
+
+ $this->Task->expects($this->exactly(4))->method('createFile');
+ $this->Task->execute();
+ }
+
+/**
+ * test `cake bake view posts index list`
+ *
+ * @return void
+ */
+ public function testExecuteWithAlternateTemplates() {
+ $this->Task->connection = 'test';
+ $this->Task->args = array('ViewTaskComments', 'index', 'list');
+ $this->Task->params = array();
+
+ $this->Task->expects($this->once())->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'list.ctp',
+ $this->stringContains('ViewTaskComment')
+ );
+ $this->Task->execute();
+ }
+
+/**
+ * test execute into interactive() with admin methods.
+ *
+ * @return void
+ */
+ public function testExecuteInteractiveWithAdmin() {
+ Configure::write('Routing.prefixes', array('admin'));
+ $this->Task->connection = 'test';
+ $this->Task->args = array();
+
+ $this->Task->Controller->expects($this->once())->method('getName')
+ ->will($this->returnValue('ViewTaskComments'));
+
+ $this->Task->Project->expects($this->once())->method('getPrefix')
+ ->will($this->returnValue('admin_'));
+
+ $this->Task->expects($this->any())->method('in')
+ ->will($this->onConsecutiveCalls('y', 'n', 'y'));
+
+ $this->Task->expects($this->at(3))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'admin_index.ctp',
+ $this->stringContains('ViewTaskComment')
+ );
+
+ $this->Task->expects($this->at(4))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'admin_view.ctp',
+ $this->stringContains('ViewTaskComment')
+ );
+
+ $this->Task->expects($this->at(5))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'admin_add.ctp',
+ $this->stringContains('Add View Task Comment')
+ );
+
+ $this->Task->expects($this->at(6))->method('createFile')
+ ->with(
+ TMP . 'ViewTaskComments' . DS . 'admin_edit.ctp',
+ $this->stringContains('Edit View Task Comment')
+ );
+
+ $this->Task->expects($this->exactly(4))->method('createFile');
+ $this->Task->execute();
+ }
+
+/**
+ * test getting templates, make sure noTemplateActions works and prefixed template is used before generic one.
+ *
+ * @return void
+ */
+ public function testGetTemplate() {
+ $result = $this->Task->getTemplate('delete');
+ $this->assertFalse($result);
+
+ $result = $this->Task->getTemplate('add');
+ $this->assertEquals('form', $result);
+
+ Configure::write('Routing.prefixes', array('admin'));
+
+ $result = $this->Task->getTemplate('admin_add');
+ $this->assertEquals('form', $result);
+
+ $this->Task->Template->templatePaths = array(
+ 'test' => CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS . 'Templates' . DS . 'test' . DS
+ );
+ $this->Task->Template->params['theme'] = 'test';
+
+ $result = $this->Task->getTemplate('admin_edit');
+ $this->assertEquals('admin_edit', $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/TestShellTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/TestShellTest.php
new file mode 100644
index 0000000..5d08c58
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/Command/TestShellTest.php
@@ -0,0 +1,335 @@
+<?php
+/**
+ * TestSuiteShell test case
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('TestShell', 'Console/Command');
+
+class TestTestShell extends TestShell {
+
+ public function mapFileToCase($file, $category, $throwOnMissingFile = true) {
+ return $this->_mapFileToCase($file, $category, $throwOnMissingFile);
+ }
+
+ public function mapFileToCategory($file) {
+ return $this->_mapFileToCategory($file);
+ }
+
+}
+
+class TestShellTest extends CakeTestCase {
+
+/**
+ * setUp test case
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $out = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+
+ $this->Shell = $this->getMock(
+ 'TestTestShell',
+ array('in', 'out', 'hr', 'help', 'error', 'err', '_stop', 'initialize', '_run', 'clear'),
+ array($out, $out, $in)
+ );
+ $this->Shell->OptionParser = $this->getMock('ConsoleOptionParser', array(), array(null, false));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Dispatch, $this->Shell);
+ }
+
+/**
+ * testMapCoreFileToCategory
+ *
+ * @return void
+ */
+ public function testMapCoreFileToCategory() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCategory('lib/Cake/basics.php');
+ $this->assertSame('core', $return);
+
+ $return = $this->Shell->mapFileToCategory('lib/Cake/Core/App.php');
+ $this->assertSame('core', $return);
+
+ $return = $this->Shell->mapFileToCategory('lib/Cake/Some/Deeply/Nested/Structure.php');
+ $this->assertSame('core', $return);
+ }
+
+/**
+ * testMapCoreFileToCase
+ *
+ * basics.php is a slightly special case - it's the only file in the core with a test that isn't Capitalized
+ *
+ * @return void
+ */
+ public function testMapCoreFileToCase() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCase('lib/Cake/basics.php', 'core');
+ $this->assertSame('Basics', $return);
+
+ $return = $this->Shell->mapFileToCase('lib/Cake/Core/App.php', 'core');
+ $this->assertSame('Core/App', $return);
+
+ $return = $this->Shell->mapFileToCase('lib/Cake/Some/Deeply/Nested/Structure.php', 'core', false);
+ $this->assertSame('Some/Deeply/Nested/Structure', $return);
+ }
+
+/**
+ * testMapAppFileToCategory
+ *
+ * @return void
+ */
+ public function testMapAppFileToCategory() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCategory(APP . 'Controller/ExampleController.php');
+ $this->assertSame('app', $return);
+
+ $return = $this->Shell->mapFileToCategory(APP . 'My/File/Is/Here.php');
+ $this->assertSame('app', $return);
+ }
+
+/**
+ * testMapAppFileToCase
+ *
+ * @return void
+ */
+ public function testMapAppFileToCase() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCase(APP . 'Controller/ExampleController.php', 'app', false);
+ $this->assertSame('Controller/ExampleController', $return);
+
+ $return = $this->Shell->mapFileToCase(APP . 'My/File/Is/Here.php', 'app', false);
+ $this->assertSame('My/File/Is/Here', $return);
+ }
+
+/**
+ * testMapPluginFileToCategory
+ *
+ * @return void
+ */
+ public function testMapPluginFileToCategory() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCategory(APP . 'Plugin/awesome/Controller/ExampleController.php');
+ $this->assertSame('awesome', $return);
+
+ $return = $this->Shell->mapFileToCategory(dirname(CAKE) . 'plugins/awesome/Controller/ExampleController.php');
+ $this->assertSame('awesome', $return);
+ }
+
+/**
+ * testMapPluginFileToCase
+ *
+ * @return void
+ */
+ public function testMapPluginFileToCase() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCase(APP . 'Plugin/awesome/Controller/ExampleController.php', 'awesome', false);
+ $this->assertSame('Controller/ExampleController', $return);
+
+ $return = $this->Shell->mapFileToCase(dirname(CAKE) . 'plugins/awesome/Controller/ExampleController.php', 'awesome', false);
+ $this->assertSame('Controller/ExampleController', $return);
+ }
+
+/**
+ * testMapCoreTestToCategory
+ *
+ * @return void
+ */
+ public function testMapCoreTestToCategory() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCategory('lib/Cake/Test/Case/BasicsTest.php');
+ $this->assertSame('core', $return);
+
+ $return = $this->Shell->mapFileToCategory('lib/Cake/Test/Case/BasicsTest.php');
+ $this->assertSame('core', $return);
+
+ $return = $this->Shell->mapFileToCategory('lib/Cake/Test/Case/Some/Deeply/Nested/StructureTest.php');
+ $this->assertSame('core', $return);
+ }
+
+/**
+ * testMapCoreTestToCase
+ *
+ * basics.php is a slightly special case - it's the only file in the core with a test that isn't Capitalized
+ *
+ * @return void
+ */
+ public function testMapCoreTestToCase() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCase('lib/Cake/Test/Case/BasicsTest.php', 'core');
+ $this->assertSame('Basics', $return);
+
+ $return = $this->Shell->mapFileToCase('lib/Cake/Test/Case/Core/AppTest.php', 'core');
+ $this->assertSame('Core/App', $return);
+
+ $return = $this->Shell->mapFileToCase('lib/Cake/Test/Case/Some/Deeply/Nested/StructureTest.php', 'core', false);
+ $this->assertSame('Some/Deeply/Nested/Structure', $return);
+ }
+
+/**
+ * testMapAppTestToCategory
+ *
+ * @return void
+ */
+ public function testMapAppTestToCategory() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCategory(APP . 'Test/Case/Controller/ExampleControllerTest.php');
+ $this->assertSame('app', $return);
+
+ $return = $this->Shell->mapFileToCategory(APP . 'Test/Case/My/File/Is/HereTest.php');
+ $this->assertSame('app', $return);
+ }
+
+/**
+ * testMapAppTestToCase
+ *
+ * @return void
+ */
+ public function testMapAppTestToCase() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCase(APP . 'Test/Case/Controller/ExampleControllerTest.php', 'app', false);
+ $this->assertSame('Controller/ExampleController', $return);
+
+ $return = $this->Shell->mapFileToCase(APP . 'Test/Case/My/File/Is/HereTest.php', 'app', false);
+ $this->assertSame('My/File/Is/Here', $return);
+ }
+
+/**
+ * testMapPluginTestToCategory
+ *
+ * @return void
+ */
+ public function testMapPluginTestToCategory() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCategory(APP . 'Plugin/awesome/Test/Case/Controller/ExampleControllerTest.php');
+ $this->assertSame('awesome', $return);
+
+ $return = $this->Shell->mapFileToCategory(dirname(CAKE) . 'plugins/awesome/Test/Case/Controller/ExampleControllerTest.php');
+ $this->assertSame('awesome', $return);
+ }
+
+/**
+ * testMapPluginTestToCase
+ *
+ * @return void
+ */
+ public function testMapPluginTestToCase() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCase(APP . 'Plugin/awesome/Test/Case/Controller/ExampleControllerTest.php', 'awesome', false);
+ $this->assertSame('Controller/ExampleController', $return);
+
+ $return = $this->Shell->mapFileToCase(dirname(CAKE) . 'plugins/awesome/Test/Case/Controller/ExampleControllerTest.php', 'awesome', false);
+ $this->assertSame('Controller/ExampleController', $return);
+ }
+
+/**
+ * testMapNotTestToNothing
+ *
+ * @return void
+ */
+ public function testMapNotTestToNothing() {
+ $this->Shell->startup();
+
+ $return = $this->Shell->mapFileToCategory(APP . 'Test/Case/NotATestFile.php');
+ $this->assertSame('app', $return);
+
+ $return = $this->Shell->mapFileToCase(APP . 'Test/Case/NotATestFile.php', false, false);
+ $this->assertFalse($return);
+
+ $return = $this->Shell->mapFileToCategory(APP . 'Test/Fixture/SomeTest.php');
+ $this->assertSame('app', $return);
+
+ $return = $this->Shell->mapFileToCase(APP . 'Test/Fixture/SomeTest.php', false, false);
+ $this->assertFalse($return);
+ }
+
+/**
+ * test available list of test cases for an empty category
+ *
+ * @return void
+ */
+ public function testAvailableWithEmptyList() {
+ $this->Shell->startup();
+ $this->Shell->args = array('unexistant-category');
+ $this->Shell->expects($this->at(0))->method('out')->with(__d('cake_console', "No test cases available \n\n"));
+ $this->Shell->OptionParser->expects($this->once())->method('help');
+ $this->Shell->available();
+ }
+
+/**
+ * test available list of test cases for core category
+ *
+ * @return void
+ */
+ public function testAvailableCoreCategory() {
+ $this->Shell->startup();
+ $this->Shell->args = array('core');
+ $this->Shell->expects($this->at(0))->method('out')->with('Core Test Cases:');
+ $this->Shell->expects($this->at(1))->method('out')
+ ->with($this->stringContains('[1]'));
+ $this->Shell->expects($this->at(2))->method('out')
+ ->with($this->stringContains('[2]'));
+
+ $this->Shell->expects($this->once())->method('in')
+ ->with(__d('cake_console', 'What test case would you like to run?'), null, 'q')
+ ->will($this->returnValue('1'));
+
+ $this->Shell->expects($this->once())->method('_run');
+ $this->Shell->available();
+ $this->assertEquals(array('core', 'AllBehaviors'), $this->Shell->args);
+ }
+
+/**
+ * Tests that correct option for test runner are passed
+ *
+ * @return void
+ */
+ public function testRunnerOptions() {
+ $this->Shell->startup();
+ $this->Shell->args = array('core', 'Basics');
+ $this->Shell->params = array('filter' => 'myFilter', 'colors' => true, 'verbose' => true);
+
+ $this->Shell->expects($this->once())->method('_run')
+ ->with(
+ array('app' => false, 'plugin' => null, 'core' => true, 'output' => 'text', 'case' => 'Basics'),
+ array('--filter', 'myFilter', '--colors', '--verbose')
+ );
+ $this->Shell->main();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php
new file mode 100644
index 0000000..ef24dcb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleErrorHandlerTest.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * ConsoleErrorHandler Test case
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleErrorHandler', 'Console');
+
+/**
+ * ConsoleErrorHandler Test case.
+ *
+ * @package Cake.Test.Case.Console
+ */
+class ConsoleErrorHandlerTest extends CakeTestCase {
+
+/**
+ * setup, create mocks
+ *
+ * @return Mock object
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Error = $this->getMock('ConsoleErrorHandler', array('_stop'));
+ ConsoleErrorHandler::$stderr = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->Error);
+ parent::tearDown();
+ }
+
+/**
+ * test that the console error handler can deal with CakeExceptions.
+ *
+ * @return void
+ */
+ public function testHandleError() {
+ $content = "<error>Notice Error:</error> This is a notice error in [/some/file, line 275]\n";
+ ConsoleErrorHandler::$stderr->expects($this->once())->method('write')
+ ->with($content);
+
+ $this->Error->handleError(E_NOTICE, 'This is a notice error', '/some/file', 275);
+ }
+
+/**
+ * test that the console error handler can deal with CakeExceptions.
+ *
+ * @return void
+ */
+ public function testCakeErrors() {
+ $exception = new MissingActionException('Missing action');
+ ConsoleErrorHandler::$stderr->expects($this->once())->method('write')
+ ->with($this->stringContains('Missing action'));
+
+ $this->Error->expects($this->once())
+ ->method('_stop')
+ ->with(404);
+
+ $this->Error->handleException($exception);
+ }
+
+/**
+ * test a non CakeException exception.
+ *
+ * @return void
+ */
+ public function testNonCakeExceptions() {
+ $exception = new InvalidArgumentException('Too many parameters.');
+
+ ConsoleErrorHandler::$stderr->expects($this->once())->method('write')
+ ->with($this->stringContains('Too many parameters.'));
+
+ $this->Error->expects($this->once())
+ ->method('_stop')
+ ->with(1);
+
+ $this->Error->handleException($exception);
+ }
+
+/**
+ * test a Error404 exception.
+ *
+ * @return void
+ */
+ public function testError404Exception() {
+ $exception = new NotFoundException('dont use me in cli.');
+
+ ConsoleErrorHandler::$stderr->expects($this->once())->method('write')
+ ->with($this->stringContains('dont use me in cli.'));
+
+ $this->Error->expects($this->once())
+ ->method('_stop')
+ ->with(404);
+
+ $this->Error->handleException($exception);
+ }
+
+/**
+ * test a Error500 exception.
+ *
+ * @return void
+ */
+ public function testError500Exception() {
+ $exception = new InternalErrorException('dont use me in cli.');
+
+ ConsoleErrorHandler::$stderr->expects($this->once())->method('write')
+ ->with($this->stringContains('dont use me in cli.'));
+
+ $this->Error->expects($this->once())
+ ->method('_stop')
+ ->with(500);
+
+ $this->Error->handleException($exception);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOptionParserTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOptionParserTest.php
new file mode 100644
index 0000000..0677b09
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOptionParserTest.php
@@ -0,0 +1,594 @@
+<?php
+/**
+ * ConsoleOptionParserTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleOptionParser', 'Console');
+
+class ConsoleOptionParserTest extends CakeTestCase {
+
+/**
+ * test setting the console description
+ *
+ * @return void
+ */
+ public function testDescription() {
+ $parser = new ConsoleOptionParser('test', false);
+ $result = $parser->description('A test');
+
+ $this->assertEquals($parser, $result, 'Setting description is not chainable');
+ $this->assertEquals('A test', $parser->description(), 'getting value is wrong.');
+
+ $result = $parser->description(array('A test', 'something'));
+ $this->assertEquals("A test\nsomething", $parser->description(), 'getting value is wrong.');
+ }
+
+/**
+ * test setting the console epilog
+ *
+ * @return void
+ */
+ public function testEpilog() {
+ $parser = new ConsoleOptionParser('test', false);
+ $result = $parser->epilog('A test');
+
+ $this->assertEquals($parser, $result, 'Setting epilog is not chainable');
+ $this->assertEquals('A test', $parser->epilog(), 'getting value is wrong.');
+
+ $result = $parser->epilog(array('A test', 'something'));
+ $this->assertEquals("A test\nsomething", $parser->epilog(), 'getting value is wrong.');
+ }
+
+/**
+ * test adding an option returns self.
+ *
+ * @return void
+ */
+ public function testAddOptionReturnSelf() {
+ $parser = new ConsoleOptionParser('test', false);
+ $result = $parser->addOption('test');
+ $this->assertEquals($parser, $result, 'Did not return $this from addOption');
+ }
+
+/**
+ * test adding an option and using the long value for parsing.
+ *
+ * @return void
+ */
+ public function testAddOptionLong() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array(
+ 'short' => 't'
+ ));
+ $result = $parser->parse(array('--test', 'value'));
+ $this->assertEquals(array('test' => 'value', 'help' => false), $result[0], 'Long parameter did not parse out');
+ }
+
+/**
+ * test addOption with an object.
+ *
+ * @return void
+ */
+ public function testAddOptionObject() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption(new ConsoleInputOption('test', 't'));
+ $result = $parser->parse(array('--test=value'));
+ $this->assertEquals(array('test' => 'value', 'help' => false), $result[0], 'Long parameter did not parse out');
+ }
+
+/**
+ * test adding an option and using the long value for parsing.
+ *
+ * @return void
+ */
+ public function testAddOptionLongEquals() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array(
+ 'short' => 't'
+ ));
+ $result = $parser->parse(array('--test=value'));
+ $this->assertEquals(array('test' => 'value', 'help' => false), $result[0], 'Long parameter did not parse out');
+ }
+
+/**
+ * test adding an option and using the default.
+ *
+ * @return void
+ */
+ public function testAddOptionDefault() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array(
+ 'default' => 'default value',
+ ));
+ $result = $parser->parse(array('--test'));
+ $this->assertEquals(array('test' => 'default value', 'help' => false), $result[0], 'Default value did not parse out');
+
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array(
+ 'default' => 'default value',
+ ));
+ $result = $parser->parse(array());
+ $this->assertEquals(array('test' => 'default value', 'help' => false), $result[0], 'Default value did not parse out');
+ }
+
+/**
+ * test adding an option and using the short value for parsing.
+ *
+ * @return void
+ */
+ public function testAddOptionShort() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array(
+ 'short' => 't'
+ ));
+ $result = $parser->parse(array('-t', 'value'));
+ $this->assertEquals(array('test' => 'value', 'help' => false), $result[0], 'Short parameter did not parse out');
+ }
+
+/**
+ * Test that adding an option using a two letter short value causes an exception.
+ * As they will not parse correctly.
+ *
+ * @expectedException ConsoleException
+ * @return void
+ */
+ public function testAddOptionShortOneLetter() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array('short' => 'te'));
+ }
+
+/**
+ * test adding and using boolean options.
+ *
+ * @return void
+ */
+ public function testAddOptionBoolean() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array(
+ 'boolean' => true,
+ ));
+
+ $result = $parser->parse(array('--test', 'value'));
+ $expected = array(array('test' => true, 'help' => false), array('value'));
+ $this->assertEquals($expected, $result);
+
+ $result = $parser->parse(array('value'));
+ $expected = array(array('test' => false, 'help' => false), array('value'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test adding an multiple shorts.
+ *
+ * @return void
+ */
+ public function testAddOptionMultipleShort() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test', array('short' => 't', 'boolean' => true))
+ ->addOption('file', array('short' => 'f', 'boolean' => true))
+ ->addOption('output', array('short' => 'o', 'boolean' => true));
+
+ $result = $parser->parse(array('-o', '-t', '-f'));
+ $expected = array('file' => true, 'test' => true, 'output' => true, 'help' => false);
+ $this->assertEquals($expected, $result[0], 'Short parameter did not parse out');
+
+ $result = $parser->parse(array('-otf'));
+ $this->assertEquals($expected, $result[0], 'Short parameter did not parse out');
+ }
+
+/**
+ * test multiple options at once.
+ *
+ * @return void
+ */
+ public function testMultipleOptions() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('test')
+ ->addOption('connection')
+ ->addOption('table', array('short' => 't', 'default' => true));
+
+ $result = $parser->parse(array('--test', 'value', '-t', '--connection', 'postgres'));
+ $expected = array('test' => 'value', 'table' => true, 'connection' => 'postgres', 'help' => false);
+ $this->assertEquals($expected, $result[0], 'multiple options did not parse');
+ }
+
+/**
+ * Test adding multiple options.
+ *
+ * @return void
+ */
+ public function testAddOptions() {
+ $parser = new ConsoleOptionParser('something', false);
+ $result = $parser->addOptions(array(
+ 'name' => array('help' => 'The name'),
+ 'other' => array('help' => 'The other arg')
+ ));
+ $this->assertEquals($parser, $result, 'addOptions is not chainable.');
+
+ $result = $parser->options();
+ $this->assertEquals(3, count($result), 'Not enough options');
+ }
+
+/**
+ * test that boolean options work
+ *
+ * @return void
+ */
+ public function testOptionWithBooleanParam() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('no-commit', array('boolean' => true))
+ ->addOption('table', array('short' => 't'));
+
+ $result = $parser->parse(array('--table', 'posts', '--no-commit', 'arg1', 'arg2'));
+ $expected = array(array('table' => 'posts', 'no-commit' => true, 'help' => false), array('arg1', 'arg2'));
+ $this->assertEquals($expected, $result, 'Boolean option did not parse correctly.');
+ }
+
+/**
+ * test parsing options that do not exist.
+ *
+ * @expectedException ConsoleException
+ */
+ public function testOptionThatDoesNotExist() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('no-commit', array('boolean' => true));
+
+ $result = $parser->parse(array('--fail', 'other'));
+ }
+
+/**
+ * test parsing short options that do not exist.
+ *
+ * @expectedException ConsoleException
+ */
+ public function testShortOptionThatDoesNotExist() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('no-commit', array('boolean' => true));
+
+ $result = $parser->parse(array('-f'));
+ }
+
+/**
+ * test that options with choices enforce them.
+ *
+ * @expectedException ConsoleException
+ * @return void
+ */
+ public function testOptionWithChoices() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('name', array('choices' => array('mark', 'jose')));
+
+ $result = $parser->parse(array('--name', 'mark'));
+ $expected = array('name' => 'mark', 'help' => false);
+ $this->assertEquals($expected, $result[0], 'Got the correct value.');
+
+ $result = $parser->parse(array('--name', 'jimmy'));
+ }
+
+/**
+ * Ensure that option values can start with -
+ *
+ * @return void
+ */
+ public function testOptionWithValueStartingWithMinus() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('name')
+ ->addOption('age');
+
+ $result = $parser->parse(array('--name', '-foo', '--age', 'old'));
+ $expected = array('name' => '-foo', 'age' => 'old', 'help' => false);
+ $this->assertEquals($expected, $result[0], 'Option values starting with "-" are broken.');
+ }
+
+/**
+ * test positional argument parsing.
+ *
+ * @return void
+ */
+ public function testPositionalArgument() {
+ $parser = new ConsoleOptionParser('test', false);
+ $result = $parser->addArgument('name', array('help' => 'An argument'));
+ $this->assertEquals($parser, $result, 'Should return this');
+ }
+
+/**
+ * test addOption with an object.
+ *
+ * @return void
+ */
+ public function testAddArgumentObject() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addArgument(new ConsoleInputArgument('test'));
+ $result = $parser->arguments();
+ $this->assertEquals(1, count($result));
+ $this->assertEquals('test', $result[0]->name());
+ }
+
+/**
+ * test overwriting positional arguments.
+ *
+ * @return void
+ */
+ public function testPositionalArgOverwrite() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addArgument('name', array('help' => 'An argument'))
+ ->addArgument('other', array('index' => 0));
+
+ $result = $parser->arguments();
+ $this->assertEquals(1, count($result), 'Overwrite did not occur');
+ }
+
+/**
+ * test parsing arguments.
+ *
+ * @expectedException ConsoleException
+ * @return void
+ */
+ public function testParseArgumentTooMany() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addArgument('name', array('help' => 'An argument'))
+ ->addArgument('other');
+
+ $expected = array('one', 'two');
+ $result = $parser->parse($expected);
+ $this->assertEquals($expected, $result[1], 'Arguments are not as expected');
+
+ $result = $parser->parse(array('one', 'two', 'three'));
+ }
+
+/**
+ * test parsing arguments with 0 value.
+ *
+ * @return void
+ */
+ public function testParseArgumentZero() {
+ $parser = new ConsoleOptionParser('test', false);
+
+ $expected = array('one', 'two', 0, 'after', 'zero');
+ $result = $parser->parse($expected);
+ $this->assertEquals($expected, $result[1], 'Arguments are not as expected');
+ }
+
+/**
+ * test that when there are not enough arguments an exception is raised
+ *
+ * @expectedException ConsoleException
+ * @return void
+ */
+ public function testPositionalArgNotEnough() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addArgument('name', array('required' => true))
+ ->addArgument('other', array('required' => true));
+
+ $parser->parse(array('one'));
+ }
+
+/**
+ * test that arguments with choices enforce them.
+ *
+ * @expectedException ConsoleException
+ * @return void
+ */
+ public function testPositionalArgWithChoices() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addArgument('name', array('choices' => array('mark', 'jose')))
+ ->addArgument('alias', array('choices' => array('cowboy', 'samurai')))
+ ->addArgument('weapon', array('choices' => array('gun', 'sword')));
+
+ $result = $parser->parse(array('mark', 'samurai', 'sword'));
+ $expected = array('mark', 'samurai', 'sword');
+ $this->assertEquals($expected, $result[1], 'Got the correct value.');
+
+ $result = $parser->parse(array('jose', 'coder'));
+ }
+
+/**
+ * Test adding multiple arguments.
+ *
+ * @return void
+ */
+ public function testAddArguments() {
+ $parser = new ConsoleOptionParser('test', false);
+ $result = $parser->addArguments(array(
+ 'name' => array('help' => 'The name'),
+ 'other' => array('help' => 'The other arg')
+ ));
+ $this->assertEquals($parser, $result, 'addArguments is not chainable.');
+
+ $result = $parser->arguments();
+ $this->assertEquals(2, count($result), 'Not enough arguments');
+ }
+
+/**
+ * test setting a subcommand up.
+ *
+ * @return void
+ */
+ public function testSubcommand() {
+ $parser = new ConsoleOptionParser('test', false);
+ $result = $parser->addSubcommand('initdb', array(
+ 'help' => 'Initialize the database'
+ ));
+ $this->assertEquals($parser, $result, 'Adding a subcommand is not chainable');
+ }
+
+/**
+ * test addSubcommand with an object.
+ *
+ * @return void
+ */
+ public function testAddSubcommandObject() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addSubcommand(new ConsoleInputSubcommand('test'));
+ $result = $parser->subcommands();
+ $this->assertEquals(1, count($result));
+ $this->assertEquals('test', $result['test']->name());
+ }
+
+/**
+ * test adding multiple subcommands
+ *
+ * @return void
+ */
+ public function testAddSubcommands() {
+ $parser = new ConsoleOptionParser('test', false);
+ $result = $parser->addSubcommands(array(
+ 'initdb' => array('help' => 'Initialize the database'),
+ 'create' => array('help' => 'Create something')
+ ));
+ $this->assertEquals($parser, $result, 'Adding a subcommands is not chainable');
+ $result = $parser->subcommands();
+ $this->assertEquals(2, count($result), 'Not enough subcommands');
+ }
+
+/**
+ * test that no exception is triggered when help is being generated
+ *
+ * @return void
+ */
+ public function testHelpNoExceptionWhenGettingHelp() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true));
+
+ $result = $parser->parse(array('--help'));
+ $this->assertTrue($result[0]['help']);
+ }
+
+/**
+ * test that help() with a command param shows the help for a subcommand
+ *
+ * @return void
+ */
+ public function testHelpSubcommandHelp() {
+ $subParser = new ConsoleOptionParser('method', false);
+ $subParser->addOption('connection', array('help' => 'Db connection.'));
+
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addSubcommand('method', array(
+ 'help' => 'This is another command',
+ 'parser' => $subParser
+ ))
+ ->addOption('test', array('help' => 'A test option.'));
+
+ $result = $parser->help('method');
+ $expected = <<<TEXT
+<info>Usage:</info>
+cake mycommand method [-h] [--connection]
+
+<info>Options:</info>
+
+--help, -h Display this help.
+--connection Db connection.
+
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Help is not correct.');
+ }
+
+/**
+ * test building a parser from an array.
+ *
+ * @return void
+ */
+ public function testBuildFromArray() {
+ $spec = array(
+ 'command' => 'test',
+ 'arguments' => array(
+ 'name' => array('help' => 'The name'),
+ 'other' => array('help' => 'The other arg')
+ ),
+ 'options' => array(
+ 'name' => array('help' => 'The name'),
+ 'other' => array('help' => 'The other arg')
+ ),
+ 'subcommands' => array(
+ 'initdb' => array('help' => 'make database')
+ ),
+ 'description' => 'description text',
+ 'epilog' => 'epilog text'
+ );
+ $parser = ConsoleOptionParser::buildFromArray($spec);
+
+ $this->assertEquals($spec['description'], $parser->description());
+ $this->assertEquals($spec['epilog'], $parser->epilog());
+
+ $options = $parser->options();
+ $this->assertTrue(isset($options['name']));
+ $this->assertTrue(isset($options['other']));
+
+ $args = $parser->arguments();
+ $this->assertEquals(2, count($args));
+
+ $commands = $parser->subcommands();
+ $this->assertEquals(1, count($commands));
+ }
+
+/**
+ * test that create() returns instances
+ *
+ * @return void
+ */
+ public function testCreateFactory() {
+ $parser = ConsoleOptionParser::create('factory', false);
+ $this->assertInstanceOf('ConsoleOptionParser', $parser);
+ $this->assertEquals('factory', $parser->command());
+ }
+
+/**
+ * test that command() inflects the command name.
+ *
+ * @return void
+ */
+ public function testCommandInflection() {
+ $parser = new ConsoleOptionParser('CommandLine');
+ $this->assertEquals('command_line', $parser->command());
+ }
+
+/**
+ * test that parse() takes a subcommand argument, and that the subcommand parser
+ * is used.
+ *
+ * @return void
+ */
+ public function testParsingWithSubParser() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->addOption('primary')
+ ->addArgument('one', array('required' => true, 'choices' => array('a', 'b')))
+ ->addArgument('two', array('required' => true))
+ ->addSubcommand('sub', array(
+ 'parser' => array(
+ 'options' => array(
+ 'secondary' => array('boolean' => true),
+ 'fourth' => array('help' => 'fourth option')
+ ),
+ 'arguments' => array(
+ 'sub_arg' => array('choices' => array('c', 'd'))
+ )
+ )
+ ));
+
+ $result = $parser->parse(array('--secondary', '--fourth', '4', 'c'), 'sub');
+ $expected = array(array(
+ 'secondary' => true,
+ 'fourth' => '4',
+ 'help' => false,
+ 'verbose' => false,
+ 'quiet' => false), array('c'));
+ $this->assertEquals($expected, $result, 'Sub parser did not parse request.');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOutputTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOutputTest.php
new file mode 100644
index 0000000..a9cd056
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ConsoleOutputTest.php
@@ -0,0 +1,242 @@
+<?php
+/**
+ * ConsoleOutputTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleOutput', 'Console');
+
+class ConsoleOutputTest extends CakeTestCase {
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->output = $this->getMock('ConsoleOutput', array('_write'));
+ $this->output->outputAs(ConsoleOutput::COLOR);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->output);
+ }
+
+/**
+ * test writing with no new line
+ *
+ * @return void
+ */
+ public function testWriteNoNewLine() {
+ $this->output->expects($this->once())->method('_write')
+ ->with('Some output');
+
+ $this->output->write('Some output', false);
+ }
+
+/**
+ * test writing with no new line
+ *
+ * @return void
+ */
+ public function testWriteNewLine() {
+ $this->output->expects($this->once())->method('_write')
+ ->with('Some output' . PHP_EOL);
+
+ $this->output->write('Some output');
+ }
+
+/**
+ * test write() with multiple new lines
+ *
+ * @return void
+ */
+ public function testWriteMultipleNewLines() {
+ $this->output->expects($this->once())->method('_write')
+ ->with('Some output' . PHP_EOL . PHP_EOL . PHP_EOL . PHP_EOL);
+
+ $this->output->write('Some output', 4);
+ }
+
+/**
+ * test writing an array of messages.
+ *
+ * @return void
+ */
+ public function testWriteArray() {
+ $this->output->expects($this->once())->method('_write')
+ ->with('Line' . PHP_EOL . 'Line' . PHP_EOL . 'Line' . PHP_EOL);
+
+ $this->output->write(array('Line', 'Line', 'Line'));
+ }
+
+/**
+ * test getting a style.
+ *
+ * @return void
+ */
+ public function testStylesGet() {
+ $result = $this->output->styles('error');
+ $expected = array('text' => 'red', 'underline' => true);
+ $this->assertEquals($expected, $result);
+
+ $this->assertNull($this->output->styles('made_up_goop'));
+
+ $result = $this->output->styles();
+ $this->assertNotEmpty($result, 'error', 'Error is missing');
+ $this->assertNotEmpty($result, 'warning', 'Warning is missing');
+ }
+
+/**
+ * test adding a style.
+ *
+ * @return void
+ */
+ public function testStylesAdding() {
+ $this->output->styles('test', array('text' => 'red', 'background' => 'black'));
+ $result = $this->output->styles('test');
+ $expected = array('text' => 'red', 'background' => 'black');
+ $this->assertEquals($expected, $result);
+
+ $this->assertTrue($this->output->styles('test', false), 'Removing a style should return true.');
+ $this->assertNull($this->output->styles('test'), 'Removed styles should be null.');
+ }
+
+/**
+ * test formatting text with styles.
+ *
+ * @return void
+ */
+ public function testFormattingSimple() {
+ $this->output->expects($this->once())->method('_write')
+ ->with("\033[31;4mError:\033[0m Something bad");
+
+ $this->output->write('<error>Error:</error> Something bad', false);
+ }
+
+/**
+ * test that formatting doesn't eat tags it doesn't know about.
+ *
+ * @return void
+ */
+ public function testFormattingNotEatingTags() {
+ $this->output->expects($this->once())->method('_write')
+ ->with("<red> Something bad");
+
+ $this->output->write('<red> Something bad', false);
+ }
+
+/**
+ * test formatting with custom styles.
+ *
+ * @return void
+ */
+ public function testFormattingCustom() {
+ $this->output->styles('annoying', array(
+ 'text' => 'magenta',
+ 'background' => 'cyan',
+ 'blink' => true,
+ 'underline' => true
+ ));
+
+ $this->output->expects($this->once())->method('_write')
+ ->with("\033[35;46;5;4mAnnoy:\033[0m Something bad");
+
+ $this->output->write('<annoying>Annoy:</annoying> Something bad', false);
+ }
+
+/**
+ * test formatting text with missing styles.
+ *
+ * @return void
+ */
+ public function testFormattingMissingStyleName() {
+ $this->output->expects($this->once())->method('_write')
+ ->with("<not_there>Error:</not_there> Something bad");
+
+ $this->output->write('<not_there>Error:</not_there> Something bad', false);
+ }
+
+/**
+ * test formatting text with multiple styles.
+ *
+ * @return void
+ */
+ public function testFormattingMultipleStylesName() {
+ $this->output->expects($this->once())->method('_write')
+ ->with("\033[31;4mBad\033[0m \033[33mWarning\033[0m Regular");
+
+ $this->output->write('<error>Bad</error> <warning>Warning</warning> Regular', false);
+ }
+
+/**
+ * test that multiple tags of the same name work in one string.
+ *
+ * @return void
+ */
+ public function testFormattingMultipleSameTags() {
+ $this->output->expects($this->once())->method('_write')
+ ->with("\033[31;4mBad\033[0m \033[31;4mWarning\033[0m Regular");
+
+ $this->output->write('<error>Bad</error> <error>Warning</error> Regular', false);
+ }
+
+/**
+ * test raw output not getting tags replaced.
+ *
+ * @return void
+ */
+ public function testOutputAsRaw() {
+ $this->output->outputAs(ConsoleOutput::RAW);
+ $this->output->expects($this->once())->method('_write')
+ ->with('<error>Bad</error> Regular');
+
+ $this->output->write('<error>Bad</error> Regular', false);
+ }
+
+/**
+ * test plain output.
+ *
+ * @return void
+ */
+ public function testOutputAsPlain() {
+ $this->output->outputAs(ConsoleOutput::PLAIN);
+ $this->output->expects($this->once())->method('_write')
+ ->with('Bad Regular');
+
+ $this->output->write('<error>Bad</error> Regular', false);
+ }
+
+/**
+ * test plain output only strips tags used for formatting.
+ *
+ * @return void
+ */
+ public function testOutputAsPlainSelectiveTagRemoval() {
+ $this->output->outputAs(ConsoleOutput::PLAIN);
+ $this->output->expects($this->once())->method('_write')
+ ->with('Bad Regular <b>Left</b> <i>behind</i> <name>');
+
+ $this->output->write('<error>Bad</error> Regular <b>Left</b> <i>behind</i> <name>', false);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/HelpFormatterTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/HelpFormatterTest.php
new file mode 100644
index 0000000..7af5c1e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/HelpFormatterTest.php
@@ -0,0 +1,505 @@
+<?php
+/**
+ * HelpFormatterTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConsoleOptionParser', 'Console');
+App::uses('HelpFormatter', 'Console');
+
+class HelpFormatterTest extends CakeTestCase {
+
+/**
+ * test that the console max width is respected when generating help.
+ *
+ * @return void
+ */
+ public function testWidthFormatting() {
+ $parser = new ConsoleOptionParser('test', false);
+ $parser->description('This is fifteen This is fifteen This is fifteen')
+ ->addOption('four', array('help' => 'this is help text this is help text'))
+ ->addArgument('four', array('help' => 'this is help text this is help text'))
+ ->addSubcommand('four', array('help' => 'this is help text this is help text'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text(30);
+ $expected = <<<TEXT
+This is fifteen This is
+fifteen This is fifteen
+
+<info>Usage:</info>
+cake test [subcommand] [-h] [--four] [<four>]
+
+<info>Subcommands:</info>
+
+four this is help text this
+ is help text
+
+To see help on a subcommand use <info>`cake test [subcommand] --help`</info>
+
+<info>Options:</info>
+
+--help, -h Display this help.
+--four this is help text
+ this is help text
+
+<info>Arguments:</info>
+
+four this is help text this
+ is help text
+ <comment>(optional)</comment>
+
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Generated help is too wide');
+ }
+
+/**
+ * test help() with options and arguments that have choices.
+ *
+ * @return void
+ */
+ public function testHelpWithChoices() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.', 'choices' => array('one', 'two')))
+ ->addArgument('type', array(
+ 'help' => 'Resource type.',
+ 'choices' => array('aco', 'aro'),
+ 'required' => true
+ ))
+ ->addArgument('other_longer', array('help' => 'Another argument.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text();
+ $expected = <<<TEXT
+<info>Usage:</info>
+cake mycommand [-h] [--test one|two] <aco|aro> [<other_longer>]
+
+<info>Options:</info>
+
+--help, -h Display this help.
+--test A test option. <comment>(choices: one|two)</comment>
+
+<info>Arguments:</info>
+
+type Resource type. <comment>(choices: aco|aro)</comment>
+other_longer Another argument. <comment>(optional)</comment>
+
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Help does not match');
+ }
+
+/**
+ * test description and epilog in the help
+ *
+ * @return void
+ */
+ public function testHelpDescriptionAndEpilog() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->description('Description text')
+ ->epilog('epilog text')
+ ->addOption('test', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text();
+ $expected = <<<TEXT
+Description text
+
+<info>Usage:</info>
+cake mycommand [-h] [--test] <model>
+
+<info>Options:</info>
+
+--help, -h Display this help.
+--test A test option.
+
+<info>Arguments:</info>
+
+model The model to make.
+
+epilog text
+
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Help is wrong.');
+ }
+
+/**
+ * test that help() outputs subcommands.
+ *
+ * @return void
+ */
+ public function testHelpSubcommand() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addSubcommand('method', array('help' => 'This is another command'))
+ ->addOption('test', array('help' => 'A test option.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text();
+ $expected = <<<TEXT
+<info>Usage:</info>
+cake mycommand [subcommand] [-h] [--test]
+
+<info>Subcommands:</info>
+
+method This is another command
+
+To see help on a subcommand use <info>`cake mycommand [subcommand] --help`</info>
+
+<info>Options:</info>
+
+--help, -h Display this help.
+--test A test option.
+
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Help is not correct.');
+ }
+
+/**
+ * test getting help with defined options.
+ *
+ * @return void
+ */
+ public function testHelpWithOptions() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.'))
+ ->addOption('connection', array(
+ 'short' => 'c', 'help' => 'The connection to use.', 'default' => 'default'
+ ));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text();
+ $expected = <<<TEXT
+<info>Usage:</info>
+cake mycommand [-h] [--test] [-c default]
+
+<info>Options:</info>
+
+--help, -h Display this help.
+--test A test option.
+--connection, -c The connection to use. <comment>(default:
+ default)</comment>
+
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Help does not match');
+ }
+
+/**
+ * test getting help with defined options.
+ *
+ * @return void
+ */
+ public function testHelpWithOptionsAndArguments() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true))
+ ->addArgument('other_longer', array('help' => 'Another argument.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text();
+ $expected = <<<TEXT
+<info>Usage:</info>
+cake mycommand [-h] [--test] <model> [<other_longer>]
+
+<info>Options:</info>
+
+--help, -h Display this help.
+--test A test option.
+
+<info>Arguments:</info>
+
+model The model to make.
+other_longer Another argument. <comment>(optional)</comment>
+
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Help does not match');
+ }
+
+/**
+ * Test that a long set of options doesn't make useless output.
+ *
+ * @return void
+ */
+ public function testHelpWithLotsOfOptions() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser
+ ->addOption('test', array('help' => 'A test option.'))
+ ->addOption('test2', array('help' => 'A test option.'))
+ ->addOption('test3', array('help' => 'A test option.'))
+ ->addOption('test4', array('help' => 'A test option.'))
+ ->addOption('test5', array('help' => 'A test option.'))
+ ->addOption('test6', array('help' => 'A test option.'))
+ ->addOption('test7', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true))
+ ->addArgument('other_longer', array('help' => 'Another argument.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text();
+ $expected = 'cake mycommand [options] <model> [<other_longer>]';
+ $this->assertContains($expected, $result);
+ }
+
+/**
+ * Test that a long set of arguments doesn't make useless output.
+ *
+ * @return void
+ */
+ public function testHelpWithLotsOfArguments() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser
+ ->addArgument('test', array('help' => 'A test option.'))
+ ->addArgument('test2', array('help' => 'A test option.'))
+ ->addArgument('test3', array('help' => 'A test option.'))
+ ->addArgument('test4', array('help' => 'A test option.'))
+ ->addArgument('test5', array('help' => 'A test option.'))
+ ->addArgument('test6', array('help' => 'A test option.'))
+ ->addArgument('test7', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true))
+ ->addArgument('other_longer', array('help' => 'Another argument.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->text();
+ $expected = 'cake mycommand [-h] [arguments]';
+ $this->assertContains($expected, $result);
+ }
+
+/**
+ * test help() with options and arguments that have choices.
+ *
+ * @return void
+ */
+ public function testXmlHelpWithChoices() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.', 'choices' => array('one', 'two')))
+ ->addArgument('type', array(
+ 'help' => 'Resource type.',
+ 'choices' => array('aco', 'aro'),
+ 'required' => true
+ ))
+ ->addArgument('other_longer', array('help' => 'Another argument.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->xml();
+ $expected = <<<TEXT
+<?xml version="1.0"?>
+<shell>
+<name>mycommand</name>
+<description>Description text</description>
+<subcommands />
+<options>
+ <option name="--help" short="-h" help="Display this help." boolean="1">
+ <default></default>
+ <choices></choices>
+ </option>
+ <option name="--test" short="" help="A test option." boolean="0">
+ <default></default>
+ <choices>
+ <choice>one</choice>
+ <choice>two</choice>
+ </choices>
+ </option>
+</options>
+<arguments>
+ <argument name="type" help="Resource type." required="1">
+ <choices>
+ <choice>aco</choice>
+ <choice>aro</choice>
+ </choices>
+ </argument>
+</arguments>
+<epilog>epilog text</epilog>
+</shell>
+TEXT;
+ $this->assertEquals(new DomDocument($expected), new DomDocument($result), 'Help does not match');
+ }
+
+/**
+ * test description and epilog in the help
+ *
+ * @return void
+ */
+ public function testXmlHelpDescriptionAndEpilog() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->description('Description text')
+ ->epilog('epilog text')
+ ->addOption('test', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->xml();
+ $expected = <<<TEXT
+<?xml version="1.0"?>
+<shell>
+<name>mycommand</name>
+<description>Description text</description>
+<subcommands />
+<options>
+ <option name="--help" short="-h" help="Display this help." boolean="1">
+ <default></default>
+ <choices></choices>
+ </option>
+ <option name="--test" short="" help="A test option." boolean="0">
+ <default></default>
+ <choices></choices>
+ </option>
+</options>
+<arguments>
+ <argument name="model" help="The model to make." required="1">
+ <choices></choices>
+ </argument>
+</arguments>
+<epilog>epilog text</epilog>
+</shell>
+TEXT;
+ $this->assertEquals(new DomDocument($expected), new DomDocument($result), 'Help does not match');
+ }
+
+/**
+ * test that help() outputs subcommands.
+ *
+ * @return void
+ */
+ public function testXmlHelpSubcommand() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addSubcommand('method', array('help' => 'This is another command'))
+ ->addOption('test', array('help' => 'A test option.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->xml();
+ $expected = <<<TEXT
+<?xml version="1.0"?>
+<shell>
+<name>mycommand</name>
+<description/>
+<subcommands>
+ <command name="method" help="This is another command" />
+</subcommands>
+<options>
+ <option name="--help" short="-h" help="Display this help." boolean="1">
+ <default></default>
+ <choices></choices>
+ </option>
+ <option name="--test" short="" help="A test option." boolean="0">
+ <default></default>
+ <choices></choices>
+ </option>
+</options>
+<arguments/>
+<epilog/>
+</shell>
+TEXT;
+ $this->assertEquals(new DomDocument($expected), new DomDocument($result), 'Help does not match');
+ }
+
+/**
+ * test getting help with defined options.
+ *
+ * @return void
+ */
+ public function testXmlHelpWithOptions() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.'))
+ ->addOption('connection', array(
+ 'short' => 'c', 'help' => 'The connection to use.', 'default' => 'default'
+ ));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->xml();
+ $expected = <<<TEXT
+<?xml version="1.0"?>
+<shell>
+<name>mycommand</name>
+<description/>
+<subcommands/>
+<options>
+ <option name="--help" short="-h" help="Display this help." boolean="1">
+ <default></default>
+ <choices></choices>
+ </option>
+ <option name="--test" short="" help="A test option." boolean="0">
+ <default></default>
+ <choices></choices>
+ </option>
+ <option name="--connection" short="-c" help="The connection to use." boolean="0">
+ <default>default</default>
+ <choices></choices>
+ </option>
+</options>
+<arguments/>
+<epilog/>
+</shell>
+TEXT;
+ $this->assertEquals(new DomDocument($expected), new DomDocument($result), 'Help does not match');
+ }
+
+/**
+ * test getting help with defined options.
+ *
+ * @return void
+ */
+ public function testXmlHelpWithOptionsAndArguments() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true))
+ ->addArgument('other_longer', array('help' => 'Another argument.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->xml();
+ $expected = <<<TEXT
+<?xml version="1.0"?>
+<shell>
+ <name>mycommand</name>
+ <description/>
+ <subcommands/>
+ <options>
+ <option name="--help" short="-h" help="Display this help." boolean="1">
+ <default></default>
+ <choices></choices>
+ </option>
+ <option name="--test" short="" help="A test option." boolean="0">
+ <default></default>
+ <choices></choices>
+ </option>
+ </options>
+ <arguments>
+ <argument name="model" help="The model to make." required="1">
+ <choices></choices>
+ </argument>
+ <argument name="other_longer" help="Another argument." required="0">
+ <choices></choices>
+ </argument>
+ </arguments>
+ <epilog/>
+</shell>
+TEXT;
+ $this->assertEquals(new DomDocument($expected), new DomDocument($result), 'Help does not match');
+ }
+
+/**
+ * Test xml help as object
+ *
+ * @return void
+ */
+ public function testXmlHelpAsObject() {
+ $parser = new ConsoleOptionParser('mycommand', false);
+ $parser->addOption('test', array('help' => 'A test option.'))
+ ->addArgument('model', array('help' => 'The model to make.', 'required' => true))
+ ->addArgument('other_longer', array('help' => 'Another argument.'));
+
+ $formatter = new HelpFormatter($parser);
+ $result = $formatter->xml(false);
+ $this->assertInstanceOf('SimpleXmlElement', $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellDispatcherTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellDispatcherTest.php
new file mode 100644
index 0000000..c115b9d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellDispatcherTest.php
@@ -0,0 +1,576 @@
+<?php
+/**
+ * ShellDispatcherTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+
+/**
+ * TestShellDispatcher class
+ *
+ * @package Cake.Test.Case.Console
+ */
+class TestShellDispatcher extends ShellDispatcher {
+
+/**
+ * params property
+ *
+ * @var array
+ */
+ public $params = array();
+
+/**
+ * stopped property
+ *
+ * @var string
+ */
+ public $stopped = null;
+
+/**
+ * TestShell
+ *
+ * @var mixed
+ */
+ public $TestShell;
+
+/**
+ * _initEnvironment method
+ *
+ * @return void
+ */
+ protected function _initEnvironment() {
+ }
+
+/**
+ * clear method
+ *
+ * @return void
+ */
+ public function clear() {
+ }
+
+/**
+ * _stop method
+ *
+ * @return void
+ */
+ protected function _stop($status = 0) {
+ $this->stopped = 'Stopped with status: ' . $status;
+ return $status;
+ }
+
+/**
+ * getShell
+ *
+ * @param string $shell
+ * @return mixed
+ */
+ public function getShell($shell) {
+ return $this->_getShell($shell);
+ }
+
+/**
+ * _getShell
+ *
+ * @param string $plugin
+ * @return mixed
+ */
+ protected function _getShell($shell) {
+ if (isset($this->TestShell)) {
+ return $this->TestShell;
+ }
+ return parent::_getShell($shell);
+ }
+
+}
+
+/**
+ * ShellDispatcherTest
+ *
+ * @package Cake.Test.Case.Console
+ */
+class ShellDispatcherTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'Plugin' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ ),
+ 'Console/Command' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Console' . DS . 'Command' . DS
+ )
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ }
+
+/**
+ * testParseParams method
+ *
+ * @return void
+ */
+ public function testParseParams() {
+ $Dispatcher = new TestShellDispatcher();
+
+ $params = array(
+ '/cake/1.2.x.x/cake/console/cake.php',
+ 'bake',
+ '-app',
+ 'new',
+ '-working',
+ '/var/www/htdocs'
+ );
+ $expected = array(
+ 'app' => 'new',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('/', DS, '/var/www/htdocs/new'),
+ 'root' => str_replace('/', DS,'/var/www/htdocs')
+ );
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array('cake.php');
+ $expected = array(
+ 'app' => 'app',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'app'),
+ 'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH)),
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ 'cake.php',
+ '-app',
+ 'new',
+ );
+ $expected = array(
+ 'app' => 'new',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'new'),
+ 'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH))
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ './cake.php',
+ 'bake',
+ '-app',
+ 'new',
+ '-working',
+ '/cake/1.2.x.x/cake/console'
+ );
+
+ $expected = array(
+ 'app' => 'new',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'new'),
+ 'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH))
+ );
+
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ './console/cake.php',
+ 'bake',
+ '-app',
+ 'new',
+ '-working',
+ '/cake/1.2.x.x/cake'
+ );
+ $expected = array(
+ 'app' => 'new',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'new'),
+ 'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH))
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ './console/cake.php',
+ 'bake',
+ '-app',
+ 'new',
+ '-dry',
+ '-working',
+ '/cake/1.2.x.x/cake'
+ );
+ $expected = array(
+ 'app' => 'new',
+ 'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'new'),
+ 'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH)),
+ 'webroot' => 'webroot'
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ './console/cake.php',
+ '-working',
+ '/cake/1.2.x.x/cake',
+ 'schema',
+ 'run',
+ 'create',
+ '-dry',
+ '-f',
+ '-name',
+ 'DbAcl'
+ );
+ $expected = array(
+ 'app' => 'app',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'app'),
+ 'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH)),
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $expected = array(
+ './console/cake.php', 'schema', 'run', 'create', '-dry', '-f', '-name', 'DbAcl'
+ );
+ $this->assertEquals($expected, $Dispatcher->args);
+
+ $params = array(
+ '/cake/1.2.x.x/cake/console/cake.php',
+ '-working',
+ '/cake/1.2.x.x/app',
+ 'schema',
+ 'run',
+ 'create',
+ '-dry',
+ '-name',
+ 'DbAcl'
+ );
+ $expected = array(
+ 'app' => 'app',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('/', DS, '/cake/1.2.x.x/app'),
+ 'root' => str_replace('/', DS, '/cake/1.2.x.x'),
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ 'cake.php',
+ '-working',
+ 'C:/wamp/www/cake/app',
+ 'bake',
+ '-app',
+ 'C:/wamp/www/apps/cake/app',
+ );
+ $expected = array(
+ 'app' => 'app',
+ 'webroot' => 'webroot',
+ 'working' => 'C:\wamp\www\apps\cake\app',
+ 'root' => 'C:\wamp\www\apps\cake'
+ );
+
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ 'cake.php',
+ '-working',
+ 'C:\wamp\www\cake\app',
+ 'bake',
+ '-app',
+ 'C:\wamp\www\apps\cake\app',
+ );
+ $expected = array(
+ 'app' => 'app',
+ 'webroot' => 'webroot',
+ 'working' => 'C:\wamp\www\apps\cake\app',
+ 'root' => 'C:\wamp\www\apps\cake'
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ 'cake.php',
+ '-working',
+ 'C:\wamp\www\apps',
+ 'bake',
+ '-app',
+ 'cake\app',
+ '-url',
+ 'http://example.com/some/url/with/a/path'
+ );
+ $expected = array(
+ 'app' => 'app',
+ 'webroot' => 'webroot',
+ 'working' => 'C:\wamp\www\apps\cake\app',
+ 'root' => 'C:\wamp\www\apps\cake',
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ '/home/amelo/dev/cake-common/cake/console/cake.php',
+ '-root',
+ '/home/amelo/dev/lsbu-vacancy',
+ '-working',
+ '/home/amelo/dev/lsbu-vacancy',
+ '-app',
+ 'app',
+ );
+ $expected = array(
+ 'app' => 'app',
+ 'webroot' => 'webroot',
+ 'working' => '/home/amelo/dev/lsbu-vacancy/app',
+ 'root' => '/home/amelo/dev/lsbu-vacancy',
+ );
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ $params = array(
+ '/cake/1.2.x.x/cake/console/cake.php',
+ 'bake',
+ '-app',
+ 'new',
+ '-app',
+ 'old',
+ '-working',
+ '/var/www/htdocs'
+ );
+ $expected = array(
+ 'app' => 'old',
+ 'webroot' => 'webroot',
+ 'working' => str_replace('/', DS, '/var/www/htdocs/old'),
+ 'root' => str_replace('/', DS,'/var/www/htdocs')
+ );
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+
+ if (DS === '\\') {
+ $params = array(
+ 'cake.php',
+ '-working',
+ 'D:\www',
+ 'bake',
+ 'my_app',
+ );
+ $expected = array(
+ 'working' => 'D:\\\\www',
+ 'app' => 'www',
+ 'root' => 'D:\\',
+ 'webroot' => 'webroot'
+ );
+
+ $Dispatcher->params = $Dispatcher->args = array();
+ $Dispatcher->parseParams($params);
+ $this->assertEquals($expected, $Dispatcher->params);
+ }
+ }
+
+/**
+ * Verify loading of (plugin-) shells
+ *
+ * @return void
+ */
+ public function testGetShell() {
+ $this->skipIf(class_exists('SampleShell'), 'SampleShell Class already loaded.');
+ $this->skipIf(class_exists('ExampleShell'), 'ExampleShell Class already loaded.');
+
+ $Dispatcher = new TestShellDispatcher();
+
+ $result = $Dispatcher->getShell('sample');
+ $this->assertInstanceOf('SampleShell', $result);
+
+ $Dispatcher = new TestShellDispatcher();
+ $result = $Dispatcher->getShell('test_plugin.example');
+ $this->assertInstanceOf('ExampleShell', $result);
+ $this->assertEquals('TestPlugin', $result->plugin);
+ $this->assertEquals('Example', $result->name);
+
+ $Dispatcher = new TestShellDispatcher();
+ $result = $Dispatcher->getShell('TestPlugin.example');
+ $this->assertInstanceOf('ExampleShell', $result);
+ }
+
+/**
+ * Verify correct dispatch of Shell subclasses with a main method
+ *
+ * @return void
+ */
+ public function testDispatchShellWithMain() {
+ $Dispatcher = new TestShellDispatcher();
+ $Mock = $this->getMock('Shell', array(), array(), 'MockWithMainShell');
+
+ $Mock->expects($this->once())->method('initialize');
+ $Mock->expects($this->once())->method('loadTasks');
+ $Mock->expects($this->once())->method('runCommand')
+ ->with(null, array())
+ ->will($this->returnValue(true));
+
+ $Dispatcher->TestShell = $Mock;
+
+ $Dispatcher->args = array('mock_with_main');
+ $result = $Dispatcher->dispatch();
+ $this->assertTrue($result);
+ $this->assertEquals(array(), $Dispatcher->args);
+ }
+
+/**
+ * Verify correct dispatch of Shell subclasses without a main method
+ *
+ * @return void
+ */
+ public function testDispatchShellWithoutMain() {
+ $Dispatcher = new TestShellDispatcher();
+ $Shell = $this->getMock('Shell', array(), array(), 'MockWithoutMainShell');
+
+ $Shell = new MockWithoutMainShell();
+ $this->mockObjects[] = $Shell;
+
+ $Shell->expects($this->once())->method('initialize');
+ $Shell->expects($this->once())->method('loadTasks');
+ $Shell->expects($this->once())->method('runCommand')
+ ->with('initdb', array('initdb'))
+ ->will($this->returnValue(true));
+
+ $Dispatcher->TestShell = $Shell;
+
+ $Dispatcher->args = array('mock_without_main', 'initdb');
+ $result = $Dispatcher->dispatch();
+ $this->assertTrue($result);
+ }
+
+/**
+ * Verify correct dispatch of custom classes with a main method
+ *
+ * @return void
+ */
+ public function testDispatchNotAShellWithMain() {
+ $Dispatcher = new TestShellDispatcher();
+ $methods = get_class_methods('Object');
+ array_push($methods, 'main', 'initdb', 'initialize', 'loadTasks', 'startup', '_secret');
+ $Shell = $this->getMock('Object', $methods, array(), 'MockWithMainNotAShell');
+
+ $Shell->expects($this->never())->method('initialize');
+ $Shell->expects($this->never())->method('loadTasks');
+ $Shell->expects($this->once())->method('startup');
+ $Shell->expects($this->once())->method('main')->will($this->returnValue(true));
+ $Dispatcher->TestShell = $Shell;
+
+ $Dispatcher->args = array('mock_with_main_not_a');
+ $result = $Dispatcher->dispatch();
+ $this->assertTrue($result);
+ $this->assertEquals(array(), $Dispatcher->args);
+
+ $Shell = new MockWithMainNotAShell($Dispatcher);
+ $this->mockObjects[] = $Shell;
+ $Shell->expects($this->once())->method('initdb')->will($this->returnValue(true));
+ $Shell->expects($this->once())->method('startup');
+ $Dispatcher->TestShell = $Shell;
+
+ $Dispatcher->args = array('mock_with_main_not_a', 'initdb');
+ $result = $Dispatcher->dispatch();
+ $this->assertTrue($result);
+ }
+
+/**
+ * Verify correct dispatch of custom classes without a main method
+ *
+ * @return void
+ */
+ public function testDispatchNotAShellWithoutMain() {
+ $Dispatcher = new TestShellDispatcher();
+ $methods = get_class_methods('Object');
+ array_push($methods, 'main', 'initdb', 'initialize', 'loadTasks', 'startup', '_secret');
+ $Shell = $this->getMock('Object', $methods, array(&$Dispatcher), 'MockWithoutMainNotAShell');
+
+ $Shell->expects($this->never())->method('initialize');
+ $Shell->expects($this->never())->method('loadTasks');
+ $Shell->expects($this->once())->method('startup');
+ $Shell->expects($this->once())->method('main')->will($this->returnValue(true));
+ $Dispatcher->TestShell = $Shell;
+
+ $Dispatcher->args = array('mock_without_main_not_a');
+ $result = $Dispatcher->dispatch();
+ $this->assertTrue($result);
+ $this->assertEquals(array(), $Dispatcher->args);
+
+ $Shell = new MockWithoutMainNotAShell($Dispatcher);
+ $this->mockObjects[] = $Shell;
+ $Shell->expects($this->once())->method('initdb')->will($this->returnValue(true));
+ $Shell->expects($this->once())->method('startup');
+ $Dispatcher->TestShell = $Shell;
+
+ $Dispatcher->args = array('mock_without_main_not_a', 'initdb');
+ $result = $Dispatcher->dispatch();
+ $this->assertTrue($result);
+ }
+
+/**
+ * Verify shifting of arguments
+ *
+ * @return void
+ */
+ public function testShiftArgs() {
+ $Dispatcher = new TestShellDispatcher();
+
+ $Dispatcher->args = array('a', 'b', 'c');
+ $this->assertEquals('a', $Dispatcher->shiftArgs());
+ $this->assertSame($Dispatcher->args, array('b', 'c'));
+
+ $Dispatcher->args = array('a' => 'b', 'c', 'd');
+ $this->assertEquals('b', $Dispatcher->shiftArgs());
+ $this->assertSame($Dispatcher->args, array('c', 'd'));
+
+ $Dispatcher->args = array('a', 'b' => 'c', 'd');
+ $this->assertEquals('a', $Dispatcher->shiftArgs());
+ $this->assertSame($Dispatcher->args, array('b' => 'c', 'd'));
+
+ $Dispatcher->args = array(0 => 'a', 2 => 'b', 30 => 'c');
+ $this->assertEquals('a', $Dispatcher->shiftArgs());
+ $this->assertSame($Dispatcher->args, array(0 => 'b', 1 => 'c'));
+
+ $Dispatcher->args = array();
+ $this->assertNull($Dispatcher->shiftArgs());
+ $this->assertSame(array(), $Dispatcher->args);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellTest.php
new file mode 100644
index 0000000..875b23d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/ShellTest.php
@@ -0,0 +1,875 @@
+<?php
+/**
+ * ShellTest file
+ *
+ * Test Case for Shell
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Console.Command
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ShellDispatcher', 'Console');
+App::uses('Shell', 'Console');
+App::uses('Folder', 'Utility');
+
+/**
+ * ShellTestShell class
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class ShellTestShell extends Shell {
+
+/**
+ * name property
+ *
+ * @var name
+ */
+ public $name = 'ShellTestShell';
+
+/**
+ * stopped property
+ *
+ * @var integer
+ */
+ public $stopped;
+
+/**
+ * testMessage property
+ *
+ * @var string
+ */
+ public $testMessage = 'all your base are belong to us';
+
+/**
+ * stop method
+ *
+ * @param integer $status
+ * @return void
+ */
+ protected function _stop($status = 0) {
+ $this->stopped = $status;
+ }
+
+ protected function _secret() {
+ }
+
+ //@codingStandardsIgnoreStart
+ public function do_something() {
+ }
+
+ protected function no_access() {
+ }
+
+ public function log_something() {
+ $this->log($this->testMessage);
+ }
+ //@codingStandardsIgnoreEnd
+
+ public function mergeVars($properties, $class, $normalize = true) {
+ return $this->_mergeVars($properties, $class, $normalize);
+ }
+
+ public function useLogger($enable = true) {
+ $this->_useLogger($enable);
+ }
+
+}
+
+/**
+ * Class for testing merging vars
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class TestMergeShell extends Shell {
+
+ public $tasks = array('DbConfig', 'Fixture');
+
+ public $uses = array('Comment');
+
+}
+
+/**
+ * TestAppleTask class
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class TestAppleTask extends Shell {
+}
+
+/**
+ * TestBananaTask class
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class TestBananaTask extends Shell {
+}
+
+/**
+ * ShellTest class
+ *
+ * @package Cake.Test.Case.Console.Command
+ */
+class ShellTest extends CakeTestCase {
+
+/**
+ * Fixtures used in this test case
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.post', 'core.comment', 'core.article', 'core.user',
+ 'core.tag', 'core.articles_tag', 'core.attachment'
+ );
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ $output = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $error = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Shell = new ShellTestShell($output, $error, $in);
+
+ if (is_dir(TMP . 'shell_test')) {
+ $Folder = new Folder(TMP . 'shell_test');
+ $Folder->delete();
+ }
+ }
+
+/**
+ * testConstruct method
+ *
+ * @return void
+ */
+ public function testConstruct() {
+ $this->assertEquals('ShellTestShell', $this->Shell->name);
+ $this->assertInstanceOf('ConsoleInput', $this->Shell->stdin);
+ $this->assertInstanceOf('ConsoleOutput', $this->Shell->stdout);
+ $this->assertInstanceOf('ConsoleOutput', $this->Shell->stderr);
+ }
+
+/**
+ * test merging vars
+ *
+ * @return void
+ */
+ public function testMergeVars() {
+ $this->Shell->tasks = array('DbConfig' => array('one', 'two'));
+ $this->Shell->uses = array('Posts');
+ $this->Shell->mergeVars(array('tasks'), 'TestMergeShell');
+ $this->Shell->mergeVars(array('uses'), 'TestMergeShell', false);
+
+ $expected = array('DbConfig' => null, 'Fixture' => null, 'DbConfig' => array('one', 'two'));
+ $this->assertEquals($expected, $this->Shell->tasks);
+
+ $expected = array('Fixture' => null, 'DbConfig' => array('one', 'two'));
+ $this->assertEquals($expected, Hash::normalize($this->Shell->tasks), 'Normalized results are wrong.');
+ $this->assertEquals(array('Comment', 'Posts'), $this->Shell->uses, 'Merged models are wrong.');
+ }
+
+/**
+ * testInitialize method
+ *
+ * @return void
+ */
+ public function testInitialize() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS)
+ ), App::RESET);
+
+ CakePlugin::load('TestPlugin');
+ $this->Shell->uses = array('TestPlugin.TestPluginPost');
+ $this->Shell->initialize();
+
+ $this->assertTrue(isset($this->Shell->TestPluginPost));
+ $this->assertInstanceOf('TestPluginPost', $this->Shell->TestPluginPost);
+ $this->assertEquals('TestPluginPost', $this->Shell->modelClass);
+ CakePlugin::unload('TestPlugin');
+
+ $this->Shell->uses = array('Comment');
+ $this->Shell->initialize();
+ $this->assertTrue(isset($this->Shell->Comment));
+ $this->assertInstanceOf('Comment', $this->Shell->Comment);
+ $this->assertEquals('Comment', $this->Shell->modelClass);
+
+ App::build();
+ }
+
+/**
+ * testIn method
+ *
+ * @return void
+ */
+ public function testIn() {
+ $this->Shell->stdin->expects($this->at(0))
+ ->method('read')
+ ->will($this->returnValue('n'));
+
+ $this->Shell->stdin->expects($this->at(1))
+ ->method('read')
+ ->will($this->returnValue('Y'));
+
+ $this->Shell->stdin->expects($this->at(2))
+ ->method('read')
+ ->will($this->returnValue('y'));
+
+ $this->Shell->stdin->expects($this->at(3))
+ ->method('read')
+ ->will($this->returnValue('y'));
+
+ $this->Shell->stdin->expects($this->at(4))
+ ->method('read')
+ ->will($this->returnValue('y'));
+
+ $this->Shell->stdin->expects($this->at(5))
+ ->method('read')
+ ->will($this->returnValue('0'));
+
+ $result = $this->Shell->in('Just a test?', array('y', 'n'), 'n');
+ $this->assertEquals('n', $result);
+
+ $result = $this->Shell->in('Just a test?', array('y', 'n'), 'n');
+ $this->assertEquals('Y', $result);
+
+ $result = $this->Shell->in('Just a test?', 'y,n', 'n');
+ $this->assertEquals('y', $result);
+
+ $result = $this->Shell->in('Just a test?', 'y/n', 'n');
+ $this->assertEquals('y', $result);
+
+ $result = $this->Shell->in('Just a test?', 'y', 'y');
+ $this->assertEquals('y', $result);
+
+ $result = $this->Shell->in('Just a test?', array(0, 1, 2), '0');
+ $this->assertEquals('0', $result);
+ }
+
+/**
+ * Test in() when not interactive.
+ *
+ * @return void
+ */
+ public function testInNonInteractive() {
+ $this->Shell->interactive = false;
+
+ $result = $this->Shell->in('Just a test?', 'y/n', 'n');
+ $this->assertEquals('n', $result);
+ }
+
+/**
+ * testOut method
+ *
+ * @return void
+ */
+ public function testOut() {
+ $this->Shell->stdout->expects($this->at(0))
+ ->method('write')
+ ->with("Just a test", 1);
+
+ $this->Shell->stdout->expects($this->at(1))
+ ->method('write')
+ ->with(array('Just', 'a', 'test'), 1);
+
+ $this->Shell->stdout->expects($this->at(2))
+ ->method('write')
+ ->with(array('Just', 'a', 'test'), 2);
+
+ $this->Shell->stdout->expects($this->at(3))
+ ->method('write')
+ ->with('', 1);
+
+ $this->Shell->out('Just a test');
+
+ $this->Shell->out(array('Just', 'a', 'test'));
+
+ $this->Shell->out(array('Just', 'a', 'test'), 2);
+
+ $this->Shell->out();
+ }
+
+/**
+ * test that verbose and quiet output levels work
+ *
+ * @return void
+ */
+ public function testVerboseOutput() {
+ $this->Shell->stdout->expects($this->at(0))->method('write')
+ ->with('Verbose', 1);
+ $this->Shell->stdout->expects($this->at(1))->method('write')
+ ->with('Normal', 1);
+ $this->Shell->stdout->expects($this->at(2))->method('write')
+ ->with('Quiet', 1);
+
+ $this->Shell->params['verbose'] = true;
+ $this->Shell->params['quiet'] = false;
+
+ $this->Shell->out('Verbose', 1, Shell::VERBOSE);
+ $this->Shell->out('Normal', 1, Shell::NORMAL);
+ $this->Shell->out('Quiet', 1, Shell::QUIET);
+ }
+
+/**
+ * test that verbose and quiet output levels work
+ *
+ * @return void
+ */
+ public function testQuietOutput() {
+ $this->Shell->stdout->expects($this->once())->method('write')
+ ->with('Quiet', 1);
+
+ $this->Shell->params['verbose'] = false;
+ $this->Shell->params['quiet'] = true;
+
+ $this->Shell->out('Verbose', 1, Shell::VERBOSE);
+ $this->Shell->out('Normal', 1, Shell::NORMAL);
+ $this->Shell->out('Quiet', 1, Shell::QUIET);
+ }
+
+/**
+ * testErr method
+ *
+ * @return void
+ */
+ public function testErr() {
+ $this->Shell->stderr->expects($this->at(0))
+ ->method('write')
+ ->with("Just a test", 1);
+
+ $this->Shell->stderr->expects($this->at(1))
+ ->method('write')
+ ->with(array('Just', 'a', 'test'), 1);
+
+ $this->Shell->stderr->expects($this->at(2))
+ ->method('write')
+ ->with(array('Just', 'a', 'test'), 2);
+
+ $this->Shell->stderr->expects($this->at(3))
+ ->method('write')
+ ->with('', 1);
+
+ $this->Shell->err('Just a test');
+
+ $this->Shell->err(array('Just', 'a', 'test'));
+
+ $this->Shell->err(array('Just', 'a', 'test'), 2);
+
+ $this->Shell->err();
+ }
+
+/**
+ * testNl
+ *
+ * @return void
+ */
+ public function testNl() {
+ $newLine = "\n";
+ if (DS === '\\') {
+ $newLine = "\r\n";
+ }
+ $this->assertEquals($this->Shell->nl(), $newLine);
+ $this->assertEquals($this->Shell->nl(true), $newLine);
+ $this->assertEquals("", $this->Shell->nl(false));
+ $this->assertEquals($this->Shell->nl(2), $newLine . $newLine);
+ $this->assertEquals($this->Shell->nl(1), $newLine);
+ }
+
+/**
+ * testHr
+ *
+ * @return void
+ */
+ public function testHr() {
+ $bar = '---------------------------------------------------------------';
+
+ $this->Shell->stdout->expects($this->at(0))->method('write')->with('', 0);
+ $this->Shell->stdout->expects($this->at(1))->method('write')->with($bar, 1);
+ $this->Shell->stdout->expects($this->at(2))->method('write')->with('', 0);
+
+ $this->Shell->stdout->expects($this->at(3))->method('write')->with("", true);
+ $this->Shell->stdout->expects($this->at(4))->method('write')->with($bar, 1);
+ $this->Shell->stdout->expects($this->at(5))->method('write')->with("", true);
+
+ $this->Shell->stdout->expects($this->at(6))->method('write')->with("", 2);
+ $this->Shell->stdout->expects($this->at(7))->method('write')->with($bar, 1);
+ $this->Shell->stdout->expects($this->at(8))->method('write')->with("", 2);
+
+ $this->Shell->hr();
+
+ $this->Shell->hr(true);
+
+ $this->Shell->hr(2);
+ }
+
+/**
+ * testError
+ *
+ * @return void
+ */
+ public function testError() {
+ $this->Shell->stderr->expects($this->at(0))
+ ->method('write')
+ ->with("<error>Error:</error> Foo Not Found", 1);
+
+ $this->Shell->stderr->expects($this->at(1))
+ ->method('write')
+ ->with("<error>Error:</error> Foo Not Found", 1);
+
+ $this->Shell->stderr->expects($this->at(2))
+ ->method('write')
+ ->with("Searched all...", 1);
+
+ $this->Shell->error('Foo Not Found');
+ $this->assertSame($this->Shell->stopped, 1);
+
+ $this->Shell->stopped = null;
+
+ $this->Shell->error('Foo Not Found', 'Searched all...');
+ $this->assertSame($this->Shell->stopped, 1);
+ }
+
+/**
+ * testLoadTasks method
+ *
+ * @return void
+ */
+ public function testLoadTasks() {
+ $this->assertTrue($this->Shell->loadTasks());
+
+ $this->Shell->tasks = null;
+ $this->assertTrue($this->Shell->loadTasks());
+
+ $this->Shell->tasks = false;
+ $this->assertTrue($this->Shell->loadTasks());
+
+ $this->Shell->tasks = true;
+ $this->assertTrue($this->Shell->loadTasks());
+
+ $this->Shell->tasks = array();
+ $this->assertTrue($this->Shell->loadTasks());
+
+ $this->Shell->tasks = array('TestApple');
+ $this->assertTrue($this->Shell->loadTasks());
+ $this->assertInstanceOf('TestAppleTask', $this->Shell->TestApple);
+
+ $this->Shell->tasks = 'TestBanana';
+ $this->assertTrue($this->Shell->loadTasks());
+ $this->assertInstanceOf('TestAppleTask', $this->Shell->TestApple);
+ $this->assertInstanceOf('TestBananaTask', $this->Shell->TestBanana);
+
+ unset($this->Shell->ShellTestApple, $this->Shell->TestBanana);
+
+ $this->Shell->tasks = array('TestApple', 'TestBanana');
+ $this->assertTrue($this->Shell->loadTasks());
+ $this->assertInstanceOf('TestAppleTask', $this->Shell->TestApple);
+ $this->assertInstanceOf('TestBananaTask', $this->Shell->TestBanana);
+ }
+
+/**
+ * test that __get() makes args and params references
+ *
+ * @return void
+ */
+ public function testMagicGetArgAndParamReferences() {
+ $this->Shell->tasks = array('TestApple');
+ $this->Shell->args = array('one');
+ $this->Shell->params = array('help' => false);
+ $this->Shell->loadTasks();
+ $result = $this->Shell->TestApple;
+
+ $this->Shell->args = array('one', 'two');
+
+ $this->assertSame($this->Shell->args, $result->args);
+ $this->assertSame($this->Shell->params, $result->params);
+ }
+
+/**
+ * testShortPath method
+ *
+ * @return void
+ */
+ public function testShortPath() {
+ $path = $expected = DS . 'tmp' . DS . 'ab' . DS . 'cd';
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+
+ $path = $expected = DS . 'tmp' . DS . 'ab' . DS . 'cd' . DS;
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+
+ $path = $expected = DS . 'tmp' . DS . 'ab' . DS . 'index.php';
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+
+ $path = DS . 'tmp' . DS . 'ab' . DS . DS . 'cd';
+ $expected = DS . 'tmp' . DS . 'ab' . DS . 'cd';
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+
+ $path = 'tmp' . DS . 'ab';
+ $expected = 'tmp' . DS . 'ab';
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+
+ $path = 'tmp' . DS . 'ab';
+ $expected = 'tmp' . DS . 'ab';
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+
+ $path = APP;
+ $expected = DS . basename(APP) . DS;
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+
+ $path = APP . 'index.php';
+ $expected = DS . basename(APP) . DS . 'index.php';
+ $this->assertEquals($expected, $this->Shell->shortPath($path));
+ }
+
+/**
+ * testCreateFile method
+ *
+ * @return void
+ */
+ public function testCreateFileNonInteractive() {
+ $eol = PHP_EOL;
+
+ $path = TMP . 'shell_test';
+ $file = $path . DS . 'file1.php';
+
+ $Folder = new Folder($path, true);
+
+ $this->Shell->interactive = false;
+
+ $contents = "<?php{$eol}echo 'test';${eol}\$te = 'st';{$eol}";
+ $result = $this->Shell->createFile($file, $contents);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($file));
+ $this->assertEquals(file_get_contents($file), $contents);
+
+ $contents = "<?php\necho 'another test';\n\$te = 'st';\n";
+ $result = $this->Shell->createFile($file, $contents);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($file));
+ $this->assertTextEquals(file_get_contents($file), $contents);
+ }
+
+/**
+ * test createFile when the shell is interactive.
+ *
+ * @return void
+ */
+ public function testCreateFileInteractive() {
+ $eol = PHP_EOL;
+
+ $path = TMP . 'shell_test';
+ $file = $path . DS . 'file1.php';
+ $Folder = new Folder($path, true);
+
+ $this->Shell->interactive = true;
+
+ $this->Shell->stdin->expects($this->at(0))
+ ->method('read')
+ ->will($this->returnValue('n'));
+
+ $this->Shell->stdin->expects($this->at(1))
+ ->method('read')
+ ->will($this->returnValue('y'));
+
+ $contents = "<?php{$eol}echo 'yet another test';{$eol}\$te = 'st';{$eol}";
+ $result = $this->Shell->createFile($file, $contents);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($file));
+ $this->assertEquals(file_get_contents($file), $contents);
+
+ // no overwrite
+ $contents = 'new contents';
+ $result = $this->Shell->createFile($file, $contents);
+ $this->assertFalse($result);
+ $this->assertTrue(file_exists($file));
+ $this->assertNotEquals($contents, file_get_contents($file));
+
+ // overwrite
+ $contents = 'more new contents';
+ $result = $this->Shell->createFile($file, $contents);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($file));
+ $this->assertEquals($contents, file_get_contents($file));
+ }
+
+/**
+ * Test that you can't create files that aren't writable.
+ *
+ * @return void
+ */
+ public function testCreateFileNoPermissions() {
+ $this->skipIf(DIRECTORY_SEPARATOR === '\\', 'Cant perform operations using permissions on windows.');
+
+ $path = TMP . 'shell_test';
+ $file = $path . DS . 'no_perms';
+
+ if (!is_dir($path)) {
+ mkdir($path);
+ }
+ chmod($path, 0444);
+
+ $this->Shell->createFile($file, 'testing');
+ $this->assertFalse(file_exists($file));
+
+ chmod($path, 0744);
+ rmdir($path);
+ }
+
+/**
+ * test hasTask method
+ *
+ * @return void
+ */
+ public function testHasTask() {
+ $this->Shell->tasks = array('Extract', 'DbConfig');
+ $this->Shell->loadTasks();
+
+ $this->assertTrue($this->Shell->hasTask('extract'));
+ $this->assertTrue($this->Shell->hasTask('Extract'));
+ $this->assertFalse($this->Shell->hasTask('random'));
+
+ $this->assertTrue($this->Shell->hasTask('db_config'));
+ $this->assertTrue($this->Shell->hasTask('DbConfig'));
+ }
+
+/**
+ * test the hasMethod
+ *
+ * @return void
+ */
+ public function testHasMethod() {
+ $this->assertTrue($this->Shell->hasMethod('do_something'));
+ $this->assertFalse($this->Shell->hasMethod('hr'), 'hr is callable');
+ $this->assertFalse($this->Shell->hasMethod('_secret'), '_secret is callable');
+ $this->assertFalse($this->Shell->hasMethod('no_access'), 'no_access is callable');
+ }
+
+/**
+ * test run command calling main.
+ *
+ * @return void
+ */
+ public function testRunCommandMain() {
+ $methods = get_class_methods('Shell');
+ $Mock = $this->getMock('Shell', array('main', 'startup'), array(), '', false);
+
+ $Mock->expects($this->once())->method('main')->will($this->returnValue(true));
+ $result = $Mock->runCommand(null, array());
+ $this->assertTrue($result);
+ }
+
+/**
+ * test run command calling a legit method.
+ *
+ * @return void
+ */
+ public function testRunCommandWithMethod() {
+ $methods = get_class_methods('Shell');
+ $Mock = $this->getMock('Shell', array('hit_me', 'startup'), array(), '', false);
+
+ $Mock->expects($this->once())->method('hit_me')->will($this->returnValue(true));
+ $result = $Mock->runCommand('hit_me', array());
+ $this->assertTrue($result);
+ }
+
+/**
+ * test run command causing exception on Shell method.
+ *
+ * @return void
+ */
+ public function testRunCommandBaseclassMethod() {
+ $Mock = $this->getMock('Shell', array('startup', 'getOptionParser', 'out'), array(), '', false);
+ $Parser = $this->getMock('ConsoleOptionParser', array(), array(), '', false);
+
+ $Parser->expects($this->once())->method('help');
+ $Mock->expects($this->once())->method('getOptionParser')
+ ->will($this->returnValue($Parser));
+ $Mock->expects($this->never())->method('hr');
+ $Mock->expects($this->once())->method('out');
+
+ $result = $Mock->runCommand('hr', array());
+ }
+
+/**
+ * test run command causing exception on Shell method.
+ *
+ * @return void
+ */
+ public function testRunCommandMissingMethod() {
+ $methods = get_class_methods('Shell');
+ $Mock = $this->getMock('Shell', array('startup', 'getOptionParser', 'out'), array(), '', false);
+ $Parser = $this->getMock('ConsoleOptionParser', array(), array(), '', false);
+
+ $Parser->expects($this->once())->method('help');
+ $Mock->expects($this->never())->method('idontexist');
+ $Mock->expects($this->once())->method('getOptionParser')
+ ->will($this->returnValue($Parser));
+ $Mock->expects($this->once())->method('out');
+
+ $result = $Mock->runCommand('idontexist', array());
+ $this->assertFalse($result);
+ }
+
+/**
+ * test that a --help causes help to show.
+ *
+ * @return void
+ */
+ public function testRunCommandTriggeringHelp() {
+ $Parser = $this->getMock('ConsoleOptionParser', array(), array(), '', false);
+ $Parser->expects($this->once())->method('parse')
+ ->with(array('--help'))
+ ->will($this->returnValue(array(array('help' => true), array())));
+ $Parser->expects($this->once())->method('help');
+
+ $Shell = $this->getMock('Shell', array('getOptionParser', 'out', 'startup', '_welcome'), array(), '', false);
+ $Shell->expects($this->once())->method('getOptionParser')
+ ->will($this->returnValue($Parser));
+ $Shell->expects($this->once())->method('out');
+
+ $Shell->runCommand(null, array('--help'));
+ }
+
+/**
+ * test that runCommand will call runCommand on the task.
+ *
+ * @return void
+ */
+ public function testRunCommandHittingTask() {
+ $Shell = $this->getMock('Shell', array('hasTask', 'startup'), array(), '', false);
+ $task = $this->getMock('Shell', array('execute', 'runCommand'), array(), '', false);
+ $task->expects($this->any())
+ ->method('runCommand')
+ ->with('execute', array('one', 'value'));
+
+ $Shell->expects($this->once())->method('startup');
+ $Shell->expects($this->any())
+ ->method('hasTask')
+ ->will($this->returnValue(true));
+
+ $Shell->RunCommand = $task;
+
+ $result = $Shell->runCommand('run_command', array('run_command', 'one', 'value'));
+ }
+
+/**
+ * test wrapBlock wrapping text.
+ *
+ * @return void
+ */
+ public function testWrapText() {
+ $text = 'This is the song that never ends. This is the song that never ends. This is the song that never ends.';
+ $result = $this->Shell->wrapText($text, 33);
+ $expected = <<<TEXT
+This is the song that never ends.
+This is the song that never ends.
+This is the song that never ends.
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Text not wrapped.');
+
+ $result = $this->Shell->wrapText($text, array('indent' => ' ', 'width' => 33));
+ $expected = <<<TEXT
+ This is the song that never ends.
+ This is the song that never ends.
+ This is the song that never ends.
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Text not wrapped.');
+ }
+
+/**
+ * Testing camel cased naming of tasks
+ *
+ * @return void
+ */
+ public function testShellNaming() {
+ $this->Shell->tasks = array('TestApple');
+ $this->Shell->loadTasks();
+ $expected = 'TestApple';
+ $this->assertEquals($expected, $this->Shell->TestApple->name);
+ }
+
+/**
+ * Test that option parsers are created with the correct name/command.
+ *
+ * @return void
+ */
+ public function testGetOptionParser() {
+ $this->Shell->name = 'test';
+ $this->Shell->plugin = 'plugin';
+ $parser = $this->Shell->getOptionParser();
+
+ $this->assertEquals('plugin.test', $parser->command());
+ }
+
+/**
+ * Test file and console and logging
+ */
+ public function testFileAndConsoleLogging() {
+ // file logging
+ $this->Shell->log_something();
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+
+ unlink(LOGS . 'error.log');
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+
+ // both file and console logging
+ require_once CORE_TEST_CASES . DS . 'Log' . DS . 'Engine' . DS . 'ConsoleLogTest.php';
+ $mock = $this->getMock('ConsoleLog', array('write'), array(
+ array('types' => 'error'),
+ ));
+ TestCakeLog::config('console', array(
+ 'engine' => 'ConsoleLog',
+ 'stream' => 'php://stderr',
+ ));
+ TestCakeLog::replace('console', $mock);
+ $mock->expects($this->once())
+ ->method('write')
+ ->with('error', $this->Shell->testMessage);
+ $this->Shell->log_something();
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $contents = file_get_contents(LOGS . 'error.log');
+ $this->assertContains($this->Shell->testMessage, $contents);
+ }
+
+/**
+ * Tests that _useLogger works properly
+ *
+ * @return void
+ **/
+ public function testProtectedUseLogger() {
+ CakeLog::drop('stdout');
+ CakeLog::drop('stderr');
+ $this->Shell->useLogger(true);
+ $this->assertNotEmpty(CakeLog::stream('stdout'));
+ $this->assertNotEmpty(CakeLog::stream('stderr'));
+ $this->Shell->useLogger(false);
+ $this->assertFalse(CakeLog::stream('stdout'));
+ $this->assertFalse(CakeLog::stream('stderr'));
+ }
+
+/**
+ * Test file and console and logging quiet output
+ */
+ public function testQuietLog() {
+ $output = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $error = $this->getMock('ConsoleOutput', array(), array(), '', false);
+ $in = $this->getMock('ConsoleInput', array(), array(), '', false);
+ $this->Shell = $this->getMock('ShellTestShell', array('_useLogger'), array($output, $error, $in));
+ $this->Shell->expects($this->once())->method('_useLogger')->with(false);
+ $this->Shell->runCommand('foo', array('--quiet'));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/TaskCollectionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/TaskCollectionTest.php
new file mode 100644
index 0000000..9317e77
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Console/TaskCollectionTest.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * TaskCollectionTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Console
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('TaskCollection', 'Console');
+App::uses('Shell', 'Console');
+
+class TaskCollectionTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $shell = $this->getMock('Shell', array(), array(), '', false);
+ $dispatcher = $this->getMock('ShellDispatcher', array(), array(), '', false);
+ $this->Tasks = new TaskCollection($shell, $dispatcher);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->Tasks);
+ parent::tearDown();
+ }
+
+/**
+ * test triggering callbacks on loaded tasks
+ *
+ * @return void
+ */
+ public function testLoad() {
+ $result = $this->Tasks->load('DbConfig');
+ $this->assertInstanceOf('DbConfigTask', $result);
+ $this->assertInstanceOf('DbConfigTask', $this->Tasks->DbConfig);
+
+ $result = $this->Tasks->attached();
+ $this->assertEquals(array('DbConfig'), $result, 'attached() results are wrong.');
+ }
+
+/**
+ * test load and enable = false
+ *
+ * @return void
+ */
+ public function testLoadWithEnableFalse() {
+ $result = $this->Tasks->load('DbConfig', array('enabled' => false));
+ $this->assertInstanceOf('DbConfigTask', $result);
+ $this->assertInstanceOf('DbConfigTask', $this->Tasks->DbConfig);
+
+ $this->assertFalse($this->Tasks->enabled('DbConfig'), 'DbConfigTask should be disabled');
+ }
+
+/**
+ * test missingtask exception
+ *
+ * @expectedException MissingTaskException
+ * @return void
+ */
+ public function testLoadMissingTask() {
+ $result = $this->Tasks->load('ThisTaskShouldAlwaysBeMissing');
+ }
+
+/**
+ * test loading a plugin helper.
+ *
+ * @return void
+ */
+ public function testLoadPluginTask() {
+ $dispatcher = $this->getMock('ShellDispatcher', array(), array(), '', false);
+ $shell = $this->getMock('Shell', array(), array(), '', false);
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $this->Tasks = new TaskCollection($shell, $dispatcher);
+
+ $result = $this->Tasks->load('TestPlugin.OtherTask');
+ $this->assertInstanceOf('OtherTaskTask', $result, 'Task class is wrong.');
+ $this->assertInstanceOf('OtherTaskTask', $this->Tasks->OtherTask, 'Class is wrong');
+ CakePlugin::unload();
+ }
+
+/**
+ * test unload()
+ *
+ * @return void
+ */
+ public function testUnload() {
+ $this->Tasks->load('Extract');
+ $this->Tasks->load('DbConfig');
+
+ $result = $this->Tasks->attached();
+ $this->assertEquals(array('Extract', 'DbConfig'), $result, 'loaded tasks is wrong');
+
+ $this->Tasks->unload('DbConfig');
+ $this->assertFalse(isset($this->Tasks->DbConfig));
+ $this->assertTrue(isset($this->Tasks->Extract));
+
+ $result = $this->Tasks->attached();
+ $this->assertEquals(array('Extract'), $result, 'loaded tasks is wrong');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php
new file mode 100644
index 0000000..bfc33f6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/DbAclTest.php
@@ -0,0 +1,543 @@
+<?php
+/**
+ * DbAclTest file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Acl
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ComponentCollection', 'Controller');
+App::uses('AclComponent', 'Controller/Component');
+App::uses('DbAcl', 'Controller/Component/Acl');
+App::uses('AclNode', 'Model');
+App::uses('Permission', 'Model');
+require_once dirname(dirname(dirname(dirname(__FILE__)))) . DS . 'Model' . DS . 'models.php';
+
+/**
+ * AclNodeTwoTestBase class
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class AclNodeTwoTestBase extends AclNode {
+
+/**
+ * useDbConfig property
+ *
+ * @var string 'test'
+ */
+ public $useDbConfig = 'test';
+
+/**
+ * cacheSources property
+ *
+ * @var bool false
+ */
+ public $cacheSources = false;
+}
+
+/**
+ * AroTwoTest class
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class AroTwoTest extends AclNodeTwoTestBase {
+
+/**
+ * name property
+ *
+ * @var string 'AroTwoTest'
+ */
+ public $name = 'AroTwoTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'aro_twos'
+ */
+ public $useTable = 'aro_twos';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('AcoTwoTest' => array('with' => 'PermissionTwoTest'));
+}
+
+/**
+ * AcoTwoTest class
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class AcoTwoTest extends AclNodeTwoTestBase {
+
+/**
+ * name property
+ *
+ * @var string 'AcoTwoTest'
+ */
+ public $name = 'AcoTwoTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'aco_twos'
+ */
+ public $useTable = 'aco_twos';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('AroTwoTest' => array('with' => 'PermissionTwoTest'));
+}
+
+/**
+ * PermissionTwoTest class
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class PermissionTwoTest extends Permission {
+
+/**
+ * name property
+ *
+ * @var string 'PermissionTwoTest'
+ */
+ public $name = 'PermissionTwoTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'aros_aco_twos'
+ */
+ public $useTable = 'aros_aco_twos';
+
+/**
+ * cacheQueries property
+ *
+ * @var bool false
+ */
+ public $cacheQueries = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('AroTwoTest' => array('foreignKey' => 'aro_id'), 'AcoTwoTest' => array('foreignKey' => 'aco_id'));
+
+/**
+ * actsAs property
+ *
+ * @var mixed null
+ */
+ public $actsAs = null;
+}
+
+/**
+ * DbAclTwoTest class
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class DbAclTwoTest extends DbAcl {
+
+/**
+ * construct method
+ *
+ * @return void
+ */
+ public function __construct() {
+ $this->Aro = new AroTwoTest();
+ $this->Aro->Permission = new PermissionTwoTest();
+ $this->Aco = new AcoTwoTest();
+ $this->Aro->Permission = new PermissionTwoTest();
+
+ $this->Permission = $this->Aro->Permission;
+ $this->Permission->Aro = $this->Aro;
+ $this->Permission->Aco = $this->Aco;
+ }
+
+}
+
+/**
+ * Test case for AclComponent using the DbAcl implementation.
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class DbAclTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.aro_two', 'core.aco_two', 'core.aros_aco_two');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Acl.classname', 'DbAclTwoTest');
+ Configure::write('Acl.database', 'test');
+ $Collection = new ComponentCollection();
+ $this->Acl = new AclComponent($Collection);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Acl);
+ }
+
+/**
+ * testAclCreate method
+ *
+ * @return void
+ */
+ public function testCreate() {
+ $this->Acl->Aro->create(array('alias' => 'Chotchkey'));
+ $this->assertTrue((bool)$this->Acl->Aro->save());
+
+ $parent = $this->Acl->Aro->id;
+
+ $this->Acl->Aro->create(array('parent_id' => $parent, 'alias' => 'Joanna'));
+ $this->assertTrue((bool)$this->Acl->Aro->save());
+
+ $this->Acl->Aro->create(array('parent_id' => $parent, 'alias' => 'Stapler'));
+ $this->assertTrue((bool)$this->Acl->Aro->save());
+
+ $root = $this->Acl->Aco->node('ROOT');
+ $parent = $root[0]['AcoTwoTest']['id'];
+
+ $this->Acl->Aco->create(array('parent_id' => $parent, 'alias' => 'Drinks'));
+ $this->assertTrue((bool)$this->Acl->Aco->save());
+
+ $this->Acl->Aco->create(array('parent_id' => $parent, 'alias' => 'PiecesOfFlair'));
+ $this->assertTrue((bool)$this->Acl->Aco->save());
+ }
+
+/**
+ * testAclCreateWithParent method
+ *
+ * @return void
+ */
+ public function testCreateWithParent() {
+ $parent = $this->Acl->Aro->findByAlias('Peter', null, null, -1);
+ $this->Acl->Aro->create();
+ $this->Acl->Aro->save(array(
+ 'alias' => 'Subordinate',
+ 'model' => 'User',
+ 'foreign_key' => 7,
+ 'parent_id' => $parent['AroTwoTest']['id']
+ ));
+ $result = $this->Acl->Aro->findByAlias('Subordinate', null, null, -1);
+ $this->assertEquals(16, $result['AroTwoTest']['lft']);
+ $this->assertEquals(17, $result['AroTwoTest']['rght']);
+ }
+
+/**
+ * testDbAclAllow method
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testAllow() {
+ $this->assertFalse($this->Acl->check('Micheal', 'tpsReports', 'read'));
+ $this->assertTrue($this->Acl->allow('Micheal', 'tpsReports', array('read', 'delete', 'update')));
+ $this->assertTrue($this->Acl->check('Micheal', 'tpsReports', 'update'));
+ $this->assertTrue($this->Acl->check('Micheal', 'tpsReports', 'read'));
+ $this->assertTrue($this->Acl->check('Micheal', 'tpsReports', 'delete'));
+
+ $this->assertFalse($this->Acl->check('Micheal', 'tpsReports', 'create'));
+ $this->assertTrue($this->Acl->allow('Micheal', 'ROOT/tpsReports', 'create'));
+ $this->assertTrue($this->Acl->check('Micheal', 'tpsReports', 'create'));
+ $this->assertTrue($this->Acl->check('Micheal', 'tpsReports', 'delete'));
+ $this->assertTrue($this->Acl->allow('Micheal', 'printers', 'create'));
+ // Michael no longer has his delete permission for tpsReports!
+ $this->assertTrue($this->Acl->check('Micheal', 'tpsReports', 'delete'));
+ $this->assertTrue($this->Acl->check('Micheal', 'printers', 'create'));
+
+ $this->assertFalse($this->Acl->check('root/users/Samir', 'ROOT/tpsReports/view'));
+ $this->assertTrue($this->Acl->allow('root/users/Samir', 'ROOT/tpsReports/view', '*'));
+ $this->assertTrue($this->Acl->check('Samir', 'view', 'read'));
+ $this->assertTrue($this->Acl->check('root/users/Samir', 'ROOT/tpsReports/view', 'update'));
+
+ $this->assertFalse($this->Acl->check('root/users/Samir', 'ROOT/tpsReports/update','*'));
+ $this->assertTrue($this->Acl->allow('root/users/Samir', 'ROOT/tpsReports/update', '*'));
+ $this->assertTrue($this->Acl->check('Samir', 'update', 'read'));
+ $this->assertTrue($this->Acl->check('root/users/Samir', 'ROOT/tpsReports/update', 'update'));
+ // Samir should still have his tpsReports/view permissions, but does not
+ $this->assertTrue($this->Acl->check('root/users/Samir', 'ROOT/tpsReports/view', 'update'));
+
+ $this->assertFalse($this->Acl->allow('Lumbergh', 'ROOT/tpsReports/DoesNotExist', 'create'));
+ }
+
+/**
+ * testAllowInvalidNode method
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testAllowInvalidNode() {
+ $this->Acl->allow('Homer', 'tpsReports', 'create');
+ }
+
+/**
+ * testDbAclCheck method
+ *
+ * @return void
+ */
+ public function testCheck() {
+ $this->assertTrue($this->Acl->check('Samir', 'print', 'read'));
+ $this->assertTrue($this->Acl->check('Lumbergh', 'current', 'read'));
+ $this->assertFalse($this->Acl->check('Milton', 'smash', 'read'));
+ $this->assertFalse($this->Acl->check('Milton', 'current', 'update'));
+
+ $this->assertFalse($this->Acl->check(null, 'printers', 'create'));
+ $this->assertFalse($this->Acl->check('managers', null, 'read'));
+
+ $this->assertTrue($this->Acl->check('Bobs', 'ROOT/tpsReports/view/current', 'read'));
+ $this->assertFalse($this->Acl->check('Samir', 'ROOT/tpsReports/update', 'read'));
+
+ $this->assertFalse($this->Acl->check('root/users/Milton', 'smash', 'delete'));
+ }
+
+/**
+ * testCheckInvalidNode method
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testCheckInvalidNode() {
+ $this->assertFalse($this->Acl->check('WRONG', 'tpsReports', 'read'));
+ }
+
+/**
+ * testCheckInvalidPermission method
+ *
+ * @expectedException PHPUnit_Framework_Error_Notice
+ * @return void
+ */
+ public function testCheckInvalidPermission() {
+ $this->Acl->check('Lumbergh', 'smash', 'foobar');
+ }
+
+/**
+ * testCheckMissingPermission method
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testCheckMissingPermission() {
+ $this->Acl->check('users', 'NonExistent', 'read');
+ }
+
+/**
+ * testDbAclCascadingDeny function
+ *
+ * Setup the acl permissions such that Bobs inherits from admin.
+ * deny Admin delete access to a specific resource, check the permissions are inherited.
+ *
+ * @return void
+ */
+ public function testAclCascadingDeny() {
+ $this->Acl->inherit('Bobs', 'ROOT', '*');
+ $this->assertTrue($this->Acl->check('admin', 'tpsReports', 'delete'));
+ $this->assertTrue($this->Acl->check('Bobs', 'tpsReports', 'delete'));
+ $this->Acl->deny('admin', 'tpsReports', 'delete');
+ $this->assertFalse($this->Acl->check('admin', 'tpsReports', 'delete'));
+ $this->assertFalse($this->Acl->check('Bobs', 'tpsReports', 'delete'));
+ }
+
+/**
+ * testDbAclDeny method
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testDeny() {
+ $this->assertTrue($this->Acl->check('Micheal', 'smash', 'delete'));
+ $this->Acl->deny('Micheal', 'smash', 'delete');
+ $this->assertFalse($this->Acl->check('Micheal', 'smash', 'delete'));
+ $this->assertTrue($this->Acl->check('Micheal', 'smash', 'read'));
+ $this->assertTrue($this->Acl->check('Micheal', 'smash', 'create'));
+ $this->assertTrue($this->Acl->check('Micheal', 'smash', 'update'));
+ $this->assertFalse($this->Acl->check('Micheal', 'smash', '*'));
+
+ $this->assertTrue($this->Acl->check('Samir', 'refill', '*'));
+ $this->Acl->deny('Samir', 'refill', '*');
+ $this->assertFalse($this->Acl->check('Samir', 'refill', 'create'));
+ $this->assertFalse($this->Acl->check('Samir', 'refill', 'update'));
+ $this->assertFalse($this->Acl->check('Samir', 'refill', 'read'));
+ $this->assertFalse($this->Acl->check('Samir', 'refill', 'delete'));
+
+ $result = $this->Acl->Aro->Permission->find('all', array('conditions' => array('AroTwoTest.alias' => 'Samir')));
+ $expected = '-1';
+ $this->assertEquals($expected, $result[0]['PermissionTwoTest']['_delete']);
+
+ $this->assertFalse($this->Acl->deny('Lumbergh', 'ROOT/tpsReports/DoesNotExist', 'create'));
+ }
+
+/**
+ * testAclNodeLookup method
+ *
+ * @return void
+ */
+ public function testAclNodeLookup() {
+ $result = $this->Acl->Aro->node('root/users/Samir');
+ $expected = array(
+ array('AroTwoTest' => array('id' => '7', 'parent_id' => '4', 'model' => 'User', 'foreign_key' => 3, 'alias' => 'Samir')),
+ array('AroTwoTest' => array('id' => '4', 'parent_id' => '1', 'model' => 'Group', 'foreign_key' => 3, 'alias' => 'users')),
+ array('AroTwoTest' => array('id' => '1', 'parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'root'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Acl->Aco->node('ROOT/tpsReports/view/current');
+ $expected = array(
+ array('AcoTwoTest' => array('id' => '4', 'parent_id' => '3', 'model' => null, 'foreign_key' => null, 'alias' => 'current')),
+ array('AcoTwoTest' => array('id' => '3', 'parent_id' => '2', 'model' => null, 'foreign_key' => null, 'alias' => 'view')),
+ array('AcoTwoTest' => array('id' => '2', 'parent_id' => '1', 'model' => null, 'foreign_key' => null, 'alias' => 'tpsReports')),
+ array('AcoTwoTest' => array('id' => '1', 'parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'ROOT')),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testDbInherit method
+ *
+ * @return void
+ */
+ public function testInherit() {
+ //parent doesn't have access inherit should still deny
+ $this->assertFalse($this->Acl->check('Milton', 'smash', 'delete'));
+ $this->Acl->inherit('Milton', 'smash', 'delete');
+ $this->assertFalse($this->Acl->check('Milton', 'smash', 'delete'));
+
+ //inherit parent
+ $this->assertFalse($this->Acl->check('Milton', 'smash', 'read'));
+ $this->Acl->inherit('Milton', 'smash', 'read');
+ $this->assertTrue($this->Acl->check('Milton', 'smash', 'read'));
+ }
+
+/**
+ * testDbGrant method
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testGrant() {
+ $this->assertFalse($this->Acl->check('Samir', 'tpsReports', 'create'));
+ $this->Acl->allow('Samir', 'tpsReports', 'create');
+ $this->assertTrue($this->Acl->check('Samir', 'tpsReports', 'create'));
+
+ $this->assertFalse($this->Acl->check('Micheal', 'view', 'read'));
+ $this->Acl->allow('Micheal', 'view', array('read', 'create', 'update'));
+ $this->assertTrue($this->Acl->check('Micheal', 'view', 'read'));
+ $this->assertTrue($this->Acl->check('Micheal', 'view', 'create'));
+ $this->assertTrue($this->Acl->check('Micheal', 'view', 'update'));
+ $this->assertFalse($this->Acl->check('Micheal', 'view', 'delete'));
+
+ $this->assertFalse($this->Acl->allow('Peter', 'ROOT/tpsReports/DoesNotExist', 'create'));
+ }
+
+/**
+ * testDbRevoke method
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testRevoke() {
+ $this->assertTrue($this->Acl->check('Bobs', 'tpsReports', 'read'));
+ $this->Acl->deny('Bobs', 'tpsReports', 'read');
+ $this->assertFalse($this->Acl->check('Bobs', 'tpsReports', 'read'));
+
+ $this->assertTrue($this->Acl->check('users', 'printers', 'read'));
+ $this->Acl->deny('users', 'printers', 'read');
+ $this->assertFalse($this->Acl->check('users', 'printers', 'read'));
+ $this->assertFalse($this->Acl->check('Samir', 'printers', 'read'));
+ $this->assertFalse($this->Acl->check('Peter', 'printers', 'read'));
+
+ $this->Acl->deny('Bobs', 'ROOT/printers/DoesNotExist', 'create');
+ }
+
+/**
+ * debug function - to help editing/creating test cases for the ACL component
+ *
+ * To check the overall ACL status at any time call $this->__debug();
+ * Generates a list of the current aro and aco structures and a grid dump of the permissions that are defined
+ * Only designed to work with the db based ACL
+ *
+ * @param bool $treesToo
+ * @return void
+ */
+ protected function __debug($printTreesToo = false) {
+ $this->Acl->Aro->displayField = 'alias';
+ $this->Acl->Aco->displayField = 'alias';
+ $aros = $this->Acl->Aro->find('list', array('order' => 'lft'));
+ $acos = $this->Acl->Aco->find('list', array('order' => 'lft'));
+ $rights = array('*', 'create', 'read', 'update', 'delete');
+ $permissions['Aros v Acos >'] = $acos;
+ foreach ($aros as $aro) {
+ $row = array();
+ foreach ($acos as $aco) {
+ $perms = '';
+ foreach ($rights as $right) {
+ if ($this->Acl->check($aro, $aco, $right)) {
+ if ($right == '*') {
+ $perms .= '****';
+ break;
+ }
+ $perms .= $right[0];
+ } elseif ($right != '*') {
+ $perms .= ' ';
+ }
+ }
+ $row[] = $perms;
+ }
+ $permissions[$aro] = $row;
+ }
+ foreach ($permissions as $key => $values) {
+ array_unshift($values, $key);
+ $values = array_map(array(&$this, '__pad'), $values);
+ $permissions[$key] = implode (' ', $values);
+ }
+ $permisssions = array_map(array(&$this, '__pad'), $permissions);
+ array_unshift($permissions, 'Current Permissions :');
+ if ($printTreesToo) {
+ debug(array('aros' => $this->Acl->Aro->generateTreeList(), 'acos' => $this->Acl->Aco->generateTreeList()));
+ }
+ debug(implode("\r\n", $permissions));
+ }
+
+/**
+ * pad function
+ * Used by debug to format strings used in the data dump
+ *
+ * @param string $string
+ * @param integer $len
+ * @return void
+ */
+ protected function __pad($string = '', $len = 14) {
+ return str_pad($string, $len);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/IniAclTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/IniAclTest.php
new file mode 100644
index 0000000..de552b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/IniAclTest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * IniAclTest file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Acl
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('IniAcl', 'Controller/Component/Acl');
+
+/**
+ * Test case for the IniAcl implementation
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class IniAclTest extends CakeTestCase {
+
+/**
+ * testIniCheck method
+ *
+ * @return void
+ */
+ public function testCheck() {
+ $iniFile = CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'acl.ini.php';
+
+ $Ini = new IniAcl();
+ $Ini->config = $Ini->readConfigFile($iniFile);
+
+ $this->assertFalse($Ini->check('admin', 'ads'));
+ $this->assertTrue($Ini->check('admin', 'posts'));
+
+ $this->assertTrue($Ini->check('jenny', 'posts'));
+ $this->assertTrue($Ini->check('jenny', 'ads'));
+
+ $this->assertTrue($Ini->check('paul', 'posts'));
+ $this->assertFalse($Ini->check('paul', 'ads'));
+
+ $this->assertFalse($Ini->check('nobody', 'comments'));
+ }
+
+/**
+ * check should accept a user array.
+ *
+ * @return void
+ */
+ public function testCheckArray() {
+ $iniFile = CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'acl.ini.php';
+
+ $Ini = new IniAcl();
+ $Ini->config = $Ini->readConfigFile($iniFile);
+ $Ini->userPath = 'User.username';
+
+ $user = array(
+ 'User' => array('username' => 'admin')
+ );
+ $this->assertTrue($Ini->check($user, 'posts'));
+ }
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php
new file mode 100644
index 0000000..92543b3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Acl/PhpAclTest.php
@@ -0,0 +1,337 @@
+<?php
+/**
+ * PhpAclTest file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Acl
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AclComponent', 'Controller/Component');
+App::uses('PhpAcl', 'Controller/Component/Acl');
+class_exists('AclComponent');
+
+/**
+ * Test case for the PhpAcl implementation
+ *
+ * @package Cake.Test.Case.Controller.Component.Acl
+ */
+class PhpAclTest extends CakeTestCase {
+
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Acl.classname', 'PhpAcl');
+ $Collection = new ComponentCollection();
+ $this->PhpAcl = new PhpAcl();
+ $this->Acl = new AclComponent($Collection, array(
+ 'adapter' => array(
+ 'config' => CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'acl.php',
+ ),
+ ));
+ }
+
+ public function testRoleInheritance() {
+ $roles = $this->Acl->Aro->roles('User/peter');
+ $this->assertEquals(array('Role/accounting'), $roles[0]);
+ $this->assertEquals(array('User/peter'), $roles[1]);
+
+ $roles = $this->Acl->Aro->roles('hardy');
+ $this->assertEquals(array('Role/database_manager', 'Role/data_acquirer'), $roles[0]);
+ $this->assertEquals(array('Role/accounting', 'Role/data_analyst'), $roles[1]);
+ $this->assertEquals(array('Role/accounting_manager', 'Role/reports'), $roles[2]);
+ $this->assertEquals(array('User/hardy'), $roles[3]);
+ }
+
+ public function testAddRole() {
+ $this->assertEquals(array(array(PhpAro::DEFAULT_ROLE)), $this->Acl->Aro->roles('foobar'));
+ $this->Acl->Aro->addRole(array('User/foobar' => 'Role/accounting'));
+ $this->assertEquals(array(array('Role/accounting'), array('User/foobar')), $this->Acl->Aro->roles('foobar'));
+ }
+
+ public function testAroResolve() {
+ $map = $this->Acl->Aro->map;
+ $this->Acl->Aro->map = array(
+ 'User' => 'FooModel/nickname',
+ 'Role' => 'FooModel/role',
+ );
+
+ $this->assertEquals('Role/default', $this->Acl->Aro->resolve('Foo.bar'));
+ $this->assertEquals('User/hardy', $this->Acl->Aro->resolve('FooModel/hardy'));
+ $this->assertEquals('User/hardy', $this->Acl->Aro->resolve('hardy'));
+ $this->assertEquals('User/hardy', $this->Acl->Aro->resolve(array('FooModel' => array('nickname' => 'hardy'))));
+ $this->assertEquals('Role/admin', $this->Acl->Aro->resolve(array('FooModel' => array('role' => 'admin'))));
+ $this->assertEquals('Role/admin', $this->Acl->Aro->resolve('Role/admin'));
+
+ $this->assertEquals('Role/admin', $this->Acl->Aro->resolve('admin'));
+ $this->assertEquals('Role/admin', $this->Acl->Aro->resolve('FooModel/admin'));
+ $this->assertEquals('Role/accounting', $this->Acl->Aro->resolve('accounting'));
+
+ $this->assertEquals(PhpAro::DEFAULT_ROLE, $this->Acl->Aro->resolve('bla'));
+ $this->assertEquals(PhpAro::DEFAULT_ROLE, $this->Acl->Aro->resolve(array('FooModel' => array('role' => 'hardy'))));
+ }
+
+/**
+ * test correct resolution of defined aliases
+ */
+ public function testAroAliases() {
+ $this->Acl->Aro->map = array(
+ 'User' => 'User/username',
+ 'Role' => 'User/group_id',
+ );
+
+ $this->Acl->Aro->aliases = array(
+ 'Role/1' => 'Role/admin',
+ 'Role/24' => 'Role/accounting',
+ );
+
+ $user = array(
+ 'User' => array(
+ 'username' => 'unknown_user',
+ 'group_id' => '1',
+ ),
+ );
+ // group/1
+ $this->assertEquals('Role/admin', $this->Acl->Aro->resolve($user));
+ // group/24
+ $this->assertEquals('Role/accounting', $this->Acl->Aro->resolve('Role/24'));
+ $this->assertEquals('Role/accounting', $this->Acl->Aro->resolve('24'));
+
+ // check department
+ $user = array(
+ 'User' => array(
+ 'username' => 'foo',
+ 'group_id' => '25',
+ ),
+ );
+
+ $this->Acl->Aro->addRole(array('Role/IT' => null));
+ $this->Acl->Aro->addAlias(array('Role/25' => 'Role/IT'));
+ $this->Acl->allow('Role/IT', '/rules/debugging/*');
+
+ $this->assertEquals(array(array('Role/IT', )), $this->Acl->Aro->roles($user));
+ $this->assertTrue($this->Acl->check($user, '/rules/debugging/stats/pageload'));
+ $this->assertTrue($this->Acl->check($user, '/rules/debugging/sql/queries'));
+ // Role/default is allowed users dashboard, but not Role/IT
+ $this->assertFalse($this->Acl->check($user, '/controllers/users/dashboard'));
+
+ $this->assertFalse($this->Acl->check($user, '/controllers/invoices/send'));
+ // wee add an more specific entry for user foo to also inherit from Role/accounting
+ $this->Acl->Aro->addRole(array('User/foo' => 'Role/IT, Role/accounting'));
+ $this->assertTrue($this->Acl->check($user, '/controllers/invoices/send'));
+ }
+
+/**
+ * test check method
+ *
+ * @return void
+ */
+ public function testCheck() {
+ $this->assertTrue($this->Acl->check('jan', '/controllers/users/Dashboard'));
+ $this->assertTrue($this->Acl->check('some_unknown_role', '/controllers/users/Dashboard'));
+ $this->assertTrue($this->Acl->check('Role/admin', 'foo/bar'));
+ $this->assertTrue($this->Acl->check('role/admin', '/foo/bar'));
+ $this->assertTrue($this->Acl->check('jan', 'foo/bar'));
+ $this->assertTrue($this->Acl->check('user/jan', 'foo/bar'));
+ $this->assertTrue($this->Acl->check('Role/admin', 'controllers/bar'));
+ $this->assertTrue($this->Acl->check(array('User' => array('username' => 'jan')), '/controllers/bar/bll'));
+ $this->assertTrue($this->Acl->check('Role/database_manager', 'controllers/db/create'));
+ $this->assertTrue($this->Acl->check('User/db_manager_2', 'controllers/db/create'));
+ $this->assertFalse($this->Acl->check('db_manager_2', '/controllers/users/Dashboard'));
+
+ // inheritance: hardy -> reports -> data_analyst -> database_manager
+ $this->assertTrue($this->Acl->check('User/hardy', 'controllers/db/create'));
+ $this->assertFalse($this->Acl->check('User/jeff', 'controllers/db/create'));
+
+ $this->assertTrue($this->Acl->check('Role/database_manager', 'controllers/db/select'));
+ $this->assertTrue($this->Acl->check('User/db_manager_2', 'controllers/db/select'));
+ $this->assertFalse($this->Acl->check('User/jeff', 'controllers/db/select'));
+
+ $this->assertTrue($this->Acl->check('Role/database_manager', 'controllers/db/drop'));
+ $this->assertTrue($this->Acl->check('User/db_manager_1', 'controllers/db/drop'));
+ $this->assertFalse($this->Acl->check('db_manager_2', 'controllers/db/drop'));
+
+ $this->assertTrue($this->Acl->check('db_manager_2', 'controllers/invoices/edit'));
+ $this->assertFalse($this->Acl->check('database_manager', 'controllers/invoices/edit'));
+ $this->assertFalse($this->Acl->check('db_manager_1', 'controllers/invoices/edit'));
+
+ // Role/manager is allowed /controllers/*/*_manager
+ $this->assertTrue($this->Acl->check('stan', 'controllers/invoices/manager_edit'));
+ $this->assertTrue($this->Acl->check('Role/manager', 'controllers/baz/manager_foo'));
+ $this->assertFalse($this->Acl->check('User/stan', 'custom/foo/manager_edit'));
+ $this->assertFalse($this->Acl->check('stan', 'bar/baz/manager_foo'));
+ $this->assertFalse($this->Acl->check('Role/accounting', 'bar/baz/manager_foo'));
+ $this->assertFalse($this->Acl->check('accounting', 'controllers/baz/manager_foo'));
+
+ $this->assertTrue($this->Acl->check('User/stan', 'controllers/articles/edit'));
+ $this->assertTrue($this->Acl->check('stan', 'controllers/articles/add'));
+ $this->assertTrue($this->Acl->check('stan', 'controllers/articles/publish'));
+ $this->assertFalse($this->Acl->check('User/stan', 'controllers/articles/delete'));
+ $this->assertFalse($this->Acl->check('accounting', 'controllers/articles/edit'));
+ $this->assertFalse($this->Acl->check('accounting', 'controllers/articles/add'));
+ $this->assertFalse($this->Acl->check('role/accounting', 'controllers/articles/publish'));
+ }
+
+/**
+ * lhs of defined rules are case insensitive
+ */
+ public function testCheckIsCaseInsensitive() {
+ $this->assertTrue($this->Acl->check('hardy', 'controllers/forms/new'));
+ $this->assertTrue($this->Acl->check('Role/data_acquirer', 'controllers/forms/new'));
+ $this->assertTrue($this->Acl->check('hardy', 'controllers/FORMS/NEW'));
+ $this->assertTrue($this->Acl->check('Role/data_acquirer', 'controllers/FORMS/NEW'));
+ }
+
+/**
+ * allow should work in-memory
+ */
+ public function testAllow() {
+ $this->assertFalse($this->Acl->check('jeff', 'foo/bar'));
+
+ $this->Acl->allow('jeff', 'foo/bar');
+
+ $this->assertTrue($this->Acl->check('jeff', 'foo/bar'));
+ $this->assertFalse($this->Acl->check('peter', 'foo/bar'));
+ $this->assertFalse($this->Acl->check('hardy', 'foo/bar'));
+
+ $this->Acl->allow('Role/accounting', 'foo/bar');
+
+ $this->assertTrue($this->Acl->check('peter', 'foo/bar'));
+ $this->assertTrue($this->Acl->check('hardy', 'foo/bar'));
+
+ $this->assertFalse($this->Acl->check('Role/reports', 'foo/bar'));
+ }
+
+/**
+ * deny should work in-memory
+ */
+ public function testDeny() {
+ $this->assertTrue($this->Acl->check('stan', 'controllers/baz/manager_foo'));
+
+ $this->Acl->deny('stan', 'controllers/baz/manager_foo');
+
+ $this->assertFalse($this->Acl->check('stan', 'controllers/baz/manager_foo'));
+ $this->assertTrue($this->Acl->check('Role/manager', 'controllers/baz/manager_foo'));
+ $this->assertTrue($this->Acl->check('stan', 'controllers/baz/manager_bar'));
+ $this->assertTrue($this->Acl->check('stan', 'controllers/baz/manager_foooooo'));
+ }
+
+/**
+ * test that a deny rule wins over an equally specific allow rule
+ */
+ public function testDenyRuleIsStrongerThanAllowRule() {
+ $this->assertFalse($this->Acl->check('peter', 'baz/bam'));
+ $this->Acl->allow('peter', 'baz/bam');
+ $this->assertTrue($this->Acl->check('peter', 'baz/bam'));
+ $this->Acl->deny('peter', 'baz/bam');
+ $this->assertFalse($this->Acl->check('peter', 'baz/bam'));
+
+ $this->assertTrue($this->Acl->check('stan', 'controllers/reports/foo'));
+ // stan is denied as he's sales and sales is denied /controllers/*/delete
+ $this->assertFalse($this->Acl->check('stan', 'controllers/reports/delete'));
+ $this->Acl->allow('stan', 'controllers/reports/delete');
+ $this->assertFalse($this->Acl->check('Role/sales', 'controllers/reports/delete'));
+ $this->assertTrue($this->Acl->check('stan', 'controllers/reports/delete'));
+ $this->Acl->deny('stan', 'controllers/reports/delete');
+ $this->assertFalse($this->Acl->check('stan', 'controllers/reports/delete'));
+
+ // there is already an equally specific deny rule that will win
+ $this->Acl->allow('stan', 'controllers/reports/delete');
+ $this->assertFalse($this->Acl->check('stan', 'controllers/reports/delete'));
+ }
+
+/**
+ * test that an invalid configuration throws exception
+ */
+ public function testInvalidConfigWithAroMissing() {
+ $this->setExpectedException(
+ 'AclException',
+ '"roles" section not found in configuration'
+ );
+ $config = array('aco' => array('allow' => array('foo' => '')));
+ $this->PhpAcl->build($config);
+ }
+
+ public function testInvalidConfigWithAcosMissing() {
+ $this->setExpectedException(
+ 'AclException',
+ 'Neither "allow" nor "deny" rules were provided in configuration.'
+ );
+
+ $config = array(
+ 'roles' => array('Role/foo' => null),
+ );
+
+ $this->PhpAcl->build($config);
+ }
+
+/**
+ * test resolving of ACOs
+ */
+ public function testAcoResolve() {
+ $this->assertEquals(array('foo', 'bar'), $this->Acl->Aco->resolve('foo/bar'));
+ $this->assertEquals(array('foo', 'bar'), $this->Acl->Aco->resolve('foo/bar'));
+ $this->assertEquals(array('foo', 'bar', 'baz'), $this->Acl->Aco->resolve('foo/bar/baz'));
+ $this->assertEquals(array('foo', '*-bar', '?-baz'), $this->Acl->Aco->resolve('foo/*-bar/?-baz'));
+
+ $this->assertEquals(array('foo', 'bar', '[a-f0-9]{24}', '*_bla', 'bla'), $this->Acl->Aco->resolve('foo/bar/[a-f0-9]{24}/*_bla/bla'));
+
+ // multiple slashes will be squashed to a single, trimmed and then exploded
+ $this->assertEquals(array('foo', 'bar'), $this->Acl->Aco->resolve('foo//bar'));
+ $this->assertEquals(array('foo', 'bar'), $this->Acl->Aco->resolve('//foo///bar/'));
+ $this->assertEquals(array('foo', 'bar'), $this->Acl->Aco->resolve('/foo//bar//'));
+ $this->assertEquals(array('foo', 'bar'), $this->Acl->Aco->resolve('/foo // bar'));
+ $this->assertEquals(array(), $this->Acl->Aco->resolve('/////'));
+ }
+
+/**
+ * test that declaring cyclic dependencies should give an error when building the tree
+ */
+ public function testAroDeclarationContainsCycles() {
+ $config = array(
+ 'roles' => array(
+ 'Role/a' => null,
+ 'Role/b' => 'User/b',
+ 'User/a' => 'Role/a, Role/b',
+ 'User/b' => 'User/a',
+
+ ),
+ 'rules' => array(
+ 'allow' => array(
+ '*' => 'Role/a',
+ ),
+ ),
+ );
+
+ $this->expectError('PHPUnit_Framework_Error', 'cycle detected' /* ... */);
+ $this->PhpAcl->build($config);
+ }
+
+/**
+ * test that with policy allow, only denies count
+ */
+ public function testPolicy() {
+ // allow by default
+ $this->Acl->settings['adapter']['policy'] = PhpAcl::ALLOW;
+ $this->Acl->adapter($this->PhpAcl);
+
+ $this->assertTrue($this->Acl->check('Role/sales', 'foo'));
+ $this->assertTrue($this->Acl->check('Role/sales', 'controllers/bla/create'));
+ $this->assertTrue($this->Acl->check('Role/default', 'foo'));
+ // undefined user, undefined aco
+ $this->assertTrue($this->Acl->check('foobar', 'foo/bar'));
+
+ // deny rule: Role.sales -> controllers.*.delete
+ $this->assertFalse($this->Acl->check('Role/sales', 'controllers/bar/delete'));
+ $this->assertFalse($this->Acl->check('Role/sales', 'controllers/bar', 'delete'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php
new file mode 100644
index 0000000..b16d7af
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * AclComponentTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.5435
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('AclComponent', 'Controller/Component');
+class_exists('AclComponent');
+
+/**
+ * Test Case for AclComponent
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class AclComponentTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ if (!class_exists('MockAclImplementation', false)) {
+ $this->getMock('AclInterface', array(), array(), 'MockAclImplementation');
+ }
+ Configure::write('Acl.classname', 'MockAclImplementation');
+ $Collection = new ComponentCollection();
+ $this->Acl = new AclComponent($Collection);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Acl);
+ }
+
+/**
+ * test that constructor throws an exception when Acl.classname is a
+ * non-existent class
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testConstrutorException() {
+ Configure::write('Acl.classname', 'AclClassNameThatDoesNotExist');
+ $Collection = new ComponentCollection();
+ $acl = new AclComponent($Collection);
+ }
+
+/**
+ * test that adapter() allows control of the internal implementation AclComponent uses.
+ *
+ * @return void
+ */
+ public function testAdapter() {
+ $implementation = new MockAclImplementation();
+ $implementation->expects($this->once())->method('initialize')->with($this->Acl);
+ $this->assertNull($this->Acl->adapter($implementation));
+
+ $this->assertEquals($this->Acl->adapter(), $implementation, 'Returned object is different %s');
+ }
+
+/**
+ * test that adapter() whines when the class is not an AclBase
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testAdapterException() {
+ $thing = new StdClass();
+ $this->Acl->adapter($thing);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php
new file mode 100644
index 0000000..6b06b37
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ActionsAuthorizeTest.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * ActionsAuthorizeTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Auth
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ActionsAuthorize', 'Controller/Component/Auth');
+App::uses('ComponentCollection', 'Controller');
+App::uses('AclComponent', 'Controller/Component');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+
+class ActionsAuthorizeTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->controller = $this->getMock('Controller', array(), array(), '', false);
+ $this->Acl = $this->getMock('AclComponent', array(), array(), '', false);
+ $this->Collection = $this->getMock('ComponentCollection');
+
+ $this->auth = new ActionsAuthorize($this->Collection);
+ $this->auth->settings['actionPath'] = '/controllers';
+ }
+
+/**
+ * setup the mock acl.
+ *
+ * @return void
+ */
+ protected function _mockAcl() {
+ $this->Collection->expects($this->any())
+ ->method('load')
+ ->with('Acl')
+ ->will($this->returnValue($this->Acl));
+ }
+
+/**
+ * test failure
+ *
+ * @return void
+ */
+ public function testAuthorizeFailure() {
+ $user = array(
+ 'User' => array(
+ 'id' => 1,
+ 'user' => 'mariano'
+ )
+ );
+ $request = new CakeRequest('/posts/index', false);
+ $request->addParams(array(
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ));
+
+ $this->_mockAcl();
+
+ $this->Acl->expects($this->once())
+ ->method('check')
+ ->with($user, 'controllers/Posts/index')
+ ->will($this->returnValue(false));
+
+ $this->assertFalse($this->auth->authorize($user['User'], $request));
+ }
+
+/**
+ * test isAuthorized working.
+ *
+ * @return void
+ */
+ public function testAuthorizeSuccess() {
+ $user = array(
+ 'User' => array(
+ 'id' => 1,
+ 'user' => 'mariano'
+ )
+ );
+ $request = new CakeRequest('/posts/index', false);
+ $request->addParams(array(
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ));
+
+ $this->_mockAcl();
+
+ $this->Acl->expects($this->once())
+ ->method('check')
+ ->with($user, 'controllers/Posts/index')
+ ->will($this->returnValue(true));
+
+ $this->assertTrue($this->auth->authorize($user['User'], $request));
+ }
+
+/**
+ * testAuthorizeSettings
+ *
+ * @return void
+ */
+ public function testAuthorizeSettings() {
+ $request = new CakeRequest('/posts/index', false);
+ $request->addParams(array(
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ));
+
+ $this->_mockAcl();
+
+ $this->auth->settings['userModel'] = 'TestPlugin.TestPluginAuthUser';
+ $user = array(
+ 'id' => 1,
+ 'user' => 'mariano'
+ );
+
+ $expected = array('TestPlugin.TestPluginAuthUser' => array('id' => 1, 'user' => 'mariano'));
+ $this->Acl->expects($this->once())
+ ->method('check')
+ ->with($expected, 'controllers/Posts/index')
+ ->will($this->returnValue(true));
+
+ $this->assertTrue($this->auth->authorize($user, $request));
+ }
+
+/**
+ * test action()
+ *
+ * @return void
+ */
+ public function testActionMethod() {
+ $request = new CakeRequest('/posts/index', false);
+ $request->addParams(array(
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ));
+
+ $result = $this->auth->action($request);
+ $this->assertEquals('controllers/Posts/index', $result);
+ }
+
+/**
+ * Make sure that action() doesn't create double slashes anywhere.
+ *
+ * @return void
+ */
+ public function testActionNoDoubleSlash() {
+ $this->auth->settings['actionPath'] = '/controllers/';
+ $request = array(
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'index'
+ );
+ $result = $this->auth->action($request);
+ $this->assertEquals('controllers/Posts/index', $result);
+ }
+
+/**
+ * test action() and plugins
+ *
+ * @return void
+ */
+ public function testActionWithPlugin() {
+ $request = new CakeRequest('/debug_kit/posts/index', false);
+ $request->addParams(array(
+ 'plugin' => 'debug_kit',
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ));
+
+ $result = $this->auth->action($request);
+ $this->assertEquals('controllers/DebugKit/Posts/index', $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php
new file mode 100644
index 0000000..b1affff
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php
@@ -0,0 +1,206 @@
+<?php
+/**
+ * BasicAuthenticateTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Auth
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AuthComponent', 'Controller/Component');
+App::uses('BasicAuthenticate', 'Controller/Component/Auth');
+App::uses('AppModel', 'Model');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+
+
+require_once CAKE . 'Test' . DS . 'Case' . DS . 'Model' . DS . 'models.php';
+
+/**
+ * Test case for BasicAuthentication
+ *
+ * @package Cake.Test.Case.Controller.Component.Auth
+ */
+class BasicAuthenticateTest extends CakeTestCase {
+
+ public $fixtures = array('core.user', 'core.auth_user');
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Collection = $this->getMock('ComponentCollection');
+ $this->auth = new BasicAuthenticate($this->Collection, array(
+ 'fields' => array('username' => 'user', 'password' => 'password'),
+ 'userModel' => 'User',
+ 'realm' => 'localhost',
+ 'recursive' => 0
+ ));
+
+ $password = Security::hash('password', null, true);
+ $User = ClassRegistry::init('User');
+ $User->updateAll(array('password' => $User->getDataSource()->value($password)));
+ $this->response = $this->getMock('CakeResponse');
+ }
+
+/**
+ * test applying settings in the constructor
+ *
+ * @return void
+ */
+ public function testConstructor() {
+ $object = new BasicAuthenticate($this->Collection, array(
+ 'userModel' => 'AuthUser',
+ 'fields' => array('username' => 'user', 'password' => 'password')
+ ));
+ $this->assertEquals('AuthUser', $object->settings['userModel']);
+ $this->assertEquals(array('username' => 'user', 'password' => 'password'), $object->settings['fields']);
+ $this->assertEquals(env('SERVER_NAME'), $object->settings['realm']);
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateNoData() {
+ $request = new CakeRequest('posts/index', false);
+
+ $this->response->expects($this->once())
+ ->method('header')
+ ->with('WWW-Authenticate: Basic realm="localhost"');
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateNoUsername() {
+ $request = new CakeRequest('posts/index', false);
+ $_SERVER['PHP_AUTH_PW'] = 'foobar';
+
+ $this->response->expects($this->once())
+ ->method('header')
+ ->with('WWW-Authenticate: Basic realm="localhost"');
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateNoPassword() {
+ $request = new CakeRequest('posts/index', false);
+ $_SERVER['PHP_AUTH_USER'] = 'mariano';
+ $_SERVER['PHP_AUTH_PW'] = null;
+
+ $this->response->expects($this->once())
+ ->method('header')
+ ->with('WWW-Authenticate: Basic realm="localhost"');
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateInjection() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $_SERVER['PHP_AUTH_USER'] = '> 1';
+ $_SERVER['PHP_AUTH_PW'] = "' OR 1 = 1";
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test that challenge headers are sent when no credentials are found.
+ *
+ * @return void
+ */
+ public function testAuthenticateChallenge() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $this->response->expects($this->at(0))
+ ->method('header')
+ ->with('WWW-Authenticate: Basic realm="localhost"');
+
+ $this->response->expects($this->at(1))
+ ->method('send');
+
+ $result = $this->auth->authenticate($request, $this->response);
+ $this->assertFalse($result);
+ }
+
+/**
+ * test authenticate sucesss
+ *
+ * @return void
+ */
+ public function testAuthenticateSuccess() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $_SERVER['PHP_AUTH_USER'] = 'mariano';
+ $_SERVER['PHP_AUTH_PW'] = 'password';
+
+ $result = $this->auth->authenticate($request, $this->response);
+ $expected = array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test scope failure.
+ *
+ * @return void
+ */
+ public function testAuthenticateFailReChallenge() {
+ $this->auth->settings['scope'] = array('user' => 'nate');
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $_SERVER['PHP_AUTH_USER'] = 'mariano';
+ $_SERVER['PHP_AUTH_PW'] = 'password';
+
+ $this->response->expects($this->at(0))
+ ->method('header')
+ ->with('WWW-Authenticate: Basic realm="localhost"');
+
+ $this->response->expects($this->at(1))
+ ->method('statusCode')
+ ->with(401);
+
+ $this->response->expects($this->at(2))
+ ->method('send');
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php
new file mode 100644
index 0000000..a1dae91
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/ControllerAuthorizeTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * ControllerAuthorizeTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Auth
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('ControllerAuthorize', 'Controller/Component/Auth');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+
+class ControllerAuthorizeTest extends CakeTestCase {
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->controller = $this->getMock('Controller', array('isAuthorized'), array(), '', false);
+ $this->components = $this->getMock('ComponentCollection');
+ $this->components->expects($this->any())
+ ->method('getController')
+ ->will($this->returnValue($this->controller));
+
+ $this->auth = new ControllerAuthorize($this->components);
+ }
+
+/**
+ * @expectedException PHPUnit_Framework_Error
+ */
+ public function testControllerTypeError() {
+ $this->auth->controller(new StdClass());
+ }
+
+/**
+ * @expectedException CakeException
+ */
+ public function testControllerErrorOnMissingMethod() {
+ $this->auth->controller(new Controller());
+ }
+
+/**
+ * test failure
+ *
+ * @return void
+ */
+ public function testAuthorizeFailure() {
+ $user = array();
+ $request = new CakeRequest('/posts/index', false);
+ $this->assertFalse($this->auth->authorize($user, $request));
+ }
+
+/**
+ * test isAuthorized working.
+ *
+ * @return void
+ */
+ public function testAuthorizeSuccess() {
+ $user = array('User' => array('username' => 'mark'));
+ $request = new CakeRequest('/posts/index', false);
+
+ $this->controller->expects($this->once())
+ ->method('isAuthorized')
+ ->with($user)
+ ->will($this->returnValue(true));
+
+ $this->assertTrue($this->auth->authorize($user, $request));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php
new file mode 100644
index 0000000..859e424
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/CrudAuthorizeTest.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * CrudAuthorizeTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Auth
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CrudAuthorize', 'Controller/Component/Auth');
+App::uses('ComponentCollection', 'Controller');
+App::uses('AclComponent', 'Controller/Component');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+
+class CrudAuthorizeTest extends CakeTestCase {
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Routing.prefixes', array());
+
+ $this->Acl = $this->getMock('AclComponent', array(), array(), '', false);
+ $this->Components = $this->getMock('ComponentCollection');
+
+ $this->auth = new CrudAuthorize($this->Components);
+ }
+
+/**
+ * setup the mock acl.
+ *
+ * @return void
+ */
+ protected function _mockAcl() {
+ $this->Components->expects($this->any())
+ ->method('load')
+ ->with('Acl')
+ ->will($this->returnValue($this->Acl));
+ }
+
+/**
+ * test authorize() without a mapped action, ensure an error is generated.
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testAuthorizeNoMappedAction() {
+ $request = new CakeRequest('/posts/foobar', false);
+ $request->addParams(array(
+ 'controller' => 'posts',
+ 'action' => 'foobar'
+ ));
+ $user = array('User' => array('user' => 'mark'));
+
+ $this->auth->authorize($user, $request);
+ }
+
+/**
+ * test check() passing
+ *
+ * @return void
+ */
+ public function testAuthorizeCheckSuccess() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array(
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ));
+ $user = array('User' => array('user' => 'mark'));
+
+ $this->_mockAcl();
+ $this->Acl->expects($this->once())
+ ->method('check')
+ ->with($user, 'Posts', 'read')
+ ->will($this->returnValue(true));
+
+ $this->assertTrue($this->auth->authorize($user['User'], $request));
+ }
+
+/**
+ * test check() failing
+ *
+ * @return void
+ */
+ public function testAuthorizeCheckFailure() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array(
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ));
+ $user = array('User' => array('user' => 'mark'));
+
+ $this->_mockAcl();
+ $this->Acl->expects($this->once())
+ ->method('check')
+ ->with($user, 'Posts', 'read')
+ ->will($this->returnValue(false));
+
+ $this->assertFalse($this->auth->authorize($user['User'], $request));
+ }
+
+/**
+ * test getting actionMap
+ *
+ * @return void
+ */
+ public function testMapActionsGet() {
+ $result = $this->auth->mapActions();
+ $expected = array(
+ 'create' => 'create',
+ 'read' => 'read',
+ 'update' => 'update',
+ 'delete' => 'delete',
+ 'index' => 'read',
+ 'add' => 'create',
+ 'edit' => 'update',
+ 'view' => 'read',
+ 'remove' => 'delete'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test adding into mapActions
+ *
+ * @return void
+ */
+ public function testMapActionsSet() {
+ $map = array(
+ 'create' => array('generate'),
+ 'read' => array('listing', 'show'),
+ 'update' => array('update'),
+ 'random' => 'custom'
+ );
+ $result = $this->auth->mapActions($map);
+ $this->assertNull($result);
+
+ $result = $this->auth->mapActions();
+ $expected = array(
+ 'add' => 'create',
+ 'create' => 'create',
+ 'read' => 'read',
+ 'index' => 'read',
+ 'add' => 'create',
+ 'edit' => 'update',
+ 'view' => 'read',
+ 'delete' => 'delete',
+ 'remove' => 'delete',
+ 'generate' => 'create',
+ 'listing' => 'read',
+ 'show' => 'read',
+ 'update' => 'update',
+ 'random' => 'custom',
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test prefix routes getting auto mapped.
+ *
+ * @return void
+ */
+ public function testAutoPrefixMapActions() {
+ Configure::write('Routing.prefixes', array('admin', 'manager'));
+ Router::reload();
+
+ $auth = new CrudAuthorize($this->Components);
+ $this->assertTrue(isset($auth->settings['actionMap']['admin_index']));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php
new file mode 100644
index 0000000..f9ca831
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/DigestAuthenticateTest.php
@@ -0,0 +1,306 @@
+<?php
+/**
+ * DigestAuthenticateTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Auth
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DigestAuthenticate', 'Controller/Component/Auth');
+App::uses('AppModel', 'Model');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+
+require_once CAKE . 'Test' . DS . 'Case' . DS . 'Model' . DS . 'models.php';
+
+/**
+ * Test case for DigestAuthentication
+ *
+ * @package Cake.Test.Case.Controller.Component.Auth
+ */
+class DigestAuthenticateTest extends CakeTestCase {
+
+ public $fixtures = array('core.user', 'core.auth_user');
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Collection = $this->getMock('ComponentCollection');
+ $this->server = $_SERVER;
+ $this->auth = new DigestAuthenticate($this->Collection, array(
+ 'fields' => array('username' => 'user', 'password' => 'password'),
+ 'userModel' => 'User',
+ 'realm' => 'localhost',
+ 'nonce' => 123,
+ 'opaque' => '123abc'
+ ));
+
+ $password = DigestAuthenticate::password('mariano', 'cake', 'localhost');
+ $User = ClassRegistry::init('User');
+ $User->updateAll(array('password' => $User->getDataSource()->value($password)));
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $this->response = $this->getMock('CakeResponse');
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ $_SERVER = $this->server;
+ }
+
+/**
+ * test applying settings in the constructor
+ *
+ * @return void
+ */
+ public function testConstructor() {
+ $object = new DigestAuthenticate($this->Collection, array(
+ 'userModel' => 'AuthUser',
+ 'fields' => array('username' => 'user', 'password' => 'password'),
+ 'nonce' => 123456
+ ));
+ $this->assertEquals('AuthUser', $object->settings['userModel']);
+ $this->assertEquals(array('username' => 'user', 'password' => 'password'), $object->settings['fields']);
+ $this->assertEquals(123456, $object->settings['nonce']);
+ $this->assertEquals(env('SERVER_NAME'), $object->settings['realm']);
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateNoData() {
+ $request = new CakeRequest('posts/index', false);
+
+ $this->response->expects($this->once())
+ ->method('header')
+ ->with('WWW-Authenticate: Digest realm="localhost",qop="auth",nonce="123",opaque="123abc"');
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateWrongUsername() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $_SERVER['PHP_AUTH_DIGEST'] = <<<DIGEST
+Digest username="incorrect_user",
+realm="localhost",
+nonce="123456",
+uri="/dir/index.html",
+qop=auth,
+nc=00000001,
+cnonce="0a4f113b",
+response="6629fae49393a05397450978507c4ef1",
+opaque="123abc"
+DIGEST;
+
+ $this->response->expects($this->at(0))
+ ->method('header')
+ ->with('WWW-Authenticate: Digest realm="localhost",qop="auth",nonce="123",opaque="123abc"');
+
+ $this->response->expects($this->at(1))
+ ->method('statusCode')
+ ->with(401);
+
+ $this->response->expects($this->at(2))
+ ->method('send');
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test that challenge headers are sent when no credentials are found.
+ *
+ * @return void
+ */
+ public function testAuthenticateChallenge() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $this->response->expects($this->at(0))
+ ->method('header')
+ ->with('WWW-Authenticate: Digest realm="localhost",qop="auth",nonce="123",opaque="123abc"');
+
+ $this->response->expects($this->at(1))
+ ->method('statusCode')
+ ->with(401);
+
+ $this->response->expects($this->at(2))
+ ->method('send');
+
+ $result = $this->auth->authenticate($request, $this->response);
+ $this->assertFalse($result);
+ }
+
+/**
+ * test authenticate success
+ *
+ * @return void
+ */
+ public function testAuthenticateSuccess() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $_SERVER['PHP_AUTH_DIGEST'] = <<<DIGEST
+Digest username="mariano",
+realm="localhost",
+nonce="123",
+uri="/dir/index.html",
+qop=auth,
+nc=1,
+cnonce="123",
+response="06b257a54befa2ddfb9bfa134224aa29",
+opaque="123abc"
+DIGEST;
+
+ $result = $this->auth->authenticate($request, $this->response);
+ $expected = array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test scope failure.
+ *
+ * @return void
+ */
+ public function testAuthenticateFailReChallenge() {
+ $this->auth->settings['scope'] = array('user' => 'nate');
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('pass' => array(), 'named' => array()));
+
+ $_SERVER['PHP_AUTH_DIGEST'] = <<<DIGEST
+Digest username="mariano",
+realm="localhost",
+nonce="123",
+uri="/dir/index.html",
+qop=auth,
+nc=1,
+cnonce="123",
+response="6629fae49393a05397450978507c4ef1",
+opaque="123abc"
+DIGEST;
+
+ $this->response->expects($this->at(0))
+ ->method('header')
+ ->with('WWW-Authenticate: Digest realm="localhost",qop="auth",nonce="123",opaque="123abc"');
+
+ $this->response->expects($this->at(1))
+ ->method('statusCode')
+ ->with(401);
+
+ $this->response->expects($this->at(2))
+ ->method('send');
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * testParseDigestAuthData method
+ *
+ * @return void
+ */
+ public function testParseAuthData() {
+ $digest = <<<DIGEST
+ Digest username="Mufasa",
+ realm="testrealm@host.com",
+ nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
+ uri="/dir/index.html",
+ qop=auth,
+ nc=00000001,
+ cnonce="0a4f113b",
+ response="6629fae49393a05397450978507c4ef1",
+ opaque="5ccc069c403ebaf9f0171e9517f40e41"
+DIGEST;
+ $expected = array(
+ 'username' => 'Mufasa',
+ 'realm' => 'testrealm@host.com',
+ 'nonce' => 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
+ 'uri' => '/dir/index.html',
+ 'qop' => 'auth',
+ 'nc' => '00000001',
+ 'cnonce' => '0a4f113b',
+ 'response' => '6629fae49393a05397450978507c4ef1',
+ 'opaque' => '5ccc069c403ebaf9f0171e9517f40e41'
+ );
+ $result = $this->auth->parseAuthData($digest);
+ $this->assertSame($expected, $result);
+
+ $result = $this->auth->parseAuthData('');
+ $this->assertNull($result);
+ }
+
+/**
+ * test parsing digest information with email addresses
+ *
+ * @return void
+ */
+ public function testParseAuthEmailAddress() {
+ $digest = <<<DIGEST
+ Digest username="mark@example.com",
+ realm="testrealm@host.com",
+ nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
+ uri="/dir/index.html",
+ qop=auth,
+ nc=00000001,
+ cnonce="0a4f113b",
+ response="6629fae49393a05397450978507c4ef1",
+ opaque="5ccc069c403ebaf9f0171e9517f40e41"
+DIGEST;
+ $expected = array(
+ 'username' => 'mark@example.com',
+ 'realm' => 'testrealm@host.com',
+ 'nonce' => 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
+ 'uri' => '/dir/index.html',
+ 'qop' => 'auth',
+ 'nc' => '00000001',
+ 'cnonce' => '0a4f113b',
+ 'response' => '6629fae49393a05397450978507c4ef1',
+ 'opaque' => '5ccc069c403ebaf9f0171e9517f40e41'
+ );
+ $result = $this->auth->parseAuthData($digest);
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * test password hashing
+ *
+ * @return void
+ */
+ public function testPassword() {
+ $result = DigestAuthenticate::password('mark', 'password', 'localhost');
+ $expected = md5('mark:localhost:password');
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php
new file mode 100644
index 0000000..a65e04f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/Auth/FormAuthenticateTest.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * FormAuthenticateTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Controller.Component.Auth
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AuthComponent', 'Controller/Component');
+App::uses('FormAuthenticate', 'Controller/Component/Auth');
+App::uses('AppModel', 'Model');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+
+require_once CAKE . 'Test' . DS . 'Case' . DS . 'Model' . DS . 'models.php';
+
+/**
+ * Test case for FormAuthentication
+ *
+ * @package Cake.Test.Case.Controller.Component.Auth
+ */
+class FormAuthenticateTest extends CakeTestCase {
+
+ public $fixtures = array('core.user', 'core.auth_user');
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Collection = $this->getMock('ComponentCollection');
+ $this->auth = new FormAuthenticate($this->Collection, array(
+ 'fields' => array('username' => 'user', 'password' => 'password'),
+ 'userModel' => 'User'
+ ));
+ $password = Security::hash('password', null, true);
+ $User = ClassRegistry::init('User');
+ $User->updateAll(array('password' => $User->getDataSource()->value($password)));
+ $this->response = $this->getMock('CakeResponse');
+ }
+
+/**
+ * test applying settings in the constructor
+ *
+ * @return void
+ */
+ public function testConstructor() {
+ $object = new FormAuthenticate($this->Collection, array(
+ 'userModel' => 'AuthUser',
+ 'fields' => array('username' => 'user', 'password' => 'password')
+ ));
+ $this->assertEquals('AuthUser', $object->settings['userModel']);
+ $this->assertEquals(array('username' => 'user', 'password' => 'password'), $object->settings['fields']);
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateNoData() {
+ $request = new CakeRequest('posts/index', false);
+ $request->data = array();
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateNoUsername() {
+ $request = new CakeRequest('posts/index', false);
+ $request->data = array('User' => array('password' => 'foobar'));
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateNoPassword() {
+ $request = new CakeRequest('posts/index', false);
+ $request->data = array('User' => array('user' => 'mariano'));
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test the authenticate method
+ *
+ * @return void
+ */
+ public function testAuthenticateInjection() {
+ $request = new CakeRequest('posts/index', false);
+ $request->data = array(
+ 'User' => array(
+ 'user' => '> 1',
+ 'password' => "' OR 1 = 1"
+ ));
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test authenticate success
+ *
+ * @return void
+ */
+ public function testAuthenticateSuccess() {
+ $request = new CakeRequest('posts/index', false);
+ $request->data = array('User' => array(
+ 'user' => 'mariano',
+ 'password' => 'password'
+ ));
+ $result = $this->auth->authenticate($request, $this->response);
+ $expected = array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test scope failure.
+ *
+ * @return void
+ */
+ public function testAuthenticateScopeFail() {
+ $this->auth->settings['scope'] = array('user' => 'nate');
+ $request = new CakeRequest('posts/index', false);
+ $request->data = array('User' => array(
+ 'user' => 'mariano',
+ 'password' => 'password'
+ ));
+
+ $this->assertFalse($this->auth->authenticate($request, $this->response));
+ }
+
+/**
+ * test a model in a plugin.
+ *
+ * @return void
+ */
+ public function testPluginModel() {
+ Cache::delete('object_map', '_cake_core_');
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+
+ $PluginModel = ClassRegistry::init('TestPlugin.TestPluginAuthUser');
+ $user['id'] = 1;
+ $user['username'] = 'gwoo';
+ $user['password'] = Security::hash(Configure::read('Security.salt') . 'cake');
+ $PluginModel->save($user, false);
+
+ $this->auth->settings['userModel'] = 'TestPlugin.TestPluginAuthUser';
+ $this->auth->settings['fields']['username'] = 'username';
+
+ $request = new CakeRequest('posts/index', false);
+ $request->data = array('TestPluginAuthUser' => array(
+ 'username' => 'gwoo',
+ 'password' => 'cake'
+ ));
+
+ $result = $this->auth->authenticate($request, $this->response);
+ $expected = array(
+ 'id' => 1,
+ 'username' => 'gwoo',
+ 'created' => '2007-03-17 01:16:23'
+ );
+ $this->assertEquals(self::date(), $result['updated']);
+ unset($result['updated']);
+ $this->assertEquals($expected, $result);
+ CakePlugin::unload();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php
new file mode 100644
index 0000000..11546e1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/AuthComponentTest.php
@@ -0,0 +1,1290 @@
+<?php
+/**
+ * AuthComponentTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.5347
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('AuthComponent', 'Controller/Component');
+App::uses('AclComponent', 'Controller/Component');
+App::uses('FormAuthenticate', 'Controller/Component/Auth');
+
+/**
+ * TestAuthComponent class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ * @package Cake.Test.Case.Controller.Component
+ */
+class TestAuthComponent extends AuthComponent {
+
+/**
+ * testStop property
+ *
+ * @var bool false
+ */
+ public $testStop = false;
+
+/**
+ * stop method
+ *
+ * @return void
+ */
+ protected function _stop($status = 0) {
+ $this->testStop = true;
+ }
+
+ public static function clearUser() {
+ self::$_user = array();
+ }
+
+}
+
+/**
+ * AuthUser class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ * @package Cake.Test.Case.Controller.Component
+ */
+class AuthUser extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'AuthUser'
+ */
+ public $name = 'AuthUser';
+
+/**
+ * useDbConfig property
+ *
+ * @var string 'test'
+ */
+ public $useDbConfig = 'test';
+
+}
+
+/**
+ * AuthTestController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ * @package Cake.Test.Case.Controller.Component
+ */
+class AuthTestController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'AuthTest'
+ */
+ public $name = 'AuthTest';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array('AuthUser');
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Session', 'Auth');
+
+/**
+ * testUrl property
+ *
+ * @var mixed null
+ */
+ public $testUrl = null;
+
+/**
+ * construct method
+ *
+ * @return void
+ */
+ public function __construct($request, $response) {
+ $request->addParams(Router::parse('/auth_test'));
+ $request->here = '/auth_test';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+ parent::__construct($request, $response);
+ }
+
+/**
+ * login method
+ *
+ * @return void
+ */
+ public function login() {
+ }
+
+/**
+ * admin_login method
+ *
+ * @return void
+ */
+ public function admin_login() {
+ }
+
+/**
+ * admin_add method
+ *
+ * @return void
+ */
+ public function admin_add() {
+ }
+
+/**
+ * logout method
+ *
+ * @return void
+ */
+ public function logout() {
+ }
+
+/**
+ * add method
+ *
+ * @return void
+ */
+ public function add() {
+ echo "add";
+ }
+
+/**
+ * add method
+ *
+ * @return void
+ */
+ public function camelCase() {
+ echo "camelCase";
+ }
+
+/**
+ * redirect method
+ *
+ * @param string|array $url
+ * @param mixed $status
+ * @param mixed $exit
+ * @return void
+ */
+ public function redirect($url, $status = null, $exit = true) {
+ $this->testUrl = Router::url($url);
+ return false;
+ }
+
+/**
+ * isAuthorized method
+ *
+ * @return void
+ */
+ public function isAuthorized() {
+ }
+
+}
+
+/**
+ * AjaxAuthController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class AjaxAuthController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'AjaxAuth'
+ */
+ public $name = 'AjaxAuth';
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Session', 'TestAuth');
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * testUrl property
+ *
+ * @var mixed null
+ */
+ public $testUrl = null;
+
+/**
+ * beforeFilter method
+ *
+ * @return void
+ */
+ public function beforeFilter() {
+ $this->TestAuth->ajaxLogin = 'test_element';
+ $this->TestAuth->userModel = 'AuthUser';
+ $this->TestAuth->RequestHandler->ajaxLayout = 'ajax2';
+ }
+
+/**
+ * add method
+ *
+ * @return void
+ */
+ public function add() {
+ if ($this->TestAuth->testStop !== true) {
+ echo 'Added Record';
+ }
+ }
+
+/**
+ * redirect method
+ *
+ * @param string|array $url
+ * @param mixed $status
+ * @param mixed $exit
+ * @return void
+ */
+ public function redirect($url, $status = null, $exit = true) {
+ $this->testUrl = Router::url($url);
+ return false;
+ }
+
+}
+
+/**
+ * AuthComponentTest class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ * @package Cake.Test.Case.Controller.Component
+ */
+class AuthComponentTest extends CakeTestCase {
+
+/**
+ * name property
+ *
+ * @var string 'Auth'
+ */
+ public $name = 'Auth';
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.auth_user');
+
+/**
+ * initialized property
+ *
+ * @var bool false
+ */
+ public $initialized = false;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Security.salt', 'YJfIxfs2guVoUubWDYhG93b0qyJfIxfs2guwvniR2G0FgaC9mi');
+ Configure::write('Security.cipherSeed', 770011223369876);
+
+ $request = new CakeRequest(null, false);
+
+ $this->Controller = new AuthTestController($request, $this->getMock('CakeResponse'));
+
+ $collection = new ComponentCollection();
+ $collection->init($this->Controller);
+ $this->Auth = new TestAuthComponent($collection);
+ $this->Auth->request = $request;
+ $this->Auth->response = $this->getMock('CakeResponse');
+
+ $this->Controller->Components->init($this->Controller);
+
+ $this->initialized = true;
+ Router::reload();
+ Router::connect('/:controller/:action/*');
+
+ $User = ClassRegistry::init('AuthUser');
+ $User->updateAll(array('password' => $User->getDataSource()->value(Security::hash('cake', null, true))));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+
+ TestAuthComponent::clearUser();
+ $this->Auth->Session->delete('Auth');
+ $this->Auth->Session->delete('Message.auth');
+ unset($this->Controller, $this->Auth);
+ }
+
+/**
+ * testNoAuth method
+ *
+ * @return void
+ */
+ public function testNoAuth() {
+ $this->assertFalse($this->Auth->isAuthorized());
+ }
+
+/**
+ * testIsErrorOrTests
+ *
+ * @return void
+ */
+ public function testIsErrorOrTests() {
+ $this->Controller->Auth->initialize($this->Controller);
+
+ $this->Controller->name = 'CakeError';
+ $this->assertTrue($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->name = 'Post';
+ $this->Controller->request['action'] = 'thisdoesnotexist';
+ $this->assertTrue($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->scaffold = null;
+ $this->Controller->request['action'] = 'index';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+ }
+
+/**
+ * testLogin method
+ *
+ * @return void
+ */
+ public function testLogin() {
+ $this->getMock('FormAuthenticate', array(), array(), 'AuthLoginFormAuthenticate', false);
+ $this->Auth->authenticate = array(
+ 'AuthLoginForm' => array(
+ 'userModel' => 'AuthUser'
+ )
+ );
+ $this->Auth->Session = $this->getMock('SessionComponent', array('renew'), array(), '', false);
+
+ $mocks = $this->Auth->constructAuthenticate();
+ $this->mockObjects[] = $mocks[0];
+
+ $this->Auth->request->data = array(
+ 'AuthUser' => array(
+ 'username' => 'mark',
+ 'password' => Security::hash('cake', null, true)
+ )
+ );
+
+ $user = array(
+ 'id' => 1,
+ 'username' => 'mark'
+ );
+
+ $mocks[0]->expects($this->once())
+ ->method('authenticate')
+ ->with($this->Auth->request)
+ ->will($this->returnValue($user));
+
+ $this->Auth->Session->expects($this->once())
+ ->method('renew');
+
+ $result = $this->Auth->login();
+ $this->assertTrue($result);
+
+ $this->assertTrue($this->Auth->loggedIn());
+ $this->assertEquals($user, $this->Auth->user());
+ }
+
+/**
+ * test that being redirected to the login page, with no post data does
+ * not set the session value. Saving the session value in this circumstance
+ * can cause the user to be redirected to an already public page.
+ *
+ * @return void
+ */
+ public function testLoginActionNotSettingAuthRedirect() {
+ $_SERVER['HTTP_REFERER'] = '/pages/display/about';
+
+ $this->Controller->data = array();
+ $this->Controller->request->addParams(Router::parse('auth_test/login'));
+ $this->Controller->request->url = 'auth_test/login';
+ $this->Auth->Session->delete('Auth');
+
+ $this->Auth->loginRedirect = '/users/dashboard';
+ $this->Auth->loginAction = 'auth_test/login';
+ $this->Auth->userModel = 'AuthUser';
+
+ $this->Auth->startup($this->Controller);
+ $redirect = $this->Auth->Session->read('Auth.redirect');
+ $this->assertNull($redirect);
+ }
+
+/**
+ * testAuthorizeFalse method
+ *
+ * @return void
+ */
+ public function testAuthorizeFalse() {
+ $this->AuthUser = new AuthUser();
+ $user = $this->AuthUser->find();
+ $this->Auth->Session->write('Auth.User', $user['AuthUser']);
+ $this->Controller->Auth->userModel = 'AuthUser';
+ $this->Controller->Auth->authorize = false;
+ $this->Controller->request->addParams(Router::parse('auth_test/add'));
+ $result = $this->Controller->Auth->startup($this->Controller);
+ $this->assertTrue($result);
+
+ $this->Auth->Session->delete('Auth');
+ $result = $this->Controller->Auth->startup($this->Controller);
+ $this->assertFalse($result);
+ $this->assertTrue($this->Auth->Session->check('Message.auth'));
+
+ $this->Controller->request->addParams(Router::parse('auth_test/camelCase'));
+ $result = $this->Controller->Auth->startup($this->Controller);
+ $this->assertFalse($result);
+ }
+
+/**
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testIsAuthorizedMissingFile() {
+ $this->Controller->Auth->authorize = 'Missing';
+ $this->Controller->Auth->isAuthorized(array('User' => array('id' => 1)));
+ }
+
+/**
+ * test that isAuthorized calls methods correctly
+ *
+ * @return void
+ */
+ public function testIsAuthorizedDelegation() {
+ $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockOneAuthorize', false);
+ $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockTwoAuthorize', false);
+ $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockThreeAuthorize', false);
+
+ $this->Auth->authorize = array(
+ 'AuthMockOne',
+ 'AuthMockTwo',
+ 'AuthMockThree'
+ );
+ $mocks = $this->Auth->constructAuthorize();
+ $request = $this->Auth->request;
+
+ $this->assertEquals(3, count($mocks));
+ $mocks[0]->expects($this->once())
+ ->method('authorize')
+ ->with(array('User'), $request)
+ ->will($this->returnValue(false));
+
+ $mocks[1]->expects($this->once())
+ ->method('authorize')
+ ->with(array('User'), $request)
+ ->will($this->returnValue(true));
+
+ $mocks[2]->expects($this->never())
+ ->method('authorize');
+
+ $this->assertTrue($this->Auth->isAuthorized(array('User'), $request));
+ }
+
+/**
+ * test that isAuthorized will use the session user if none is given.
+ *
+ * @return void
+ */
+ public function testIsAuthorizedUsingUserInSession() {
+ $this->getMock('BaseAuthorize', array('authorize'), array(), 'AuthMockFourAuthorize', false);
+ $this->Auth->authorize = array('AuthMockFour');
+
+ $user = array('user' => 'mark');
+ $this->Auth->Session->write('Auth.User', $user);
+ $mocks = $this->Auth->constructAuthorize();
+ $request = $this->Controller->request;
+
+ $mocks[0]->expects($this->once())
+ ->method('authorize')
+ ->with($user, $request)
+ ->will($this->returnValue(true));
+
+ $this->assertTrue($this->Auth->isAuthorized(null, $request));
+ }
+
+/**
+ * test that loadAuthorize resets the loaded objects each time.
+ *
+ * @return void
+ */
+ public function testLoadAuthorizeResets() {
+ $this->Controller->Auth->authorize = array(
+ 'Controller'
+ );
+ $result = $this->Controller->Auth->constructAuthorize();
+ $this->assertEquals(1, count($result));
+
+ $result = $this->Controller->Auth->constructAuthorize();
+ $this->assertEquals(1, count($result));
+ }
+
+/**
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testLoadAuthenticateNoFile() {
+ $this->Controller->Auth->authenticate = 'Missing';
+ $this->Controller->Auth->identify($this->Controller->request, $this->Controller->response);
+ }
+
+/**
+ * test the * key with authenticate
+ *
+ * @return void
+ */
+ public function testAllConfigWithAuthorize() {
+ $this->Controller->Auth->authorize = array(
+ AuthComponent::ALL => array('actionPath' => 'controllers/'),
+ 'Actions'
+ );
+ $objects = $this->Controller->Auth->constructAuthorize();
+ $result = $objects[0];
+ $this->assertEquals('controllers/', $result->settings['actionPath']);
+ }
+
+/**
+ * test that loadAuthorize resets the loaded objects each time.
+ *
+ * @return void
+ */
+ public function testLoadAuthenticateResets() {
+ $this->Controller->Auth->authenticate = array(
+ 'Form'
+ );
+ $result = $this->Controller->Auth->constructAuthenticate();
+ $this->assertEquals(1, count($result));
+
+ $result = $this->Controller->Auth->constructAuthenticate();
+ $this->assertEquals(1, count($result));
+ }
+
+/**
+ * test the * key with authenticate
+ *
+ * @return void
+ */
+ public function testAllConfigWithAuthenticate() {
+ $this->Controller->Auth->authenticate = array(
+ AuthComponent::ALL => array('userModel' => 'AuthUser'),
+ 'Form'
+ );
+ $objects = $this->Controller->Auth->constructAuthenticate();
+ $result = $objects[0];
+ $this->assertEquals('AuthUser', $result->settings['userModel']);
+ }
+
+/**
+ * Tests that deny always takes precedence over allow
+ *
+ * @return void
+ */
+ public function testAllowDenyAll() {
+ $this->Controller->Auth->initialize($this->Controller);
+
+ $this->Controller->Auth->allow();
+ $this->Controller->Auth->deny('add', 'camelCase');
+
+ $this->Controller->request['action'] = 'delete';
+ $this->assertTrue($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->request['action'] = 'add';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->request['action'] = 'camelCase';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->Auth->allow();
+ $this->Controller->Auth->deny(array('add', 'camelCase'));
+
+ $this->Controller->request['action'] = 'delete';
+ $this->assertTrue($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->request['action'] = 'camelCase';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->Auth->allow('*');
+ $this->Controller->Auth->deny();
+
+ $this->Controller->request['action'] = 'camelCase';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->request['action'] = 'add';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->Auth->allow('camelCase');
+ $this->Controller->Auth->deny();
+
+ $this->Controller->request['action'] = 'camelCase';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->request['action'] = 'login';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->Auth->deny();
+ $this->Controller->Auth->allow(null);
+
+ $this->Controller->request['action'] = 'camelCase';
+ $this->assertTrue($this->Controller->Auth->startup($this->Controller));
+
+ $this->Controller->Auth->allow();
+ $this->Controller->Auth->deny(null);
+
+ $this->Controller->request['action'] = 'camelCase';
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+ }
+
+/**
+ * test that deny() converts camel case inputs to lowercase.
+ *
+ * @return void
+ */
+ public function testDenyWithCamelCaseMethods() {
+ $this->Controller->Auth->initialize($this->Controller);
+ $this->Controller->Auth->allow();
+ $this->Controller->Auth->deny('add', 'camelCase');
+
+ $url = '/auth_test/camelCase';
+ $this->Controller->request->addParams(Router::parse($url));
+ $this->Controller->request->query['url'] = Router::normalize($url);
+
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+
+ $url = '/auth_test/CamelCase';
+ $this->Controller->request->addParams(Router::parse($url));
+ $this->Controller->request->query['url'] = Router::normalize($url);
+ $this->assertFalse($this->Controller->Auth->startup($this->Controller));
+ }
+
+/**
+ * test that allow() and allowedActions work with camelCase method names.
+ *
+ * @return void
+ */
+ public function testAllowedActionsWithCamelCaseMethods() {
+ $url = '/auth_test/camelCase';
+ $this->Controller->request->addParams(Router::parse($url));
+ $this->Controller->request->query['url'] = Router::normalize($url);
+ $this->Controller->Auth->initialize($this->Controller);
+ $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Controller->Auth->userModel = 'AuthUser';
+ $this->Controller->Auth->allow();
+ $result = $this->Controller->Auth->startup($this->Controller);
+ $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
+
+ $url = '/auth_test/camelCase';
+ $this->Controller->request->addParams(Router::parse($url));
+ $this->Controller->request->query['url'] = Router::normalize($url);
+ $this->Controller->Auth->initialize($this->Controller);
+ $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Controller->Auth->userModel = 'AuthUser';
+ $this->Controller->Auth->allowedActions = array('delete', 'camelCase', 'add');
+ $result = $this->Controller->Auth->startup($this->Controller);
+ $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
+
+ $this->Controller->Auth->allowedActions = array('delete', 'add');
+ $result = $this->Controller->Auth->startup($this->Controller);
+ $this->assertFalse($result, 'startup() should return false, as action is not allowed. %s');
+
+ $url = '/auth_test/delete';
+ $this->Controller->request->addParams(Router::parse($url));
+ $this->Controller->request->query['url'] = Router::normalize($url);
+ $this->Controller->Auth->initialize($this->Controller);
+ $this->Controller->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Controller->Auth->userModel = 'AuthUser';
+
+ $this->Controller->Auth->allow(array('delete', 'add'));
+ $result = $this->Controller->Auth->startup($this->Controller);
+ $this->assertTrue($result, 'startup() should return true, as action is allowed. %s');
+ }
+
+ public function testAllowedActionsSetWithAllowMethod() {
+ $url = '/auth_test/action_name';
+ $this->Controller->request->addParams(Router::parse($url));
+ $this->Controller->request->query['url'] = Router::normalize($url);
+ $this->Controller->Auth->initialize($this->Controller);
+ $this->Controller->Auth->allow('action_name', 'anotherAction');
+ $this->assertEquals(array('action_name', 'anotherAction'), $this->Controller->Auth->allowedActions);
+ }
+
+/**
+ * testLoginRedirect method
+ *
+ * @return void
+ */
+ public function testLoginRedirect() {
+ $_SERVER['HTTP_REFERER'] = false;
+ $_ENV['HTTP_REFERER'] = false;
+ putenv('HTTP_REFERER=');
+
+ $this->Auth->Session->write('Auth', array(
+ 'AuthUser' => array('id' => '1', 'username' => 'nate')
+ ));
+
+ $this->Auth->request->addParams(Router::parse('users/login'));
+ $this->Auth->request->url = 'users/login';
+ $this->Auth->initialize($this->Controller);
+
+ $this->Auth->loginRedirect = array(
+ 'controller' => 'pages', 'action' => 'display', 'welcome'
+ );
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize($this->Auth->loginRedirect);
+ $this->assertEquals($expected, $this->Auth->redirect());
+
+ $this->Auth->Session->delete('Auth');
+
+ //empty referer no session
+ $_SERVER['HTTP_REFERER'] = false;
+ $_ENV['HTTP_REFERER'] = false;
+ putenv('HTTP_REFERER=');
+ $url = '/posts/view/1';
+
+ $this->Auth->Session->write('Auth', array(
+ 'AuthUser' => array('id' => '1', 'username' => 'nate'))
+ );
+ $this->Controller->testUrl = null;
+ $this->Auth->request->addParams(Router::parse($url));
+ array_push($this->Controller->methods, 'view', 'edit', 'index');
+
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->authorize = 'controller';
+
+ $this->Auth->loginAction = array(
+ 'controller' => 'AuthTest', 'action' => 'login'
+ );
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize('/AuthTest/login');
+ $this->assertEquals($expected, $this->Controller->testUrl);
+
+ $this->Auth->Session->delete('Auth');
+ $_SERVER['HTTP_REFERER'] = $_ENV['HTTP_REFERER'] = Router::url('/admin', true);
+ $this->Auth->Session->write('Auth', array(
+ 'AuthUser' => array('id' => '1', 'username' => 'nate')
+ ));
+ $this->Auth->request->params['action'] = 'login';
+ $this->Auth->request->url = 'auth_test/login';
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->loginAction = 'auth_test/login';
+ $this->Auth->loginRedirect = false;
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize('/admin');
+ $this->assertEquals($expected, $this->Auth->redirect());
+
+ // Ticket #4750
+ // Named Parameters
+ $this->Controller->request = $this->Auth->request;
+ $this->Auth->Session->delete('Auth');
+ $url = '/posts/index/year:2008/month:feb';
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize('posts/index/year:2008/month:feb');
+ $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
+
+ // Passed Arguments
+ $this->Auth->Session->delete('Auth');
+ $url = '/posts/view/1';
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize('posts/view/1');
+ $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
+
+ // QueryString parameters
+ $_back = $_GET;
+ $_GET = array(
+ 'print' => 'true',
+ 'refer' => 'menu'
+ );
+ $this->Auth->Session->delete('Auth');
+ $url = '/posts/index/29';
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
+ $this->Auth->request->query = $_GET;
+
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize('posts/index/29?print=true&refer=menu');
+ $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
+
+ $_GET = $_back;
+
+ // External Authed Action
+ $_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
+ $this->Auth->Session->delete('Auth');
+ $url = '/posts/edit/1';
+ $request = new CakeRequest($url);
+ $request->query = array();
+ $this->Auth->request = $this->Controller->request = $request;
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->request->url = $this->Auth->request->here = Router::normalize($url);
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize('/posts/edit/1');
+ $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
+
+ // External Direct Login Link
+ $_SERVER['HTTP_REFERER'] = 'http://webmail.example.com/view/message';
+ $this->Auth->Session->delete('Auth');
+ $url = '/AuthTest/login';
+ $this->Auth->request = $this->Controller->request = new CakeRequest($url);
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->request->url = Router::normalize($url);
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Auth->startup($this->Controller);
+ $expected = Router::normalize('/');
+ $this->assertEquals($expected, $this->Auth->Session->read('Auth.redirect'));
+
+ $this->Auth->Session->delete('Auth');
+ }
+
+/**
+ * Default to loginRedirect, if set, on authError.
+ *
+ * @return void
+ */
+ public function testDefaultToLoginRedirect() {
+ $_SERVER['HTTP_REFERER'] = false;
+ $_ENV['HTTP_REFERER'] = false;
+ putenv('HTTP_REFERER=');
+
+ $url = '/party/on';
+ $this->Auth->request = $CakeRequest = new CakeRequest($url);
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->authorize = array('Controller');
+ $this->Auth->login(array('username' => 'mariano', 'password' => 'cake'));
+ $this->Auth->loginRedirect = array(
+ 'controller' => 'something', 'action' => 'else',
+ );
+
+ $CakeResponse = new CakeResponse();
+ $Controller = $this->getMock(
+ 'Controller',
+ array('on', 'redirect'),
+ array($CakeRequest, $CakeResponse)
+ );
+
+ $expected = Router::url($this->Auth->loginRedirect, true);
+ $Controller->expects($this->once())
+ ->method('redirect')
+ ->with($this->equalTo($expected));
+ $this->Auth->startup($Controller);
+ }
+
+/**
+ * Test that no redirects or authorization tests occur on the loginAction
+ *
+ * @return void
+ */
+ public function testNoRedirectOnLoginAction() {
+ $controller = $this->getMock('Controller');
+ $controller->methods = array('login');
+
+ $url = '/AuthTest/login';
+ $this->Auth->request = $controller->request = new CakeRequest($url);
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->loginAction = array('controller' => 'AuthTest', 'action' => 'login');
+ $this->Auth->authorize = array('Controller');
+
+ $controller->expects($this->never())
+ ->method('redirect');
+
+ $this->Auth->startup($controller);
+ }
+
+/**
+ * Ensure that no redirect is performed when a 404 is reached
+ * And the user doesn't have a session.
+ *
+ * @return void
+ */
+ public function testNoRedirectOn404() {
+ $this->Auth->Session->delete('Auth');
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->request->addParams(Router::parse('auth_test/something_totally_wrong'));
+ $result = $this->Auth->startup($this->Controller);
+ $this->assertTrue($result, 'Auth redirected a missing action %s');
+ }
+
+/**
+ * testAdminRoute method
+ *
+ * @return void
+ */
+ public function testAdminRoute() {
+ $pref = Configure::read('Routing.prefixes');
+ Configure::write('Routing.prefixes', array('admin'));
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+
+ $url = '/admin/auth_test/add';
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->request->query['url'] = ltrim($url, '/');
+ $this->Auth->request->base = '';
+
+ Router::setRequestInfo($this->Auth->request);
+ $this->Auth->initialize($this->Controller);
+
+ $this->Auth->loginAction = array(
+ 'admin' => true, 'controller' => 'auth_test', 'action' => 'login'
+ );
+
+ $this->Auth->startup($this->Controller);
+ $this->assertEquals('/admin/auth_test/login', $this->Controller->testUrl);
+
+ Configure::write('Routing.prefixes', $pref);
+ }
+
+/**
+ * testAjaxLogin method
+ *
+ * @return void
+ */
+ public function testAjaxLogin() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = "XMLHttpRequest";
+
+ App::uses('Dispatcher', 'Routing');
+
+ ob_start();
+ $Dispatcher = new Dispatcher();
+ $Dispatcher->dispatch(new CakeRequest('/ajax_auth/add'), new CakeResponse(), array('return' => 1));
+ $result = ob_get_clean();
+
+ $this->assertEquals("Ajax!\nthis is the test element", str_replace("\r\n", "\n", $result));
+ unset($_SERVER['HTTP_X_REQUESTED_WITH']);
+ }
+
+/**
+ * testLoginActionRedirect method
+ *
+ * @return void
+ */
+ public function testLoginActionRedirect() {
+ $admin = Configure::read('Routing.prefixes');
+ Configure::write('Routing.prefixes', array('admin'));
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+
+ $url = '/admin/auth_test/login';
+ $this->Auth->request->addParams(Router::parse($url));
+ $this->Auth->request->url = ltrim($url, '/');
+ Router::setRequestInfo(array(
+ array(
+ 'pass' => array(), 'action' => 'admin_login', 'plugin' => null, 'controller' => 'auth_test',
+ 'admin' => true,
+ ),
+ array(
+ 'base' => null, 'here' => $url,
+ 'webroot' => '/', 'passedArgs' => array(),
+ )
+ ));
+
+ $this->Auth->initialize($this->Controller);
+ $this->Auth->loginAction = array('admin' => true, 'controller' => 'auth_test', 'action' => 'login');
+ $this->Auth->startup($this->Controller);
+
+ $this->assertNull($this->Controller->testUrl);
+
+ Configure::write('Routing.prefixes', $admin);
+ }
+
+/**
+ * Stateless auth methods like Basic should populate data that can be
+ * accessed by $this->user().
+ *
+ * @return void
+ */
+ public function testStatelessAuthWorksWithUser() {
+ $_SERVER['PHP_AUTH_USER'] = 'mariano';
+ $_SERVER['PHP_AUTH_PW'] = 'cake';
+ $url = '/auth_test/add';
+ $this->Auth->request->addParams(Router::parse($url));
+
+ $this->Auth->authenticate = array(
+ 'Basic' => array('userModel' => 'AuthUser')
+ );
+ $this->Auth->startup($this->Controller);
+
+ $result = $this->Auth->user();
+ $this->assertEquals('mariano', $result['username']);
+
+ $result = $this->Auth->user('username');
+ $this->assertEquals('mariano', $result);
+ }
+
+/**
+ * Tests that shutdown destroys the redirect session var
+ *
+ * @return void
+ */
+ public function testShutDown() {
+ $this->Auth->Session->write('Auth.User', 'not empty');
+ $this->Auth->Session->write('Auth.redirect', 'foo');
+ $this->Controller->Auth->loggedIn(true);
+
+ $this->Controller->Auth->shutdown($this->Controller);
+ $this->assertNull($this->Auth->Session->read('Auth.redirect'));
+ }
+
+/**
+ * test $settings in Controller::$components
+ *
+ * @return void
+ */
+ public function testComponentSettings() {
+ $request = new CakeRequest(null, false);
+ $this->Controller = new AuthTestController($request, $this->getMock('CakeResponse'));
+
+ $this->Controller->components = array(
+ 'Auth' => array(
+ 'loginAction' => array('controller' => 'people', 'action' => 'login'),
+ 'logoutRedirect' => array('controller' => 'people', 'action' => 'login'),
+ ),
+ 'Session'
+ );
+ $this->Controller->Components->init($this->Controller);
+ $this->Controller->Components->trigger('initialize', array(&$this->Controller));
+ Router::reload();
+
+ $expected = array(
+ 'loginAction' => array('controller' => 'people', 'action' => 'login'),
+ 'logoutRedirect' => array('controller' => 'people', 'action' => 'login'),
+ );
+ $this->assertEquals($expected['loginAction'], $this->Controller->Auth->loginAction);
+ $this->assertEquals($expected['logoutRedirect'], $this->Controller->Auth->logoutRedirect);
+ }
+
+/**
+ * test that logout deletes the session variables. and returns the correct url
+ *
+ * @return void
+ */
+ public function testLogout() {
+ $this->Auth->Session->write('Auth.User.id', '1');
+ $this->Auth->Session->write('Auth.redirect', '/users/login');
+ $this->Auth->logoutRedirect = '/';
+ $result = $this->Auth->logout();
+
+ $this->assertEquals('/', $result);
+ $this->assertNull($this->Auth->Session->read('Auth.AuthUser'));
+ $this->assertNull($this->Auth->Session->read('Auth.redirect'));
+ }
+
+/**
+ * Logout should trigger a logout method on authentication objects.
+ *
+ * @return void
+ */
+ public function testLogoutTrigger() {
+ $this->getMock('BaseAuthenticate', array('authenticate', 'logout'), array(), 'LogoutTriggerMockAuthenticate', false);
+
+ $this->Auth->authenticate = array('LogoutTriggerMock');
+ $mock = $this->Auth->constructAuthenticate();
+ $mock[0]->expects($this->once())
+ ->method('logout');
+
+ $this->Auth->logout();
+ }
+
+/**
+ * test mapActions loading and delegating to authorize objects.
+ *
+ * @return void
+ */
+ public function testMapActionsDelegation() {
+ $this->getMock('BaseAuthorize', array('authorize'), array(), 'MapActionMockAuthorize', false);
+ $this->Auth->authorize = array('MapActionMock');
+ $mock = $this->Auth->constructAuthorize();
+ $mock[0]->expects($this->once())
+ ->method('mapActions')
+ ->with(array('create' => array('my_action')));
+
+ $this->Auth->mapActions(array('create' => array('my_action')));
+ }
+
+/**
+ * test logging in with a request.
+ *
+ * @return void
+ */
+ public function testLoginWithRequestData() {
+ $this->getMock('FormAuthenticate', array(), array(), 'RequestLoginMockAuthenticate', false);
+ $request = new CakeRequest('users/login', false);
+ $user = array('username' => 'mark', 'role' => 'admin');
+
+ $this->Auth->request = $request;
+ $this->Auth->authenticate = array('RequestLoginMock');
+ $mock = $this->Auth->constructAuthenticate();
+ $mock[0]->expects($this->once())
+ ->method('authenticate')
+ ->with($request)
+ ->will($this->returnValue($user));
+
+ $this->assertTrue($this->Auth->login());
+ $this->assertEquals($user['username'], $this->Auth->user('username'));
+ }
+
+/**
+ * test login() with user data
+ *
+ * @return void
+ */
+ public function testLoginWithUserData() {
+ $this->assertFalse($this->Auth->loggedIn());
+
+ $user = array(
+ 'username' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ );
+ $this->assertTrue($this->Auth->login($user));
+ $this->assertTrue($this->Auth->loggedIn());
+ $this->assertEquals($user['username'], $this->Auth->user('username'));
+ }
+
+/**
+ * test flash settings.
+ *
+ * @return void
+ */
+ public function testFlashSettings() {
+ $this->Auth->Session = $this->getMock('SessionComponent', array(), array(), '', false);
+ $this->Auth->Session->expects($this->once())
+ ->method('setFlash')
+ ->with('Auth failure', 'custom', array(1), 'auth-key');
+
+ $this->Auth->flash = array(
+ 'element' => 'custom',
+ 'params' => array(1),
+ 'key' => 'auth-key'
+ );
+ $this->Auth->flash('Auth failure');
+ }
+
+/**
+ * test the various states of Auth::redirect()
+ *
+ * @return void
+ */
+ public function testRedirectSet() {
+ $value = array('controller' => 'users', 'action' => 'home');
+ $result = $this->Auth->redirect($value);
+ $this->assertEquals('/users/home', $result);
+ $this->assertEquals($value, $this->Auth->Session->read('Auth.redirect'));
+ }
+
+/**
+ * test redirect using Auth.redirect from the session.
+ *
+ * @return void
+ */
+ public function testRedirectSessionRead() {
+ $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
+ $this->Auth->Session->write('Auth.redirect', '/users/home');
+
+ $result = $this->Auth->redirect();
+ $this->assertEquals('/users/home', $result);
+ $this->assertFalse($this->Auth->Session->check('Auth.redirect'));
+ }
+
+/**
+ * test that redirect does not return loginAction if that is what's stored in Auth.redirect.
+ * instead loginRedirect should be used.
+ *
+ * @return void
+ */
+ public function testRedirectSessionReadEqualToLoginAction() {
+ $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
+ $this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'home');
+ $this->Auth->Session->write('Auth.redirect', array('controller' => 'users', 'action' => 'login'));
+
+ $result = $this->Auth->redirect();
+ $this->assertEquals('/users/home', $result);
+ $this->assertFalse($this->Auth->Session->check('Auth.redirect'));
+ }
+
+/**
+ * test password hashing
+ *
+ * @return void
+ */
+ public function testPassword() {
+ $result = $this->Auth->password('password');
+ $expected = Security::hash('password', null, true);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUser method
+ *
+ * @return void
+ */
+ public function testUser() {
+ $data = array(
+ 'User' => array(
+ 'id' => '2',
+ 'username' => 'mark',
+ 'group_id' => 1,
+ 'Group' => array(
+ 'id' => '1',
+ 'name' => 'Members'
+ ),
+ ));
+ $this->Auth->Session->write('Auth', $data);
+
+ $result = $this->Auth->user();
+ $this->assertEquals($data['User'], $result);
+
+ $result = $this->Auth->user('username');
+ $this->assertEquals($data['User']['username'], $result);
+
+ $result = $this->Auth->user('Group.name');
+ $this->assertEquals($data['User']['Group']['name'], $result);
+
+ $result = $this->Auth->user('invalid');
+ $this->assertEquals(null, $result);
+
+ $result = $this->Auth->user('Company.invalid');
+ $this->assertEquals(null, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php
new file mode 100644
index 0000000..6ed65a6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php
@@ -0,0 +1,602 @@
+<?php
+/**
+ * CookieComponentTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.5435
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Component', 'Controller');
+App::uses('Controller', 'Controller');
+App::uses('CookieComponent', 'Controller/Component');
+
+
+/**
+ * CookieComponentTestController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class CookieComponentTestController extends Controller {
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Cookie');
+
+/**
+ * beforeFilter method
+ *
+ * @return void
+ */
+ public function beforeFilter() {
+ $this->Cookie->name = 'CakeTestCookie';
+ $this->Cookie->time = 10;
+ $this->Cookie->path = '/';
+ $this->Cookie->domain = '';
+ $this->Cookie->secure = false;
+ $this->Cookie->key = 'somerandomhaskey';
+ }
+
+}
+
+/**
+ * CookieComponentTest class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class CookieComponentTest extends CakeTestCase {
+
+/**
+ * Controller property
+ *
+ * @var CookieComponentTestController
+ */
+ public $Controller;
+
+/**
+ * start
+ *
+ * @return void
+ */
+ public function setUp() {
+ $_COOKIE = array();
+ $this->Controller = new CookieComponentTestController(new CakeRequest(), new CakeResponse());
+ $this->Controller->constructClasses();
+ $this->Cookie = $this->Controller->Cookie;
+
+ $this->Cookie->name = 'CakeTestCookie';
+ $this->Cookie->time = 10;
+ $this->Cookie->path = '/';
+ $this->Cookie->domain = '';
+ $this->Cookie->secure = false;
+ $this->Cookie->key = 'somerandomhaskey';
+
+ $this->Cookie->startup($this->Controller);
+ }
+
+/**
+ * end
+ *
+ * @return void
+ */
+ public function tearDown() {
+ $this->Cookie->destroy();
+ }
+
+/**
+ * sets up some default cookie data.
+ *
+ * @return void
+ */
+ protected function _setCookieData() {
+ $this->Cookie->write(array('Encrytped_array' => array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')));
+ $this->Cookie->write(array('Encrytped_multi_cookies.name' => 'CakePHP'));
+ $this->Cookie->write(array('Encrytped_multi_cookies.version' => '1.2.0.x'));
+ $this->Cookie->write(array('Encrytped_multi_cookies.tag' => 'CakePHP Rocks!'));
+
+ $this->Cookie->write(array('Plain_array' => array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')), null, false);
+ $this->Cookie->write(array('Plain_multi_cookies.name' => 'CakePHP'), null, false);
+ $this->Cookie->write(array('Plain_multi_cookies.version' => '1.2.0.x'), null, false);
+ $this->Cookie->write(array('Plain_multi_cookies.tag' => 'CakePHP Rocks!'), null, false);
+ }
+
+/**
+ * test that initialize sets settings from components array
+ *
+ * @return void
+ */
+ public function testSettings() {
+ $settings = array(
+ 'time' => '5 days',
+ 'path' => '/'
+ );
+ $Cookie = new CookieComponent(new ComponentCollection(), $settings);
+ $this->assertEquals($Cookie->time, $settings['time']);
+ $this->assertEquals($Cookie->path, $settings['path']);
+ }
+
+/**
+ * testCookieName
+ *
+ * @return void
+ */
+ public function testCookieName() {
+ $this->assertEquals('CakeTestCookie', $this->Cookie->name);
+ }
+
+/**
+ * testReadEncryptedCookieData
+ *
+ * @return void
+ */
+ public function testReadEncryptedCookieData() {
+ $this->_setCookieData();
+ $data = $this->Cookie->read('Encrytped_array');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+ }
+
+/**
+ * testReadPlainCookieData
+ *
+ * @return void
+ */
+ public function testReadPlainCookieData() {
+ $this->_setCookieData();
+ $data = $this->Cookie->read('Plain_array');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+ }
+
+/**
+ * test read() after switching the cookie name.
+ *
+ * @return void
+ */
+ public function testReadWithNameSwitch() {
+ $_COOKIE = array(
+ 'CakeTestCookie' => array(
+ 'key' => 'value'
+ ),
+ 'OtherTestCookie' => array(
+ 'key' => 'other value'
+ )
+ );
+ $this->assertEquals('value', $this->Cookie->read('key'));
+
+ $this->Cookie->name = 'OtherTestCookie';
+ $this->assertEquals('other value', $this->Cookie->read('key'));
+ }
+
+/**
+ * test a simple write()
+ *
+ * @return void
+ */
+ public function testWriteSimple() {
+ $this->Cookie->write('Testing', 'value');
+ $result = $this->Cookie->read('Testing');
+
+ $this->assertEquals('value', $result);
+ }
+
+/**
+ * test write with httpOnly cookies
+ *
+ * @return void
+ */
+ public function testWriteHttpOnly() {
+ $this->Cookie->httpOnly = true;
+ $this->Cookie->secure = false;
+ $this->Cookie->write('Testing', 'value', false);
+ $expected = array(
+ 'name' => $this->Cookie->name . '[Testing]',
+ 'value' => 'value',
+ 'expire' => time() + 10,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => false,
+ 'httpOnly' => true);
+ $result = $this->Controller->response->cookie($this->Cookie->name . '[Testing]');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test delete with httpOnly
+ *
+ * @return void
+ */
+ public function testDeleteHttpOnly() {
+ $this->Cookie->httpOnly = true;
+ $this->Cookie->secure = false;
+ $this->Cookie->delete('Testing', false);
+ $expected = array(
+ 'name' => $this->Cookie->name . '[Testing]',
+ 'value' => '',
+ 'expire' => time() - 42000,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => false,
+ 'httpOnly' => true);
+ $result = $this->Controller->response->cookie($this->Cookie->name . '[Testing]');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testWritePlainCookieArray
+ *
+ * @return void
+ */
+ public function testWritePlainCookieArray() {
+ $this->Cookie->write(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!'), null, false);
+
+ $this->assertEquals('CakePHP', $this->Cookie->read('name'));
+ $this->assertEquals('1.2.0.x', $this->Cookie->read('version'));
+ $this->assertEquals('CakePHP Rocks!', $this->Cookie->read('tag'));
+
+ $this->Cookie->delete('name');
+ $this->Cookie->delete('version');
+ $this->Cookie->delete('tag');
+ }
+
+/**
+ * test writing values that are not scalars
+ *
+ * @return void
+ */
+ public function testWriteArrayValues() {
+ $this->Cookie->secure = false;
+ $this->Cookie->write('Testing', array(1, 2, 3), false);
+ $expected = array(
+ 'name' => $this->Cookie->name . '[Testing]',
+ 'value' => '[1,2,3]',
+ 'expire' => time() + 10,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => false,
+ 'httpOnly' => false);
+ $result = $this->Controller->response->cookie($this->Cookie->name . '[Testing]');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testReadingCookieValue
+ *
+ * @return void
+ */
+ public function testReadingCookieValue() {
+ $this->_setCookieData();
+ $data = $this->Cookie->read();
+ $expected = array(
+ 'Encrytped_array' => array(
+ 'name' => 'CakePHP',
+ 'version' => '1.2.0.x',
+ 'tag' => 'CakePHP Rocks!'),
+ 'Encrytped_multi_cookies' => array(
+ 'name' => 'CakePHP',
+ 'version' => '1.2.0.x',
+ 'tag' => 'CakePHP Rocks!'),
+ 'Plain_array' => array(
+ 'name' => 'CakePHP',
+ 'version' => '1.2.0.x',
+ 'tag' => 'CakePHP Rocks!'),
+ 'Plain_multi_cookies' => array(
+ 'name' => 'CakePHP',
+ 'version' => '1.2.0.x',
+ 'tag' => 'CakePHP Rocks!'));
+ $this->assertEquals($expected, $data);
+ }
+
+/**
+ * testDeleteCookieValue
+ *
+ * @return void
+ */
+ public function testDeleteCookieValue() {
+ $this->_setCookieData();
+ $this->Cookie->delete('Encrytped_multi_cookies.name');
+ $data = $this->Cookie->read('Encrytped_multi_cookies');
+ $expected = array('version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $this->Cookie->delete('Encrytped_array');
+ $data = $this->Cookie->read('Encrytped_array');
+ $this->assertNull($data);
+
+ $this->Cookie->delete('Plain_multi_cookies.name');
+ $data = $this->Cookie->read('Plain_multi_cookies');
+ $expected = array('version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $this->Cookie->delete('Plain_array');
+ $data = $this->Cookie->read('Plain_array');
+ $this->assertNull($data);
+ }
+
+/**
+ * testReadingCookieArray
+ *
+ * @return void
+ */
+ public function testReadingCookieArray() {
+ $this->_setCookieData();
+
+ $data = $this->Cookie->read('Encrytped_array.name');
+ $expected = 'CakePHP';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_array.version');
+ $expected = '1.2.0.x';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_array.tag');
+ $expected = 'CakePHP Rocks!';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies.name');
+ $expected = 'CakePHP';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies.version');
+ $expected = '1.2.0.x';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies.tag');
+ $expected = 'CakePHP Rocks!';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_array.name');
+ $expected = 'CakePHP';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_array.version');
+ $expected = '1.2.0.x';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_array.tag');
+ $expected = 'CakePHP Rocks!';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies.name');
+ $expected = 'CakePHP';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies.version');
+ $expected = '1.2.0.x';
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies.tag');
+ $expected = 'CakePHP Rocks!';
+ $this->assertEquals($expected, $data);
+ }
+
+/**
+ * testReadingCookieDataOnStartup
+ *
+ * @return void
+ */
+ public function testReadingCookieDataOnStartup() {
+ $data = $this->Cookie->read('Encrytped_array');
+ $this->assertNull($data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies');
+ $this->assertNull($data);
+
+ $data = $this->Cookie->read('Plain_array');
+ $this->assertNull($data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies');
+ $this->assertNull($data);
+
+ $_COOKIE['CakeTestCookie'] = array(
+ 'Encrytped_array' => $this->__encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')),
+ 'Encrytped_multi_cookies' => array(
+ 'name' => $this->__encrypt('CakePHP'),
+ 'version' => $this->__encrypt('1.2.0.x'),
+ 'tag' => $this->__encrypt('CakePHP Rocks!')),
+ 'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}',
+ 'Plain_multi_cookies' => array(
+ 'name' => 'CakePHP',
+ 'version' => '1.2.0.x',
+ 'tag' => 'CakePHP Rocks!'));
+
+ $this->Cookie->startup(new CookieComponentTestController());
+
+ $data = $this->Cookie->read('Encrytped_array');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_array');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+ $this->Cookie->destroy();
+ unset($_COOKIE['CakeTestCookie']);
+ }
+
+/**
+ * testReadingCookieDataWithoutStartup
+ *
+ * @return void
+ */
+ public function testReadingCookieDataWithoutStartup() {
+ $data = $this->Cookie->read('Encrytped_array');
+ $expected = null;
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies');
+ $expected = null;
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_array');
+ $expected = null;
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies');
+ $expected = null;
+ $this->assertEquals($expected, $data);
+
+ $_COOKIE['CakeTestCookie'] = array(
+ 'Encrytped_array' => $this->__encrypt(array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!')),
+ 'Encrytped_multi_cookies' => array(
+ 'name' => $this->__encrypt('CakePHP'),
+ 'version' => $this->__encrypt('1.2.0.x'),
+ 'tag' => $this->__encrypt('CakePHP Rocks!')),
+ 'Plain_array' => '{"name":"CakePHP","version":"1.2.0.x","tag":"CakePHP Rocks!"}',
+ 'Plain_multi_cookies' => array(
+ 'name' => 'CakePHP',
+ 'version' => '1.2.0.x',
+ 'tag' => 'CakePHP Rocks!'));
+
+ $data = $this->Cookie->read('Encrytped_array');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Encrytped_multi_cookies');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_array');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+
+ $data = $this->Cookie->read('Plain_multi_cookies');
+ $expected = array('name' => 'CakePHP', 'version' => '1.2.0.x', 'tag' => 'CakePHP Rocks!');
+ $this->assertEquals($expected, $data);
+ $this->Cookie->destroy();
+ unset($_COOKIE['CakeTestCookie']);
+ }
+
+/**
+ * Test Reading legacy cookie values.
+ *
+ * @return void
+ */
+ public function testReadLegacyCookieValue() {
+ $_COOKIE['CakeTestCookie'] = array(
+ 'Legacy' => array('value' => $this->_oldImplode(array(1, 2, 3)))
+ );
+ $result = $this->Cookie->read('Legacy.value');
+ $expected = array(1, 2, 3);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test reading empty values.
+ */
+ public function testReadEmpty() {
+ $_COOKIE['CakeTestCookie'] = array(
+ 'JSON' => '{"name":"value"}',
+ 'Empty' => '',
+ 'String' => '{"somewhat:"broken"}'
+ );
+ $this->assertEquals(array('name' => 'value'), $this->Cookie->read('JSON'));
+ $this->assertEquals('value', $this->Cookie->read('JSON.name'));
+ $this->assertEquals('', $this->Cookie->read('Empty'));
+ $this->assertEquals('{"somewhat:"broken"}', $this->Cookie->read('String'));
+ }
+
+/**
+ * test that no error is issued for non array data.
+ *
+ * @return void
+ */
+ public function testNoErrorOnNonArrayData() {
+ $this->Cookie->destroy();
+ $_COOKIE['CakeTestCookie'] = 'kaboom';
+
+ $this->assertNull($this->Cookie->read('value'));
+ }
+
+/**
+ * test that deleting a top level keys kills the child elements too.
+ *
+ * @return void
+ */
+ public function testDeleteRemovesChildren() {
+ $_COOKIE['CakeTestCookie'] = array(
+ 'User' => array('email' => 'example@example.com', 'name' => 'mark'),
+ 'other' => 'value'
+ );
+ $this->assertEquals('mark', $this->Cookie->read('User.name'));
+
+ $this->Cookie->delete('User');
+ $this->assertNull($this->Cookie->read('User.email'));
+ $this->Cookie->destroy();
+ }
+
+/**
+ * Test deleting recursively with keys that don't exist.
+ *
+ * @return void
+ */
+ public function testDeleteChildrenNotExist() {
+ $this->assertNull($this->Cookie->delete('NotFound'));
+ $this->assertNull($this->Cookie->delete('Not.Found'));
+ }
+
+/**
+ * Helper method for generating old style encoded cookie values.
+ *
+ * @return string.
+ */
+ protected function _oldImplode(array $array) {
+ $string = '';
+ foreach ($array as $key => $value) {
+ $string .= ',' . $key . '|' . $value;
+ }
+ return substr($string, 1);
+ }
+
+/**
+ * Implode method to keep keys are multidimensional arrays
+ *
+ * @param array $array Map of key and values
+ * @return string String in the form key1|value1,key2|value2
+ */
+ protected function _implode(array $array) {
+ return json_encode($array);
+ }
+
+/**
+ * encrypt method
+ *
+ * @param array|string $value
+ * @return string
+ */
+ protected function __encrypt($value) {
+ if (is_array($value)) {
+ $value = $this->_implode($value);
+ }
+ return "Q2FrZQ==." . base64_encode(Security::cipher($value, $this->Cookie->key));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/EmailComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/EmailComponentTest.php
new file mode 100644
index 0000000..4e81833
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/EmailComponentTest.php
@@ -0,0 +1,889 @@
+<?php
+/**
+ * EmailComponentTest file
+ *
+ * Series of tests for email component.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.5347
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Controller', 'Controller');
+App::uses('EmailComponent', 'Controller/Component');
+App::uses('AbstractTransport', 'Network/Email');
+
+/**
+ * EmailTestComponent class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class EmailTestComponent extends EmailComponent {
+
+/**
+ * Convenience method for testing.
+ *
+ * @return string
+ */
+ public function strip($content, $message = false) {
+ return parent::_strip($content, $message);
+ }
+
+}
+
+/**
+ * DebugCompTransport class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class DebugCompTransport extends AbstractTransport {
+
+/**
+ * Last email
+ *
+ * @var string
+ */
+ public static $lastEmail = null;
+
+/**
+ * Send mail
+ *
+ * @params object $email CakeEmail
+ * @return boolean
+ */
+ public function send(CakeEmail $email) {
+ $email->addHeaders(array('Date' => EmailComponentTest::$sentDate));
+ $headers = $email->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), true));
+ $to = $headers['To'];
+ $subject = $headers['Subject'];
+ unset($headers['To'], $headers['Subject']);
+
+ $message = implode("\n", $email->message());
+
+ $last = '<pre>';
+ $last .= sprintf("%s %s\n", 'To:', $to);
+ $last .= sprintf("%s %s\n", 'From:', $headers['From']);
+ $last .= sprintf("%s %s\n", 'Subject:', $subject);
+ $last .= sprintf("%s\n\n%s", 'Header:', $this->_headersToString($headers, "\n"));
+ $last .= sprintf("%s\n\n%s", 'Message:', $message);
+ $last .= '</pre>';
+
+ self::$lastEmail = $last;
+
+ return true;
+ }
+
+}
+
+/**
+ * EmailTestController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class EmailTestController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'EmailTest'
+ */
+ public $name = 'EmailTest';
+
+/**
+ * uses property
+ *
+ * @var mixed null
+ */
+ public $uses = null;
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Session', 'EmailTest');
+
+}
+
+/**
+ * EmailTest class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class EmailComponentTest extends CakeTestCase {
+
+/**
+ * Controller property
+ *
+ * @var EmailTestController
+ */
+ public $Controller;
+
+/**
+ * name property
+ *
+ * @var string 'Email'
+ */
+ public $name = 'Email';
+
+/**
+ * sentDate
+ *
+ * @var string
+ */
+ public static $sentDate = null;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ Configure::write('App.encoding', 'UTF-8');
+
+ $this->Controller = new EmailTestController();
+ $this->Controller->Components->init($this->Controller);
+ $this->Controller->EmailTest->initialize($this->Controller, array());
+
+ self::$sentDate = date(DATE_RFC2822);
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ }
+
+/**
+ * testSendFormats method
+ *
+ * @return void
+ */
+ public function testSendFormats() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake SMTP test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->Controller->EmailTest->messageId = false;
+
+ $date = self::$sentDate;
+ $message = <<<MSGBLOC
+<pre>To: postmaster@example.com
+From: noreply@example.com
+Subject: Cake SMTP test
+Header:
+
+From: noreply@example.com
+Reply-To: noreply@example.com
+X-Mailer: CakePHP Email Component
+Date: $date
+MIME-Version: 1.0
+Content-Type: {CONTENTTYPE}
+Content-Transfer-Encoding: 8bitMessage:
+
+This is the body of the message
+
+</pre>
+MSGBLOC;
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $expect = str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $message);
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertTextEquals(DebugCompTransport::$lastEmail, $expect);
+
+ $this->Controller->EmailTest->sendAs = 'html';
+ $expect = str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $message);
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertTextEquals(DebugCompTransport::$lastEmail, $expect);
+ }
+
+/**
+ * testTemplates method
+ *
+ * @return void
+ */
+ public function testTemplates() {
+ ClassRegistry::flush();
+
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake SMTP test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->Controller->EmailTest->messageId = false;
+
+ $date = self::$sentDate;
+ $header = <<<HEADBLOC
+To: postmaster@example.com
+From: noreply@example.com
+Subject: Cake SMTP test
+Header:
+
+From: noreply@example.com
+Reply-To: noreply@example.com
+X-Mailer: CakePHP Email Component
+Date: $date
+MIME-Version: 1.0
+Content-Type: {CONTENTTYPE}
+Content-Transfer-Encoding: 8bitMessage:
+
+
+HEADBLOC;
+
+ $this->Controller->EmailTest->layout = 'default';
+ $this->Controller->EmailTest->template = 'default';
+ $this->Controller->set('title_for_layout', 'Email Test');
+
+ $text = <<<TEXTBLOC
+
+This is the body of the message
+
+This email was sent using the CakePHP Framework, http://cakephp.org.
+TEXTBLOC;
+
+ $html = <<<HTMLBLOC
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+
+<html>
+<head>
+ <title>Email Test</title>
+</head>
+
+<body>
+ <p> This is the body of the message</p><p> </p>
+ <p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>
+</body>
+</html>
+HTMLBLOC;
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $expect = '<pre>' . str_replace('{CONTENTTYPE}', 'text/plain; charset=UTF-8', $header) . $text . "\n" . '</pre>';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertTextEquals(DebugCompTransport::$lastEmail, $expect);
+
+ $this->Controller->EmailTest->sendAs = 'html';
+ $expect = '<pre>' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . "\n" . '</pre>';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertTextEquals(DebugCompTransport::$lastEmail, $expect);
+
+ $this->Controller->EmailTest->sendAs = 'both';
+ $expect = str_replace('{CONTENTTYPE}', 'multipart/mixed; boundary="{boundary}"', $header);
+ $expect .= "--{boundary}\n" .
+ 'Content-Type: multipart/alternative; boundary="alt-{boundary}"' . "\n\n" .
+ '--alt-{boundary}' . "\n" .
+ 'Content-Type: text/plain; charset=UTF-8' . "\n" .
+ 'Content-Transfer-Encoding: 8bit' . "\n\n" .
+ $text .
+ "\n\n" .
+ '--alt-{boundary}' . "\n" .
+ 'Content-Type: text/html; charset=UTF-8' . "\n" .
+ 'Content-Transfer-Encoding: 8bit' . "\n\n" .
+ $html .
+ "\n\n" .
+ '--alt-{boundary}--' . "\n\n\n" .
+ '--{boundary}--' . "\n";
+
+ $expect = '<pre>' . $expect . '</pre>';
+
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertTextEquals(
+ $expect,
+ preg_replace('/[a-z0-9]{32}/i', '{boundary}', DebugCompTransport::$lastEmail)
+ );
+
+ $html = <<<HTMLBLOC
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+
+<html>
+<head>
+ <title>Email Test</title>
+</head>
+
+<body>
+ <p> This is the body of the message</p><p> </p>
+ <p>This email was sent using the CakePHP Framework</p>
+</body>
+</html>
+
+HTMLBLOC;
+
+ $this->Controller->EmailTest->sendAs = 'html';
+ $expect = '<pre>' . str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $header) . $html . '</pre>';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message', 'default', 'thin'));
+ $this->assertTextEquals(DebugCompTransport::$lastEmail, $expect);
+ }
+
+/**
+ * test that elements used in email templates get helpers.
+ *
+ * @return void
+ */
+ public function testTemplateNestedElements() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake SMTP test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->Controller->EmailTest->messageId = false;
+ $this->Controller->EmailTest->layout = 'default';
+ $this->Controller->EmailTest->template = 'nested_element';
+ $this->Controller->EmailTest->sendAs = 'html';
+ $this->Controller->helpers = array('Html');
+
+ $this->Controller->EmailTest->send();
+ $result = DebugCompTransport::$lastEmail;
+ $this->assertRegExp('/Test/', $result);
+ $this->assertRegExp('/http\:\/\/example\.com/', $result);
+ }
+
+/**
+ * testSendDebug method
+ *
+ * @return void
+ */
+ public function testSendDebug() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->cc = 'cc@example.com';
+ $this->Controller->EmailTest->bcc = 'bcc@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $result = DebugCompTransport::$lastEmail;
+
+ $this->assertRegExp('/To: postmaster@example.com\n/', $result);
+ $this->assertRegExp('/Subject: Cake Debug Test\n/', $result);
+ $this->assertRegExp('/Reply-To: noreply@example.com\n/', $result);
+ $this->assertRegExp('/From: noreply@example.com\n/', $result);
+ $this->assertRegExp('/Cc: cc@example.com\n/', $result);
+ $this->assertRegExp('/Bcc: bcc@example.com\n/', $result);
+ $this->assertRegExp('/Date: ' . preg_quote(self::$sentDate) . '\n/', $result);
+ $this->assertRegExp('/X-Mailer: CakePHP Email Component\n/', $result);
+ $this->assertRegExp('/Content-Type: text\/plain; charset=UTF-8\n/', $result);
+ $this->assertRegExp('/Content-Transfer-Encoding: 8bitMessage:\n/', $result);
+ $this->assertRegExp('/This is the body of the message/', $result);
+ }
+
+/**
+ * test send with delivery = debug and not using sessions.
+ *
+ * @return void
+ */
+ public function testSendDebugWithNoSessions() {
+ $session = $this->Controller->Session;
+ unset($this->Controller->Session);
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->Controller->EmailTest->send('This is the body of the message');
+ $result = DebugCompTransport::$lastEmail;
+
+ $this->assertRegExp('/To: postmaster@example.com\n/', $result);
+ $this->assertRegExp('/Subject: Cake Debug Test\n/', $result);
+ $this->assertRegExp('/Reply-To: noreply@example.com\n/', $result);
+ $this->assertRegExp('/From: noreply@example.com\n/', $result);
+ $this->assertRegExp('/Date: ' . preg_quote(self::$sentDate) . '\n/', $result);
+ $this->assertRegExp('/X-Mailer: CakePHP Email Component\n/', $result);
+ $this->assertRegExp('/Content-Type: text\/plain; charset=UTF-8\n/', $result);
+ $this->assertRegExp('/Content-Transfer-Encoding: 8bitMessage:\n/', $result);
+ $this->assertRegExp('/This is the body of the message/', $result);
+ $this->Controller->Session = $session;
+ }
+
+/**
+ * testMessageRetrievalWithoutTemplate method
+ *
+ * @return void
+ */
+ public function testMessageRetrievalWithoutTemplate() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->layout = 'default';
+ $this->Controller->EmailTest->template = null;
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+
+ $text = $html = "This is the body of the message\n";
+
+ $this->Controller->EmailTest->sendAs = 'both';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertTextEquals($this->Controller->EmailTest->textMessage, $text);
+ $this->assertTextEquals($this->Controller->EmailTest->htmlMessage, $html);
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertTextEquals($this->Controller->EmailTest->textMessage, $text);
+ $this->assertNull($this->Controller->EmailTest->htmlMessage);
+
+ $this->Controller->EmailTest->sendAs = 'html';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $this->assertNull($this->Controller->EmailTest->textMessage);
+ $this->assertTextEquals($this->Controller->EmailTest->htmlMessage, $html);
+ }
+
+/**
+ * testMessageRetrievalWithTemplate method
+ *
+ * @return void
+ */
+ public function testMessageRetrievalWithTemplate() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+
+ $this->Controller->set('value', 22091985);
+ $this->Controller->set('title_for_layout', 'EmailTest');
+
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->layout = 'default';
+ $this->Controller->EmailTest->template = 'custom';
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+
+ $text = <<<TEXTBLOC
+
+Here is your value: 22091985
+This email was sent using the CakePHP Framework, http://cakephp.org.
+TEXTBLOC;
+
+ $html = <<<HTMLBLOC
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+
+<html>
+<head>
+ <title>EmailTest</title>
+</head>
+
+<body>
+ <p>Here is your value: <b>22091985</b></p>
+
+ <p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>
+</body>
+</html>
+HTMLBLOC;
+
+ $this->Controller->EmailTest->sendAs = 'both';
+ $this->assertTrue($this->Controller->EmailTest->send());
+ $this->assertTextEquals($this->Controller->EmailTest->textMessage, $text);
+ $this->assertTextEquals($this->Controller->EmailTest->htmlMessage, $html);
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->assertTrue($this->Controller->EmailTest->send());
+ $this->assertTextEquals($this->Controller->EmailTest->textMessage, $text);
+ $this->assertNull($this->Controller->EmailTest->htmlMessage);
+
+ $this->Controller->EmailTest->sendAs = 'html';
+ $this->assertTrue($this->Controller->EmailTest->send());
+ $this->assertNull($this->Controller->EmailTest->textMessage);
+ $this->assertTextEquals($this->Controller->EmailTest->htmlMessage, $html);
+ }
+
+/**
+ * testMessageRetrievalWithHelper method
+ *
+ * @return void
+ */
+ public function testMessageRetrievalWithHelper() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+
+ $timestamp = time();
+ $this->Controller->set('time', $timestamp);
+ $this->Controller->set('title_for_layout', 'EmailTest');
+ $this->Controller->helpers = array('Time');
+
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->layout = 'default';
+ $this->Controller->EmailTest->template = 'custom_helper';
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+
+ $this->assertTrue($this->Controller->EmailTest->send());
+ $this->assertTrue((bool)strpos($this->Controller->EmailTest->textMessage, 'Right now: ' . date('Y-m-d\TH:i:s\Z', $timestamp)));
+ }
+
+/**
+ * testContentArray method
+ *
+ * @return void
+ */
+ public function testSendContentArray() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+
+ $content = array('First line', 'Second line', 'Third line');
+ $this->assertTrue($this->Controller->EmailTest->send($content));
+ $result = DebugCompTransport::$lastEmail;
+
+ $this->assertRegExp('/To: postmaster@example.com\n/', $result);
+ $this->assertRegExp('/Subject: Cake Debug Test\n/', $result);
+ $this->assertRegExp('/Reply-To: noreply@example.com\n/', $result);
+ $this->assertRegExp('/From: noreply@example.com\n/', $result);
+ $this->assertRegExp('/X-Mailer: CakePHP Email Component\n/', $result);
+ $this->assertRegExp('/Content-Type: text\/plain; charset=UTF-8\n/', $result);
+ $this->assertRegExp('/Content-Transfer-Encoding: 8bitMessage:\n/', $result);
+ $this->assertRegExp('/First line\n/', $result);
+ $this->assertRegExp('/Second line\n/', $result);
+ $this->assertRegExp('/Third line\n/', $result);
+ }
+
+/**
+ * test setting a custom date.
+ *
+ * @return void
+ */
+ public function testDateProperty() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->date = self::$sentDate = 'Today!';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+
+ $this->assertTrue($this->Controller->EmailTest->send('test message'));
+ $result = DebugCompTransport::$lastEmail;
+ $this->assertRegExp('/Date: Today!\n/', $result);
+ }
+
+/**
+ * testContentStripping method
+ *
+ * @return void
+ */
+ public function testContentStripping() {
+ $content = "Previous content\n--alt-\nContent-TypeContent-Type:: text/html; charsetcharset==utf-8\nContent-Transfer-Encoding: 8bit";
+ $content .= "\n\n<p>My own html content</p>";
+
+ $result = $this->Controller->EmailTest->strip($content, true);
+ $expected = "Previous content\n--alt-\n text/html; utf-8\n 8bit\n\n<p>My own html content</p>";
+ $this->assertEquals($expected, $result);
+
+ $content = '<p>Some HTML content with an <a href="mailto:test@example.com">email link</a>';
+ $result = $this->Controller->EmailTest->strip($content, true);
+ $expected = $content;
+ $this->assertEquals($expected, $result);
+
+ $content = '<p>Some HTML content with an ';
+ $content .= '<a href="mailto:test@example.com,test2@example.com">email link</a>';
+ $result = $this->Controller->EmailTest->strip($content, true);
+ $expected = $content;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that the _encode() will set mb_internal_encoding.
+ *
+ * @return void
+ */
+ public function testEncodeSettingInternalCharset() {
+ $this->skipIf(!function_exists('mb_internal_encoding'), 'Missing mb_* functions, cannot run test.');
+
+ $restore = mb_internal_encoding();
+ mb_internal_encoding('ISO-8859-1');
+
+ $this->Controller->charset = 'UTF-8';
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'هذه رسالة بعنوان طويل مرسل للمستلم';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+
+ $subject = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?=';
+
+ preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches);
+ $this->assertEquals(trim($matches[1]), $subject);
+
+ $result = mb_internal_encoding();
+ $this->assertEquals('ISO-8859-1', $result);
+
+ mb_internal_encoding($restore);
+ }
+
+/**
+ * testMultibyte method
+ *
+ * @return void
+ */
+ public function testMultibyte() {
+ $this->Controller->charset = 'UTF-8';
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'هذه رسالة بعنوان طويل مرسل للمستلم';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+
+ $subject = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?=';
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches);
+ $this->assertEquals(trim($matches[1]), $subject);
+
+ $this->Controller->EmailTest->sendAs = 'html';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches);
+ $this->assertEquals(trim($matches[1]), $subject);
+
+ $this->Controller->EmailTest->sendAs = 'both';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ preg_match('/Subject: (.*)Header:/s', DebugCompTransport::$lastEmail, $matches);
+ $this->assertEquals(trim($matches[1]), $subject);
+ }
+
+/**
+ * undocumented function
+ *
+ * @return void
+ */
+ public function testSendWithAttachments() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Attachment Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->Controller->EmailTest->attachments = array(
+ __FILE__,
+ 'some-name.php' => __FILE__
+ );
+ $body = '<p>This is the body of the message</p>';
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->assertTrue($this->Controller->EmailTest->send($body));
+ $msg = DebugCompTransport::$lastEmail;
+ $this->assertRegExp('/' . preg_quote('Content-Disposition: attachment; filename="EmailComponentTest.php"') . '/', $msg);
+ $this->assertRegExp('/' . preg_quote('Content-Disposition: attachment; filename="some-name.php"') . '/', $msg);
+ }
+
+/**
+ * testSendAsIsNotIgnoredIfAttachmentsPresent method
+ *
+ * @return void
+ */
+ public function testSendAsIsNotIgnoredIfAttachmentsPresent() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Attachment Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->Controller->EmailTest->attachments = array(__FILE__);
+ $body = '<p>This is the body of the message</p>';
+
+ $this->Controller->EmailTest->sendAs = 'html';
+ $this->assertTrue($this->Controller->EmailTest->send($body));
+ $msg = DebugCompTransport::$lastEmail;
+ $this->assertNotRegExp('/text\/plain/', $msg);
+ $this->assertRegExp('/text\/html/', $msg);
+
+ $this->Controller->EmailTest->sendAs = 'text';
+ $this->assertTrue($this->Controller->EmailTest->send($body));
+ $msg = DebugCompTransport::$lastEmail;
+ $this->assertRegExp('/text\/plain/', $msg);
+ $this->assertNotRegExp('/text\/html/', $msg);
+
+ $this->Controller->EmailTest->sendAs = 'both';
+ $this->assertTrue($this->Controller->EmailTest->send($body));
+ $msg = DebugCompTransport::$lastEmail;
+
+ $this->assertRegExp('/text\/plain/', $msg);
+ $this->assertRegExp('/text\/html/', $msg);
+ $this->assertRegExp('/multipart\/alternative/', $msg);
+ }
+
+/**
+ * testNoDoubleNewlinesInHeaders function
+ *
+ * @return void
+ */
+ public function testNoDoubleNewlinesInHeaders() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Attachment Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $body = '<p>This is the body of the message</p>';
+
+ $this->Controller->EmailTest->sendAs = 'both';
+ $this->assertTrue($this->Controller->EmailTest->send($body));
+ $msg = DebugCompTransport::$lastEmail;
+
+ $this->assertNotRegExp('/\n\nContent-Transfer-Encoding/', $msg);
+ $this->assertRegExp('/\nContent-Transfer-Encoding/', $msg);
+ }
+
+/**
+ * testReset method
+ *
+ * @return void
+ */
+ public function testReset() {
+ $this->Controller->EmailTest->template = 'default';
+ $this->Controller->EmailTest->to = 'test.recipient@example.com';
+ $this->Controller->EmailTest->from = 'test.sender@example.com';
+ $this->Controller->EmailTest->replyTo = 'test.replyto@example.com';
+ $this->Controller->EmailTest->return = 'test.return@example.com';
+ $this->Controller->EmailTest->cc = array('cc1@example.com', 'cc2@example.com');
+ $this->Controller->EmailTest->bcc = array('bcc1@example.com', 'bcc2@example.com');
+ $this->Controller->EmailTest->date = 'Today!';
+ $this->Controller->EmailTest->subject = 'Test subject';
+ $this->Controller->EmailTest->additionalParams = 'X-additional-header';
+ $this->Controller->EmailTest->delivery = 'smtp';
+ $this->Controller->EmailTest->smtpOptions['host'] = 'blah';
+ $this->Controller->EmailTest->smtpOptions['timeout'] = 0.2;
+ $this->Controller->EmailTest->attachments = array('attachment1', 'attachment2');
+ $this->Controller->EmailTest->textMessage = 'This is the body of the message';
+ $this->Controller->EmailTest->htmlMessage = 'This is the body of the message';
+ $this->Controller->EmailTest->messageId = false;
+
+ try {
+ $this->Controller->EmailTest->send('Should not work');
+ $this->fail('No exception');
+ } catch (SocketException $e) {
+ $this->assertTrue(true, 'SocketException raised');
+ }
+
+ $this->Controller->EmailTest->reset();
+
+ $this->assertNull($this->Controller->EmailTest->template);
+ $this->assertSame($this->Controller->EmailTest->to, array());
+ $this->assertNull($this->Controller->EmailTest->from);
+ $this->assertNull($this->Controller->EmailTest->replyTo);
+ $this->assertNull($this->Controller->EmailTest->return);
+ $this->assertSame($this->Controller->EmailTest->cc, array());
+ $this->assertSame($this->Controller->EmailTest->bcc, array());
+ $this->assertNull($this->Controller->EmailTest->date);
+ $this->assertNull($this->Controller->EmailTest->subject);
+ $this->assertNull($this->Controller->EmailTest->additionalParams);
+ $this->assertNull($this->Controller->EmailTest->smtpError);
+ $this->assertSame($this->Controller->EmailTest->attachments, array());
+ $this->assertNull($this->Controller->EmailTest->textMessage);
+ $this->assertTrue($this->Controller->EmailTest->messageId);
+ $this->assertEquals('mail', $this->Controller->EmailTest->delivery);
+ }
+
+ public function testPluginCustomViewClass() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+
+ $this->Controller->view = 'TestPlugin.Email';
+
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'CustomViewClass test';
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $body = 'Body of message';
+
+ $this->assertTrue($this->Controller->EmailTest->send($body));
+ $result = DebugCompTransport::$lastEmail;
+
+ $this->assertRegExp('/Body of message/', $result);
+ }
+
+/**
+ * testStartup method
+ *
+ * @return void
+ */
+ public function testStartup() {
+ $this->assertNull($this->Controller->EmailTest->startup($this->Controller));
+ }
+
+/**
+ * testMessageId method
+ *
+ * @return void
+ */
+ public function testMessageId() {
+ $this->Controller->EmailTest->to = 'postmaster@example.com';
+ $this->Controller->EmailTest->from = 'noreply@example.com';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $result = DebugCompTransport::$lastEmail;
+
+ $host = env('HTTP_HOST') ? env('HTTP_HOST') : php_uname('n');
+ $this->assertRegExp('/Message-ID: \<[a-f0-9]{8}[a-f0-9]{4}[a-f0-9]{4}[a-f0-9]{4}[a-f0-9]{12}@' . $host . '\>\n/', $result);
+
+ $this->Controller->EmailTest->messageId = '<22091985.998877@example.com>';
+
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $result = DebugCompTransport::$lastEmail;
+
+ $this->assertRegExp('/Message-ID: <22091985.998877@example.com>\n/', $result);
+
+ $this->Controller->EmailTest->messageId = false;
+
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $result = DebugCompTransport::$lastEmail;
+
+ $this->assertNotRegExp('/Message-ID:/', $result);
+ }
+
+/**
+ * Make sure from/to are not double encoded when UTF-8 is present
+ */
+ public function testEncodingFrom() {
+ $this->Controller->EmailTest->to = 'Teßt <test@example.com>';
+ $this->Controller->EmailTest->from = 'Teßt <test@example.com>';
+ $this->Controller->EmailTest->subject = 'Cake Debug Test';
+ $this->Controller->EmailTest->replyTo = 'noreply@example.com';
+ $this->Controller->EmailTest->template = null;
+
+ $this->Controller->EmailTest->delivery = 'DebugComp';
+ $this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
+ $result = DebugCompTransport::$lastEmail;
+
+ $this->assertContains('From: =?UTF-8?B?VGXDn3Qg?= <test@example.com>', $result);
+ $this->assertContains('To: =?UTF-8?B?VGXDn3Qg?= <test@example.com>', $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php
new file mode 100644
index 0000000..1908e92
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php
@@ -0,0 +1,1194 @@
+<?php
+/**
+ * PaginatorComponentTest file
+ *
+ * Series of tests for paginator component.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('PaginatorComponent', 'Controller/Component');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * PaginatorTestController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class PaginatorTestController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'PaginatorTest'
+ */
+ public $name = 'PaginatorTest';
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Paginator');
+}
+
+/**
+ * PaginatorControllerPost class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class PaginatorControllerPost extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'PaginatorControllerPost'
+ */
+ public $name = 'PaginatorControllerPost';
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'posts';
+
+/**
+ * invalidFields property
+ *
+ * @var array
+ */
+ public $invalidFields = array('name' => 'error_msg');
+
+/**
+ * lastQueries property
+ *
+ * @var array
+ */
+ public $lastQueries = array();
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('PaginatorAuthor' => array('foreignKey' => 'author_id'));
+
+/**
+ * beforeFind method
+ *
+ * @param mixed $query
+ * @return void
+ */
+ public function beforeFind($query) {
+ array_unshift($this->lastQueries, $query);
+ }
+
+/**
+ * find method
+ *
+ * @param mixed $type
+ * @param array $options
+ * @return void
+ */
+ public function find($conditions = null, $fields = array(), $order = null, $recursive = null) {
+ if ($conditions == 'popular') {
+ $conditions = array($this->name . '.' . $this->primaryKey . ' > ' => '1');
+ $options = Hash::merge($fields, compact('conditions'));
+ return parent::find('all', $options);
+ }
+ return parent::find($conditions, $fields);
+ }
+
+}
+
+/**
+ * ControllerPaginateModel class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class ControllerPaginateModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ControllerPaginateModel'
+ */
+ public $name = 'ControllerPaginateModel';
+
+/**
+ * useTable property
+ *
+ * @var string 'comments'
+ */
+ public $useTable = 'comments';
+
+/**
+ * paginate method
+ *
+ * @return void
+ */
+ public function paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra) {
+ $this->extra = $extra;
+ }
+
+/**
+ * paginateCount
+ *
+ * @return void
+ */
+ public function paginateCount($conditions, $recursive, $extra) {
+ $this->extraCount = $extra;
+ }
+
+}
+
+/**
+ * PaginatorControllerComment class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class PaginatorControllerComment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Comment'
+ */
+ public $name = 'Comment';
+
+/**
+ * useTable property
+ *
+ * @var string 'comments'
+ */
+ public $useTable = 'comments';
+
+/**
+ * alias property
+ *
+ * @var string 'PaginatorControllerComment'
+ */
+ public $alias = 'PaginatorControllerComment';
+}
+
+/**
+ * PaginatorAuthor class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class PaginatorAuthor extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'PaginatorAuthor'
+ */
+ public $name = 'PaginatorAuthor';
+
+/**
+ * useTable property
+ *
+ * @var string 'authors'
+ */
+ public $useTable = 'authors';
+
+/**
+ * alias property
+ *
+ * @var string 'PaginatorAuthor'
+ */
+ public $alias = 'PaginatorAuthor';
+
+/**
+ * alias property
+ *
+ * @var string 'PaginatorAuthor'
+ */
+ public $virtualFields = array(
+ 'joined_offset' => 'PaginatorAuthor.id + 1'
+ );
+
+}
+
+/**
+ * PaginatorCustomPost class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class PaginatorCustomPost extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = 'posts';
+
+/**
+ * belongsTo property
+ *
+ * @var string
+ */
+ public $belongsTo = array('Author');
+
+/**
+ * findMethods property
+ *
+ * @var array
+ */
+ public $findMethods = array(
+ 'published' => true,
+ 'totals' => true,
+ 'totalsOperation' => true
+ );
+
+/**
+ * _findPublished custom find
+ *
+ * @return array
+ */
+ protected function _findPublished($state, $query, $results = array()) {
+ if ($state === 'before') {
+ $query['conditions']['published'] = 'Y';
+ return $query;
+ }
+ return $results;
+ }
+
+/**
+ * _findTotals custom find
+ *
+ * @return array
+ */
+ protected function _findTotals($state, $query, $results = array()) {
+ if ($state == 'before') {
+ $query['fields'] = array('author_id');
+ $this->virtualFields['total_posts'] = "COUNT({$this->alias}.id)";
+ $query['fields'][] = 'total_posts';
+ $query['group'] = array('author_id');
+ $query['order'] = array('author_id' => 'ASC');
+ return $query;
+ }
+ $this->virtualFields = array();
+ return $results;
+ }
+
+/**
+ * _findTotalsOperation custom find
+ *
+ * @return array
+ */
+ protected function _findTotalsOperation($state, $query, $results = array()) {
+ if ($state == 'before') {
+ if (!empty($query['operation']) && $query['operation'] === 'count') {
+ unset($query['limit']);
+ $query['recursive'] = -1;
+ $query['fields'] = array('COUNT(DISTINCT author_id) AS count');
+ return $query;
+ }
+ $query['recursive'] = 0;
+ $query['callbacks'] = 'before';
+ $query['fields'] = array('author_id', 'Author.user');
+ $this->virtualFields['total_posts'] = "COUNT({$this->alias}.id)";
+ $query['fields'][] = 'total_posts';
+ $query['group'] = array('author_id', 'Author.user');
+ $query['order'] = array('author_id' => 'ASC');
+ return $query;
+ }
+ $this->virtualFields = array();
+ return $results;
+ }
+
+}
+
+class PaginatorComponentTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.post', 'core.comment', 'core.author');
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->request = new CakeRequest('controller_posts/index');
+ $this->request->params['pass'] = $this->request->params['named'] = array();
+ $this->Controller = new Controller($this->request);
+ $this->Paginator = new PaginatorComponent($this->getMock('ComponentCollection'), array());
+ $this->Paginator->Controller = $this->Controller;
+ $this->Controller->Post = $this->getMock('Model');
+ $this->Controller->Post->alias = 'Post';
+ }
+
+/**
+ * testPaginate method
+ *
+ * @return void
+ */
+ public function testPaginate() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
+ $Controller->request->params['pass'] = array('1');
+ $Controller->request->query = array();
+ $Controller->constructClasses();
+
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(array(1, 2, 3), $results);
+
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerComment'), '{n}.PaginatorControllerComment.id');
+ $this->assertEquals(array(1, 2, 3, 4, 5, 6), $results);
+
+ $Controller->modelClass = null;
+
+ $Controller->uses[0] = 'Plugin.PaginatorControllerPost';
+ $results = Hash::extract($Controller->Paginator->paginate(), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(array(1, 2, 3), $results);
+
+ $Controller->request->params['named'] = array('page' => '-1');
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertEquals(array(1, 2, 3), $results);
+
+ $Controller->request->params['named'] = array('sort' => 'PaginatorControllerPost.id', 'direction' => 'asc');
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertEquals(array(1, 2, 3), $results);
+
+ $Controller->request->params['named'] = array('sort' => 'PaginatorControllerPost.id', 'direction' => 'desc');
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertEquals(array(3, 2, 1), $results);
+
+ $Controller->request->params['named'] = array('sort' => 'id', 'direction' => 'desc');
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertEquals(array(3, 2, 1), $results);
+
+ $Controller->request->params['named'] = array('sort' => 'NotExisting.field', 'direction' => 'desc');
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page'], 'Invalid field in query %s');
+ $this->assertEquals(array(1, 2, 3), $results);
+
+ $Controller->request->params['named'] = array(
+ 'sort' => 'PaginatorControllerPost.author_id', 'direction' => 'allYourBase'
+ );
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals(array('PaginatorControllerPost.author_id' => 'asc'), $Controller->PaginatorControllerPost->lastQueries[1]['order'][0]);
+ $this->assertEquals(array(1, 3, 2), $results);
+
+ $Controller->request->params['named'] = array();
+ $Controller->Paginator->settings = array('limit' => 0, 'maxLimit' => 10, 'paramType' => 'named');
+ $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertSame(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['prevPage'], false);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['nextPage'], true);
+
+ $Controller->request->params['named'] = array();
+ $Controller->Paginator->settings = array('limit' => 'garbage!', 'maxLimit' => 10, 'paramType' => 'named');
+ $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertSame(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['prevPage'], false);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['nextPage'], true);
+
+ $Controller->request->params['named'] = array();
+ $Controller->Paginator->settings = array('limit' => '-1', 'maxLimit' => 10, 'paramType' => 'named');
+ $Controller->Paginator->paginate('PaginatorControllerPost');
+
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['limit'], 1);
+ $this->assertSame(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['pageCount'], 3);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['prevPage'], false);
+ $this->assertSame($Controller->params['paging']['PaginatorControllerPost']['nextPage'], true);
+
+ $Controller->Paginator->settings = array('conditions' => array('PaginatorAuthor.user' => 'mariano'));
+ $Controller->Paginator->paginate('PaginatorControllerPost');
+
+ $this->assertSame(2, $Controller->params['paging']['PaginatorControllerPost']['count']);
+ }
+
+/**
+ * Test that non-numeric values are rejected for page, and limit
+ *
+ * @return void
+ */
+ public function testPageParamCasting() {
+ $this->Controller->Post->expects($this->at(0))
+ ->method('hasMethod')
+ ->with('paginate')
+ ->will($this->returnValue(false));
+
+ $this->Controller->Post->expects($this->at(1))
+ ->method('find')
+ ->will($this->returnValue(array('stuff')));
+
+ $this->Controller->Post->expects($this->at(2))
+ ->method('hasMethod')
+ ->with('paginateCount')
+ ->will($this->returnValue(false));
+
+ $this->Controller->Post->expects($this->at(3))
+ ->method('find')
+ ->will($this->returnValue(2));
+
+ $this->request->params['named'] = array('page' => '1 " onclick="alert(\'xss\');">');
+ $this->Paginator->settings = array('limit' => 1, 'maxLimit' => 10, 'paramType' => 'named');
+ $this->Paginator->paginate('Post');
+ $this->assertSame(1, $this->request->params['paging']['Post']['page'], 'XSS exploit opened');
+ }
+
+/**
+ * testPaginateExtraParams method
+ *
+ * @return void
+ */
+ public function testPaginateExtraParams() {
+ $Controller = new PaginatorTestController($this->request);
+
+ $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
+ $Controller->request->params['pass'] = array('1');
+ $Controller->params['url'] = array();
+ $Controller->constructClasses();
+
+ $Controller->request->params['named'] = array('page' => '-1', 'contain' => array('PaginatorControllerComment'));
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertEquals(array(1, 2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
+ $this->assertTrue(!isset($Controller->PaginatorControllerPost->lastQueries[1]['contain']));
+
+ $Controller->request->params['named'] = array('page' => '-1');
+ $Controller->Paginator->settings = array(
+ 'PaginatorControllerPost' => array(
+ 'contain' => array('PaginatorControllerComment'),
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ ),
+ );
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(1, $Controller->params['paging']['PaginatorControllerPost']['page']);
+ $this->assertEquals(array(1, 2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
+ $this->assertTrue(isset($Controller->PaginatorControllerPost->lastQueries[1]['contain']));
+
+ $Controller->Paginator->settings = array(
+ 'PaginatorControllerPost' => array(
+ 'popular', 'fields' => array('id', 'title'), 'maxLimit' => 10, 'paramType' => 'named'
+ ),
+ );
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(array(2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
+ $this->assertEquals(array('PaginatorControllerPost.id > ' => '1'), $Controller->PaginatorControllerPost->lastQueries[1]['conditions']);
+
+ $Controller->request->params['named'] = array('limit' => 12);
+ $Controller->Paginator->settings = array('limit' => 30, 'maxLimit' => 100, 'paramType' => 'named');
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $paging = $Controller->params['paging']['PaginatorControllerPost'];
+
+ $this->assertEquals(12, $Controller->PaginatorControllerPost->lastQueries[1]['limit']);
+ $this->assertEquals(12, $paging['options']['limit']);
+
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->uses = array('ControllerPaginateModel');
+ $Controller->request->query = array();
+ $Controller->constructClasses();
+ $Controller->Paginator->settings = array(
+ 'ControllerPaginateModel' => array(
+ 'contain' => array('ControllerPaginateModel'),
+ 'group' => 'Comment.author_id',
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ )
+ );
+ $result = $Controller->Paginator->paginate('ControllerPaginateModel');
+ $expected = array(
+ 'contain' => array('ControllerPaginateModel'),
+ 'group' => 'Comment.author_id',
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ );
+ $this->assertEquals($expected, $Controller->ControllerPaginateModel->extra);
+ $this->assertEquals($expected, $Controller->ControllerPaginateModel->extraCount);
+
+ $Controller->Paginator->settings = array(
+ 'ControllerPaginateModel' => array(
+ 'foo', 'contain' => array('ControllerPaginateModel'),
+ 'group' => 'Comment.author_id',
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ )
+ );
+ $Controller->Paginator->paginate('ControllerPaginateModel');
+ $expected = array(
+ 'contain' => array('ControllerPaginateModel'),
+ 'group' => 'Comment.author_id',
+ 'type' => 'foo',
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ );
+ $this->assertEquals($expected, $Controller->ControllerPaginateModel->extra);
+ $this->assertEquals($expected, $Controller->ControllerPaginateModel->extraCount);
+ }
+
+/**
+ * Test that special paginate types are called and that the type param doesn't leak out into defaults or options.
+ *
+ * @return void
+ */
+ public function testPaginateSpecialType() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
+ $Controller->passedArgs[] = '1';
+ $Controller->params['url'] = array();
+ $Controller->constructClasses();
+
+ $Controller->Paginator->settings = array(
+ 'PaginatorControllerPost' => array(
+ 'popular',
+ 'fields' => array('id', 'title'),
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ )
+ );
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+
+ $this->assertEquals(array(2, 3), Hash::extract($result, '{n}.PaginatorControllerPost.id'));
+ $this->assertEquals(
+ $Controller->PaginatorControllerPost->lastQueries[1]['conditions'],
+ array('PaginatorControllerPost.id > ' => '1')
+ );
+ $this->assertFalse(isset($Controller->params['paging']['PaginatorControllerPost']['options'][0]));
+ }
+
+/**
+ * testDefaultPaginateParams method
+ *
+ * @return void
+ */
+ public function testDefaultPaginateParams() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->modelClass = 'PaginatorControllerPost';
+ $Controller->params['url'] = array();
+ $Controller->constructClasses();
+ $Controller->Paginator->settings = array(
+ 'order' => 'PaginatorControllerPost.id DESC',
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ );
+ $results = Hash::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id');
+ $this->assertEquals('PaginatorControllerPost.id DESC', $Controller->params['paging']['PaginatorControllerPost']['order']);
+ $this->assertEquals(array(3, 2, 1), $results);
+ }
+
+/**
+ * test paginate() and virtualField interactions
+ *
+ * @return void
+ */
+ public function testPaginateOrderVirtualField() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
+ $Controller->params['url'] = array();
+ $Controller->constructClasses();
+ $Controller->PaginatorControllerPost->virtualFields = array(
+ 'offset_test' => 'PaginatorControllerPost.id + 1'
+ );
+
+ $Controller->Paginator->settings = array(
+ 'fields' => array('id', 'title', 'offset_test'),
+ 'order' => array('offset_test' => 'DESC'),
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ );
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(array(4, 3, 2), Hash::extract($result, '{n}.PaginatorControllerPost.offset_test'));
+
+ $Controller->request->params['named'] = array('sort' => 'offset_test', 'direction' => 'asc');
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(array(2, 3, 4), Hash::extract($result, '{n}.PaginatorControllerPost.offset_test'));
+ }
+
+/**
+ * test paginate() and virtualField on joined model
+ *
+ * @return void
+ */
+ public function testPaginateOrderVirtualFieldJoinedModel() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->uses = array('PaginatorControllerPost');
+ $Controller->params['url'] = array();
+ $Controller->constructClasses();
+ $Controller->PaginatorControllerPost->recursive = 0;
+ $Controller->Paginator->settings = array(
+ 'order' => array('PaginatorAuthor.joined_offset' => 'DESC'),
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ );
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(array(4, 2, 2), Hash::extract($result, '{n}.PaginatorAuthor.joined_offset'));
+
+ $Controller->request->params['named'] = array('sort' => 'PaginatorAuthor.joined_offset', 'direction' => 'asc');
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(array(2, 2, 4), Hash::extract($result, '{n}.PaginatorAuthor.joined_offset'));
+ }
+
+/**
+ * Tests for missing models
+ *
+ * @expectedException MissingModelException
+ */
+ public function testPaginateMissingModel() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->constructClasses();
+ $Controller->Paginator->paginate('MissingModel');
+ }
+
+/**
+ * test that option merging prefers specific models
+ *
+ * @return void
+ */
+ public function testMergeOptionsModelSpecific() {
+ $this->Paginator->settings = array(
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'paramType' => 'named',
+ 'Post' => array(
+ 'page' => 1,
+ 'limit' => 10,
+ 'maxLimit' => 50,
+ 'paramType' => 'named',
+ )
+ );
+ $result = $this->Paginator->mergeOptions('Silly');
+ $this->assertEquals($this->Paginator->settings, $result);
+
+ $result = $this->Paginator->mergeOptions('Post');
+ $expected = array('page' => 1, 'limit' => 10, 'paramType' => 'named', 'maxLimit' => 50);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test mergeOptions with named params.
+ *
+ * @return void
+ */
+ public function testMergeOptionsNamedParams() {
+ $this->request->params['named'] = array(
+ 'page' => 10,
+ 'limit' => 10
+ );
+ $this->Paginator->settings = array(
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'paramType' => 'named',
+ );
+ $result = $this->Paginator->mergeOptions('Post');
+ $expected = array('page' => 10, 'limit' => 10, 'maxLimit' => 100, 'paramType' => 'named');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test merging options from the querystring.
+ *
+ * @return void
+ */
+ public function testMergeOptionsQueryString() {
+ $this->request->params['named'] = array(
+ 'page' => 10,
+ 'limit' => 10
+ );
+ $this->request->query = array(
+ 'page' => 99,
+ 'limit' => 75
+ );
+ $this->Paginator->settings = array(
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'paramType' => 'querystring',
+ );
+ $result = $this->Paginator->mergeOptions('Post');
+ $expected = array('page' => 99, 'limit' => 75, 'maxLimit' => 100, 'paramType' => 'querystring');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that the default whitelist doesn't let people screw with things they should not be allowed to.
+ *
+ * @return void
+ */
+ public function testMergeOptionsDefaultWhiteList() {
+ $this->request->params['named'] = array(
+ 'page' => 10,
+ 'limit' => 10,
+ 'fields' => array('bad.stuff'),
+ 'recursive' => 1000,
+ 'conditions' => array('bad.stuff'),
+ 'contain' => array('bad')
+ );
+ $this->Paginator->settings = array(
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'paramType' => 'named',
+ );
+ $result = $this->Paginator->mergeOptions('Post');
+ $expected = array('page' => 10, 'limit' => 10, 'maxLimit' => 100, 'paramType' => 'named');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that modifying the whitelist works.
+ *
+ * @return void
+ */
+ public function testMergeOptionsExtraWhitelist() {
+ $this->request->params['named'] = array(
+ 'page' => 10,
+ 'limit' => 10,
+ 'fields' => array('bad.stuff'),
+ 'recursive' => 1000,
+ 'conditions' => array('bad.stuff'),
+ 'contain' => array('bad')
+ );
+ $this->Paginator->settings = array(
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'paramType' => 'named',
+ );
+ $this->Paginator->whitelist[] = 'fields';
+ $result = $this->Paginator->mergeOptions('Post');
+ $expected = array(
+ 'page' => 10, 'limit' => 10, 'maxLimit' => 100, 'paramType' => 'named', 'fields' => array('bad.stuff')
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that invalid directions are ignored.
+ *
+ * @return void
+ */
+ public function testValidateSortInvalidDirection() {
+ $model = $this->getMock('Model');
+ $model->alias = 'model';
+ $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
+
+ $options = array('sort' => 'something', 'direction' => 'boogers');
+ $result = $this->Paginator->validateSort($model, $options);
+
+ $this->assertEquals('asc', $result['order']['model.something']);
+ }
+
+/**
+ * Test that a really large page number gets clamped to the max page size.
+ */
+ public function testOutOfRangePageNumberGetsClamped() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->uses = array('PaginatorControllerPost');
+ $Controller->params['named'] = array(
+ 'page' => 3000,
+ );
+ $Controller->constructClasses();
+ $Controller->PaginatorControllerPost->recursive = 0;
+ $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(
+ 1,
+ $Controller->request->params['paging']['PaginatorControllerPost']['page'],
+ 'Super big page number should be capped to max number of pages'
+ );
+
+ $Controller->paginate = array(
+ 'conditions' => array('PaginatorControllerPost.id >' => 100)
+ );
+ $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEquals(
+ 1,
+ $Controller->request->params['paging']['PaginatorControllerPost']['page'],
+ 'Page number should not be 0'
+ );
+ }
+
+/**
+ * test that fields not in whitelist won't be part of order conditions.
+ *
+ * @return void
+ */
+ public function testValidateSortWhitelistFailure() {
+ $model = $this->getMock('Model');
+ $model->alias = 'model';
+ $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
+
+ $options = array('sort' => 'body', 'direction' => 'asc');
+ $result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
+
+ $this->assertNull($result['order']);
+ }
+
+/**
+ * test that virtual fields work.
+ *
+ * @return void
+ */
+ public function testValidateSortVirtualField() {
+ $model = $this->getMock('Model');
+ $model->alias = 'model';
+
+ $model->expects($this->at(0))
+ ->method('hasField')
+ ->with('something')
+ ->will($this->returnValue(false));
+
+ $model->expects($this->at(1))
+ ->method('hasField')
+ ->with('something', true)
+ ->will($this->returnValue(true));
+
+ $options = array('sort' => 'something', 'direction' => 'desc');
+ $result = $this->Paginator->validateSort($model, $options);
+
+ $this->assertEquals('desc', $result['order']['something']);
+ }
+
+/**
+ * test that multiple sort works.
+ *
+ * @return void
+ */
+ public function testValidateSortMultiple() {
+ $model = $this->getMock('Model');
+ $model->alias = 'model';
+ $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
+
+ $options = array('order' => array(
+ 'author_id' => 'asc',
+ 'title' => 'asc'
+ ));
+ $result = $this->Paginator->validateSort($model, $options);
+ $expected = array(
+ 'model.author_id' => 'asc',
+ 'model.title' => 'asc'
+ );
+
+ $this->assertEquals($expected, $result['order']);
+ }
+
+/**
+ * Test that no sort doesn't trigger an error.
+ *
+ * @return void
+ */
+ public function testValidateSortNoSort() {
+ $model = $this->getMock('Model');
+ $model->alias = 'model';
+ $model->expects($this->any())->method('hasField')->will($this->returnValue(true));
+
+ $options = array('direction' => 'asc');
+ $result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
+ $this->assertFalse(isset($result['order']));
+
+ $options = array('order' => 'invalid desc');
+ $result = $this->Paginator->validateSort($model, $options, array('title', 'id'));
+
+ $this->assertEquals($options['order'], $result['order']);
+ }
+
+/**
+ * test that maxLimit is respected
+ *
+ * @return void
+ */
+ public function testCheckLimit() {
+ $result = $this->Paginator->checkLimit(array('limit' => 1000000, 'maxLimit' => 100));
+ $this->assertEquals(100, $result['limit']);
+
+ $result = $this->Paginator->checkLimit(array('limit' => 'sheep!', 'maxLimit' => 100));
+ $this->assertEquals(1, $result['limit']);
+
+ $result = $this->Paginator->checkLimit(array('limit' => '-1', 'maxLimit' => 100));
+ $this->assertEquals(1, $result['limit']);
+
+ $result = $this->Paginator->checkLimit(array('limit' => null, 'maxLimit' => 100));
+ $this->assertEquals(1, $result['limit']);
+
+ $result = $this->Paginator->checkLimit(array('limit' => 0, 'maxLimit' => 100));
+ $this->assertEquals(1, $result['limit']);
+ }
+
+/**
+ * testPaginateMaxLimit
+ *
+ * @return void
+ */
+ public function testPaginateMaxLimit() {
+ $Controller = new Controller($this->request);
+
+ $Controller->uses = array('PaginatorControllerPost', 'ControllerComment');
+ $Controller->passedArgs[] = '1';
+ $Controller->constructClasses();
+
+ $Controller->request->params['named'] = array(
+ 'contain' => array('ControllerComment'), 'limit' => '1000'
+ );
+ $result = $Controller->paginate('PaginatorControllerPost');
+ $this->assertEquals(100, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
+
+ $Controller->request->params['named'] = array(
+ 'contain' => array('ControllerComment'), 'limit' => '1000', 'maxLimit' => 1000
+ );
+ $result = $Controller->paginate('PaginatorControllerPost');
+ $this->assertEquals(100, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
+
+ $Controller->request->params['named'] = array('contain' => array('ControllerComment'), 'limit' => '10');
+ $result = $Controller->paginate('PaginatorControllerPost');
+ $this->assertEquals(10, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
+
+ $Controller->request->params['named'] = array('contain' => array('ControllerComment'), 'limit' => '1000');
+ $Controller->paginate = array('maxLimit' => 2000, 'paramType' => 'named');
+ $result = $Controller->paginate('PaginatorControllerPost');
+ $this->assertEquals(1000, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
+
+ $Controller->request->params['named'] = array('contain' => array('ControllerComment'), 'limit' => '5000');
+ $result = $Controller->paginate('PaginatorControllerPost');
+ $this->assertEquals(2000, $Controller->params['paging']['PaginatorControllerPost']['options']['limit']);
+ }
+
+/**
+ * test paginate() and virtualField overlapping with real fields.
+ *
+ * @return void
+ */
+ public function testPaginateOrderVirtualFieldSharedWithRealField() {
+ $Controller = new Controller($this->request);
+ $Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
+ $Controller->constructClasses();
+ $Controller->PaginatorControllerComment->virtualFields = array(
+ 'title' => 'PaginatorControllerComment.comment'
+ );
+ $Controller->PaginatorControllerComment->bindModel(array(
+ 'belongsTo' => array(
+ 'PaginatorControllerPost' => array(
+ 'className' => 'PaginatorControllerPost',
+ 'foreignKey' => 'article_id'
+ )
+ )
+ ), false);
+
+ $Controller->paginate = array(
+ 'fields' => array('PaginatorControllerComment.id', 'title', 'PaginatorControllerPost.title'),
+ );
+ $Controller->passedArgs = array('sort' => 'PaginatorControllerPost.title', 'dir' => 'asc');
+ $result = $Controller->paginate('PaginatorControllerComment');
+ $this->assertEquals(array(1, 2, 3, 4, 5, 6), Hash::extract($result, '{n}.PaginatorControllerComment.id'));
+ }
+
+/**
+ * test paginate() and custom find, to make sure the correct count is returned.
+ *
+ * @return void
+ */
+ public function testPaginateCustomFind() {
+ $Controller =& new Controller($this->request);
+ $Controller->uses = array('PaginatorCustomPost');
+ $Controller->constructClasses();
+ $data = array('author_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
+ $Controller->PaginatorCustomPost->create($data);
+ $result = $Controller->PaginatorCustomPost->save();
+ $this->assertTrue(!empty($result));
+
+ $result = $Controller->paginate();
+ $this->assertEquals(array(1, 2, 3, 4), Hash::extract($result, '{n}.PaginatorCustomPost.id'));
+
+ $result = $Controller->params['paging']['PaginatorCustomPost'];
+ $this->assertEquals(4, $result['current']);
+ $this->assertEquals(4, $result['count']);
+
+ $Controller->paginate = array('published');
+ $result = $Controller->paginate();
+ $this->assertEquals(array(1, 2, 3), Hash::extract($result, '{n}.PaginatorCustomPost.id'));
+
+ $result = $Controller->params['paging']['PaginatorCustomPost'];
+ $this->assertEquals(3, $result['current']);
+ $this->assertEquals(3, $result['count']);
+
+ $Controller->paginate = array('published', 'limit' => 2);
+ $result = $Controller->paginate();
+ $this->assertEquals(array(1, 2), Hash::extract($result, '{n}.PaginatorCustomPost.id'));
+
+ $result = $Controller->params['paging']['PaginatorCustomPost'];
+ $this->assertEquals(2, $result['current']);
+ $this->assertEquals(3, $result['count']);
+ $this->assertEquals(2, $result['pageCount']);
+ $this->assertTrue($result['nextPage']);
+ $this->assertFalse($result['prevPage']);
+ }
+/**
+ * test paginate() and custom find with fields array, to make sure the correct count is returned.
+ *
+ * @return void
+ */
+ public function testPaginateCustomFindFieldsArray() {
+ $Controller =& new Controller($this->request);
+ $Controller->uses = array('PaginatorCustomPost');
+ $Controller->constructClasses();
+ $data = array('author_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
+ $Controller->PaginatorCustomPost->create($data);
+ $result = $Controller->PaginatorCustomPost->save();
+ $this->assertTrue(!empty($result));
+
+ $Controller->paginate = array(
+ 'list',
+ 'conditions' => array('PaginatorCustomPost.published' => 'Y'),
+ 'limit' => 2
+ );
+ $result = $Controller->paginate();
+ $expected = array(
+ 1 => 'First Post',
+ 2 => 'Second Post',
+ );
+ $this->assertEquals($expected, $result);
+ $result = $Controller->params['paging']['PaginatorCustomPost'];
+ $this->assertEquals(2, $result['current']);
+ $this->assertEquals(3, $result['count']);
+ $this->assertEquals(2, $result['pageCount']);
+ $this->assertTrue($result['nextPage']);
+ $this->assertFalse($result['prevPage']);
+ }
+
+/**
+ * test paginate() and custom find with fields array, to make sure the correct count is returned.
+ *
+ * @return void
+ */
+ public function testPaginateCustomFindGroupBy() {
+ $Controller =& new Controller($this->request);
+ $Controller->uses = array('PaginatorCustomPost');
+ $Controller->constructClasses();
+ $data = array('author_id' => 2, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
+ $Controller->PaginatorCustomPost->create($data);
+ $result = $Controller->PaginatorCustomPost->save();
+ $this->assertTrue(!empty($result));
+
+ $Controller->paginate = array(
+ 'totals',
+ 'limit' => 2
+ );
+ $result = $Controller->paginate();
+ $expected = array(
+ array(
+ 'PaginatorCustomPost' => array(
+ 'author_id' => '1',
+ 'total_posts' => '2'
+ )
+ ),
+ array(
+ 'PaginatorCustomPost' => array(
+ 'author_id' => '2',
+ 'total_posts' => '1'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ $result = $Controller->params['paging']['PaginatorCustomPost'];
+ $this->assertEquals(2, $result['current']);
+ $this->assertEquals(3, $result['count']);
+ $this->assertEquals(2, $result['pageCount']);
+ $this->assertTrue($result['nextPage']);
+ $this->assertFalse($result['prevPage']);
+
+ $Controller->paginate = array(
+ 'totals',
+ 'limit' => 2,
+ 'page' => 2
+ );
+ $result = $Controller->paginate();
+ $expected = array(
+ array(
+ 'PaginatorCustomPost' => array(
+ 'author_id' => '3',
+ 'total_posts' => '1'
+ )
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ $result = $Controller->params['paging']['PaginatorCustomPost'];
+ $this->assertEquals(1, $result['current']);
+ $this->assertEquals(3, $result['count']);
+ $this->assertEquals(2, $result['pageCount']);
+ $this->assertFalse($result['nextPage']);
+ $this->assertTrue($result['prevPage']);
+ }
+
+/**
+ * test paginate() and custom find with returning other query on count operation,
+ * to make sure the correct count is returned.
+ *
+ * @return void
+ */
+ public function testPaginateCustomFindCount() {
+ $Controller =& new Controller($this->request);
+ $Controller->uses = array('PaginatorCustomPost');
+ $Controller->constructClasses();
+ $data = array('author_id' => 2, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
+ $Controller->PaginatorCustomPost->create($data);
+ $result = $Controller->PaginatorCustomPost->save();
+ $this->assertTrue(!empty($result));
+
+ $Controller->paginate = array(
+ 'totalsOperation',
+ 'limit' => 2
+ );
+ $result = $Controller->paginate();
+ $expected = array(
+ array(
+ 'PaginatorCustomPost' => array(
+ 'author_id' => '1',
+ 'total_posts' => '2'
+ ),
+ 'Author' => array(
+ 'user' => 'mariano',
+ )
+ ),
+ array(
+ 'PaginatorCustomPost' => array(
+ 'author_id' => '2',
+ 'total_posts' => '1'
+ ),
+ 'Author' => array(
+ 'user' => 'nate'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ $result = $Controller->params['paging']['PaginatorCustomPost'];
+ $this->assertEquals(2, $result['current']);
+ $this->assertEquals(3, $result['count']);
+ $this->assertEquals(2, $result['pageCount']);
+ $this->assertTrue($result['nextPage']);
+ $this->assertFalse($result['prevPage']);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php
new file mode 100644
index 0000000..fb6c431
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/RequestHandlerComponentTest.php
@@ -0,0 +1,879 @@
+<?php
+/**
+ * RequestHandlerComponentTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.5435
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Controller', 'Controller');
+App::uses('RequestHandlerComponent', 'Controller/Component');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+App::uses('Router', 'Routing');
+
+/**
+ * RequestHandlerTestController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class RequestHandlerTestController extends Controller {
+
+/**
+ * uses property
+ *
+ * @var mixed null
+ */
+ public $uses = null;
+
+/**
+ * test method for ajax redirection
+ *
+ * @return void
+ */
+ public function destination() {
+ $this->viewPath = 'Posts';
+ $this->render('index');
+ }
+
+/**
+ * test method for ajax redirection + parameter parsing
+ *
+ * @return void
+ */
+ public function param_method($one = null, $two = null) {
+ echo "one: $one two: $two";
+ $this->autoRender = false;
+ }
+
+/**
+ * test method for testing layout rendering when isAjax()
+ *
+ * @return void
+ */
+ public function ajax2_layout() {
+ if ($this->autoLayout) {
+ $this->layout = 'ajax2';
+ }
+ $this->destination();
+ }
+
+}
+
+
+/**
+ * RequestHandlerComponentTest class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class RequestHandlerComponentTest extends CakeTestCase {
+
+/**
+ * Controller property
+ *
+ * @var RequestHandlerTestController
+ */
+ public $Controller;
+
+/**
+ * RequestHandler property
+ *
+ * @var RequestHandlerComponent
+ */
+ public $RequestHandler;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->_init();
+ }
+
+/**
+ * init method
+ *
+ * @return void
+ */
+ protected function _init() {
+ $request = new CakeRequest('controller_posts/index');
+ $response = new CakeResponse();
+ $this->Controller = new RequestHandlerTestController($request, $response);
+ $this->Controller->constructClasses();
+ $this->RequestHandler = new RequestHandlerComponent($this->Controller->Components);
+ $this->_extensions = Router::extensions();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->RequestHandler, $this->Controller);
+ if (!headers_sent()) {
+ header('Content-type: text/html'); //reset content type.
+ }
+ call_user_func_array('Router::parseExtensions', $this->_extensions);
+ }
+
+/**
+ * Test that the constructor sets the settings.
+ *
+ * @return void
+ */
+ public function testConstructorSettings() {
+ $settings = array(
+ 'ajaxLayout' => 'test_ajax'
+ );
+ $Collection = new ComponentCollection();
+ $Collection->init($this->Controller);
+ $RequestHandler = new RequestHandlerComponent($Collection, $settings);
+ $this->assertEquals('test_ajax', $RequestHandler->ajaxLayout);
+ }
+
+/**
+ * testInitializeCallback method
+ *
+ * @return void
+ */
+ public function testInitializeCallback() {
+ $this->assertNull($this->RequestHandler->ext);
+ $this->Controller->request->params['ext'] = 'rss';
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertEquals('rss', $this->RequestHandler->ext);
+ }
+
+/**
+ * test that a mapped Accept-type header will set $this->ext correctly.
+ *
+ * @return void
+ */
+ public function testInitializeContentTypeSettingExt() {
+ $this->assertNull($this->RequestHandler->ext);
+
+ $_SERVER['HTTP_ACCEPT'] = 'application/json';
+ Router::parseExtensions('json');
+
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertEquals('json', $this->RequestHandler->ext);
+ }
+
+/**
+ * Test that RequestHandler sets $this->ext when jQuery sends its wonky-ish headers.
+ *
+ * @return void
+ */
+ public function testInitializeContentTypeWithjQueryAccept() {
+ $_SERVER['HTTP_ACCEPT'] = 'application/json, text/javascript, */*; q=0.01';
+ $this->assertNull($this->RequestHandler->ext);
+ Router::parseExtensions('json');
+
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertEquals('json', $this->RequestHandler->ext);
+ }
+
+/**
+ * Test that RequestHandler sets $this->ext when jQuery sends its wonky-ish headers
+ * and the application is configured to handle multiple extensions
+ *
+ * @return void
+ */
+ public function testInitializeContentTypeWithjQueryAcceptAndMultiplesExtensions() {
+ $_SERVER['HTTP_ACCEPT'] = 'application/json, text/javascript, */*; q=0.01';
+ $this->assertNull($this->RequestHandler->ext);
+ Router::parseExtensions('rss', 'json');
+
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertEquals('json', $this->RequestHandler->ext);
+ }
+
+/**
+ * Test that RequestHandler does not set $this->ext when multiple accepts are sent.
+ *
+ * @return void
+ */
+ public function testInitializeNoContentTypeWithSingleAccept() {
+ $_SERVER['HTTP_ACCEPT'] = 'application/json, text/html, */*; q=0.01';
+ $this->assertNull($this->RequestHandler->ext);
+ Router::parseExtensions('json');
+
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertNull($this->RequestHandler->ext);
+ }
+
+/**
+ * Test that ext is not set with multiple accepted content types.
+ *
+ * @return void
+ */
+ public function testInitializeNoContentTypeWithMultipleAcceptedTypes() {
+ $_SERVER['HTTP_ACCEPT'] = 'application/json, text/javascript, application/xml, */*; q=0.01';
+ $this->assertNull($this->RequestHandler->ext);
+ Router::parseExtensions('xml', 'json');
+
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertNull($this->RequestHandler->ext);
+ }
+
+/**
+ * Test that ext is not set with confusing android accepts headers.
+ *
+ * @return void
+ */
+ public function testInitializeAmbiguousAndroidAccepts() {
+ $_SERVER['HTTP_ACCEPT'] = 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
+ $this->assertNull($this->RequestHandler->ext);
+ Router::parseExtensions('html', 'xml');
+
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertNull($this->RequestHandler->ext);
+ }
+
+/**
+ * Test that a type mismatch doesn't incorrectly set the ext
+ *
+ * @return void
+ */
+ public function testInitializeContentTypeAndExtensionMismatch() {
+ $this->assertNull($this->RequestHandler->ext);
+ $extensions = Router::extensions();
+ Router::parseExtensions('xml');
+
+ $this->Controller->request = $this->getMock('CakeRequest');
+ $this->Controller->request->expects($this->any())
+ ->method('accepts')
+ ->will($this->returnValue(array('application/json')));
+
+ $this->RequestHandler->initialize($this->Controller);
+ $this->assertNull($this->RequestHandler->ext);
+
+ call_user_func_array(array('Router', 'parseExtensions'), $extensions);
+ }
+
+/**
+ * testDisabling method
+ *
+ * @return void
+ */
+ public function testDisabling() {
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
+ $this->_init();
+ $this->RequestHandler->initialize($this->Controller);
+ $this->Controller->beforeFilter();
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertEquals(true, $this->Controller->params['isAjax']);
+ }
+
+/**
+ * testAutoResponseType method
+ *
+ * @return void
+ */
+ public function testAutoResponseType() {
+ $this->Controller->ext = '.thtml';
+ $this->Controller->request->params['ext'] = 'rss';
+ $this->RequestHandler->initialize($this->Controller);
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertEquals('.ctp', $this->Controller->ext);
+ }
+
+/**
+ * testAutoAjaxLayout method
+ *
+ * @return void
+ */
+ public function testAutoAjaxLayout() {
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertEquals($this->Controller->layout, $this->RequestHandler->ajaxLayout);
+
+ $this->_init();
+ $this->Controller->request->params['ext'] = 'js';
+ $this->RequestHandler->initialize($this->Controller);
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertNotEquals('ajax', $this->Controller->layout);
+
+ unset($_SERVER['HTTP_X_REQUESTED_WITH']);
+ }
+
+/**
+ * testStartupCallback method
+ *
+ * @return void
+ */
+ public function testStartupCallback() {
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $_SERVER['CONTENT_TYPE'] = 'application/xml';
+ $this->Controller->request = $this->getMock('CakeRequest', array('_readInput'));
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertTrue(is_array($this->Controller->data));
+ $this->assertFalse(is_object($this->Controller->data));
+ }
+
+/**
+ * testStartupCallback with charset.
+ *
+ * @return void
+ */
+ public function testStartupCallbackCharset() {
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $_SERVER['CONTENT_TYPE'] = 'application/xml; charset=UTF-8';
+ $this->Controller->request = $this->getMock('CakeRequest', array('_readInput'));
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertTrue(is_array($this->Controller->data));
+ $this->assertFalse(is_object($this->Controller->data));
+ }
+
+/**
+ * Test mapping a new type and having startup process it.
+ *
+ * @return void
+ */
+ public function testStartupCustomTypeProcess() {
+ if (!function_exists('str_getcsv')) {
+ $this->markTestSkipped('Need "str_getcsv" for this test.');
+ }
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $_SERVER['CONTENT_TYPE'] = 'text/csv';
+ $this->Controller->request = $this->getMock('CakeRequest', array('_readInput'));
+ $this->Controller->request->expects($this->once())
+ ->method('_readInput')
+ ->will($this->returnValue('"A","csv","string"'));
+ $this->RequestHandler->addInputType('csv', array('str_getcsv'));
+ $this->RequestHandler->startup($this->Controller);
+ $expected = array(
+ 'A', 'csv', 'string'
+ );
+ $this->assertEquals($expected, $this->Controller->request->data);
+ }
+
+/**
+ * testNonAjaxRedirect method
+ *
+ * @return void
+ */
+ public function testNonAjaxRedirect() {
+ $this->RequestHandler->initialize($this->Controller);
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertNull($this->RequestHandler->beforeRedirect($this->Controller, '/'));
+ }
+
+/**
+ * testRenderAs method
+ *
+ * @return void
+ */
+ public function testRenderAs() {
+ $this->assertFalse(in_array('Rss', $this->Controller->helpers));
+ $this->RequestHandler->renderAs($this->Controller, 'rss');
+ $this->assertTrue(in_array('Rss', $this->Controller->helpers));
+
+ $this->Controller->viewPath = 'request_handler_test\\rss';
+ $this->RequestHandler->renderAs($this->Controller, 'js');
+ $this->assertEquals('request_handler_test' . DS . 'js', $this->Controller->viewPath);
+ }
+
+/**
+ * test that attachment headers work with renderAs
+ *
+ * @return void
+ */
+ public function testRenderAsWithAttachment() {
+ $this->RequestHandler->request = $this->getMock('CakeRequest');
+ $this->RequestHandler->request->expects($this->any())
+ ->method('parseAccept')
+ ->will($this->returnValue(array('1.0' => array('application/xml'))));
+
+ $this->RequestHandler->response = $this->getMock('CakeResponse', array('type', 'download', 'charset'));
+ $this->RequestHandler->response->expects($this->at(0))
+ ->method('type')
+ ->with('application/xml');
+ $this->RequestHandler->response->expects($this->at(1))
+ ->method('charset')
+ ->with('UTF-8');
+ $this->RequestHandler->response->expects($this->at(2))
+ ->method('download')
+ ->with('myfile.xml');
+
+ $this->RequestHandler->renderAs($this->Controller, 'xml', array('attachment' => 'myfile.xml'));
+
+ $this->assertEquals('Xml', $this->Controller->viewClass);
+ }
+
+/**
+ * test that respondAs works as expected.
+ *
+ * @return void
+ */
+ public function testRespondAs() {
+ $this->RequestHandler->response = $this->getMock('CakeResponse', array('type'));
+ $this->RequestHandler->response->expects($this->at(0))->method('type')
+ ->with('application/json');
+ $this->RequestHandler->response->expects($this->at(1))->method('type')
+ ->with('text/xml');
+
+ $result = $this->RequestHandler->respondAs('json');
+ $this->assertTrue($result);
+ $result = $this->RequestHandler->respondAs('text/xml');
+ $this->assertTrue($result);
+ }
+
+/**
+ * test that attachment headers work with respondAs
+ *
+ * @return void
+ */
+ public function testRespondAsWithAttachment() {
+ $this->RequestHandler = $this->getMock(
+ 'RequestHandlerComponent',
+ array('_header'),
+ array(&$this->Controller->Components)
+ );
+ $this->RequestHandler->response = $this->getMock('CakeResponse', array('type', 'download'));
+ $this->RequestHandler->request = $this->getMock('CakeRequest');
+
+ $this->RequestHandler->request->expects($this->once())
+ ->method('parseAccept')
+ ->will($this->returnValue(array('1.0' => array('application/xml'))));
+
+ $this->RequestHandler->response->expects($this->once())->method('download')
+ ->with('myfile.xml');
+ $this->RequestHandler->response->expects($this->once())->method('type')
+ ->with('application/xml');
+
+ $result = $this->RequestHandler->respondAs('xml', array('attachment' => 'myfile.xml'));
+ $this->assertTrue($result);
+ }
+
+/**
+ * test that calling renderAs() more than once continues to work.
+ *
+ * @link #6466
+ * @return void
+ */
+ public function testRenderAsCalledTwice() {
+ $this->RequestHandler->renderAs($this->Controller, 'print');
+ $this->assertEquals('RequestHandlerTest' . DS . 'print', $this->Controller->viewPath);
+ $this->assertEquals('print', $this->Controller->layoutPath);
+
+ $this->RequestHandler->renderAs($this->Controller, 'js');
+ $this->assertEquals('RequestHandlerTest' . DS . 'js', $this->Controller->viewPath);
+ $this->assertEquals('js', $this->Controller->layoutPath);
+ $this->assertTrue(in_array('Js', $this->Controller->helpers));
+ }
+
+/**
+ * testRequestClientTypes method
+ *
+ * @return void
+ */
+ public function testRequestClientTypes() {
+ $_SERVER['HTTP_X_PROTOTYPE_VERSION'] = '1.5';
+ $this->assertEquals('1.5', $this->RequestHandler->getAjaxVersion());
+
+ unset($_SERVER['HTTP_X_REQUESTED_WITH'], $_SERVER['HTTP_X_PROTOTYPE_VERSION']);
+ $this->assertFalse($this->RequestHandler->getAjaxVersion());
+ }
+
+/**
+ * Tests the detection of various Flash versions
+ *
+ * @return void
+ */
+ public function testFlashDetection() {
+ $request = $this->getMock('CakeRequest');
+ $request->expects($this->once())->method('is')
+ ->with('flash')
+ ->will($this->returnValue(true));
+
+ $this->RequestHandler->request = $request;
+ $this->assertTrue($this->RequestHandler->isFlash());
+ }
+
+/**
+ * testRequestContentTypes method
+ *
+ * @return void
+ */
+ public function testRequestContentTypes() {
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $this->assertNull($this->RequestHandler->requestedWith());
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $_SERVER['CONTENT_TYPE'] = 'application/json';
+ $this->assertEquals('json', $this->RequestHandler->requestedWith());
+
+ $result = $this->RequestHandler->requestedWith(array('json', 'xml'));
+ $this->assertEquals('json', $result);
+
+ $result = $this->RequestHandler->requestedWith(array('rss', 'atom'));
+ $this->assertFalse($result);
+
+ $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
+ $this->assertTrue($this->RequestHandler->isXml());
+ $this->assertFalse($this->RequestHandler->isAtom());
+ $this->assertFalse($this->RequestHandler->isRSS());
+
+ $_SERVER['HTTP_ACCEPT'] = 'application/atom+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
+ $this->assertTrue($this->RequestHandler->isAtom());
+ $this->assertFalse($this->RequestHandler->isRSS());
+
+ $_SERVER['HTTP_ACCEPT'] = 'application/rss+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
+ $this->assertFalse($this->RequestHandler->isAtom());
+ $this->assertTrue($this->RequestHandler->isRSS());
+
+ $this->assertFalse($this->RequestHandler->isWap());
+ $_SERVER['HTTP_ACCEPT'] = 'text/vnd.wap.wml,text/html,text/plain,image/png,*/*';
+ $this->assertTrue($this->RequestHandler->isWap());
+
+ $_SERVER['HTTP_ACCEPT'] = 'application/rss+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
+ }
+
+/**
+ * testResponseContentType method
+ *
+ * @return void
+ */
+ public function testResponseContentType() {
+ $this->assertEquals('html', $this->RequestHandler->responseType());
+ $this->assertTrue($this->RequestHandler->respondAs('atom'));
+ $this->assertEquals('atom', $this->RequestHandler->responseType());
+ }
+
+/**
+ * testMobileDeviceDetection method
+ *
+ * @return void
+ */
+ public function testMobileDeviceDetection() {
+ $request = $this->getMock('CakeRequest');
+ $request->expects($this->once())->method('is')
+ ->with('mobile')
+ ->will($this->returnValue(true));
+
+ $this->RequestHandler->request = $request;
+ $this->assertTrue($this->RequestHandler->isMobile());
+ }
+
+/**
+ * testRequestProperties method
+ *
+ * @return void
+ */
+ public function testRequestProperties() {
+ $request = $this->getMock('CakeRequest');
+ $request->expects($this->once())->method('is')
+ ->with('ssl')
+ ->will($this->returnValue(true));
+
+ $this->RequestHandler->request = $request;
+ $this->assertTrue($this->RequestHandler->isSsl());
+ }
+
+/**
+ * testRequestMethod method
+ *
+ * @return void
+ */
+ public function testRequestMethod() {
+ $request = $this->getMock('CakeRequest');
+ $request->expects($this->at(0))->method('is')
+ ->with('get')
+ ->will($this->returnValue(true));
+
+ $request->expects($this->at(1))->method('is')
+ ->with('post')
+ ->will($this->returnValue(false));
+
+ $request->expects($this->at(2))->method('is')
+ ->with('delete')
+ ->will($this->returnValue(true));
+
+ $request->expects($this->at(3))->method('is')
+ ->with('put')
+ ->will($this->returnValue(false));
+
+ $this->RequestHandler->request = $request;
+ $this->assertTrue($this->RequestHandler->isGet());
+ $this->assertFalse($this->RequestHandler->isPost());
+ $this->assertTrue($this->RequestHandler->isDelete());
+ $this->assertFalse($this->RequestHandler->isPut());
+ }
+
+/**
+ * test that map alias converts aliases to content types.
+ *
+ * @return void
+ */
+ public function testMapAlias() {
+ $result = $this->RequestHandler->mapAlias('xml');
+ $this->assertEquals('application/xml', $result);
+
+ $result = $this->RequestHandler->mapAlias('text/html');
+ $this->assertNull($result);
+
+ $result = $this->RequestHandler->mapAlias('wap');
+ $this->assertEquals('text/vnd.wap.wml', $result);
+
+ $result = $this->RequestHandler->mapAlias(array('xml', 'js', 'json'));
+ $expected = array('application/xml', 'text/javascript', 'application/json');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test accepts() on the component
+ *
+ * @return void
+ */
+ public function testAccepts() {
+ $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
+ $this->assertTrue($this->RequestHandler->accepts(array('js', 'xml', 'html')));
+ $this->assertFalse($this->RequestHandler->accepts(array('gif', 'jpeg', 'foo')));
+
+ $_SERVER['HTTP_ACCEPT'] = '*/*;q=0.5';
+ $this->assertFalse($this->RequestHandler->accepts('rss'));
+ }
+
+/**
+ * test accepts and prefers methods.
+ *
+ * @return void
+ */
+ public function testPrefers() {
+ $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*';
+ $this->assertNotEquals('rss', $this->RequestHandler->prefers());
+ $this->RequestHandler->ext = 'rss';
+ $this->assertEquals('rss', $this->RequestHandler->prefers());
+ $this->assertFalse($this->RequestHandler->prefers('xml'));
+ $this->assertEquals('xml', $this->RequestHandler->prefers(array('js', 'xml', 'xhtml')));
+ $this->assertFalse($this->RequestHandler->prefers(array('red', 'blue')));
+ $this->assertEquals('xhtml', $this->RequestHandler->prefers(array('js', 'json', 'xhtml')));
+ $this->assertTrue($this->RequestHandler->prefers(array('rss')), 'Should return true if input matches ext.');
+ $this->assertFalse($this->RequestHandler->prefers(array('html')), 'No match with ext, return false.');
+
+ $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5';
+ $this->_init();
+ $this->assertEquals('xml', $this->RequestHandler->prefers());
+
+ $_SERVER['HTTP_ACCEPT'] = '*/*;q=0.5';
+ $this->assertEquals('html', $this->RequestHandler->prefers());
+ $this->assertFalse($this->RequestHandler->prefers('rss'));
+ }
+
+/**
+ * testCustomContent method
+ *
+ * @return void
+ */
+ public function testCustomContent() {
+ $_SERVER['HTTP_ACCEPT'] = 'text/x-mobile,text/html;q=0.9,text/plain;q=0.8,*/*;q=0.5';
+ $this->RequestHandler->setContent('mobile', 'text/x-mobile');
+ $this->RequestHandler->startup($this->Controller);
+ $this->assertEquals('mobile', $this->RequestHandler->prefers());
+ }
+
+/**
+ * testClientProperties method
+ *
+ * @return void
+ */
+ public function testClientProperties() {
+ $request = $this->getMock('CakeRequest');
+ $request->expects($this->once())->method('referer');
+ $request->expects($this->once())->method('clientIp')->will($this->returnValue(false));
+
+ $this->RequestHandler->request = $request;
+
+ $this->RequestHandler->getReferer();
+ $this->RequestHandler->getClientIP(false);
+ }
+
+/**
+ * test that ajax requests involving redirects trigger requestAction instead.
+ *
+ * @return void
+ */
+ public function testAjaxRedirectAsRequestAction() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), App::RESET);
+
+ $this->Controller->RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $this->Controller->request = $this->getMock('CakeRequest');
+ $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $this->Controller->RequestHandler->request = $this->Controller->request;
+ $this->Controller->RequestHandler->response = $this->Controller->response;
+ $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
+ $this->Controller->RequestHandler->expects($this->once())->method('_stop');
+
+ ob_start();
+ $this->Controller->RequestHandler->beforeRedirect(
+ $this->Controller, array('controller' => 'request_handler_test', 'action' => 'destination')
+ );
+ $result = ob_get_clean();
+ $this->assertRegExp('/posts index/', $result, 'RequestAction redirect failed.');
+
+ App::build();
+ }
+
+/**
+ * test that ajax requests involving redirects don't force no layout
+ * this would cause the ajax layout to not be rendered.
+ *
+ * @return void
+ */
+ public function testAjaxRedirectAsRequestActionStillRenderingLayout() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), App::RESET);
+
+ $this->Controller->RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $this->Controller->request = $this->getMock('CakeRequest');
+ $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $this->Controller->RequestHandler->request = $this->Controller->request;
+ $this->Controller->RequestHandler->response = $this->Controller->response;
+ $this->Controller->request->expects($this->any())->method('is')->will($this->returnValue(true));
+ $this->Controller->RequestHandler->expects($this->once())->method('_stop');
+
+ ob_start();
+ $this->Controller->RequestHandler->beforeRedirect(
+ $this->Controller, array('controller' => 'request_handler_test', 'action' => 'ajax2_layout')
+ );
+ $result = ob_get_clean();
+ $this->assertRegExp('/posts index/', $result, 'RequestAction redirect failed.');
+ $this->assertRegExp('/Ajax!/', $result, 'Layout was not rendered.');
+
+ App::build();
+ }
+
+/**
+ * test that the beforeRedirect callback properly converts
+ * array urls into their correct string ones, and adds base => false so
+ * the correct urls are generated.
+ *
+ * @link http://cakephp.lighthouseapp.com/projects/42648-cakephp-1x/tickets/276
+ * @return void
+ */
+ public function testBeforeRedirectCallbackWithArrayUrl() {
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
+
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'named' => array(), 'form' => array(), 'url' => array('url' => 'accounts/')),
+ array('base' => '/officespace', 'here' => '/officespace/accounts/', 'webroot' => '/officespace/')
+ ));
+
+ $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $RequestHandler->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $RequestHandler->request = new CakeRequest('posts/index');
+ $RequestHandler->response = $this->getMock('CakeResponse', array('_sendHeader'));
+
+ ob_start();
+ $RequestHandler->beforeRedirect(
+ $this->Controller,
+ array('controller' => 'request_handler_test', 'action' => 'param_method', 'first', 'second')
+ );
+ $result = ob_get_clean();
+ $this->assertEquals('one: first two: second', $result);
+ }
+
+/**
+ * assure that beforeRedirect with a status code will correctly set the status header
+ *
+ * @return void
+ */
+ public function testBeforeRedirectCallingHeader() {
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
+
+ $controller = $this->getMock('Controller', array('header'));
+ $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $RequestHandler->response = $this->getMock('CakeResponse', array('_sendHeader','statusCode'));
+ $RequestHandler->request = $this->getMock('CakeRequest');
+ $RequestHandler->request->expects($this->once())->method('is')
+ ->with('ajax')
+ ->will($this->returnValue(true));
+
+ $RequestHandler->response->expects($this->once())->method('statusCode')->with(403);
+
+ ob_start();
+ $RequestHandler->beforeRedirect($controller, 'request_handler_test/param_method/first/second', 403);
+ $result = ob_get_clean();
+ }
+
+/**
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testAddInputTypeException() {
+ $this->RequestHandler->addInputType('csv', array('I am not callable'));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagStar() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = '*';
+ $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
+ $RequestHandler->response->etag('something');
+ $RequestHandler->response->expects($this->once())->method('notModified');
+ $this->assertFalse($RequestHandler->beforeRender($this->Controller));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagExact() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
+ $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
+ $RequestHandler->response->etag('something', true);
+ $RequestHandler->response->expects($this->once())->method('notModified');
+ $this->assertFalse($RequestHandler->beforeRender($this->Controller));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagAndTime() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
+ $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
+ $RequestHandler->response->etag('something', true);
+ $RequestHandler->response->modified('2012-01-01 00:00:00');
+ $RequestHandler->response->expects($this->once())->method('notModified');
+ $this->assertFalse($RequestHandler->beforeRender($this->Controller));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedNoInfo() {
+ $RequestHandler = $this->getMock('RequestHandlerComponent', array('_stop'), array(&$this->Controller->Components));
+ $RequestHandler->response = $this->getMock('CakeResponse', array('notModified'));
+ $RequestHandler->response->expects($this->never())->method('notModified');
+ $this->assertNull($RequestHandler->beforeRender($this->Controller));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php
new file mode 100644
index 0000000..84f7803
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php
@@ -0,0 +1,1375 @@
+<?php
+/**
+ * SecurityComponentTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.5435
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('SecurityComponent', 'Controller/Component');
+App::uses('Controller', 'Controller');
+
+/**
+ * TestSecurityComponent
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class TestSecurityComponent extends SecurityComponent {
+
+/**
+ * validatePost method
+ *
+ * @param Controller $controller
+ * @return boolean
+ */
+ public function validatePost(Controller $controller) {
+ return $this->_validatePost($controller);
+ }
+
+}
+
+/**
+ * SecurityTestController
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class SecurityTestController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'SecurityTest'
+ */
+ public $name = 'SecurityTest';
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Session', 'TestSecurity');
+
+/**
+ * failed property
+ *
+ * @var boolean false
+ */
+ public $failed = false;
+
+/**
+ * Used for keeping track of headers in test
+ *
+ * @var array
+ */
+ public $testHeaders = array();
+
+/**
+ * fail method
+ *
+ * @return void
+ */
+ public function fail() {
+ $this->failed = true;
+ }
+
+/**
+ * redirect method
+ *
+ * @param string|array $url
+ * @param mixed $code
+ * @param mixed $exit
+ * @return void
+ */
+ public function redirect($url, $status = null, $exit = true) {
+ return $status;
+ }
+
+/**
+ * Convenience method for header()
+ *
+ * @param string $status
+ * @return void
+ */
+ public function header($status) {
+ $this->testHeaders[] = $status;
+ }
+
+}
+
+class BrokenCallbackController extends Controller {
+
+ public $name = 'UncallableCallback';
+
+ public $components = array('Session', 'TestSecurity');
+
+ public function index() {
+ }
+
+ protected function _fail() {
+ }
+
+}
+
+/**
+ * SecurityComponentTest class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class SecurityComponentTest extends CakeTestCase {
+
+/**
+ * Controller property
+ *
+ * @var SecurityTestController
+ */
+ public $Controller;
+
+/**
+ * oldSalt property
+ *
+ * @var string
+ */
+ public $oldSalt;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array('controller' => 'posts', 'action' => 'index'));
+ $this->Controller = new SecurityTestController($request);
+ $this->Controller->Components->init($this->Controller);
+ $this->Controller->Security = $this->Controller->TestSecurity;
+ $this->Controller->Security->blackHoleCallback = 'fail';
+ $this->Security = $this->Controller->Security;
+ $this->Security->csrfCheck = false;
+
+ Configure::write('Security.salt', 'foo!');
+ }
+
+/**
+ * Tear-down method. Resets environment state.
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ $this->Controller->Session->delete('_Token');
+ unset($this->Controller->Security);
+ unset($this->Controller->Component);
+ unset($this->Controller);
+ }
+
+/**
+ * Test that requests are still blackholed when controller has incorrect
+ * visibility keyword in the blackhole callback
+ *
+ * @expectedException BadRequestException
+ */
+ public function testBlackholeWithBrokenCallback() {
+ $request = new CakeRequest('posts/index', false);
+ $request->addParams(array(
+ 'controller' => 'posts', 'action' => 'index')
+ );
+ $this->Controller = new BrokenCallbackController($request);
+ $this->Controller->Components->init($this->Controller);
+ $this->Controller->Security = $this->Controller->TestSecurity;
+ $this->Controller->Security->blackHoleCallback = '_fail';
+ $this->Controller->Security->startup($this->Controller);
+ $this->Controller->Security->blackHole($this->Controller, 'csrf');
+ }
+
+/**
+ * test that initialize can set properties.
+ *
+ * @return void
+ */
+ public function testConstructorSettingProperties() {
+ $settings = array(
+ 'requirePost' => array('edit', 'update'),
+ 'requireSecure' => array('update_account'),
+ 'requireGet' => array('index'),
+ 'validatePost' => false,
+ );
+ $Security = new SecurityComponent($this->Controller->Components, $settings);
+ $this->Controller->Security->initialize($this->Controller, $settings);
+ $this->assertEquals($Security->requirePost, $settings['requirePost']);
+ $this->assertEquals($Security->requireSecure, $settings['requireSecure']);
+ $this->assertEquals($Security->requireGet, $settings['requireGet']);
+ $this->assertEquals($Security->validatePost, $settings['validatePost']);
+ }
+
+/**
+ * testStartup method
+ *
+ * @return void
+ */
+ public function testStartup() {
+ $this->Controller->Security->startup($this->Controller);
+ $result = $this->Controller->params['_Token']['key'];
+ $this->assertNotNull($result);
+ $this->assertTrue($this->Controller->Session->check('_Token'));
+ }
+
+/**
+ * testRequirePostFail method
+ *
+ * @return void
+ */
+ public function testRequirePostFail() {
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requirePost(array('posted'));
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+ }
+
+/**
+ * testRequirePostSucceed method
+ *
+ * @return void
+ */
+ public function testRequirePostSucceed() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requirePost('posted');
+ $this->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequireSecureFail method
+ *
+ * @return void
+ */
+ public function testRequireSecureFail() {
+ $_SERVER['HTTPS'] = 'off';
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requireSecure(array('posted'));
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+ }
+
+/**
+ * testRequireSecureSucceed method
+ *
+ * @return void
+ */
+ public function testRequireSecureSucceed() {
+ $_SERVER['REQUEST_METHOD'] = 'Secure';
+ $this->Controller->request['action'] = 'posted';
+ $_SERVER['HTTPS'] = 'on';
+ $this->Controller->Security->requireSecure('posted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequireAuthFail method
+ *
+ * @return void
+ */
+ public function testRequireAuthFail() {
+ $_SERVER['REQUEST_METHOD'] = 'AUTH';
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->request->data = array('username' => 'willy', 'password' => 'somePass');
+ $this->Controller->Security->requireAuth(array('posted'));
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+
+ $this->Controller->Session->write('_Token', array('allowedControllers' => array()));
+ $this->Controller->request->data = array('username' => 'willy', 'password' => 'somePass');
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requireAuth('posted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+
+ $this->Controller->Session->write('_Token', array(
+ 'allowedControllers' => array('SecurityTest'), 'allowedActions' => array('posted2')
+ ));
+ $this->Controller->request->data = array('username' => 'willy', 'password' => 'somePass');
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requireAuth('posted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+ }
+
+/**
+ * testRequireAuthSucceed method
+ *
+ * @return void
+ */
+ public function testRequireAuthSucceed() {
+ $_SERVER['REQUEST_METHOD'] = 'AUTH';
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requireAuth('posted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+
+ $this->Controller->Security->Session->write('_Token', array(
+ 'allowedControllers' => array('SecurityTest'), 'allowedActions' => array('posted')
+ ));
+ $this->Controller->request['controller'] = 'SecurityTest';
+ $this->Controller->request['action'] = 'posted';
+
+ $this->Controller->request->data = array(
+ 'username' => 'willy', 'password' => 'somePass', '_Token' => ''
+ );
+ $this->Controller->action = 'posted';
+ $this->Controller->Security->requireAuth('posted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequirePostSucceedWrongMethod method
+ *
+ * @return void
+ */
+ public function testRequirePostSucceedWrongMethod() {
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $this->Controller->request['action'] = 'getted';
+ $this->Controller->Security->requirePost('posted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequireGetFail method
+ *
+ * @return void
+ */
+ public function testRequireGetFail() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'getted';
+ $this->Controller->Security->requireGet(array('getted'));
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+ }
+
+/**
+ * testRequireGetSucceed method
+ *
+ * @return void
+ */
+ public function testRequireGetSucceed() {
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $this->Controller->request['action'] = 'getted';
+ $this->Controller->Security->requireGet('getted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequireGetSucceedWrongMethod method
+ *
+ * @return void
+ */
+ public function testRequireGetSucceedWrongMethod() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'posted';
+ $this->Security->requireGet('getted');
+ $this->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequirePutFail method
+ *
+ * @return void
+ */
+ public function testRequirePutFail() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'putted';
+ $this->Controller->Security->requirePut(array('putted'));
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+ }
+
+/**
+ * testRequirePutSucceed method
+ *
+ * @return void
+ */
+ public function testRequirePutSucceed() {
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $this->Controller->request['action'] = 'putted';
+ $this->Controller->Security->requirePut('putted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequirePutSucceedWrongMethod method
+ *
+ * @return void
+ */
+ public function testRequirePutSucceedWrongMethod() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requirePut('putted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequireDeleteFail method
+ *
+ * @return void
+ */
+ public function testRequireDeleteFail() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'deleted';
+ $this->Controller->Security->requireDelete(array('deleted', 'other_method'));
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed);
+ }
+
+/**
+ * testRequireDeleteSucceed method
+ *
+ * @return void
+ */
+ public function testRequireDeleteSucceed() {
+ $_SERVER['REQUEST_METHOD'] = 'DELETE';
+ $this->Controller->request['action'] = 'deleted';
+ $this->Controller->Security->requireDelete('deleted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * testRequireDeleteSucceedWrongMethod method
+ *
+ * @return void
+ */
+ public function testRequireDeleteSucceedWrongMethod() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->Controller->request['action'] = 'posted';
+ $this->Controller->Security->requireDelete('deleted');
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertFalse($this->Controller->failed);
+ }
+
+/**
+ * Simple hash validation test
+ *
+ * @return void
+ */
+ public function testValidatePost() {
+ $this->Controller->Security->startup($this->Controller);
+
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3AModel.valid';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $this->assertTrue($this->Controller->Security->validatePost($this->Controller));
+ }
+
+/**
+ * Test that validatePost fails if you are missing the session information.
+ *
+ * @return void
+ */
+ public function testValidatePostNoSession() {
+ $this->Controller->Security->startup($this->Controller);
+ $this->Controller->Session->delete('_Token');
+
+ $key = $this->Controller->params['_Token']['key'];
+ $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3AModel.valid';
+
+ $this->Controller->data = array(
+ 'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
+ '_Token' => compact('key', 'fields')
+ );
+ $this->assertFalse($this->Controller->Security->validatePost($this->Controller));
+ }
+
+/**
+ * test that validatePost fails if any of its required fields are missing.
+ *
+ * @return void
+ */
+ public function testValidatePostFormHacking() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->params['_Token']['key'];
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
+ '_Token' => compact('key', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertFalse($result, 'validatePost passed when fields were missing. %s');
+ }
+
+/**
+ * Test that objects can't be passed into the serialized string. This was a vector for RFI and LFI
+ * attacks. Thanks to Felix Wilhelm
+ *
+ * @return void
+ */
+ public function testValidatePostObjectDeserialize() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877';
+ $unlocked = '';
+
+ // a corrupted serialized object, so we can see if it ever gets to deserialize
+ $attack = 'O:3:"App":1:{s:5:"__map";a:1:{s:3:"foo";s:7:"Hacked!";s:1:"fail"}}';
+ $fields .= urlencode(':' . str_rot13($attack));
+
+ $this->Controller->request->data = array(
+ 'Model' => array('username' => 'mark', 'password' => 'foo', 'valid' => '0'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertFalse($result, 'validatePost passed when key was missing. %s');
+ }
+
+/**
+ * Tests validation of checkbox arrays
+ *
+ * @return void
+ */
+ public function testValidatePostArray() {
+ $this->Controller->Security->startup($this->Controller);
+
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = 'f7d573650a295b94e0938d32b323fde775e5f32b%3A';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array('multi_field' => array('1', '3')),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $this->assertTrue($this->Controller->Security->validatePost($this->Controller));
+ }
+
+/**
+ * testValidatePostNoModel method
+ *
+ * @return void
+ */
+ public function testValidatePostNoModel() {
+ $this->Controller->Security->startup($this->Controller);
+
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '540ac9c60d323c22bafe997b72c0790f39a8bdef%3A';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'anything' => 'some_data',
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testValidatePostSimple method
+ *
+ * @return void
+ */
+ public function testValidatePostSimple() {
+ $this->Controller->Security->startup($this->Controller);
+
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '69f493434187b867ea14b901fdf58b55d27c935d%3A';
+ $unlocked = '';
+
+ $this->Controller->request->data = $data = array(
+ 'Model' => array('username' => '', 'password' => ''),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * Tests hash validation for multiple records, including locked fields
+ *
+ * @return void
+ */
+ public function testValidatePostComplex() {
+ $this->Controller->Security->startup($this->Controller);
+
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = 'c9118120e680a7201b543f562e5301006ccfcbe2%3AAddresses.0.id%7CAddresses.1.id';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Addresses' => array(
+ '0' => array(
+ 'id' => '123456', 'title' => '', 'first_name' => '', 'last_name' => '',
+ 'address' => '', 'city' => '', 'phone' => '', 'primary' => ''
+ ),
+ '1' => array(
+ 'id' => '654321', 'title' => '', 'first_name' => '', 'last_name' => '',
+ 'address' => '', 'city' => '', 'phone' => '', 'primary' => ''
+ )
+ ),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * test ValidatePost with multiple select elements.
+ *
+ * @return void
+ */
+ public function testValidatePostMultipleSelect() {
+ $this->Controller->Security->startup($this->Controller);
+
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '422cde416475abc171568be690a98cad20e66079%3A';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Tag' => array('Tag' => array(1, 2)),
+ '_Token' => compact('key', 'fields', 'unlocked'),
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+
+ $this->Controller->request->data = array(
+ 'Tag' => array('Tag' => array(1, 2, 3)),
+ '_Token' => compact('key', 'fields', 'unlocked'),
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+
+ $this->Controller->request->data = array(
+ 'Tag' => array('Tag' => array(1, 2, 3, 4)),
+ '_Token' => compact('key', 'fields', 'unlocked'),
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+
+ $fields = '19464422eafe977ee729c59222af07f983010c5f%3A';
+ $this->Controller->request->data = array(
+ 'User.password' => 'bar', 'User.name' => 'foo', 'User.is_valid' => '1',
+ 'Tag' => array('Tag' => array(1)),
+ '_Token' => compact('key', 'fields', 'unlocked'),
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testValidatePostCheckbox method
+ *
+ * First block tests un-checked checkbox
+ * Second block tests checked checkbox
+ *
+ * @return void
+ */
+ public function testValidatePostCheckbox() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3AModel.valid';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+
+ $fields = '874439ca69f89b4c4a5f50fb9c36ff56a28f5d42%3A';
+
+ $this->Controller->request->data = array(
+ 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+
+ $this->Controller->request->data = array();
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+
+ $this->Controller->request->data = $data = array(
+ 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testValidatePostHidden method
+ *
+ * @return void
+ */
+ public function testValidatePostHidden() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '51ccd8cb0997c7b3d4523ecde5a109318405ef8c%3AModel.hidden%7CModel.other_hidden';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array(
+ 'username' => '', 'password' => '', 'hidden' => '0',
+ 'other_hidden' => 'some hidden value'
+ ),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testValidatePostWithDisabledFields method
+ *
+ * @return void
+ */
+ public function testValidatePostWithDisabledFields() {
+ $this->Controller->Security->disabledFields = array('Model.username', 'Model.password');
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = 'ef1082968c449397bcd849f963636864383278b1%3AModel.hidden';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array(
+ 'username' => '', 'password' => '', 'hidden' => '0'
+ ),
+ '_Token' => compact('fields', 'key', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * test validating post data with posted unlocked fields.
+ *
+ * @return void
+ */
+ public function testValidatePostDisabledFieldsInData() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $unlocked = 'Model.username';
+ $fields = array('Model.hidden', 'Model.password');
+ $fields = urlencode(Security::hash(serialize($fields) . $unlocked . Configure::read('Security.salt')));
+
+ $this->Controller->request->data = array(
+ 'Model' => array(
+ 'username' => 'mark',
+ 'password' => 'sekret',
+ 'hidden' => '0'
+ ),
+ '_Token' => compact('fields', 'key', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * test that missing 'unlocked' input causes failure
+ *
+ * @return void
+ */
+ public function testValidatePostFailNoDisabled() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = array('Model.hidden', 'Model.password', 'Model.username');
+ $fields = urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt')));
+
+ $this->Controller->request->data = array(
+ 'Model' => array(
+ 'username' => 'mark',
+ 'password' => 'sekret',
+ 'hidden' => '0'
+ ),
+ '_Token' => compact('fields', 'key')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertFalse($result);
+ }
+
+/**
+ * Test that validatePost fails when unlocked fields are changed.
+ *
+ * @return
+ */
+ public function testValidatePostFailDisabledFieldTampering() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $unlocked = 'Model.username';
+ $fields = array('Model.hidden', 'Model.password');
+ $fields = urlencode(Security::hash(serialize($fields) . $unlocked . Configure::read('Security.salt')));
+
+ // Tamper the values.
+ $unlocked = 'Model.username|Model.password';
+
+ $this->Controller->request->data = array(
+ 'Model' => array(
+ 'username' => 'mark',
+ 'password' => 'sekret',
+ 'hidden' => '0'
+ ),
+ '_Token' => compact('fields', 'key', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertFalse($result);
+ }
+
+/**
+ * testValidateHiddenMultipleModel method
+ *
+ * @return void
+ */
+ public function testValidateHiddenMultipleModel() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = 'a2d01072dc4660eea9d15007025f35a7a5b58e18%3AModel.valid%7CModel2.valid%7CModel3.valid';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array('username' => '', 'password' => '', 'valid' => '0'),
+ 'Model2' => array('valid' => '0'),
+ 'Model3' => array('valid' => '0'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testValidateHasManyModel method
+ *
+ * @return void
+ */
+ public function testValidateHasManyModel() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '51e3b55a6edd82020b3f29c9ae200e14bbeb7ee5%3AModel.0.hidden%7CModel.0.valid';
+ $fields .= '%7CModel.1.hidden%7CModel.1.valid';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Model' => array(
+ array(
+ 'username' => 'username', 'password' => 'password',
+ 'hidden' => 'value', 'valid' => '0'
+ ),
+ array(
+ 'username' => 'username', 'password' => 'password',
+ 'hidden' => 'value', 'valid' => '0'
+ )
+ ),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testValidateHasManyRecordsPass method
+ *
+ * @return void
+ */
+ public function testValidateHasManyRecordsPass() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3AAddress.0.id%7CAddress.0.primary%7C';
+ $fields .= 'Address.1.id%7CAddress.1.primary';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Address' => array(
+ 0 => array(
+ 'id' => '123',
+ 'title' => 'home',
+ 'first_name' => 'Bilbo',
+ 'last_name' => 'Baggins',
+ 'address' => '23 Bag end way',
+ 'city' => 'the shire',
+ 'phone' => 'N/A',
+ 'primary' => '1',
+ ),
+ 1 => array(
+ 'id' => '124',
+ 'title' => 'home',
+ 'first_name' => 'Frodo',
+ 'last_name' => 'Baggins',
+ 'address' => '50 Bag end way',
+ 'city' => 'the shire',
+ 'phone' => 'N/A',
+ 'primary' => '1'
+ )
+ ),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * Test that values like Foo.0.1
+ *
+ * @return void
+ */
+ public function testValidateNestedNumericSets() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $unlocked = '';
+ $hashFields = array('TaxonomyData');
+ $fields = urlencode(Security::hash(serialize($hashFields) . $unlocked . Configure::read('Security.salt')));
+
+ $this->Controller->request->data = array(
+ 'TaxonomyData' => array(
+ 1 => array(array(2)),
+ 2 => array(array(3))
+ ),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testValidateHasManyRecords method
+ *
+ * validatePost should fail, hidden fields have been changed.
+ *
+ * @return void
+ */
+ public function testValidateHasManyRecordsFail() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '7a203edb3d345bbf38fe0dccae960da8842e11d7%3AAddress.0.id%7CAddress.0.primary%7C';
+ $fields .= 'Address.1.id%7CAddress.1.primary';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'Address' => array(
+ 0 => array(
+ 'id' => '123',
+ 'title' => 'home',
+ 'first_name' => 'Bilbo',
+ 'last_name' => 'Baggins',
+ 'address' => '23 Bag end way',
+ 'city' => 'the shire',
+ 'phone' => 'N/A',
+ 'primary' => '5',
+ ),
+ 1 => array(
+ 'id' => '124',
+ 'title' => 'home',
+ 'first_name' => 'Frodo',
+ 'last_name' => 'Baggins',
+ 'address' => '50 Bag end way',
+ 'city' => 'the shire',
+ 'phone' => 'N/A',
+ 'primary' => '1'
+ )
+ ),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertFalse($result);
+ }
+
+/**
+ * testFormDisabledFields method
+ *
+ * @return void
+ */
+ public function testFormDisabledFields() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '11842060341b9d0fc3808b90ba29fdea7054d6ad%3An%3A0%3A%7B%7D';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ 'MyModel' => array('name' => 'some data'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertFalse($result);
+
+ $this->Controller->Security->startup($this->Controller);
+ $this->Controller->Security->disabledFields = array('MyModel.name');
+ $key = $this->Controller->request->params['_Token']['key'];
+
+ $this->Controller->request->data = array(
+ 'MyModel' => array('name' => 'some data'),
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testRadio method
+ *
+ * @return void
+ */
+ public function testRadio() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+ $fields = '575ef54ca4fc8cab468d6d898e9acd3a9671c17e%3An%3A0%3A%7B%7D';
+ $unlocked = '';
+
+ $this->Controller->request->data = array(
+ '_Token' => compact('key', 'fields', 'unlocked')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertFalse($result);
+
+ $this->Controller->request->data = array(
+ '_Token' => compact('key', 'fields', 'unlocked'),
+ 'Test' => array('test' => '')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+
+ $this->Controller->request->data = array(
+ '_Token' => compact('key', 'fields', 'unlocked'),
+ 'Test' => array('test' => '1')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+
+ $this->Controller->request->data = array(
+ '_Token' => compact('key', 'fields', 'unlocked'),
+ 'Test' => array('test' => '2')
+ );
+ $result = $this->Controller->Security->validatePost($this->Controller);
+ $this->assertTrue($result);
+ }
+
+/**
+ * test that a requestAction's controller will have the _Token appended to
+ * the params.
+ *
+ * @return void
+ * @see http://cakephp.lighthouseapp.com/projects/42648/tickets/68
+ */
+ public function testSettingTokenForRequestAction() {
+ $this->Controller->Security->startup($this->Controller);
+ $key = $this->Controller->request->params['_Token']['key'];
+
+ $this->Controller->params['requested'] = 1;
+ unset($this->Controller->request->params['_Token']);
+
+ $this->Controller->Security->startup($this->Controller);
+ $this->assertEquals($this->Controller->request->params['_Token']['key'], $key);
+ }
+
+/**
+ * test that blackhole doesn't delete the _Token session key so repeat data submissions
+ * stay blackholed.
+ *
+ * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/214
+ * @return void
+ */
+ public function testBlackHoleNotDeletingSessionInformation() {
+ $this->Controller->Security->startup($this->Controller);
+
+ $this->Controller->Security->blackHole($this->Controller, 'auth');
+ $this->assertTrue($this->Controller->Security->Session->check('_Token'), '_Token was deleted by blackHole %s');
+ }
+
+/**
+ * test that csrf checks are skipped for request action.
+ *
+ * @return void
+ */
+ public function testCsrfSkipRequestAction() {
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfExpires = '+10 minutes';
+ $this->Controller->request->params['requested'] = 1;
+ $this->Security->startup($this->Controller);
+
+ $this->assertFalse($this->Controller->failed, 'fail() was called.');
+ }
+
+/**
+ * test setting
+ *
+ * @return void
+ */
+ public function testCsrfSettings() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfExpires = '+10 minutes';
+ $this->Security->startup($this->Controller);
+
+ $token = $this->Security->Session->read('_Token');
+ $this->assertEquals(1, count($token['csrfTokens']), 'Missing the csrf token.');
+ $this->assertEquals(strtotime('+10 minutes'), current($token['csrfTokens']), 'Token expiry does not match');
+ $this->assertEquals(array('key', 'unlockedFields'), array_keys($this->Controller->request->params['_Token']), 'Keys don not match');
+ }
+
+/**
+ * Test setting multiple nonces, when startup() is called more than once, (ie more than one request.)
+ *
+ * @return void
+ */
+ public function testCsrfSettingMultipleNonces() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfExpires = '+10 minutes';
+ $csrfExpires = strtotime('+10 minutes');
+ $this->Security->startup($this->Controller);
+ $this->Security->startup($this->Controller);
+
+ $token = $this->Security->Session->read('_Token');
+ $this->assertEquals(2, count($token['csrfTokens']), 'Missing the csrf token.');
+ foreach ($token['csrfTokens'] as $key => $expires) {
+ $diff = $csrfExpires - $expires;
+ $this->assertTrue($diff === 0 || $diff === 1, 'Token expiry does not match');
+ }
+ }
+
+/**
+ * test that nonces are consumed by form submits.
+ *
+ * @return void
+ */
+ public function testCsrfNonceConsumption() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfExpires = '+10 minutes';
+
+ $this->Security->Session->write('_Token.csrfTokens', array('nonce1' => strtotime('+10 minutes')));
+
+ $this->Controller->request = $this->getMock('CakeRequest', array('is'));
+ $this->Controller->request->expects($this->once())->method('is')
+ ->with('post')
+ ->will($this->returnValue(true));
+
+ $this->Controller->request->params['action'] = 'index';
+ $this->Controller->request->data = array(
+ '_Token' => array(
+ 'key' => 'nonce1'
+ ),
+ 'Post' => array(
+ 'title' => 'Woot'
+ )
+ );
+ $this->Security->startup($this->Controller);
+ $token = $this->Security->Session->read('_Token');
+ $this->assertFalse(isset($token['csrfTokens']['nonce1']), 'Token was not consumed');
+ }
+
+/**
+ * test that expired values in the csrfTokens are cleaned up.
+ *
+ * @return void
+ */
+ public function testCsrfNonceVacuum() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfExpires = '+10 minutes';
+
+ $this->Security->Session->write('_Token.csrfTokens', array(
+ 'valid' => strtotime('+30 minutes'),
+ 'poof' => strtotime('-11 minutes'),
+ 'dust' => strtotime('-20 minutes')
+ ));
+ $this->Security->startup($this->Controller);
+ $tokens = $this->Security->Session->read('_Token.csrfTokens');
+ $this->assertEquals(2, count($tokens), 'Too many tokens left behind');
+ $this->assertNotEmpty('valid', $tokens, 'Valid token was removed.');
+ }
+
+/**
+ * test that when the key is missing the request is blackHoled
+ *
+ * @return void
+ */
+ public function testCsrfBlackHoleOnKeyMismatch() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfExpires = '+10 minutes';
+
+ $this->Security->Session->write('_Token.csrfTokens', array('nonce1' => strtotime('+10 minutes')));
+
+ $this->Controller->request = $this->getMock('CakeRequest', array('is'));
+ $this->Controller->request->expects($this->once())->method('is')
+ ->with('post')
+ ->will($this->returnValue(true));
+
+ $this->Controller->request->params['action'] = 'index';
+ $this->Controller->request->data = array(
+ '_Token' => array(
+ 'key' => 'not the right value'
+ ),
+ 'Post' => array(
+ 'title' => 'Woot'
+ )
+ );
+ $this->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed, 'fail() was not called.');
+ }
+
+/**
+ * test that when the key is missing the request is blackHoled
+ *
+ * @return void
+ */
+ public function testCsrfBlackHoleOnExpiredKey() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfExpires = '+10 minutes';
+
+ $this->Security->Session->write('_Token.csrfTokens', array('nonce1' => strtotime('-5 minutes')));
+
+ $this->Controller->request = $this->getMock('CakeRequest', array('is'));
+ $this->Controller->request->expects($this->once())->method('is')
+ ->with('post')
+ ->will($this->returnValue(true));
+
+ $this->Controller->request->params['action'] = 'index';
+ $this->Controller->request->data = array(
+ '_Token' => array(
+ 'key' => 'nonce1'
+ ),
+ 'Post' => array(
+ 'title' => 'Woot'
+ )
+ );
+ $this->Security->startup($this->Controller);
+ $this->assertTrue($this->Controller->failed, 'fail() was not called.');
+ }
+
+/**
+ * test that csrfUseOnce = false works.
+ *
+ * @return void
+ */
+ public function testCsrfNotUseOnce() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfUseOnce = false;
+ $this->Security->csrfExpires = '+10 minutes';
+
+ // Generate one token
+ $this->Security->startup($this->Controller);
+ $token = $this->Security->Session->read('_Token.csrfTokens');
+ $this->assertEquals(1, count($token), 'Should only be one token.');
+
+ $this->Security->startup($this->Controller);
+ $tokenTwo = $this->Security->Session->read('_Token.csrfTokens');
+ $this->assertEquals(1, count($tokenTwo), 'Should only be one token.');
+ $this->assertEquals($token, $tokenTwo, 'Tokens should not be different.');
+
+ $key = $this->Controller->request->params['_Token']['key'];
+ $this->assertEquals(array($key), array_keys($token), '_Token.key and csrfToken do not match request will blackhole.');
+ }
+
+/**
+ * ensure that longer session tokens are not consumed
+ *
+ * @return void
+ */
+ public function testCsrfNotUseOnceValidationLeavingToken() {
+ $this->Security->validatePost = false;
+ $this->Security->csrfCheck = true;
+ $this->Security->csrfUseOnce = false;
+ $this->Security->csrfExpires = '+10 minutes';
+
+ $this->Security->Session->write('_Token.csrfTokens', array('nonce1' => strtotime('+10 minutes')));
+
+ $this->Controller->request = $this->getMock('CakeRequest', array('is'));
+ $this->Controller->request->expects($this->once())->method('is')
+ ->with('post')
+ ->will($this->returnValue(true));
+
+ $this->Controller->request->params['action'] = 'index';
+ $this->Controller->request->data = array(
+ '_Token' => array(
+ 'key' => 'nonce1'
+ ),
+ 'Post' => array(
+ 'title' => 'Woot'
+ )
+ );
+ $this->Security->startup($this->Controller);
+ $token = $this->Security->Session->read('_Token');
+ $this->assertTrue(isset($token['csrfTokens']['nonce1']), 'Token was consumed');
+ }
+
+/**
+ * Test generateToken()
+ *
+ * @return void
+ */
+ public function testGenerateToken() {
+ $request = $this->Controller->request;
+ $this->Security->generateToken($request);
+
+ $this->assertNotEmpty($request->params['_Token']);
+ $this->assertTrue(isset($request->params['_Token']['unlockedFields']));
+ $this->assertTrue(isset($request->params['_Token']['key']));
+ }
+
+/**
+ * Test the limiting of CSRF tokens.
+ *
+ * @return void
+ */
+ public function testCsrfLimit() {
+ $this->Security->csrfLimit = 3;
+ $time = strtotime('+10 minutes');
+ $tokens = array(
+ '1' => $time,
+ '2' => $time,
+ '3' => $time,
+ '4' => $time,
+ '5' => $time,
+ );
+ $this->Security->Session->write('_Token', array('csrfTokens' => $tokens));
+ $this->Security->generateToken($this->Controller->request);
+ $result = $this->Security->Session->read('_Token.csrfTokens');
+
+ $this->assertFalse(isset($result['1']));
+ $this->assertFalse(isset($result['2']));
+ $this->assertFalse(isset($result['3']));
+ $this->assertTrue(isset($result['4']));
+ $this->assertTrue(isset($result['5']));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php
new file mode 100644
index 0000000..0920186
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/Component/SessionComponentTest.php
@@ -0,0 +1,294 @@
+<?php
+/**
+ * SessionComponentTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.5436
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Controller', 'Controller');
+App::uses('SessionComponent', 'Controller/Component');
+
+/**
+ * SessionTestController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class SessionTestController extends Controller {
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * sessionId method
+ *
+ * @return string
+ */
+ public function sessionId() {
+ return $this->Session->id();
+ }
+
+}
+
+/**
+ * OrangeSessionTestController class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class OrangeSessionTestController extends Controller {
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * sessionId method
+ *
+ * @return string
+ */
+ public function sessionId() {
+ return $this->Session->id();
+ }
+
+}
+
+/**
+ * SessionComponentTest class
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class SessionComponentTest extends CakeTestCase {
+
+ protected static $_sessionBackup;
+
+/**
+ * fixtures
+ *
+ * @var string
+ */
+ public $fixtures = array('core.session');
+
+/**
+ * test case startup
+ *
+ * @return void
+ */
+ public static function setupBeforeClass() {
+ self::$_sessionBackup = Configure::read('Session');
+ Configure::write('Session', array(
+ 'defaults' => 'php',
+ 'timeout' => 100,
+ 'cookie' => 'test'
+ ));
+ }
+
+/**
+ * cleanup after test case.
+ *
+ * @return void
+ */
+ public static function teardownAfterClass() {
+ Configure::write('Session', self::$_sessionBackup);
+ }
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $_SESSION = null;
+ $this->ComponentCollection = new ComponentCollection();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakeSession::destroy();
+ }
+
+/**
+ * ensure that session ids don't change when request action is called.
+ *
+ * @return void
+ */
+ public function testSessionIdConsistentAcrossRequestAction() {
+ $Session = new SessionComponent($this->ComponentCollection);
+ $Session->check('Test');
+ $this->assertTrue(isset($_SESSION));
+
+ $Object = new Object();
+ $Session = new SessionComponent($this->ComponentCollection);
+ $expected = $Session->id();
+
+ $result = $Object->requestAction('/session_test/sessionId');
+ $this->assertEquals($expected, $result);
+
+ $result = $Object->requestAction('/orange_session_test/sessionId');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSessionValid method
+ *
+ * @return void
+ */
+ public function testSessionValid() {
+ $Session = new SessionComponent($this->ComponentCollection);
+
+ $this->assertTrue($Session->valid());
+
+ Configure::write('Session.checkAgent', true);
+ $Session->userAgent('rweerw');
+ $this->assertFalse($Session->valid());
+
+ $Session = new SessionComponent($this->ComponentCollection);
+ $Session->time = $Session->read('Config.time') + 1;
+ $this->assertFalse($Session->valid());
+ }
+
+/**
+ * testSessionError method
+ *
+ * @return void
+ */
+ public function testSessionError() {
+ $Session = new SessionComponent($this->ComponentCollection);
+ $this->assertFalse($Session->error());
+ }
+
+/**
+ * testSessionReadWrite method
+ *
+ * @return void
+ */
+ public function testSessionReadWrite() {
+ $Session = new SessionComponent($this->ComponentCollection);
+
+ $this->assertNull($Session->read('Test'));
+
+ $this->assertTrue($Session->write('Test', 'some value'));
+ $this->assertEquals('some value', $Session->read('Test'));
+ $Session->delete('Test');
+
+ $this->assertTrue($Session->write('Test.key.path', 'some value'));
+ $this->assertEquals('some value', $Session->read('Test.key.path'));
+ $this->assertEquals(array('path' => 'some value'), $Session->read('Test.key'));
+ $this->assertTrue($Session->write('Test.key.path2', 'another value'));
+ $this->assertEquals(array('path' => 'some value', 'path2' => 'another value'), $Session->read('Test.key'));
+ $Session->delete('Test');
+
+ $array = array('key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3');
+ $this->assertTrue($Session->write('Test', $array));
+ $this->assertEquals($Session->read('Test'), $array);
+ $Session->delete('Test');
+
+ $this->assertFalse($Session->write(array('Test'), 'some value'));
+ $this->assertTrue($Session->write(array('Test' => 'some value')));
+ $this->assertEquals('some value', $Session->read('Test'));
+ $Session->delete('Test');
+ }
+
+/**
+ * testSessionDelete method
+ *
+ * @return void
+ */
+ public function testSessionDelete() {
+ $Session = new SessionComponent($this->ComponentCollection);
+
+ $this->assertFalse($Session->delete('Test'));
+
+ $Session->write('Test', 'some value');
+ $this->assertTrue($Session->delete('Test'));
+ }
+
+/**
+ * testSessionCheck method
+ *
+ * @return void
+ */
+ public function testSessionCheck() {
+ $Session = new SessionComponent($this->ComponentCollection);
+
+ $this->assertFalse($Session->check('Test'));
+
+ $Session->write('Test', 'some value');
+ $this->assertTrue($Session->check('Test'));
+ $Session->delete('Test');
+ }
+
+/**
+ * testSessionFlash method
+ *
+ * @return void
+ */
+ public function testSessionFlash() {
+ $Session = new SessionComponent($this->ComponentCollection);
+
+ $this->assertNull($Session->read('Message.flash'));
+
+ $Session->setFlash('This is a test message');
+ $this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.flash'));
+
+ $Session->setFlash('This is a test message', 'test', array('name' => 'Joel Moss'));
+ $this->assertEquals(array('message' => 'This is a test message', 'element' => 'test', 'params' => array('name' => 'Joel Moss')), $Session->read('Message.flash'));
+
+ $Session->setFlash('This is a test message', 'default', array(), 'myFlash');
+ $this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.myFlash'));
+
+ $Session->setFlash('This is a test message', 'non_existing_layout');
+ $this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.myFlash'));
+
+ $Session->delete('Message');
+ }
+
+/**
+ * testSessionId method
+ *
+ * @return void
+ */
+ public function testSessionId() {
+ unset($_SESSION);
+ $Session = new SessionComponent($this->ComponentCollection);
+ $Session->check('test');
+ $this->assertEquals(session_id(), $Session->id());
+ }
+
+/**
+ * testSessionDestroy method
+ *
+ * @return void
+ */
+ public function testSessionDestroy() {
+ $Session = new SessionComponent($this->ComponentCollection);
+
+ $Session->write('Test', 'some value');
+ $this->assertEquals('some value', $Session->read('Test'));
+ $Session->destroy('Test');
+ $this->assertNull($Session->read('Test'));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php
new file mode 100644
index 0000000..11f5e6a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentCollectionTest.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * ComponentCollectionTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeResponse', 'Network');
+App::uses('CookieComponent', 'Controller/Component');
+App::uses('SecurityComponent', 'Controller/Component');
+App::uses('ComponentCollection', 'Controller');
+
+/**
+ * Extended CookieComponent
+ */
+class CookieAliasComponent extends CookieComponent {
+}
+
+class ComponentCollectionTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Components = new ComponentCollection();
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Components);
+ }
+
+/**
+ * test triggering callbacks on loaded helpers
+ *
+ * @return void
+ */
+ public function testLoad() {
+ $result = $this->Components->load('Cookie');
+ $this->assertInstanceOf('CookieComponent', $result);
+ $this->assertInstanceOf('CookieComponent', $this->Components->Cookie);
+
+ $result = $this->Components->attached();
+ $this->assertEquals(array('Cookie'), $result, 'attached() results are wrong.');
+
+ $this->assertTrue($this->Components->enabled('Cookie'));
+
+ $result = $this->Components->load('Cookie');
+ $this->assertSame($result, $this->Components->Cookie);
+ }
+
+/**
+ * Tests loading as an alias
+ *
+ * @return void
+ */
+ public function testLoadWithAlias() {
+ $result = $this->Components->load('Cookie', array('className' => 'CookieAlias', 'somesetting' => true));
+ $this->assertInstanceOf('CookieAliasComponent', $result);
+ $this->assertInstanceOf('CookieAliasComponent', $this->Components->Cookie);
+ $this->assertTrue($this->Components->Cookie->settings['somesetting']);
+
+ $result = $this->Components->attached();
+ $this->assertEquals(array('Cookie'), $result, 'attached() results are wrong.');
+
+ $this->assertTrue($this->Components->enabled('Cookie'));
+
+ $result = $this->Components->load('Cookie');
+ $this->assertInstanceOf('CookieAliasComponent', $result);
+
+ App::build(array('Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
+ CakePlugin::load('TestPlugin');
+ $result = $this->Components->load('SomeOther', array('className' => 'TestPlugin.Other'));
+ $this->assertInstanceOf('OtherComponent', $result);
+ $this->assertInstanceOf('OtherComponent', $this->Components->SomeOther);
+
+ $result = $this->Components->attached();
+ $this->assertEquals(array('Cookie', 'SomeOther'), $result, 'attached() results are wrong.');
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * test load and enable = false
+ *
+ * @return void
+ */
+ public function testLoadWithEnableFalse() {
+ $result = $this->Components->load('Cookie', array('enabled' => false));
+ $this->assertInstanceOf('CookieComponent', $result);
+ $this->assertInstanceOf('CookieComponent', $this->Components->Cookie);
+
+ $this->assertFalse($this->Components->enabled('Cookie'), 'Cookie should be disabled');
+ }
+
+/**
+ * test missingcomponent exception
+ *
+ * @expectedException MissingComponentException
+ * @return void
+ */
+ public function testLoadMissingComponent() {
+ $this->Components->load('ThisComponentShouldAlwaysBeMissing');
+ }
+
+/**
+ * test loading a plugin component.
+ *
+ * @return void
+ */
+ public function testLoadPluginComponent() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ ));
+ CakePlugin::load('TestPlugin');
+ $result = $this->Components->load('TestPlugin.Other');
+ $this->assertInstanceOf('OtherComponent', $result, 'Component class is wrong.');
+ $this->assertInstanceOf('OtherComponent', $this->Components->Other, 'Class is wrong');
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * test unload()
+ *
+ * @return void
+ */
+ public function testUnload() {
+ $this->Components->load('Cookie');
+ $this->Components->load('Security');
+
+ $result = $this->Components->attached();
+ $this->assertEquals(array('Cookie', 'Security'), $result, 'loaded components is wrong');
+
+ $this->Components->unload('Cookie');
+ $this->assertFalse(isset($this->Components->Cookie));
+ $this->assertTrue(isset($this->Components->Security));
+
+ $result = $this->Components->attached();
+ $this->assertEquals(array('Security'), $result, 'loaded components is wrong');
+
+ $result = $this->Components->enabled();
+ $this->assertEquals(array('Security'), $result, 'enabled components is wrong');
+ }
+
+/**
+ * test getting the controller out of the collection
+ *
+ * @return void
+ */
+ public function testGetController() {
+ $controller = $this->getMock('Controller');
+ $controller->components = array('Security');
+ $this->Components->init($controller);
+ $result = $this->Components->getController();
+
+ $this->assertSame($controller, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentTest.php
new file mode 100644
index 0000000..6085407
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ComponentTest.php
@@ -0,0 +1,305 @@
+<?php
+/**
+ * ComponentTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller
+ * @since CakePHP(tm) v 1.2.0.5436
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('Component', 'Controller');
+
+/**
+ * ParamTestComponent
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ParamTestComponent extends Component {
+
+/**
+ * name property
+ *
+ * @var string 'ParamTest'
+ */
+ public $name = 'ParamTest';
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Banana' => array('config' => 'value'));
+}
+
+/**
+ * ComponentTestController class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ComponentTestController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'ComponentTest'
+ */
+ public $name = 'ComponentTest';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+}
+
+/**
+ * AppleComponent class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class AppleComponent extends Component {
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Orange');
+
+/**
+ * testName property
+ *
+ * @var mixed null
+ */
+ public $testName = null;
+
+/**
+ * startup method
+ *
+ * @param Controller $controller
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ $this->testName = $controller->name;
+ }
+
+}
+
+/**
+ * OrangeComponent class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class OrangeComponent extends Component {
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Banana');
+
+/**
+ * initialize method
+ *
+ * @param Controller $controller
+ * @return void
+ */
+ public function initialize(Controller $controller) {
+ $this->Controller = $controller;
+ $this->Banana->testField = 'OrangeField';
+ }
+
+/**
+ * startup method
+ *
+ * @param Controller $controller
+ * @return string
+ */
+ public function startup(Controller $controller) {
+ $controller->foo = 'pass';
+ }
+
+}
+
+/**
+ * BananaComponent class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class BananaComponent extends Component {
+
+/**
+ * testField property
+ *
+ * @var string 'BananaField'
+ */
+ public $testField = 'BananaField';
+
+/**
+ * startup method
+ *
+ * @param Controller $controller
+ * @return string
+ */
+ public function startup(Controller $controller) {
+ $controller->bar = 'fail';
+ }
+
+}
+
+/**
+ * MutuallyReferencingOneComponent class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class MutuallyReferencingOneComponent extends Component {
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('MutuallyReferencingTwo');
+}
+
+/**
+ * MutuallyReferencingTwoComponent class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class MutuallyReferencingTwoComponent extends Component {
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('MutuallyReferencingOne');
+}
+
+/**
+ * SomethingWithEmailComponent class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class SomethingWithEmailComponent extends Component {
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Email');
+}
+
+
+/**
+ * ComponentTest class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ComponentTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->_pluginPaths = App::path('plugins');
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ }
+
+/**
+ * test accessing inner components.
+ *
+ * @return void
+ */
+ public function testInnerComponentConstruction() {
+ $Collection = new ComponentCollection();
+ $Component = new AppleComponent($Collection);
+
+ $this->assertInstanceOf('OrangeComponent', $Component->Orange, 'class is wrong');
+ }
+
+/**
+ * test component loading
+ *
+ * @return void
+ */
+ public function testNestedComponentLoading() {
+ $Collection = new ComponentCollection();
+ $Apple = new AppleComponent($Collection);
+
+ $this->assertInstanceOf('OrangeComponent', $Apple->Orange, 'class is wrong');
+ $this->assertInstanceOf('BananaComponent', $Apple->Orange->Banana, 'class is wrong');
+ $this->assertTrue(empty($Apple->Session));
+ $this->assertTrue(empty($Apple->Orange->Session));
+ }
+
+/**
+ * test that component components are not enabled in the collection.
+ *
+ * @return void
+ */
+ public function testInnerComponentsAreNotEnabled() {
+ $Collection = new ComponentCollection();
+ $Apple = $Collection->load('Apple');
+
+ $this->assertInstanceOf('OrangeComponent', $Apple->Orange, 'class is wrong');
+ $result = $Collection->enabled();
+ $this->assertEquals(array('Apple'), $result, 'Too many components enabled.');
+ }
+
+/**
+ * test a component being used more than once.
+ *
+ * @return void
+ */
+ public function testMultipleComponentInitialize() {
+ $Collection = new ComponentCollection();
+ $Banana = $Collection->load('Banana');
+ $Orange = $Collection->load('Orange');
+
+ $this->assertSame($Banana, $Orange->Banana, 'Should be references');
+ $Banana->testField = 'OrangeField';
+
+ $this->assertSame($Banana->testField, $Orange->Banana->testField, 'References are broken');
+ }
+
+/**
+ * Test mutually referencing components.
+ *
+ * @return void
+ */
+ public function testSomethingReferencingEmailComponent() {
+ $Controller = new ComponentTestController();
+ $Controller->components = array('SomethingWithEmail');
+ $Controller->uses = false;
+ $Controller->constructClasses();
+ $Controller->Components->trigger('initialize', array(&$Controller));
+ $Controller->beforeFilter();
+ $Controller->Components->trigger('startup', array(&$Controller));
+
+ $this->assertInstanceOf('SomethingWithEmailComponent', $Controller->SomethingWithEmail);
+ $this->assertInstanceOf('EmailComponent', $Controller->SomethingWithEmail->Email);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerMergeVarsTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerMergeVarsTest.php
new file mode 100644
index 0000000..93a5cec
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerMergeVarsTest.php
@@ -0,0 +1,252 @@
+<?php
+/**
+ * Controller Merge vars Test file
+ *
+ * Isolated from the Controller and Component test as to not pollute their AppController class
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller
+ * @since CakePHP(tm) v 1.2.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Controller', 'Controller');
+
+/**
+ * Test case AppController
+ *
+ * @package Cake.Test.Case.Controller
+ * @package Cake.Test.Case.Controller
+ */
+class MergeVarsAppController extends Controller {
+
+/**
+ * components
+ *
+ * @var array
+ */
+ public $components = array('MergeVar' => array('flag', 'otherFlag', 'redirect' => false));
+
+/**
+ * helpers
+ *
+ * @var array
+ */
+ public $helpers = array('MergeVar' => array('format' => 'html', 'terse'));
+}
+
+/**
+ * MergeVar Component
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class MergeVarComponent extends Object {
+
+}
+
+/**
+ * Additional controller for testing
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class MergeVariablesController extends MergeVarsAppController {
+
+/**
+ * name
+ *
+ * @var string
+ */
+ public $name = 'MergeVariables';
+
+/**
+ * uses
+ *
+ * @var arrays
+ */
+ public $uses = array();
+
+/**
+ * parent for mergeVars
+ *
+ * @var string
+ */
+ protected $_mergeParent = 'MergeVarsAppController';
+}
+
+/**
+ * MergeVarPlugin App Controller
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class MergeVarPluginAppController extends MergeVarsAppController {
+
+/**
+ * components
+ *
+ * @var array
+ */
+ public $components = array('Auth' => array('setting' => 'val', 'otherVal'));
+
+/**
+ * helpers
+ *
+ * @var array
+ */
+ public $helpers = array('Javascript');
+
+/**
+ * parent for mergeVars
+ *
+ * @var string
+ */
+ protected $_mergeParent = 'MergeVarsAppController';
+}
+
+/**
+ * MergePostsController
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class MergePostsController extends MergeVarPluginAppController {
+
+/**
+ * name
+ *
+ * @var string
+ */
+ public $name = 'MergePosts';
+
+/**
+ * uses
+ *
+ * @var array
+ */
+ public $uses = array();
+}
+
+
+/**
+ * Test Case for Controller Merging of Vars.
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ControllerMergeVarsTest extends CakeTestCase {
+
+/**
+ * test that component settings are not duplicated when merging component settings
+ *
+ * @return void
+ */
+ public function testComponentParamMergingNoDuplication() {
+ $Controller = new MergeVariablesController();
+ $Controller->constructClasses();
+
+ $expected = array('MergeVar' => array('flag', 'otherFlag', 'redirect' => false));
+ $this->assertEquals($expected, $Controller->components, 'Duplication of settings occurred. %s');
+ }
+
+/**
+ * test component merges with redeclared components
+ *
+ * @return void
+ */
+ public function testComponentMergingWithRedeclarations() {
+ $Controller = new MergeVariablesController();
+ $Controller->components['MergeVar'] = array('remote', 'redirect' => true);
+ $Controller->constructClasses();
+
+ $expected = array('MergeVar' => array('flag', 'otherFlag', 'redirect' => true, 'remote'));
+ $this->assertEquals($expected, $Controller->components, 'Merging of settings is wrong. %s');
+ }
+
+/**
+ * test merging of helpers array, ensure no duplication occurs
+ *
+ * @return void
+ */
+ public function testHelperSettingMergingNoDuplication() {
+ $Controller = new MergeVariablesController();
+ $Controller->constructClasses();
+
+ $expected = array('MergeVar' => array('format' => 'html', 'terse'));
+ $this->assertEquals($expected, $Controller->helpers, 'Duplication of settings occurred. %s');
+ }
+
+/**
+ * Test that helpers declared in appcontroller come before those in the subclass
+ * orderwise
+ *
+ * @return void
+ */
+ public function testHelperOrderPrecedence() {
+ $Controller = new MergeVariablesController();
+ $Controller->helpers = array('Custom', 'Foo' => array('something'));
+ $Controller->constructClasses();
+
+ $expected = array(
+ 'MergeVar' => array('format' => 'html', 'terse'),
+ 'Custom' => null,
+ 'Foo' => array('something')
+ );
+ $this->assertSame($expected, $Controller->helpers, 'Order is incorrect.');
+ }
+
+/**
+ * test merging of vars with plugin
+ *
+ * @return void
+ */
+ public function testMergeVarsWithPlugin() {
+ $Controller = new MergePostsController();
+ $Controller->components = array('Email' => array('ports' => 'open'));
+ $Controller->plugin = 'MergeVarPlugin';
+ $Controller->constructClasses();
+
+ $expected = array(
+ 'MergeVar' => array('flag', 'otherFlag', 'redirect' => false),
+ 'Auth' => array('setting' => 'val', 'otherVal'),
+ 'Email' => array('ports' => 'open')
+ );
+ $this->assertEquals($expected, $Controller->components, 'Components are unexpected.');
+
+ $expected = array(
+ 'MergeVar' => array('format' => 'html', 'terse'),
+ 'Javascript' => null
+ );
+ $this->assertEquals($expected, $Controller->helpers, 'Helpers are unexpected.');
+
+ $Controller = new MergePostsController();
+ $Controller->components = array();
+ $Controller->plugin = 'MergeVarPlugin';
+ $Controller->constructClasses();
+
+ $expected = array(
+ 'MergeVar' => array('flag', 'otherFlag', 'redirect' => false),
+ 'Auth' => array('setting' => 'val', 'otherVal'),
+ );
+ $this->assertEquals($expected, $Controller->components, 'Components are unexpected.');
+ }
+
+/**
+ * Ensure that _mergeControllerVars is not being greedy and merging with
+ * AppController when you make an instance of Controller
+ *
+ * @return void
+ */
+ public function testMergeVarsNotGreedy() {
+ $Controller = new Controller();
+ $Controller->components = array();
+ $Controller->uses = array();
+ $Controller->constructClasses();
+
+ $this->assertFalse(isset($Controller->Session));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerTest.php
new file mode 100644
index 0000000..36116ad
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ControllerTest.php
@@ -0,0 +1,1441 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Controller
+ * @since CakePHP(tm) v 1.2.0.5436
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Controller', 'Controller');
+App::uses('Router', 'Routing');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+App::uses('SecurityComponent', 'Controller/Component');
+App::uses('CookieComponent', 'Controller/Component');
+
+/**
+ * AppController class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ControllerTestAppController extends Controller {
+
+/**
+ * helpers property
+ *
+ * @var array
+ */
+ public $helpers = array('Html');
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array('ControllerPost');
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Cookie');
+}
+
+
+/**
+ * ControllerPost class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ControllerPost extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ControllerPost'
+ */
+ public $name = 'ControllerPost';
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'posts';
+
+/**
+ * invalidFields property
+ *
+ * @var array
+ */
+ public $invalidFields = array('name' => 'error_msg');
+
+/**
+ * lastQuery property
+ *
+ * @var mixed null
+ */
+ public $lastQuery = null;
+
+/**
+ * beforeFind method
+ *
+ * @param mixed $query
+ * @return void
+ */
+ public function beforeFind($query) {
+ $this->lastQuery = $query;
+ }
+
+/**
+ * find method
+ *
+ * @param string $type
+ * @param array $options
+ * @return void
+ */
+ public function find($type = 'first', $options = array()) {
+ if ($type == 'popular') {
+ $conditions = array($this->name . '.' . $this->primaryKey . ' > ' => '1');
+ $options = Hash::merge($options, compact('conditions'));
+ return parent::find('all', $options);
+ }
+ return parent::find($type, $options);
+ }
+
+}
+
+/**
+ * ControllerPostsController class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ControllerCommentsController extends ControllerTestAppController {
+
+/**
+ * name property
+ *
+ * @var string 'ControllerPost'
+ */
+ public $name = 'ControllerComments';
+
+ protected $_mergeParent = 'ControllerTestAppController';
+}
+
+/**
+ * ControllerComment class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ControllerComment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ControllerComment'
+ */
+ public $name = 'Comment';
+
+/**
+ * useTable property
+ *
+ * @var string 'comments'
+ */
+ public $useTable = 'comments';
+
+/**
+ * data property
+ *
+ * @var array
+ */
+ public $data = array('name' => 'Some Name');
+
+/**
+ * alias property
+ *
+ * @var string 'ControllerComment'
+ */
+ public $alias = 'ControllerComment';
+}
+
+/**
+ * ControllerAlias class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ControllerAlias extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ControllerAlias'
+ */
+ public $name = 'ControllerAlias';
+
+/**
+ * alias property
+ *
+ * @var string 'ControllerSomeAlias'
+ */
+ public $alias = 'ControllerSomeAlias';
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'posts';
+}
+
+/**
+ * NameTest class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class NameTest extends CakeTestModel {
+
+/**
+ * name property
+ * @var string 'Name'
+ */
+ public $name = 'Name';
+
+/**
+ * useTable property
+ * @var string 'names'
+ */
+ public $useTable = 'comments';
+
+/**
+ * alias property
+ *
+ * @var string 'ControllerComment'
+ */
+ public $alias = 'Name';
+}
+
+/**
+ * TestController class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class TestController extends ControllerTestAppController {
+
+/**
+ * name property
+ * @var string 'Name'
+ */
+ public $name = 'Test';
+
+/**
+ * helpers property
+ *
+ * @var array
+ */
+ public $helpers = array('Session');
+
+/**
+ * components property
+ *
+ * @var array
+ */
+ public $components = array('Security');
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array('ControllerComment', 'ControllerAlias');
+
+ protected $_mergeParent = 'ControllerTestAppController';
+
+/**
+ * index method
+ *
+ * @param mixed $testId
+ * @param mixed $test2Id
+ * @return void
+ */
+ public function index($testId, $testTwoId) {
+ $this->data = array(
+ 'testId' => $testId,
+ 'test2Id' => $testTwoId
+ );
+ }
+
+/**
+ * view method
+ *
+ * @param mixed $testId
+ * @param mixed $test2Id
+ * @return void
+ */
+ public function view($testId, $testTwoId) {
+ $this->data = array(
+ 'testId' => $testId,
+ 'test2Id' => $testTwoId
+ );
+ }
+
+ public function returner() {
+ return 'I am from the controller.';
+ }
+
+ //@codingStandardsIgnoreStart
+ protected function protected_m() {
+ }
+
+ private function private_m() {
+ }
+
+ public function _hidden() {
+ }
+ //@codingStandardsIgnoreEnd
+
+ public function admin_add() {
+ }
+
+}
+
+/**
+ * TestComponent class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class TestComponent extends Object {
+
+/**
+ * beforeRedirect method
+ *
+ * @return void
+ */
+ public function beforeRedirect() {
+ }
+
+/**
+ * initialize method
+ *
+ * @return void
+ */
+ public function initialize(Controller $controller) {
+ }
+
+/**
+ * startup method
+ *
+ * @return void
+ */
+ public function startup(Controller $controller) {
+ }
+
+/**
+ * shutdown method
+ *
+ * @return void
+ */
+ public function shutdown(Controller $controller) {
+ }
+
+/**
+ * beforeRender callback
+ *
+ * @return void
+ */
+ public function beforeRender(Controller $controller) {
+ if ($this->viewclass) {
+ $controller->viewClass = $this->viewclass;
+ }
+ }
+
+}
+
+class Test2Component extends TestComponent {
+
+ public function beforeRender(Controller $controller) {
+ return false;
+ }
+
+}
+
+/**
+ * AnotherTestController class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class AnotherTestController extends ControllerTestAppController {
+
+/**
+ * name property
+ * @var string 'Name'
+ */
+ public $name = 'AnotherTest';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = false;
+
+/**
+ * merge parent
+ *
+ * @var string
+ */
+ protected $_mergeParent = 'ControllerTestAppController';
+}
+
+/**
+ * ControllerTest class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ControllerTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.post',
+ 'core.comment'
+ );
+
+/**
+ * reset environment.
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::objects('plugin', null, false);
+ App::build();
+ Router::reload();
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ }
+
+/**
+ * testLoadModel method
+ *
+ * @return void
+ */
+ public function testLoadModel() {
+ $request = new CakeRequest('controller_posts/index');
+ $response = $this->getMock('CakeResponse');
+ $Controller = new Controller($request, $response);
+
+ $this->assertFalse(isset($Controller->ControllerPost));
+
+ $result = $Controller->loadModel('ControllerPost');
+ $this->assertTrue($result);
+ $this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost'));
+ $this->assertTrue(in_array('ControllerPost', $Controller->uses));
+
+ ClassRegistry::flush();
+ unset($Controller);
+ }
+
+/**
+ * testLoadModel method from a plugin controller
+ *
+ * @return void
+ */
+ public function testLoadModelInPlugins() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Controller' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS),
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ App::uses('TestPluginAppController', 'TestPlugin.Controller');
+ App::uses('TestPluginController', 'TestPlugin.Controller');
+
+ $Controller = new TestPluginController();
+ $Controller->plugin = 'TestPlugin';
+ $Controller->uses = false;
+
+ $this->assertFalse(isset($Controller->Comment));
+
+ $result = $Controller->loadModel('Comment');
+ $this->assertTrue($result);
+ $this->assertInstanceOf('Comment', $Controller->Comment);
+ $this->assertTrue(in_array('Comment', $Controller->uses));
+
+ ClassRegistry::flush();
+ unset($Controller);
+ }
+
+/**
+ * testConstructClasses method
+ *
+ * @return void
+ */
+ public function testConstructClasses() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $Controller = new Controller($request);
+ $Controller->uses = array('ControllerPost', 'ControllerComment');
+ $Controller->constructClasses();
+ $this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost'));
+ $this->assertTrue(is_a($Controller->ControllerComment, 'ControllerComment'));
+
+ $this->assertEquals('Comment', $Controller->ControllerComment->name);
+
+ unset($Controller);
+
+ App::build(array('Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
+ CakePlugin::load('TestPlugin');
+
+ $Controller = new Controller($request);
+ $Controller->uses = array('TestPlugin.TestPluginPost');
+ $Controller->constructClasses();
+
+ $this->assertTrue(isset($Controller->TestPluginPost));
+ $this->assertTrue(is_a($Controller->TestPluginPost, 'TestPluginPost'));
+ }
+
+/**
+ * testAliasName method
+ *
+ * @return void
+ */
+ public function testAliasName() {
+ $request = new CakeRequest('controller_posts/index');
+ $Controller = new Controller($request);
+ $Controller->uses = array('NameTest');
+ $Controller->constructClasses();
+
+ $this->assertEquals('Name', $Controller->NameTest->name);
+ $this->assertEquals('Name', $Controller->NameTest->alias);
+
+ unset($Controller);
+ }
+
+/**
+ * testFlash method
+ *
+ * @return void
+ */
+ public function testFlash() {
+ $request = new CakeRequest('controller_posts/index');
+ $request->webroot = '/';
+ $request->base = '/';
+
+ $Controller = new Controller($request, $this->getMock('CakeResponse', array('_sendHeader')));
+ $Controller->flash('this should work', '/flash');
+ $result = $Controller->response->body();
+
+ $expected = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>this should work</title>
+ <style><!--
+ P { text-align:center; font:bold 1.1em sans-serif }
+ A { color:#444; text-decoration:none }
+ A:HOVER { text-decoration: underline; color:#44E }
+ --></style>
+ </head>
+ <body>
+ <p><a href="/flash">this should work</a></p>
+ </body>
+ </html>';
+ $result = str_replace(array("\t", "\r\n", "\n"), "", $result);
+ $expected = str_replace(array("\t", "\r\n", "\n"), "", $expected);
+ $this->assertEquals($expected, $result);
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $Controller = new Controller($request);
+ $Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $Controller->flash('this should work', '/flash', 1, 'ajax2');
+ $result = $Controller->response->body();
+ $this->assertRegExp('/Ajax!/', $result);
+ App::build();
+ }
+
+/**
+ * testControllerSet method
+ *
+ * @return void
+ */
+ public function testControllerSet() {
+ $request = new CakeRequest('controller_posts/index');
+ $Controller = new Controller($request);
+
+ $Controller->set('variable_with_underscores', null);
+ $this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
+
+ $Controller->viewVars = array();
+ $viewVars = array('ModelName' => array('id' => 1, 'name' => 'value'));
+ $Controller->set($viewVars);
+ $this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
+
+ $Controller->viewVars = array();
+ $Controller->set('variable_with_underscores', 'value');
+ $this->assertTrue(array_key_exists('variable_with_underscores', $Controller->viewVars));
+
+ $Controller->viewVars = array();
+ $viewVars = array('ModelName' => 'name');
+ $Controller->set($viewVars);
+ $this->assertTrue(array_key_exists('ModelName', $Controller->viewVars));
+
+ $Controller->set('title', 'someTitle');
+ $this->assertSame($Controller->viewVars['title'], 'someTitle');
+ $this->assertTrue(empty($Controller->pageTitle));
+
+ $Controller->viewVars = array();
+ $expected = array('ModelName' => 'name', 'ModelName2' => 'name2');
+ $Controller->set(array('ModelName', 'ModelName2'), array('name', 'name2'));
+ $this->assertSame($expected, $Controller->viewVars);
+
+ $Controller->viewVars = array();
+ $Controller->set(array(3 => 'three', 4 => 'four'));
+ $Controller->set(array(1 => 'one', 2 => 'two'));
+ $expected = array(3 => 'three', 4 => 'four', 1 => 'one', 2 => 'two');
+ $this->assertEquals($expected, $Controller->viewVars);
+ }
+
+/**
+ * testRender method
+ *
+ * @return void
+ */
+ public function testRender() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), App::RESET);
+ ClassRegistry::flush();
+ $request = new CakeRequest('controller_posts/index');
+ $request->params['action'] = 'index';
+
+ $Controller = new Controller($request, new CakeResponse());
+ $Controller->viewPath = 'Posts';
+
+ $result = $Controller->render('index');
+ $this->assertRegExp('/posts index/', (string)$result);
+
+ $Controller->view = 'index';
+ $result = $Controller->render();
+ $this->assertRegExp('/posts index/', (string)$result);
+
+ $result = $Controller->render('/Elements/test_element');
+ $this->assertRegExp('/this is the test element/', (string)$result);
+ $Controller->view = null;
+
+ $Controller = new TestController($request, new CakeResponse());
+ $Controller->uses = array('ControllerAlias', 'TestPlugin.ControllerComment', 'ControllerPost');
+ $Controller->helpers = array('Html');
+ $Controller->constructClasses();
+ $Controller->ControllerComment->validationErrors = array('title' => 'tooShort');
+ $expected = $Controller->ControllerComment->validationErrors;
+
+ $Controller->viewPath = 'Posts';
+ $result = $Controller->render('index');
+ $View = $Controller->View;
+ $this->assertTrue(isset($View->validationErrors['ControllerComment']));
+ $this->assertEquals($expected, $View->validationErrors['ControllerComment']);
+
+ $expectedModels = array(
+ 'ControllerAlias' => array('plugin' => null, 'className' => 'ControllerAlias'),
+ 'ControllerComment' => array('plugin' => 'TestPlugin', 'className' => 'ControllerComment'),
+ 'ControllerPost' => array('plugin' => null, 'className' => 'ControllerPost')
+ );
+ $this->assertEquals($expectedModels, $Controller->request->params['models']);
+
+ ClassRegistry::flush();
+ App::build();
+ }
+
+/**
+ * test that a component beforeRender can change the controller view class.
+ *
+ * @return void
+ */
+ public function testComponentBeforeRenderChangingViewClass() {
+ App::build(array(
+ 'View' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
+ )
+ ), true);
+ $Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
+ $Controller->uses = array();
+ $Controller->components = array('Test');
+ $Controller->constructClasses();
+ $Controller->Test->viewclass = 'Theme';
+ $Controller->viewPath = 'Posts';
+ $Controller->theme = 'TestTheme';
+ $result = $Controller->render('index');
+ $this->assertRegExp('/default test_theme layout/', (string)$result);
+ App::build();
+ }
+
+/**
+ * test that a component beforeRender can change the controller view class.
+ *
+ * @return void
+ */
+ public function testComponentCancelRender() {
+ $Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
+ $Controller->uses = array();
+ $Controller->components = array('Test2');
+ $Controller->constructClasses();
+ $result = $Controller->render('index');
+ $this->assertInstanceOf('CakeResponse', $result);
+ }
+
+/**
+ * testToBeInheritedGuardmethods method
+ *
+ * @return void
+ */
+ public function testToBeInheritedGuardmethods() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $Controller = new Controller($request, $this->getMock('CakeResponse'));
+ $this->assertTrue($Controller->beforeScaffold(''));
+ $this->assertTrue($Controller->afterScaffoldSave(''));
+ $this->assertTrue($Controller->afterScaffoldSaveError(''));
+ $this->assertFalse($Controller->scaffoldError(''));
+ }
+
+/**
+ * Generates status codes for redirect test.
+ *
+ * @return void
+ */
+ public static function statusCodeProvider() {
+ return array(
+ array(300, "Multiple Choices"),
+ array(301, "Moved Permanently"),
+ array(302, "Found"),
+ array(303, "See Other"),
+ array(304, "Not Modified"),
+ array(305, "Use Proxy"),
+ array(307, "Temporary Redirect"),
+ array(403, "Forbidden"),
+ );
+ }
+
+/**
+ * testRedirect method
+ *
+ * @dataProvider statusCodeProvider
+ * @return void
+ */
+ public function testRedirectByCode($code, $msg) {
+ $Controller = new Controller(null);
+ $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
+
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->response->expects($this->once())->method('statusCode')
+ ->with($code);
+ $Controller->response->expects($this->once())->method('header')
+ ->with('Location', 'http://cakephp.org');
+
+ $Controller->redirect('http://cakephp.org', (int)$code, false);
+ $this->assertFalse($Controller->autoRender);
+ }
+
+/**
+ * test redirecting by message
+ *
+ * @dataProvider statusCodeProvider
+ * @return void
+ */
+ public function testRedirectByMessage($code, $msg) {
+ $Controller = new Controller(null);
+ $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
+
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->response->expects($this->once())->method('statusCode')
+ ->with($code);
+
+ $Controller->response->expects($this->once())->method('header')
+ ->with('Location', 'http://cakephp.org');
+
+ $Controller->redirect('http://cakephp.org', $msg, false);
+ $this->assertFalse($Controller->autoRender);
+ }
+
+/**
+ * test that redirect triggers methods on the components.
+ *
+ * @return void
+ */
+ public function testRedirectTriggeringComponentsReturnNull() {
+ $Controller = new Controller(null);
+ $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->Components->expects($this->once())->method('trigger')
+ ->will($this->returnValue(null));
+
+ $Controller->response->expects($this->once())->method('statusCode')
+ ->with(301);
+
+ $Controller->response->expects($this->once())->method('header')
+ ->with('Location', 'http://cakephp.org');
+
+ $Controller->redirect('http://cakephp.org', 301, false);
+ }
+
+/**
+ * test that beforeRedirect callback returning null doesn't affect things.
+ *
+ * @return void
+ */
+ public function testRedirectBeforeRedirectModifyingParams() {
+ $Controller = new Controller(null);
+ $Controller->response = $this->getMock('CakeResponse', array('header', 'statusCode'));
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->Components->expects($this->once())->method('trigger')
+ ->will($this->returnValue(array('http://book.cakephp.org')));
+
+ $Controller->response->expects($this->once())->method('statusCode')
+ ->with(301);
+
+ $Controller->response->expects($this->once())->method('header')
+ ->with('Location', 'http://book.cakephp.org');
+
+ $Controller->redirect('http://cakephp.org', 301, false);
+ }
+
+/**
+ * test that beforeRedirect callback returning null doesn't affect things.
+ *
+ * @return void
+ */
+ public function testRedirectBeforeRedirectModifyingParamsArrayReturn() {
+ $Controller = $this->getMock('Controller', array('header', '_stop'));
+ $Controller->response = $this->getMock('CakeResponse');
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $return = array(
+ array(
+ 'url' => 'http://example.com/test/1',
+ 'exit' => false,
+ 'status' => 302
+ ),
+ array(
+ 'url' => 'http://example.com/test/2',
+ ),
+ );
+ $Controller->Components->expects($this->once())->method('trigger')
+ ->will($this->returnValue($return));
+
+ $Controller->response->expects($this->once())->method('header')
+ ->with('Location', 'http://example.com/test/2');
+
+ $Controller->response->expects($this->at(1))->method('statusCode')
+ ->with(302);
+
+ $Controller->expects($this->never())->method('_stop');
+ $Controller->redirect('http://cakephp.org', 301);
+ }
+
+/**
+ * test that beforeRedirect callback returning false in controller
+ *
+ * @return void
+ */
+ public function testRedirectBeforeRedirectInController() {
+ $Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
+ $Controller->response = $this->getMock('CakeResponse', array('header'));
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->expects($this->once())->method('beforeRedirect')
+ ->with('http://cakephp.org')
+ ->will($this->returnValue(false));
+ $Controller->response->expects($this->never())->method('header');
+ $Controller->expects($this->never())->method('_stop');
+ $Controller->redirect('http://cakephp.org');
+ }
+
+/**
+ * Test that beforeRedirect works with returning an array from the controller method.
+ *
+ * @return void
+ */
+ public function testRedirectBeforeRedirectInControllerWithArray() {
+ $Controller = $this->getMock('Controller', array('_stop', 'beforeRedirect'));
+ $Controller->response = $this->getMock('CakeResponse', array('header'));
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->expects($this->once())
+ ->method('beforeRedirect')
+ ->with('http://cakephp.org', null, true)
+ ->will($this->returnValue(array(
+ 'url' => 'http://example.org',
+ 'status' => 302,
+ 'exit' => true
+ )));
+
+ $Controller->response->expects($this->at(0))
+ ->method('header')
+ ->with('Location', 'http://example.org');
+
+ $Controller->expects($this->once())->method('_stop');
+ $Controller->redirect('http://cakephp.org');
+ }
+
+/**
+ * testMergeVars method
+ *
+ * @return void
+ */
+ public function testMergeVars() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $TestController = new TestController($request);
+ $TestController->constructClasses();
+
+ $testVars = get_class_vars('TestController');
+ $appVars = get_class_vars('ControllerTestAppController');
+
+ $components = is_array($appVars['components'])
+ ? array_merge($appVars['components'], $testVars['components'])
+ : $testVars['components'];
+ if (!in_array('Session', $components)) {
+ $components[] = 'Session';
+ }
+ $helpers = is_array($appVars['helpers'])
+ ? array_merge($appVars['helpers'], $testVars['helpers'])
+ : $testVars['helpers'];
+ $uses = is_array($appVars['uses'])
+ ? array_merge($appVars['uses'], $testVars['uses'])
+ : $testVars['uses'];
+
+ $this->assertEquals(0, count(array_diff_key($TestController->helpers, array_flip($helpers))));
+ $this->assertEquals(0, count(array_diff($TestController->uses, $uses)));
+ $this->assertEquals(count(array_diff_assoc(Hash::normalize($TestController->components), Hash::normalize($components))), 0);
+
+ $expected = array('ControllerComment', 'ControllerAlias', 'ControllerPost');
+ $this->assertEquals($expected, $TestController->uses, '$uses was merged incorrectly, ControllerTestAppController models should be last.');
+
+ $TestController = new AnotherTestController($request);
+ $TestController->constructClasses();
+
+ $appVars = get_class_vars('ControllerTestAppController');
+ $testVars = get_class_vars('AnotherTestController');
+
+ $this->assertTrue(in_array('ControllerPost', $appVars['uses']));
+ $this->assertFalse($testVars['uses']);
+
+ $this->assertFalse(property_exists($TestController, 'ControllerPost'));
+
+ $TestController = new ControllerCommentsController($request);
+ $TestController->constructClasses();
+
+ $appVars = get_class_vars('ControllerTestAppController');
+ $testVars = get_class_vars('ControllerCommentsController');
+
+ $this->assertTrue(in_array('ControllerPost', $appVars['uses']));
+ $this->assertEquals(array('ControllerPost'), $testVars['uses']);
+
+ $this->assertTrue(isset($TestController->ControllerPost));
+ $this->assertTrue(isset($TestController->ControllerComment));
+ }
+
+/**
+ * test that options from child classes replace those in the parent classes.
+ *
+ * @return void
+ */
+ public function testChildComponentOptionsSupercedeParents() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $TestController = new TestController($request);
+
+ $expected = array('foo');
+ $TestController->components = array('Cookie' => $expected);
+ $TestController->constructClasses();
+ $this->assertEquals($expected, $TestController->components['Cookie']);
+ }
+
+/**
+ * Ensure that _mergeControllerVars is not being greedy and merging with
+ * ControllerTestAppController when you make an instance of Controller
+ *
+ * @return void
+ */
+ public function testMergeVarsNotGreedy() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $Controller = new Controller($request);
+ $Controller->components = array();
+ $Controller->uses = array();
+ $Controller->constructClasses();
+
+ $this->assertFalse(isset($Controller->Session));
+ }
+
+/**
+ * testReferer method
+ *
+ * @return void
+ */
+ public function testReferer() {
+ $request = $this->getMock('CakeRequest');
+
+ $request->expects($this->any())->method('referer')
+ ->with(true)
+ ->will($this->returnValue('/posts/index'));
+
+ $Controller = new Controller($request);
+ $result = $Controller->referer(null, true);
+ $this->assertEquals('/posts/index', $result);
+
+ $Controller = new Controller($request);
+ $request->setReturnValue('referer', '/', array(true));
+ $result = $Controller->referer(array('controller' => 'posts', 'action' => 'index'), true);
+ $this->assertEquals('/posts/index', $result);
+
+ $request = $this->getMock('CakeRequest');
+
+ $request->expects($this->any())->method('referer')
+ ->with(false)
+ ->will($this->returnValue('http://localhost/posts/index'));
+
+ $Controller = new Controller($request);
+ $result = $Controller->referer();
+ $this->assertEquals('http://localhost/posts/index', $result);
+
+ $Controller = new Controller(null);
+ $result = $Controller->referer();
+ $this->assertEquals('/', $result);
+ }
+
+/**
+ * testSetAction method
+ *
+ * @return void
+ */
+ public function testSetAction() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $TestController = new TestController($request);
+ $TestController->setAction('view', 1, 2);
+ $expected = array('testId' => 1, 'test2Id' => 2);
+ $this->assertSame($expected, $TestController->request->data);
+ $this->assertSame('view', $TestController->request->params['action']);
+ $this->assertSame('view', $TestController->view);
+ }
+
+/**
+ * testValidateErrors method
+ *
+ * @return void
+ */
+ public function testValidateErrors() {
+ ClassRegistry::flush();
+ $request = new CakeRequest('controller_posts/index');
+
+ $TestController = new TestController($request);
+ $TestController->constructClasses();
+ $this->assertFalse($TestController->validateErrors());
+ $this->assertEquals(0, $TestController->validate());
+
+ $TestController->ControllerComment->invalidate('some_field', 'error_message');
+ $TestController->ControllerComment->invalidate('some_field2', 'error_message2');
+
+ $comment = new ControllerComment($request);
+ $comment->set('someVar', 'data');
+ $result = $TestController->validateErrors($comment);
+ $expected = array('some_field' => array('error_message'), 'some_field2' => array('error_message2'));
+ $this->assertSame($expected, $result);
+ $this->assertEquals(2, $TestController->validate($comment));
+ }
+
+/**
+ * test that validateErrors works with any old model.
+ *
+ * @return void
+ */
+ public function testValidateErrorsOnArbitraryModels() {
+ $TestController = new TestController();
+
+ $Post = new ControllerPost();
+ $Post->validate = array('title' => 'notEmpty');
+ $Post->set('title', '');
+ $result = $TestController->validateErrors($Post);
+
+ $expected = array('title' => array('This field cannot be left blank'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testPostConditions method
+ *
+ * @return void
+ */
+ public function testPostConditions() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $Controller = new Controller($request);
+
+ $data = array(
+ 'Model1' => array('field1' => '23'),
+ 'Model2' => array('field2' => 'string'),
+ 'Model3' => array('field3' => '23'),
+ );
+ $expected = array(
+ 'Model1.field1' => '23',
+ 'Model2.field2' => 'string',
+ 'Model3.field3' => '23',
+ );
+ $result = $Controller->postConditions($data);
+ $this->assertSame($expected, $result);
+
+ $data = array();
+ $Controller->data = array(
+ 'Model1' => array('field1' => '23'),
+ 'Model2' => array('field2' => 'string'),
+ 'Model3' => array('field3' => '23'),
+ );
+ $expected = array(
+ 'Model1.field1' => '23',
+ 'Model2.field2' => 'string',
+ 'Model3.field3' => '23',
+ );
+ $result = $Controller->postConditions($data);
+ $this->assertSame($expected, $result);
+
+ $data = array();
+ $Controller->data = array();
+ $result = $Controller->postConditions($data);
+ $this->assertNull($result);
+
+ $data = array();
+ $Controller->data = array(
+ 'Model1' => array('field1' => '23'),
+ 'Model2' => array('field2' => 'string'),
+ 'Model3' => array('field3' => '23'),
+ );
+ $ops = array(
+ 'Model1.field1' => '>',
+ 'Model2.field2' => 'LIKE',
+ 'Model3.field3' => '<=',
+ );
+ $expected = array(
+ 'Model1.field1 >' => '23',
+ 'Model2.field2 LIKE' => "%string%",
+ 'Model3.field3 <=' => '23',
+ );
+ $result = $Controller->postConditions($data, $ops);
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testControllerHttpCodes method
+ *
+ * @return void
+ */
+ public function testControllerHttpCodes() {
+ $response = $this->getMock('CakeResponse', array('httpCodes'));
+ $Controller = new Controller(null, $response);
+ $Controller->response->expects($this->at(0))->method('httpCodes')->with(null);
+ $Controller->response->expects($this->at(1))->method('httpCodes')->with(100);
+ $Controller->httpCodes();
+ $Controller->httpCodes(100);
+ }
+
+/**
+ * Tests that the startup process calls the correct functions
+ *
+ * @return void
+ */
+ public function testStartupProcess() {
+ $Controller = $this->getMock('Controller', array('getEventManager'));
+
+ $eventManager = $this->getMock('CakeEventManager');
+ $eventManager->expects($this->at(0))->method('dispatch')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'Controller.initialize'),
+ $this->attributeEqualTo('_subject', $Controller)
+ )
+ );
+ $eventManager->expects($this->at(1))->method('dispatch')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'Controller.startup'),
+ $this->attributeEqualTo('_subject', $Controller)
+ )
+ );
+ $Controller->expects($this->exactly(2))->method('getEventManager')
+ ->will($this->returnValue($eventManager));
+ $Controller->startupProcess();
+ }
+
+/**
+ * Tests that the shutdown process calls the correct functions
+ *
+ * @return void
+ */
+ public function testStartupProcessIndirect() {
+ $Controller = $this->getMock('Controller', array('beforeFilter'));
+
+ $Controller->components = array('MockShutdown');
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->expects($this->once())->method('beforeFilter');
+ $Controller->Components->expects($this->exactly(2))->method('trigger')->with($this->isInstanceOf('CakeEvent'));
+
+ $Controller->startupProcess();
+ }
+
+/**
+ * Tests that the shutdown process calls the correct functions
+ *
+ * @return void
+ */
+ public function testShutdownProcess() {
+ $Controller = $this->getMock('Controller', array('getEventManager'));
+
+ $eventManager = $this->getMock('CakeEventManager');
+ $eventManager->expects($this->once())->method('dispatch')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'Controller.shutdown'),
+ $this->attributeEqualTo('_subject', $Controller)
+ )
+ );
+ $Controller->expects($this->once())->method('getEventManager')
+ ->will($this->returnValue($eventManager));
+ $Controller->shutdownProcess();
+ }
+
+/**
+ * Tests that the shutdown process calls the correct functions
+ *
+ * @return void
+ */
+ public function testShutdownProcessIndirect() {
+ $Controller = $this->getMock('Controller', array('afterFilter'));
+
+ $Controller->components = array('MockShutdown');
+ $Controller->Components = $this->getMock('ComponentCollection', array('trigger'));
+
+ $Controller->expects($this->once())->method('afterFilter');
+ $Controller->Components->expects($this->exactly(1))->method('trigger')->with($this->isInstanceOf('CakeEvent'));
+
+ $Controller->shutdownProcess();
+ }
+
+/**
+ * test that BC works for attributes on the request object.
+ *
+ * @return void
+ */
+ public function testPropertyBackwardsCompatibility() {
+ $request = new CakeRequest('posts/index', null);
+ $request->addParams(array('controller' => 'posts', 'action' => 'index'));
+ $request->data = array('Post' => array('id' => 1));
+ $request->here = '/posts/index';
+ $request->webroot = '/';
+
+ $Controller = new TestController($request);
+ $this->assertEquals($request->data, $Controller->data);
+ $this->assertEquals($request->webroot, $Controller->webroot);
+ $this->assertEquals($request->here, $Controller->here);
+ $this->assertEquals($request->action, $Controller->action);
+
+ $this->assertFalse(empty($Controller->data));
+ $this->assertTrue(isset($Controller->data));
+ $this->assertTrue(empty($Controller->something));
+ $this->assertFalse(isset($Controller->something));
+
+ $this->assertEquals($request, $Controller->params);
+ $this->assertEquals($request->params['controller'], $Controller->params['controller']);
+ }
+
+/**
+ * test that the BC wrapper doesn't interfere with models and components.
+ *
+ * @return void
+ */
+ public function testPropertyCompatibilityAndModelsComponents() {
+ $request = new CakeRequest('controller_posts/index');
+
+ $Controller = new TestController($request);
+ $Controller->constructClasses();
+ $this->assertInstanceOf('SecurityComponent', $Controller->Security);
+ $this->assertInstanceOf('ControllerComment', $Controller->ControllerComment);
+ }
+
+/**
+ * test that using Controller::paginate() falls back to PaginatorComponent
+ *
+ * @return void
+ */
+ public function testPaginateBackwardsCompatibility() {
+ $request = new CakeRequest('controller_posts/index');
+ $request->params['pass'] = $request->params['named'] = array();
+ $response = $this->getMock('CakeResponse', array('httpCodes'));
+
+ $Controller = new Controller($request, $response);
+ $Controller->uses = array('ControllerPost', 'ControllerComment');
+ $Controller->passedArgs[] = '1';
+ $Controller->params['url'] = array();
+ $Controller->constructClasses();
+ $expected = array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named');
+ $this->assertEquals($expected, $Controller->paginate);
+
+ $results = Hash::extract($Controller->paginate('ControllerPost'), '{n}.ControllerPost.id');
+ $this->assertEquals(array(1, 2, 3), $results);
+
+ $Controller->passedArgs = array();
+ $Controller->paginate = array('limit' => '-1');
+ $this->assertEquals(array('limit' => '-1'), $Controller->paginate);
+ $Controller->paginate('ControllerPost');
+ $this->assertSame($Controller->params['paging']['ControllerPost']['page'], 1);
+ $this->assertSame($Controller->params['paging']['ControllerPost']['pageCount'], 3);
+ $this->assertSame($Controller->params['paging']['ControllerPost']['prevPage'], false);
+ $this->assertSame($Controller->params['paging']['ControllerPost']['nextPage'], true);
+ }
+
+/**
+ * testMissingAction method
+ *
+ * @expectedException MissingActionException
+ * @expectedExceptionMessage Action TestController::missing() could not be found.
+ * @return void
+ */
+ public function testInvokeActionMissingAction() {
+ $url = new CakeRequest('test/missing');
+ $url->addParams(array('controller' => 'test_controller', 'action' => 'missing'));
+ $response = $this->getMock('CakeResponse');
+
+ $Controller = new TestController($url, $response);
+ $Controller->invokeAction($url);
+ }
+
+/**
+ * test invoking private methods.
+ *
+ * @expectedException PrivateActionException
+ * @expectedExceptionMessage Private Action TestController::private_m() is not directly accessible.
+ * @return void
+ */
+ public function testInvokeActionPrivate() {
+ $url = new CakeRequest('test/private_m/');
+ $url->addParams(array('controller' => 'test_controller', 'action' => 'private_m'));
+ $response = $this->getMock('CakeResponse');
+
+ $Controller = new TestController($url, $response);
+ $Controller->invokeAction($url);
+ }
+
+/**
+ * test invoking protected methods.
+ *
+ * @expectedException PrivateActionException
+ * @expectedExceptionMessage Private Action TestController::protected_m() is not directly accessible.
+ * @return void
+ */
+ public function testInvokeActionProtected() {
+ $url = new CakeRequest('test/protected_m/');
+ $url->addParams(array('controller' => 'test_controller', 'action' => 'protected_m'));
+ $response = $this->getMock('CakeResponse');
+
+ $Controller = new TestController($url, $response);
+ $Controller->invokeAction($url);
+ }
+
+/**
+ * test invoking hidden methods.
+ *
+ * @expectedException PrivateActionException
+ * @expectedExceptionMessage Private Action TestController::_hidden() is not directly accessible.
+ * @return void
+ */
+ public function testInvokeActionHidden() {
+ $url = new CakeRequest('test/_hidden/');
+ $url->addParams(array('controller' => 'test_controller', 'action' => '_hidden'));
+ $response = $this->getMock('CakeResponse');
+
+ $Controller = new TestController($url, $response);
+ $Controller->invokeAction($url);
+ }
+
+/**
+ * test invoking controller methods.
+ *
+ * @expectedException PrivateActionException
+ * @expectedExceptionMessage Private Action TestController::redirect() is not directly accessible.
+ * @return void
+ */
+ public function testInvokeActionBaseMethods() {
+ $url = new CakeRequest('test/redirect/');
+ $url->addParams(array('controller' => 'test_controller', 'action' => 'redirect'));
+ $response = $this->getMock('CakeResponse');
+
+ $Controller = new TestController($url, $response);
+ $Controller->invokeAction($url);
+ }
+
+/**
+ * test invoking controller methods.
+ *
+ * @expectedException PrivateActionException
+ * @expectedExceptionMessage Private Action TestController::admin_add() is not directly accessible.
+ * @return void
+ */
+ public function testInvokeActionPrefixProtection() {
+ Router::reload();
+ Router::connect('/admin/:controller/:action/*', array('prefix' => 'admin'));
+
+ $url = new CakeRequest('test/admin_add/');
+ $url->addParams(array('controller' => 'test_controller', 'action' => 'admin_add'));
+ $response = $this->getMock('CakeResponse');
+
+ $Controller = new TestController($url, $response);
+ $Controller->invokeAction($url);
+ }
+
+/**
+ * test invoking controller methods.
+ *
+ * @return void
+ */
+ public function testInvokeActionReturnValue() {
+ $url = new CakeRequest('test/returner/');
+ $url->addParams(array(
+ 'controller' => 'test_controller',
+ 'action' => 'returner',
+ 'pass' => array()
+ ));
+ $response = $this->getMock('CakeResponse');
+
+ $Controller = new TestController($url, $response);
+ $result = $Controller->invokeAction($url);
+ $this->assertEquals('I am from the controller.', $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/PagesControllerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/PagesControllerTest.php
new file mode 100644
index 0000000..614edea
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/PagesControllerTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * PagesControllerTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller
+ * @since CakePHP(tm) v 1.2.0.5436
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('PagesController', 'Controller');
+
+/**
+ * PagesControllerTest class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class PagesControllerTest extends CakeTestCase {
+
+/**
+ * testDisplay method
+ *
+ * @return void
+ */
+ public function testDisplay() {
+ App::build(array(
+ 'View' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
+ )
+ ));
+ $Pages = new PagesController(new CakeRequest(null, false), new CakeResponse());
+
+ $Pages->viewPath = 'Posts';
+ $Pages->display('index');
+ $this->assertRegExp('/posts index/', $Pages->response->body());
+ $this->assertEquals('index', $Pages->viewVars['page']);
+
+ $Pages->viewPath = 'Themed';
+ $Pages->display('TestTheme', 'Posts', 'index');
+ $this->assertRegExp('/posts index themed view/', $Pages->response->body());
+ $this->assertEquals('TestTheme', $Pages->viewVars['page']);
+ $this->assertEquals('Posts', $Pages->viewVars['subpage']);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ScaffoldTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ScaffoldTest.php
new file mode 100644
index 0000000..14fe182
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Controller/ScaffoldTest.php
@@ -0,0 +1,350 @@
+<?php
+/**
+ * ScaffoldTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller
+ * @since CakePHP(tm) v 1.2.0.5436
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Router', 'Routing');
+App::uses('Controller', 'Controller');
+App::uses('Scaffold', 'Controller');
+App::uses('ScaffoldView', 'View');
+App::uses('AppModel', 'Model');
+
+require_once dirname(dirname(__FILE__)) . DS . 'Model' . DS . 'models.php';
+
+/**
+ * ScaffoldMockController class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldMockController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'ScaffoldMock'
+ */
+ public $name = 'ScaffoldMock';
+
+/**
+ * scaffold property
+ *
+ * @var mixed
+ */
+ public $scaffold;
+}
+
+/**
+ * ScaffoldMockControllerWithFields class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldMockControllerWithFields extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'ScaffoldMock'
+ */
+ public $name = 'ScaffoldMock';
+
+/**
+ * scaffold property
+ *
+ * @var mixed
+ */
+ public $scaffold;
+
+/**
+ * function beforeScaffold
+ *
+ * @param string method
+ */
+ public function beforeScaffold($method) {
+ $this->set('scaffoldFields', array('title'));
+ return true;
+ }
+
+}
+
+/**
+ * TestScaffoldMock class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class TestScaffoldMock extends Scaffold {
+
+/**
+ * Overload _scaffold
+ *
+ * @param unknown_type $params
+ */
+ protected function _scaffold(CakeRequest $request) {
+ $this->_params = $request;
+ }
+
+/**
+ * Get Params from the Controller.
+ *
+ * @return unknown
+ */
+ public function getParams() {
+ return $this->_params;
+ }
+
+}
+
+/**
+ * Scaffold Test class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldTest extends CakeTestCase {
+
+/**
+ * Controller property
+ *
+ * @var SecurityTestController
+ */
+ public $Controller;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.article', 'core.user', 'core.comment', 'core.join_thing', 'core.tag');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $request = new CakeRequest(null, false);
+ $this->Controller = new ScaffoldMockController($request);
+ $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Controller);
+ }
+
+/**
+ * Test the correct Generation of Scaffold Params.
+ * This ensures that the correct action and view will be generated
+ *
+ * @return void
+ */
+ public function testScaffoldParams() {
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'admin/scaffold_mock/edit'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'admin_edit',
+ 'admin' => true,
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/admin/scaffold_mock/edit';
+ $this->Controller->request->addParams($params);
+
+ //set router.
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->constructClasses();
+ $Scaffold = new TestScaffoldMock($this->Controller, $this->Controller->request);
+ $result = $Scaffold->getParams();
+ $this->assertEquals('admin_edit', $result['action']);
+ }
+
+/**
+ * test that the proper names and variable values are set by Scaffold
+ *
+ * @return void
+ */
+ public function testScaffoldVariableSetting() {
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'admin/scaffold_mock/edit'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'admin_edit',
+ 'admin' => true,
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/admin/scaffold_mock/edit';
+ $this->Controller->request->addParams($params);
+
+ //set router.
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->constructClasses();
+ $Scaffold = new TestScaffoldMock($this->Controller, $this->Controller->request);
+ $result = $Scaffold->controller->viewVars;
+
+ $this->assertEquals('Scaffold :: Admin Edit :: Scaffold Mock', $result['title_for_layout']);
+ $this->assertEquals('Scaffold Mock', $result['singularHumanName']);
+ $this->assertEquals('Scaffold Mock', $result['pluralHumanName']);
+ $this->assertEquals('ScaffoldMock', $result['modelClass']);
+ $this->assertEquals('id', $result['primaryKey']);
+ $this->assertEquals('title', $result['displayField']);
+ $this->assertEquals('scaffoldMock', $result['singularVar']);
+ $this->assertEquals('scaffoldMock', $result['pluralVar']);
+ $this->assertEquals(array('id', 'user_id', 'title', 'body', 'published', 'created', 'updated'), $result['scaffoldFields']);
+ }
+
+/**
+ * test that Scaffold overrides the view property even if its set to 'Theme'
+ *
+ * @return void
+ */
+ public function testScaffoldChangingViewProperty() {
+ $this->Controller->action = 'edit';
+ $this->Controller->theme = 'TestTheme';
+ $this->Controller->viewClass = 'Theme';
+ $this->Controller->constructClasses();
+ $Scaffold = new TestScaffoldMock($this->Controller, $this->Controller->request);
+
+ $this->assertEquals('Scaffold', $this->Controller->viewClass);
+ }
+
+/**
+ * test that scaffold outputs flash messages when sessions are unset.
+ *
+ * @return void
+ */
+ public function testScaffoldFlashMessages() {
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(1),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'scaffold_mock'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'edit',
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/scaffold_mock/edit';
+ $this->Controller->request->addParams($params);
+
+ //set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+ $this->Controller->request->data = array(
+ 'ScaffoldMock' => array(
+ 'id' => 1,
+ 'title' => 'New title',
+ 'body' => 'new body'
+ )
+ );
+ $this->Controller->constructClasses();
+ unset($this->Controller->Session);
+
+ ob_start();
+ new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+ $this->assertRegExp('/Scaffold Mock has been updated/', $result);
+ }
+
+/**
+ * test that habtm relationship keys get added to scaffoldFields.
+ *
+ * @return void
+ */
+ public function testHabtmFieldAdditionWithScaffoldForm() {
+ CakePlugin::unload();
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(1),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'scaffold_mock'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'edit',
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/scaffold_mock/edit';
+ $this->Controller->request->addParams($params);
+
+ //set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->constructClasses();
+ ob_start();
+ $Scaffold = new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+ $this->assertRegExp('/name="data\[ScaffoldTag\]\[ScaffoldTag\]"/', $result);
+
+ $result = $Scaffold->controller->viewVars;
+ $this->assertEquals(array('id', 'user_id', 'title', 'body', 'published', 'created', 'updated', 'ScaffoldTag'), $result['scaffoldFields']);
+ }
+
+/**
+ * test that the proper names and variable values are set by Scaffold
+ *
+ * @return void
+ */
+ public function testEditScaffoldWithScaffoldFields() {
+ $request = new CakeRequest(null, false);
+ $this->Controller = new ScaffoldMockControllerWithFields($request);
+ $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
+
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(1),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'scaffold_mock/edit'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'edit',
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/scaffold_mock/edit';
+ $this->Controller->request->addParams($params);
+
+ //set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->constructClasses();
+ ob_start();
+ new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+
+ $this->assertNotRegExp('/textarea name="data\[ScaffoldMock\]\[body\]" cols="30" rows="6" id="ScaffoldMockBody"/', $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/AppTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/AppTest.php
new file mode 100644
index 0000000..3b6cef5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/AppTest.php
@@ -0,0 +1,851 @@
+<?php
+/**
+ * AppTest file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Core
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AppTest class
+ *
+ * @package Cake.Test.Case.Core
+ */
+class AppTest extends CakeTestCase {
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ }
+
+/**
+ * testBuild method
+ *
+ * @return void
+ */
+ public function testBuild() {
+ $old = App::path('Model');
+ $expected = array(
+ APP . 'Model' . DS
+ );
+ $this->assertEquals($expected, $old);
+
+ App::build(array('Model' => array('/path/to/models/')));
+ $new = App::path('Model');
+ $expected = array(
+ '/path/to/models/',
+ APP . 'Model' . DS
+ );
+ $this->assertEquals($expected, $new);
+
+ App::build();
+ App::build(array('Model' => array('/path/to/models/')), App::PREPEND);
+ $new = App::path('Model');
+ $expected = array(
+ '/path/to/models/',
+ APP . 'Model' . DS
+ );
+ $this->assertEquals($expected, $new);
+
+ App::build();
+ App::build(array('Model' => array('/path/to/models/')), App::APPEND);
+ $new = App::path('Model');
+ $expected = array(
+ APP . 'Model' . DS,
+ '/path/to/models/'
+ );
+ $this->assertEquals($expected, $new);
+
+ App::build();
+ App::build(array(
+ 'Model' => array('/path/to/models/'),
+ 'Controller' => array('/path/to/controllers/'),
+ ), App::APPEND);
+ $new = App::path('Model');
+ $expected = array(
+ APP . 'Model' . DS,
+ '/path/to/models/'
+ );
+ $this->assertEquals($expected, $new);
+ $new = App::path('Controller');
+ $expected = array(
+ APP . 'Controller' . DS,
+ '/path/to/controllers/'
+ );
+ $this->assertEquals($expected, $new);
+
+ App::build(); //reset defaults
+ $defaults = App::path('Model');
+ $this->assertEquals($old, $defaults);
+ }
+
+/**
+ * tests that it is possible to set up paths using the cake 1.3 notation for them (models, behaviors, controllers...)
+ *
+ * @return void
+ */
+ public function testCompatibleBuild() {
+ $old = App::path('models');
+ $expected = array(
+ APP . 'Model' . DS
+ );
+ $this->assertEquals($expected, $old);
+
+ App::build(array('models' => array('/path/to/models/')));
+
+ $new = App::path('models');
+
+ $expected = array(
+ '/path/to/models/',
+ APP . 'Model' . DS
+ );
+ $this->assertEquals($expected, $new);
+ $this->assertEquals($expected, App::path('Model'));
+
+ App::build(array('datasources' => array('/path/to/datasources/')));
+ $expected = array(
+ '/path/to/datasources/',
+ APP . 'Model' . DS . 'Datasource' . DS
+ );
+ $result = App::path('datasources');
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($expected, App::path('Model/Datasource'));
+
+ App::build(array('behaviors' => array('/path/to/behaviors/')));
+ $expected = array(
+ '/path/to/behaviors/',
+ APP . 'Model' . DS . 'Behavior' . DS
+ );
+ $result = App::path('behaviors');
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($expected, App::path('Model/Behavior'));
+
+ App::build(array('controllers' => array('/path/to/controllers/')));
+ $expected = array(
+ '/path/to/controllers/',
+ APP . 'Controller' . DS
+ );
+ $result = App::path('controllers');
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($expected, App::path('Controller'));
+
+ App::build(array('components' => array('/path/to/components/')));
+ $expected = array(
+ '/path/to/components/',
+ APP . 'Controller' . DS . 'Component' . DS
+ );
+ $result = App::path('components');
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($expected, App::path('Controller/Component'));
+
+ App::build(array('views' => array('/path/to/views/')));
+ $expected = array(
+ '/path/to/views/',
+ APP . 'View' . DS
+ );
+ $result = App::path('views');
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($expected, App::path('View'));
+
+ App::build(array('helpers' => array('/path/to/helpers/')));
+ $expected = array(
+ '/path/to/helpers/',
+ APP . 'View' . DS . 'Helper' . DS
+ );
+ $result = App::path('helpers');
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($expected, App::path('View/Helper'));
+
+ App::build(array('shells' => array('/path/to/shells/')));
+ $expected = array(
+ '/path/to/shells/',
+ APP . 'Console' . DS . 'Command' . DS
+ );
+ $result = App::path('shells');
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($expected, App::path('Console/Command'));
+
+ App::build(); //reset defaults
+ $defaults = App::path('Model');
+ $this->assertEquals($old, $defaults);
+ }
+
+/**
+ * test package build() with App::REGISTER.
+ *
+ * @return void
+ */
+ public function testBuildPackage() {
+ $pluginPaths = array(
+ '/foo/bar',
+ APP . 'Plugin' . DS,
+ dirname(dirname(CAKE)) . DS . 'plugins' . DS
+ );
+ App::build(array(
+ 'Plugin' => array(
+ '/foo/bar'
+ )
+ ));
+ $result = App::path('Plugin');
+ $this->assertEquals($pluginPaths, $result);
+
+ $paths = App::path('Service');
+ $this->assertEquals(array(), $paths);
+
+ App::build(array(
+ 'Service' => array(
+ '%s' . 'Service' . DS,
+ ),
+ ), App::REGISTER);
+
+ $expected = array(
+ APP . 'Service' . DS,
+ );
+ $result = App::path('Service');
+ $this->assertEquals($expected, $result);
+
+ //Ensure new paths registered for other packages are not affected
+ $result = App::path('Plugin');
+ $this->assertEquals($pluginPaths, $result);
+
+ App::build();
+ $paths = App::path('Service');
+ $this->assertEquals(array(), $paths);
+ }
+
+/**
+ * test path() with a plugin.
+ *
+ * @return void
+ */
+ public function testPathWithPlugins() {
+ $basepath = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS;
+ App::build(array(
+ 'Plugin' => array($basepath),
+ ));
+ CakePlugin::load('TestPlugin');
+
+ $result = App::path('Vendor', 'TestPlugin');
+ $this->assertEquals($basepath . 'TestPlugin' . DS . 'Vendor' . DS, $result[0]);
+ }
+
+/**
+ * testBuildWithReset method
+ *
+ * @return void
+ */
+ public function testBuildWithReset() {
+ $old = App::path('Model');
+ $expected = array(
+ APP . 'Model' . DS
+ );
+ $this->assertEquals($expected, $old);
+
+ App::build(array('Model' => array('/path/to/models/')), App::RESET);
+
+ $new = App::path('Model');
+
+ $expected = array(
+ '/path/to/models/'
+ );
+ $this->assertEquals($expected, $new);
+
+ App::build(); //reset defaults
+ $defaults = App::path('Model');
+ $this->assertEquals($old, $defaults);
+ }
+
+/**
+ * testCore method
+ *
+ * @return void
+ */
+ public function testCore() {
+ $model = App::core('Model');
+ $this->assertEquals(array(CAKE . 'Model' . DS), $model);
+
+ $view = App::core('View');
+ $this->assertEquals(array(CAKE . 'View' . DS), $view);
+
+ $controller = App::core('Controller');
+ $this->assertEquals(array(CAKE . 'Controller' . DS), $controller);
+
+ $component = App::core('Controller/Component');
+ $this->assertEquals(array(CAKE . 'Controller' . DS . 'Component' . DS), str_replace('/', DS, $component));
+
+ $auth = App::core('Controller/Component/Auth');
+ $this->assertEquals(array(CAKE . 'Controller' . DS . 'Component' . DS . 'Auth' . DS), str_replace('/', DS, $auth));
+
+ $datasource = App::core('Model/Datasource');
+ $this->assertEquals(array(CAKE . 'Model' . DS . 'Datasource' . DS), str_replace('/', DS, $datasource));
+ }
+
+/**
+ * testListObjects method
+ *
+ * @return void
+ */
+ public function testListObjects() {
+ $result = App::objects('class', CAKE . 'Routing', false);
+ $this->assertTrue(in_array('Dispatcher', $result));
+ $this->assertTrue(in_array('Router', $result));
+
+ App::build(array(
+ 'Model/Behavior' => App::core('Model/Behavior'),
+ 'Controller' => App::core('Controller'),
+ 'Controller/Component' => App::core('Controller/Component'),
+ 'View' => App::core('View'),
+ 'Model' => App::core('Model'),
+ 'View/Helper' => App::core('View/Helper'),
+ ), App::RESET);
+ $result = App::objects('behavior', null, false);
+ $this->assertTrue(in_array('TreeBehavior', $result));
+ $result = App::objects('Model/Behavior', null, false);
+ $this->assertTrue(in_array('TreeBehavior', $result));
+
+ $result = App::objects('component', null, false);
+ $this->assertTrue(in_array('AuthComponent', $result));
+ $result = App::objects('Controller/Component', null, false);
+ $this->assertTrue(in_array('AuthComponent', $result));
+
+ $result = App::objects('view', null, false);
+ $this->assertTrue(in_array('MediaView', $result));
+ $result = App::objects('View', null, false);
+ $this->assertTrue(in_array('MediaView', $result));
+
+ $result = App::objects('helper', null, false);
+ $this->assertTrue(in_array('HtmlHelper', $result));
+ $result = App::objects('View/Helper', null, false);
+ $this->assertTrue(in_array('HtmlHelper', $result));
+
+ $result = App::objects('model', null, false);
+ $this->assertTrue(in_array('AcoAction', $result));
+ $result = App::objects('Model', null, false);
+ $this->assertTrue(in_array('AcoAction', $result));
+
+ $result = App::objects('file');
+ $this->assertFalse($result);
+
+ $result = App::objects('file', 'non_existing_configure');
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = App::objects('NonExistingType');
+ $this->assertEquals(array(), $result);
+
+ App::build(array(
+ 'plugins' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS
+ )
+ ));
+ $result = App::objects('plugin', null, false);
+ $this->assertTrue(in_array('Cache', $result));
+ $this->assertTrue(in_array('Log', $result));
+
+ App::build();
+ }
+
+/**
+ * Make sure that .svn and friends are excluded from App::objects('plugin')
+ */
+ public function testListObjectsIgnoreDotDirectories() {
+ $path = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS;
+
+ $this->skipIf(!is_writable($path), $path . ' is not writable.');
+
+ App::build(array(
+ 'plugins' => array($path)
+ ), App::RESET);
+ mkdir($path . '.svn');
+ $result = App::objects('plugin', null, false);
+ rmdir($path . '.svn');
+
+ $this->assertNotContains('.svn', $result);
+ }
+
+/**
+ * Tests listing objects within a plugin
+ *
+ * @return void
+ */
+ public function testListObjectsInPlugin() {
+ App::build(array(
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS),
+ 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ $result = App::objects('TestPlugin.model');
+ $this->assertTrue(in_array('TestPluginPost', $result));
+ $result = App::objects('TestPlugin.Model');
+ $this->assertTrue(in_array('TestPluginPost', $result));
+
+ $result = App::objects('TestPlugin.behavior');
+ $this->assertTrue(in_array('TestPluginPersisterOneBehavior', $result));
+ $result = App::objects('TestPlugin.Model/Behavior');
+ $this->assertTrue(in_array('TestPluginPersisterOneBehavior', $result));
+
+ $result = App::objects('TestPlugin.helper');
+ $expected = array('OtherHelperHelper', 'PluggedHelperHelper', 'TestPluginAppHelper');
+ $this->assertEquals($expected, $result);
+ $result = App::objects('TestPlugin.View/Helper');
+ $expected = array('OtherHelperHelper', 'PluggedHelperHelper', 'TestPluginAppHelper');
+ $this->assertEquals($expected, $result);
+
+ $result = App::objects('TestPlugin.component');
+ $this->assertTrue(in_array('OtherComponent', $result));
+ $result = App::objects('TestPlugin.Controller/Component');
+ $this->assertTrue(in_array('OtherComponent', $result));
+
+ $result = App::objects('TestPluginTwo.behavior');
+ $this->assertEquals(array(), $result);
+ $result = App::objects('TestPluginTwo.Model/Behavior');
+ $this->assertEquals(array(), $result);
+
+ $result = App::objects('model', null, false);
+ $this->assertTrue(in_array('Comment', $result));
+ $this->assertTrue(in_array('Post', $result));
+
+ $result = App::objects('Model', null, false);
+ $this->assertTrue(in_array('Comment', $result));
+ $this->assertTrue(in_array('Post', $result));
+
+ App::build();
+ }
+
+/**
+ * test that pluginPath can find paths for plugins.
+ *
+ * @return void
+ */
+ public function testPluginPath() {
+ App::build(array(
+ 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ $path = App::pluginPath('TestPlugin');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS;
+ $this->assertEquals($expected, $path);
+
+ $path = App::pluginPath('TestPluginTwo');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPluginTwo' . DS;
+ $this->assertEquals($expected, $path);
+ App::build();
+ }
+
+/**
+ * test that themePath can find paths for themes.
+ *
+ * @return void
+ */
+ public function testThemePath() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $path = App::themePath('test_theme');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS;
+ $this->assertEquals($expected, $path);
+
+ $path = App::themePath('TestTheme');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS;
+ $this->assertEquals($expected, $path);
+
+ App::build();
+ }
+
+/**
+ * testClassLoading method
+ *
+ * @return void
+ */
+ public function testClassLoading() {
+ $file = App::import('Model', 'Model', false);
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('Model'));
+
+ $file = App::import('Controller', 'Controller', false);
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('Controller'));
+
+ $file = App::import('Component', 'Auth', false);
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('AuthComponent'));
+
+ $file = App::import('Shell', 'Shell', false);
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('Shell'));
+
+ $file = App::import('Configure', 'PhpReader');
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('PhpReader'));
+
+ $file = App::import('Model', 'SomeRandomModelThatDoesNotExist', false);
+ $this->assertFalse($file);
+
+ $file = App::import('Model', 'AppModel', false);
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('AppModel'));
+
+ $file = App::import('WrongType', null, true, array(), '');
+ $this->assertFalse($file);
+
+ $file = App::import('Model', 'NonExistingPlugin.NonExistingModel', false);
+ $this->assertFalse($file);
+
+ $file = App::import('Model', array('NonExistingPlugin.NonExistingModel'), false);
+ $this->assertFalse($file);
+
+ if (!class_exists('AppController', false)) {
+ $classes = array_flip(get_declared_classes());
+
+ $this->assertFalse(isset($classes['PagesController']));
+ $this->assertFalse(isset($classes['AppController']));
+
+ $file = App::import('Controller', 'Pages');
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('PagesController'));
+
+ $classes = array_flip(get_declared_classes());
+
+ $this->assertTrue(isset($classes['PagesController']));
+ $this->assertTrue(isset($classes['AppController']));
+
+ $file = App::import('Behavior', 'Containable');
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('ContainableBehavior'));
+
+ $file = App::import('Component', 'RequestHandler');
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('RequestHandlerComponent'));
+
+ $file = App::import('Helper', 'Form');
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('FormHelper'));
+
+ $file = App::import('Model', 'NonExistingModel');
+ $this->assertFalse($file);
+
+ $file = App::import('Datasource', 'DboSource');
+ $this->assertTrue($file);
+ $this->assertTrue(class_exists('DboSource'));
+ }
+ App::build();
+ }
+
+/**
+ * test import() with plugins
+ *
+ * @return void
+ */
+ public function testPluginImporting() {
+ App::build(array(
+ 'Lib' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ $result = App::import('Controller', 'TestPlugin.Tests');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('TestPluginAppController'));
+ $this->assertTrue(class_exists('TestsController'));
+
+ $result = App::import('Lib', 'TestPlugin.TestPluginLibrary');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('TestPluginLibrary'));
+
+ $result = App::import('Lib', 'Library');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('Library'));
+
+ $result = App::import('Helper', 'TestPlugin.OtherHelper');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('OtherHelperHelper'));
+
+ $result = App::import('Helper', 'TestPlugin.TestPluginApp');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('TestPluginAppHelper'));
+
+ $result = App::import('Datasource', 'TestPlugin.TestSource');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('TestSource'));
+
+ App::uses('ExampleExample', 'TestPlugin.Vendor/Example');
+ $this->assertTrue(class_exists('ExampleExample'));
+
+ App::build();
+ }
+
+/**
+ * test that building helper paths actually works.
+ *
+ * @return void
+ * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/410
+ */
+ public function testImportingHelpersFromAlternatePaths() {
+ $this->assertFalse(class_exists('BananaHelper', false), 'BananaHelper exists, cannot test importing it.');
+ App::build(array(
+ 'View/Helper' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Helper' . DS
+ )
+ ));
+ $this->assertFalse(class_exists('BananaHelper', false), 'BananaHelper exists, cannot test importing it.');
+ App::import('Helper', 'Banana');
+ $this->assertTrue(class_exists('BananaHelper', false), 'BananaHelper was not loaded.');
+
+ App::build();
+ }
+
+/**
+ * testFileLoading method
+ *
+ * @return void
+ */
+ public function testFileLoading() {
+ $file = App::import('File', 'RealFile', false, array(), CAKE . 'Config' . DS . 'config.php');
+ $this->assertTrue($file);
+
+ $file = App::import('File', 'NoFile', false, array(), CAKE . 'Config' . DS . 'cake' . DS . 'config.php');
+ $this->assertFalse($file);
+ }
+
+/**
+ * testFileLoadingWithArray method
+ *
+ * @return void
+ */
+ public function testFileLoadingWithArray() {
+ $type = array(
+ 'type' => 'File',
+ 'name' => 'SomeName',
+ 'parent' => false,
+ 'file' => CAKE . DS . 'Config' . DS . 'config.php'
+ );
+ $file = App::import($type);
+ $this->assertTrue($file);
+
+ $type = array(
+ 'type' => 'File',
+ 'name' => 'NoFile',
+ 'parent' => false,
+ 'file' => CAKE . 'Config' . DS . 'cake' . DS . 'config.php'
+ );
+ $file = App::import($type);
+ $this->assertFalse($file);
+ }
+
+/**
+ * testFileLoadingReturnValue method
+ *
+ * @return void
+ */
+ public function testFileLoadingReturnValue() {
+ $file = App::import('File', 'Name', false, array(), CAKE . 'Config' . DS . 'config.php', true);
+ $this->assertTrue(!empty($file));
+
+ $this->assertTrue(isset($file['Cake.version']));
+
+ $type = array(
+ 'type' => 'File',
+ 'name' => 'OtherName',
+ 'parent' => false,
+ 'file' => CAKE . 'Config' . DS . 'config.php', 'return' => true
+ );
+ $file = App::import($type);
+ $this->assertTrue(!empty($file));
+
+ $this->assertTrue(isset($file['Cake.version']));
+ }
+
+/**
+ * testLoadingWithSearch method
+ *
+ * @return void
+ */
+ public function testLoadingWithSearch() {
+ $file = App::import('File', 'NewName', false, array(CAKE . 'Config' . DS), 'config.php');
+ $this->assertTrue($file);
+
+ $file = App::import('File', 'AnotherNewName', false, array(CAKE), 'config.php');
+ $this->assertFalse($file);
+ }
+
+/**
+ * testLoadingWithSearchArray method
+ *
+ * @return void
+ */
+ public function testLoadingWithSearchArray() {
+ $type = array(
+ 'type' => 'File',
+ 'name' => 'RandomName',
+ 'parent' => false,
+ 'file' => 'config.php',
+ 'search' => array(CAKE . 'Config' . DS)
+ );
+ $file = App::import($type);
+ $this->assertTrue($file);
+
+ $type = array(
+ 'type' => 'File',
+ 'name' => 'AnotherRandomName',
+ 'parent' => false,
+ 'file' => 'config.php',
+ 'search' => array(CAKE)
+ );
+ $file = App::import($type);
+ $this->assertFalse($file);
+ }
+
+/**
+ * testMultipleLoading method
+ *
+ * @return void
+ */
+ public function testMultipleLoading() {
+ if (class_exists('PersisterOne', false) || class_exists('PersisterTwo', false)) {
+ $this->markTestSkipped('Cannot test loading of classes that exist.');
+ }
+ App::build(array(
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS)
+ ));
+ $toLoad = array('PersisterOne', 'PersisterTwo');
+ $load = App::import('Model', $toLoad);
+ $this->assertTrue($load);
+
+ $classes = array_flip(get_declared_classes());
+
+ $this->assertTrue(isset($classes['PersisterOne']));
+ $this->assertTrue(isset($classes['PersisterTwo']));
+
+ $load = App::import('Model', array('PersisterOne', 'SomeNotFoundClass', 'PersisterTwo'));
+ $this->assertFalse($load);
+ }
+
+ public function testLoadingVendor() {
+ App::build(array(
+ 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'vendors' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS),
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ ob_start();
+ $result = App::import('Vendor', 'css/TestAsset', array('ext' => 'css'));
+ $text = ob_get_clean();
+ $this->assertTrue($result);
+ $this->assertEquals('this is the test asset css file', $text);
+
+ $result = App::import('Vendor', 'TestPlugin.sample/SamplePlugin');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('SamplePluginClassTestName'));
+
+ $result = App::import('Vendor', 'sample/ConfigureTestVendorSample');
+ $this->assertTrue($result);
+ $this->assertTrue(class_exists('ConfigureTestVendorSample'));
+
+ ob_start();
+ $result = App::import('Vendor', 'SomeNameInSubfolder', array('file' => 'somename/some.name.php'));
+ $text = ob_get_clean();
+ $this->assertTrue($result);
+ $this->assertEquals('This is a file with dot in file name', $text);
+
+ ob_start();
+ $result = App::import('Vendor', 'TestHello', array('file' => 'Test' . DS . 'hello.php'));
+ $text = ob_get_clean();
+ $this->assertTrue($result);
+ $this->assertEquals('This is the hello.php file in Test directory', $text);
+
+ ob_start();
+ $result = App::import('Vendor', 'MyTest', array('file' => 'Test' . DS . 'MyTest.php'));
+ $text = ob_get_clean();
+ $this->assertTrue($result);
+ $this->assertEquals('This is the MyTest.php file', $text);
+
+ ob_start();
+ $result = App::import('Vendor', 'Welcome');
+ $text = ob_get_clean();
+ $this->assertTrue($result);
+ $this->assertEquals('This is the welcome.php file in vendors directory', $text);
+
+ ob_start();
+ $result = App::import('Vendor', 'TestPlugin.Welcome');
+ $text = ob_get_clean();
+ $this->assertTrue($result);
+ $this->assertEquals('This is the welcome.php file in test_plugin/vendors directory', $text);
+ }
+
+/**
+ * Tests that the automatic class loader will also find in "libs" folder for both
+ * app and plugins if it does not find the class in other configured paths
+ *
+ */
+ public function testLoadClassInLibs() {
+ App::build(array(
+ 'libs' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS),
+ 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ $this->assertFalse(class_exists('CustomLibClass', false));
+ App::uses('CustomLibClass', 'TestPlugin.Custom/Package');
+ $this->assertTrue(class_exists('CustomLibClass'));
+
+ $this->assertFalse(class_exists('TestUtilityClass', false));
+ App::uses('TestUtilityClass', 'Utility');
+ $this->assertTrue(class_exists('CustomLibClass'));
+ }
+
+/**
+ * Tests that App::location() returns the defined path for a class
+ *
+ * @return void
+ */
+ public function testClassLocation() {
+ App::uses('MyCustomClass', 'MyPackage/Name');
+ $this->assertEquals('MyPackage/Name', App::location('MyCustomClass'));
+ }
+
+/**
+ * Test that paths() works.
+ *
+ * @return void
+ */
+ public function testPaths() {
+ $result = App::paths();
+ $this->assertArrayHasKey('Plugin', $result);
+ $this->assertArrayHasKey('Controller', $result);
+ $this->assertArrayHasKey('Controller/Component', $result);
+ }
+
+/**
+ * Proves that it is possible to load plugin libraries in top
+ * level Lib dir for plugins
+ *
+ * @return void
+ */
+ public function testPluginLibClasses() {
+ App::build(array(
+ 'plugins' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+ $this->assertFalse(class_exists('TestPluginOtherLibrary', false));
+ App::uses('TestPluginOtherLibrary', 'TestPlugin.Lib');
+ $this->assertTrue(class_exists('TestPluginOtherLibrary'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/CakePluginTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/CakePluginTest.php
new file mode 100644
index 0000000..893e671
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/CakePluginTest.php
@@ -0,0 +1,268 @@
+<?php
+/**
+ * CakePluginTest file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Core
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakePlugin', 'Core');
+
+/**
+ * CakePluginTest class
+ *
+ */
+class CakePluginTest extends CakeTestCase {
+
+/**
+ * Sets the plugins folder for this test
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ App::objects('plugins', null, false);
+ }
+
+/**
+ * Reverts the changes done to the environment while testing
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ }
+
+/**
+ * Tests loading a single plugin
+ *
+ * @return void
+ */
+ public function testLoadSingle() {
+ CakePlugin::unload();
+ CakePlugin::load('TestPlugin');
+ $expected = array('TestPlugin');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ }
+
+/**
+ * Tests unloading plugins
+ *
+ * @return void
+ */
+ public function testUnload() {
+ CakePlugin::load('TestPlugin');
+ $expected = array('TestPlugin');
+ $this->assertEquals($expected, CakePlugin::loaded());
+
+ CakePlugin::unload('TestPlugin');
+ $this->assertEquals(array(), CakePlugin::loaded());
+
+ CakePlugin::load('TestPlugin');
+ $expected = array('TestPlugin');
+ $this->assertEquals($expected, CakePlugin::loaded());
+
+ CakePlugin::unload('TestFakePlugin');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ }
+
+/**
+ * Tests loading a plugin and its bootstrap file
+ *
+ * @return void
+ */
+ public function testLoadSingleWithBootstrap() {
+ CakePlugin::load('TestPlugin', array('bootstrap' => true));
+ $this->assertTrue(CakePlugin::loaded('TestPlugin'));
+ $this->assertEquals('loaded plugin bootstrap', Configure::read('CakePluginTest.test_plugin.bootstrap'));
+ }
+
+/**
+ * Tests loading a plugin with bootstrap file and routes file
+ *
+ * @return void
+ */
+ public function testLoadSingleWithBootstrapAndRoutes() {
+ CakePlugin::load('TestPlugin', array('bootstrap' => true, 'routes' => true));
+ $this->assertTrue(CakePlugin::loaded('TestPlugin'));
+ $this->assertEquals('loaded plugin bootstrap', Configure::read('CakePluginTest.test_plugin.bootstrap'));
+
+ CakePlugin::routes();
+ $this->assertEquals('loaded plugin routes', Configure::read('CakePluginTest.test_plugin.routes'));
+ }
+
+/**
+ * Tests loading multiple plugins at once
+ *
+ * @return void
+ */
+ public function testLoadMultiple() {
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+ $expected = array('TestPlugin', 'TestPluginTwo');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ }
+
+/**
+ * Tests loading multiple plugins and their bootstrap files
+ *
+ * @return void
+ */
+ public function testLoadMultipleWithDefaults() {
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'), array('bootstrap' => true, 'routes' => false));
+ $expected = array('TestPlugin', 'TestPluginTwo');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ $this->assertEquals('loaded plugin bootstrap', Configure::read('CakePluginTest.test_plugin.bootstrap'));
+ $this->assertEquals('loaded plugin two bootstrap', Configure::read('CakePluginTest.test_plugin_two.bootstrap'));
+ }
+
+/**
+ * Tests loading multiple plugins with default loading params and some overrides
+ *
+ * @return void
+ */
+ public function testLoadMultipleWithDefaultsAndOverride() {
+ CakePlugin::load(
+ array('TestPlugin', 'TestPluginTwo' => array('routes' => false)),
+ array('bootstrap' => true, 'routes' => true)
+ );
+ $expected = array('TestPlugin', 'TestPluginTwo');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ $this->assertEquals('loaded plugin bootstrap', Configure::read('CakePluginTest.test_plugin.bootstrap'));
+ $this->assertEquals(null, Configure::read('CakePluginTest.test_plugin_two.bootstrap'));
+ }
+
+/**
+ * Tests that it is possible to load multiple bootstrap files at once
+ *
+ * @return void
+ */
+ public function testMultipleBootstrapFiles() {
+ CakePlugin::load('TestPlugin', array('bootstrap' => array('bootstrap', 'custom_config')));
+ $this->assertTrue(CakePlugin::loaded('TestPlugin'));
+ $this->assertEquals('loaded plugin bootstrap', Configure::read('CakePluginTest.test_plugin.bootstrap'));
+ }
+
+/**
+ * Tests that it is possible to load plugin bootstrap by calling a callback function
+ *
+ * @return void
+ */
+ public function testCallbackBootstrap() {
+ CakePlugin::load('TestPlugin', array('bootstrap' => array($this, 'pluginBootstrap')));
+ $this->assertTrue(CakePlugin::loaded('TestPlugin'));
+ $this->assertEquals('called plugin bootstrap callback', Configure::read('CakePluginTest.test_plugin.bootstrap'));
+ }
+
+/**
+ * Tests that loading a missing routes file throws a warning
+ *
+ * @return void
+ * @expectedException PHPUNIT_FRAMEWORK_ERROR_WARNING
+ */
+ public function testLoadMultipleWithDefaultsMissingFile() {
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'), array('bootstrap' => true, 'routes' => true));
+ CakePlugin::routes();
+ }
+
+/**
+ * Tests that CakePlugin::load() throws an exception on unknown plugin
+ *
+ * @return void
+ * @expectedException MissingPluginException
+ */
+ public function testLoadNotFound() {
+ CakePlugin::load('MissingPlugin');
+ }
+
+/**
+ * Tests that CakePlugin::path() returns the correct path for the loaded plugins
+ *
+ * @return void
+ */
+ public function testPath() {
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS;
+ $this->assertEquals(CakePlugin::path('TestPlugin'), $expected);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPluginTwo' . DS;
+ $this->assertEquals(CakePlugin::path('TestPluginTwo'), $expected);
+ }
+
+/**
+ * Tests that CakePlugin::path() throws an exception on unknown plugin
+ *
+ * @return void
+ * @expectedException MissingPluginException
+ */
+ public function testPathNotFound() {
+ CakePlugin::path('TestPlugin');
+ }
+
+/**
+ * Tests that CakePlugin::loadAll() will load all plugins in the configured folder
+ *
+ * @return void
+ */
+ public function testLoadAll() {
+ CakePlugin::loadAll();
+ $expected = array('PluginJs', 'TestPlugin', 'TestPluginTwo');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ }
+
+/**
+ * Tests that CakePlugin::loadAll() will load all plugins in the configured folder with bootstrap loading
+ *
+ * @return void
+ */
+ public function testLoadAllWithDefaults() {
+ $defaults = array('bootstrap' => true);
+ CakePlugin::loadAll(array($defaults));
+ $expected = array('PluginJs', 'TestPlugin', 'TestPluginTwo');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ $this->assertEquals('loaded js plugin bootstrap', Configure::read('CakePluginTest.js_plugin.bootstrap'));
+ $this->assertEquals('loaded plugin bootstrap', Configure::read('CakePluginTest.test_plugin.bootstrap'));
+ $this->assertEquals('loaded plugin two bootstrap', Configure::read('CakePluginTest.test_plugin_two.bootstrap'));
+ }
+
+/**
+ * Tests that CakePlugin::loadAll() will load all plugins in the configured folder wit defaults
+ * and overrides for a plugin
+ *
+ * @return void
+ */
+ public function testLoadAllWithDefaultsAndOverride() {
+ CakePlugin::loadAll(array(array('bootstrap' => true), 'TestPlugin' => array('routes' => true)));
+ CakePlugin::routes();
+
+ $expected = array('PluginJs', 'TestPlugin', 'TestPluginTwo');
+ $this->assertEquals($expected, CakePlugin::loaded());
+ $this->assertEquals('loaded js plugin bootstrap', Configure::read('CakePluginTest.js_plugin.bootstrap'));
+ $this->assertEquals('loaded plugin routes', Configure::read('CakePluginTest.test_plugin.routes'));
+ $this->assertEquals(null, Configure::read('CakePluginTest.test_plugin.bootstrap'));
+ $this->assertEquals('loaded plugin two bootstrap', Configure::read('CakePluginTest.test_plugin_two.bootstrap'));
+ }
+
+/**
+ * Auxiliary function to test plugin bootstrap callbacks
+ *
+ * @return void
+ */
+ public function pluginBootstrap() {
+ Configure::write('CakePluginTest.test_plugin.bootstrap', 'called plugin bootstrap callback');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ConfigureTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ConfigureTest.php
new file mode 100644
index 0000000..7351f83
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ConfigureTest.php
@@ -0,0 +1,408 @@
+<?php
+/**
+ * ConfigureTest file
+ *
+ * Holds several tests
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Core
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('PhpReader', 'Configure');
+
+/**
+ * ConfigureTest
+ *
+ * @package Cake.Test.Case.Core
+ */
+class ConfigureTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Cache.disable', true);
+ App::build();
+ App::objects('plugin', null, true);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ if (file_exists(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_core_paths')) {
+ unlink(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_core_paths');
+ }
+ if (file_exists(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_dir_map')) {
+ unlink(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_dir_map');
+ }
+ if (file_exists(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_file_map')) {
+ unlink(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_file_map');
+ }
+ if (file_exists(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_object_map')) {
+ unlink(TMP . 'cache' . DS . 'persistent' . DS . 'cake_core_object_map');
+ }
+ if (file_exists(TMP . 'cache' . DS . 'persistent' . DS . 'test.config.php')) {
+ unlink(TMP . 'cache' . DS . 'persistent' . DS . 'test.config.php');
+ }
+ if (file_exists(TMP . 'cache' . DS . 'persistent' . DS . 'test.php')) {
+ unlink(TMP . 'cache' . DS . 'persistent' . DS . 'test.php');
+ }
+ Configure::drop('test');
+ }
+
+/**
+ * testRead method
+ *
+ * @return void
+ */
+ public function testRead() {
+ $expected = 'ok';
+ Configure::write('level1.level2.level3_1', $expected);
+ Configure::write('level1.level2.level3_2', 'something_else');
+ $result = Configure::read('level1.level2.level3_1');
+ $this->assertEquals($expected, $result);
+
+ $result = Configure::read('level1.level2.level3_2');
+ $this->assertEquals('something_else', $result);
+
+ $result = Configure::read('debug');
+ $this->assertTrue($result >= 0);
+
+ $result = Configure::read();
+ $this->assertTrue(is_array($result));
+ $this->assertTrue(isset($result['debug']));
+ $this->assertTrue(isset($result['level1']));
+
+ $result = Configure::read('something_I_just_made_up_now');
+ $this->assertEquals(null, $result, 'Missing key should return null.');
+ }
+
+/**
+ * testWrite method
+ *
+ * @return void
+ */
+ public function testWrite() {
+ $writeResult = Configure::write('SomeName.someKey', 'myvalue');
+ $this->assertTrue($writeResult);
+ $result = Configure::read('SomeName.someKey');
+ $this->assertEquals('myvalue', $result);
+
+ $writeResult = Configure::write('SomeName.someKey', null);
+ $this->assertTrue($writeResult);
+ $result = Configure::read('SomeName.someKey');
+ $this->assertEquals(null, $result);
+
+ $expected = array('One' => array('Two' => array('Three' => array('Four' => array('Five' => 'cool')))));
+ $writeResult = Configure::write('Key', $expected);
+ $this->assertTrue($writeResult);
+
+ $result = Configure::read('Key');
+ $this->assertEquals($expected, $result);
+
+ $result = Configure::read('Key.One');
+ $this->assertEquals($expected['One'], $result);
+
+ $result = Configure::read('Key.One.Two');
+ $this->assertEquals($expected['One']['Two'], $result);
+
+ $result = Configure::read('Key.One.Two.Three.Four.Five');
+ $this->assertEquals('cool', $result);
+
+ Configure::write('one.two.three.four', '4');
+ $result = Configure::read('one.two.three.four');
+ $this->assertEquals('4', $result);
+ }
+
+/**
+ * test setting display_errors with debug.
+ *
+ * @return void
+ */
+ public function testDebugSettingDisplayErrors() {
+ Configure::write('debug', 0);
+ $result = ini_get('display_errors');
+ $this->assertEquals(0, $result);
+
+ Configure::write('debug', 2);
+ $result = ini_get('display_errors');
+ $this->assertEquals(1, $result);
+ }
+
+/**
+ * testDelete method
+ *
+ * @return void
+ */
+ public function testDelete() {
+ Configure::write('SomeName.someKey', 'myvalue');
+ $result = Configure::read('SomeName.someKey');
+ $this->assertEquals('myvalue', $result);
+
+ Configure::delete('SomeName.someKey');
+ $result = Configure::read('SomeName.someKey');
+ $this->assertTrue($result === null);
+
+ Configure::write('SomeName', array('someKey' => 'myvalue', 'otherKey' => 'otherValue'));
+
+ $result = Configure::read('SomeName.someKey');
+ $this->assertEquals('myvalue', $result);
+
+ $result = Configure::read('SomeName.otherKey');
+ $this->assertEquals('otherValue', $result);
+
+ Configure::delete('SomeName');
+
+ $result = Configure::read('SomeName.someKey');
+ $this->assertTrue($result === null);
+
+ $result = Configure::read('SomeName.otherKey');
+ $this->assertTrue($result === null);
+ }
+
+/**
+ * testLoad method
+ *
+ * @expectedException RuntimeException
+ * @return void
+ */
+ public function testLoadExceptionOnNonExistantFile() {
+ Configure::config('test', new PhpReader());
+ $result = Configure::load('non_existing_configuration_file', 'test');
+ }
+
+/**
+ * test load method for default config creation
+ *
+ * @return void
+ */
+ public function testLoadDefaultConfig() {
+ try {
+ Configure::load('non_existing_configuration_file');
+ } catch (Exception $e) {
+ $result = Configure::configured('default');
+ $this->assertTrue($result);
+ }
+ }
+
+/**
+ * test load with merging
+ *
+ * @return void
+ */
+ public function testLoadWithMerge() {
+ Configure::config('test', new PhpReader(CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS));
+
+ $result = Configure::load('var_test', 'test');
+ $this->assertTrue($result);
+
+ $this->assertEquals('value', Configure::read('Read'));
+
+ $result = Configure::load('var_test2', 'test', true);
+ $this->assertTrue($result);
+
+ $this->assertEquals('value2', Configure::read('Read'));
+ $this->assertEquals('buried2', Configure::read('Deep.Second.SecondDeepest'));
+ $this->assertEquals('buried', Configure::read('Deep.Deeper.Deepest'));
+ $this->assertEquals('Overwrite', Configure::read('TestAcl.classname'));
+ $this->assertEquals('one', Configure::read('TestAcl.custom'));
+ }
+
+/**
+ * test loading with overwrite
+ *
+ * @return void
+ */
+ public function testLoadNoMerge() {
+ Configure::config('test', new PhpReader(CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS));
+
+ $result = Configure::load('var_test', 'test');
+ $this->assertTrue($result);
+
+ $this->assertEquals('value', Configure::read('Read'));
+
+ $result = Configure::load('var_test2', 'test', false);
+ $this->assertTrue($result);
+
+ $this->assertEquals('value2', Configure::read('Read'));
+ $this->assertEquals('buried2', Configure::read('Deep.Second.SecondDeepest'));
+ $this->assertNull(Configure::read('Deep.Deeper.Deepest'));
+ }
+
+/**
+ * testLoad method
+ *
+ * @return void
+ */
+ public function testLoadPlugin() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ Configure::config('test', new PhpReader());
+ CakePlugin::load('TestPlugin');
+ $result = Configure::load('TestPlugin.load', 'test');
+ $this->assertTrue($result);
+ $expected = '/test_app/plugins/test_plugin/config/load.php';
+ $config = Configure::read('plugin_load');
+ $this->assertEquals($expected, $config);
+
+ $result = Configure::load('TestPlugin.more.load', 'test');
+ $this->assertTrue($result);
+ $expected = '/test_app/plugins/test_plugin/config/more.load.php';
+ $config = Configure::read('plugin_more_load');
+ $this->assertEquals($expected, $config);
+ CakePlugin::unload();
+ }
+
+/**
+ * testStore method
+ *
+ * @return void
+ */
+ public function testStoreAndRestore() {
+ Configure::write('Cache.disable', false);
+
+ Configure::write('Testing', 'yummy');
+ $this->assertTrue(Configure::store('store_test', 'default'));
+
+ Configure::delete('Testing');
+ $this->assertNull(Configure::read('Testing'));
+
+ Configure::restore('store_test', 'default');
+ $this->assertEquals('yummy', Configure::read('Testing'));
+
+ Cache::delete('store_test', 'default');
+ }
+
+/**
+ * test that store and restore only store/restore the provided data.
+ *
+ * @return void
+ */
+ public function testStoreAndRestoreWithData() {
+ Configure::write('Cache.disable', false);
+
+ Configure::write('testing', 'value');
+ Configure::store('store_test', 'default', array('store_test' => 'one'));
+ Configure::delete('testing');
+ $this->assertNull(Configure::read('store_test'), 'Calling store with data shouldn\'t modify runtime.');
+
+ Configure::restore('store_test', 'default');
+ $this->assertEquals('one', Configure::read('store_test'));
+ $this->assertNull(Configure::read('testing'), 'Values that were not stored are not restored.');
+
+ Cache::delete('store_test', 'default');
+ }
+
+/**
+ * testVersion method
+ *
+ * @return void
+ */
+ public function testVersion() {
+ $result = Configure::version();
+ $this->assertTrue(version_compare($result, '1.2', '>='));
+ }
+
+/**
+ * test adding new readers.
+ *
+ * @return void
+ */
+ public function testReaderSetup() {
+ $reader = new PhpReader();
+ Configure::config('test', $reader);
+ $configured = Configure::configured();
+
+ $this->assertTrue(in_array('test', $configured));
+
+ $this->assertTrue(Configure::configured('test'));
+ $this->assertFalse(Configure::configured('fake_garbage'));
+
+ $this->assertTrue(Configure::drop('test'));
+ $this->assertFalse(Configure::drop('test'), 'dropping things that do not exist should return false.');
+ }
+
+/**
+ * test reader() throwing exceptions on missing interface.
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testReaderExceptionOnIncorrectClass() {
+ $reader = new StdClass();
+ Configure::config('test', $reader);
+ }
+
+/**
+ * Test that clear wipes all values.
+ *
+ * @return void
+ */
+ public function testClear() {
+ Configure::write('test', 'value');
+ $this->assertTrue(Configure::clear());
+ $this->assertNull(Configure::read('debug'));
+ $this->assertNull(Configure::read('test'));
+ }
+
+/**
+ * @expectedException ConfigureException
+ */
+ public function testDumpNoAdapter() {
+ Configure::dump(TMP . 'test.php', 'does_not_exist');
+ }
+
+/**
+ * test dump integrated with the PhpReader.
+ *
+ * @return void
+ */
+ public function testDump() {
+ Configure::config('test_reader', new PhpReader(TMP));
+
+ $result = Configure::dump('config_test.php', 'test_reader');
+ $this->assertTrue($result > 0);
+ $result = file_get_contents(TMP . 'config_test.php');
+ $this->assertContains('<?php', $result);
+ $this->assertContains('$config = ', $result);
+ @unlink(TMP . 'config_test.php');
+ }
+
+/**
+ * Test dumping only some of the data.
+ *
+ * @return
+ */
+ public function testDumpPartial() {
+ Configure::config('test_reader', new PhpReader(TMP));
+
+ $result = Configure::dump('config_test.php', 'test_reader', array('Error'));
+ $this->assertTrue($result > 0);
+ $result = file_get_contents(TMP . 'config_test.php');
+ $this->assertContains('<?php', $result);
+ $this->assertContains('$config = ', $result);
+ $this->assertContains('Error', $result);
+ $this->assertNotContains('debug', $result);
+
+ @unlink(TMP . 'config_test.php');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ObjectTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ObjectTest.php
new file mode 100644
index 0000000..222a231
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Core/ObjectTest.php
@@ -0,0 +1,673 @@
+<?php
+/**
+ * ObjectTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Core
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Object', 'Core');
+App::uses('Router', 'Routing');
+App::uses('Controller', 'Controller');
+App::uses('Model', 'Model');
+
+/**
+ * RequestActionPost class
+ *
+ * @package Cake.Test.Case.Core
+ */
+class RequestActionPost extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ControllerPost'
+ */
+ public $name = 'RequestActionPost';
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'posts';
+}
+
+/**
+ * RequestActionController class
+ *
+ * @package Cake.Test.Case.Core
+ */
+class RequestActionController extends Controller {
+
+/**
+ * uses property
+ *
+ * @var array
+ * @access public
+ */
+ public $uses = array('RequestActionPost');
+
+/**
+ * test_request_action method
+ *
+ * @access public
+ * @return void
+ */
+ public function test_request_action() {
+ return 'This is a test';
+ }
+
+/**
+ * another_ra_test method
+ *
+ * @param mixed $id
+ * @param mixed $other
+ * @access public
+ * @return void
+ */
+ public function another_ra_test($id, $other) {
+ return $id + $other;
+ }
+
+/**
+ * normal_request_action method
+ *
+ * @return void
+ */
+ public function normal_request_action() {
+ return 'Hello World';
+ }
+
+/**
+ * returns $this->here
+ *
+ * @return void
+ */
+ public function return_here() {
+ return $this->here;
+ }
+
+/**
+ * paginate_request_action method
+ *
+ * @return void
+ */
+ public function paginate_request_action() {
+ $data = $this->paginate();
+ return true;
+ }
+
+/**
+ * post pass, testing post passing
+ *
+ * @return array
+ */
+ public function post_pass() {
+ return $this->request->data;
+ }
+
+/**
+ * test param passing and parsing.
+ *
+ * @return array
+ */
+ public function params_pass() {
+ return $this->request;
+ }
+
+ public function param_check() {
+ $this->autoRender = false;
+ $content = '';
+ if (isset($this->request->params[0])) {
+ $content = 'return found';
+ }
+ $this->response->body($content);
+ }
+
+}
+
+/**
+ * TestObject class
+ *
+ * @package Cake.Test.Case.Core
+ */
+class TestObject extends Object {
+
+/**
+ * firstName property
+ *
+ * @var string 'Joel'
+ */
+ public $firstName = 'Joel';
+
+/**
+ * lastName property
+ *
+ * @var string 'Moss'
+ */
+ public $lastName = 'Moss';
+
+/**
+ * methodCalls property
+ *
+ * @var array
+ */
+ public $methodCalls = array();
+
+/**
+ * emptyMethod method
+ *
+ * @return void
+ */
+ public function emptyMethod() {
+ $this->methodCalls[] = 'emptyMethod';
+ }
+
+/**
+ * oneParamMethod method
+ *
+ * @param mixed $param
+ * @return void
+ */
+ public function oneParamMethod($param) {
+ $this->methodCalls[] = array('oneParamMethod' => array($param));
+ }
+
+/**
+ * twoParamMethod method
+ *
+ * @param mixed $param
+ * @param mixed $paramTwo
+ * @return void
+ */
+ public function twoParamMethod($param, $paramTwo) {
+ $this->methodCalls[] = array('twoParamMethod' => array($param, $paramTwo));
+ }
+
+/**
+ * threeParamMethod method
+ *
+ * @param mixed $param
+ * @param mixed $paramTwo
+ * @param mixed $paramThree
+ * @return void
+ */
+ public function threeParamMethod($param, $paramTwo, $paramThree) {
+ $this->methodCalls[] = array('threeParamMethod' => array($param, $paramTwo, $paramThree));
+ }
+
+/**
+ * fourParamMethod method
+ *
+ * @param mixed $param
+ * @param mixed $paramTwo
+ * @param mixed $paramThree
+ * @param mixed $paramFour
+ * @return void
+ */
+ public function fourParamMethod($param, $paramTwo, $paramThree, $paramFour) {
+ $this->methodCalls[] = array('fourParamMethod' => array($param, $paramTwo, $paramThree, $paramFour));
+ }
+
+/**
+ * fiveParamMethod method
+ *
+ * @param mixed $param
+ * @param mixed $paramTwo
+ * @param mixed $paramThree
+ * @param mixed $paramFour
+ * @param mixed $paramFive
+ * @return void
+ */
+ public function fiveParamMethod($param, $paramTwo, $paramThree, $paramFour, $paramFive) {
+ $this->methodCalls[] = array('fiveParamMethod' => array($param, $paramTwo, $paramThree, $paramFour, $paramFive));
+ }
+
+/**
+ * crazyMethod method
+ *
+ * @param mixed $param
+ * @param mixed $paramTwo
+ * @param mixed $paramThree
+ * @param mixed $paramFour
+ * @param mixed $paramFive
+ * @param mixed $paramSix
+ * @param mixed $paramSeven
+ * @return void
+ */
+ public function crazyMethod($param, $paramTwo, $paramThree, $paramFour, $paramFive, $paramSix, $paramSeven = null) {
+ $this->methodCalls[] = array('crazyMethod' => array($param, $paramTwo, $paramThree, $paramFour, $paramFive, $paramSix, $paramSeven));
+ }
+
+/**
+ * methodWithOptionalParam method
+ *
+ * @param mixed $param
+ * @return void
+ */
+ public function methodWithOptionalParam($param = null) {
+ $this->methodCalls[] = array('methodWithOptionalParam' => array($param));
+ }
+
+/**
+ * undocumented function
+ *
+ * @return void
+ */
+ public function set($properties = array()) {
+ return parent::_set($properties);
+ }
+
+}
+
+/**
+ * ObjectTestModel class
+ *
+ * @package Cake.Test.Case.Core
+ */
+class ObjectTestModel extends CakeTestModel {
+
+ public $useTable = false;
+
+ public $name = 'ObjectTestModel';
+
+}
+
+/**
+ * Object Test class
+ *
+ * @package Cake.Test.Case.Core
+ */
+class ObjectTest extends CakeTestCase {
+
+/**
+ * fixtures
+ *
+ * @var string
+ */
+ public $fixtures = array('core.post', 'core.test_plugin_comment', 'core.comment');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->object = new TestObject();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ unset($this->object);
+ }
+
+/**
+ * testLog method
+ *
+ * @return void
+ */
+ public function testLog() {
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ $this->assertTrue($this->object->log('Test warning 1'));
+ $this->assertTrue($this->object->log(array('Test' => 'warning 2')));
+ $result = file(LOGS . 'error.log');
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Error: Test warning 1$/', $result[0]);
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Error: Array$/', $result[1]);
+ $this->assertRegExp('/^\($/', $result[2]);
+ $this->assertRegExp('/\[Test\] => warning 2$/', $result[3]);
+ $this->assertRegExp('/^\)$/', $result[4]);
+ unlink(LOGS . 'error.log');
+
+ $this->assertTrue($this->object->log('Test warning 1', LOG_WARNING));
+ $this->assertTrue($this->object->log(array('Test' => 'warning 2'), LOG_WARNING));
+ $result = file(LOGS . 'error.log');
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning 1$/', $result[0]);
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Array$/', $result[1]);
+ $this->assertRegExp('/^\($/', $result[2]);
+ $this->assertRegExp('/\[Test\] => warning 2$/', $result[3]);
+ $this->assertRegExp('/^\)$/', $result[4]);
+ unlink(LOGS . 'error.log');
+ }
+
+/**
+ * testSet method
+ *
+ * @return void
+ */
+ public function testSet() {
+ $this->object->set('a string');
+ $this->assertEquals('Joel', $this->object->firstName);
+
+ $this->object->set(array('firstName'));
+ $this->assertEquals('Joel', $this->object->firstName);
+
+ $this->object->set(array('firstName' => 'Ashley'));
+ $this->assertEquals('Ashley', $this->object->firstName);
+
+ $this->object->set(array('firstName' => 'Joel', 'lastName' => 'Moose'));
+ $this->assertEquals('Joel', $this->object->firstName);
+ $this->assertEquals('Moose', $this->object->lastName);
+ }
+
+/**
+ * testToString method
+ *
+ * @return void
+ */
+ public function testToString() {
+ $result = strtolower($this->object->toString());
+ $this->assertEquals('testobject', $result);
+ }
+
+/**
+ * testMethodDispatching method
+ *
+ * @return void
+ */
+ public function testMethodDispatching() {
+ $this->object->emptyMethod();
+ $expected = array('emptyMethod');
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->oneParamMethod('Hello');
+ $expected[] = array('oneParamMethod' => array('Hello'));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->twoParamMethod(true, false);
+ $expected[] = array('twoParamMethod' => array(true, false));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->threeParamMethod(true, false, null);
+ $expected[] = array('threeParamMethod' => array(true, false, null));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->crazyMethod(1, 2, 3, 4, 5, 6, 7);
+ $expected[] = array('crazyMethod' => array(1, 2, 3, 4, 5, 6, 7));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object = new TestObject();
+ $this->assertSame($this->object->methodCalls, array());
+
+ $this->object->dispatchMethod('emptyMethod');
+ $expected = array('emptyMethod');
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('oneParamMethod', array('Hello'));
+ $expected[] = array('oneParamMethod' => array('Hello'));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('twoParamMethod', array(true, false));
+ $expected[] = array('twoParamMethod' => array(true, false));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('threeParamMethod', array(true, false, null));
+ $expected[] = array('threeParamMethod' => array(true, false, null));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('fourParamMethod', array(1, 2, 3, 4));
+ $expected[] = array('fourParamMethod' => array(1, 2, 3, 4));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('fiveParamMethod', array(1, 2, 3, 4, 5));
+ $expected[] = array('fiveParamMethod' => array(1, 2, 3, 4, 5));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('crazyMethod', array(1, 2, 3, 4, 5, 6, 7));
+ $expected[] = array('crazyMethod' => array(1, 2, 3, 4, 5, 6, 7));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('methodWithOptionalParam', array('Hello'));
+ $expected[] = array('methodWithOptionalParam' => array("Hello"));
+ $this->assertSame($this->object->methodCalls, $expected);
+
+ $this->object->dispatchMethod('methodWithOptionalParam');
+ $expected[] = array('methodWithOptionalParam' => array(null));
+ $this->assertSame($this->object->methodCalls, $expected);
+ }
+
+/**
+ * testRequestAction method
+ *
+ * @return void
+ */
+ public function testRequestAction() {
+ App::build(array(
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
+ 'Controller' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS)
+ ), App::RESET);
+ $this->assertNull(Router::getRequest(), 'request stack should be empty.');
+
+ $result = $this->object->requestAction('');
+ $this->assertFalse($result);
+
+ $result = $this->object->requestAction('/request_action/test_request_action');
+ $expected = 'This is a test';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(FULL_BASE_URL . '/request_action/test_request_action');
+ $expected = 'This is a test';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction('/request_action/another_ra_test/2/5');
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction('/tests_apps/index', array('return'));
+ $expected = 'This is the TestsAppsController index view ';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction('/tests_apps/some_method');
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction('/request_action/paginate_request_action');
+ $this->assertTrue($result);
+
+ $result = $this->object->requestAction('/request_action/normal_request_action');
+ $expected = 'Hello World';
+ $this->assertEquals($expected, $result);
+
+ $this->assertNull(Router::getRequest(), 'requests were not popped off the stack, this will break url generation');
+ }
+
+/**
+ * test requestAction() and plugins.
+ *
+ * @return void
+ */
+ public function testRequestActionPlugins() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+ Router::reload();
+
+ $result = $this->object->requestAction('/test_plugin/tests/index', array('return'));
+ $expected = 'test plugin index';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction('/test_plugin/tests/index/some_param', array('return'));
+ $expected = 'test plugin index';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'tests', 'action' => 'index', 'plugin' => 'test_plugin'), array('return')
+ );
+ $expected = 'test plugin index';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction('/test_plugin/tests/some_method');
+ $expected = 25;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'tests', 'action' => 'some_method', 'plugin' => 'test_plugin')
+ );
+ $expected = 25;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test requestAction() with arrays.
+ *
+ * @return void
+ */
+ public function testRequestActionArray() {
+ App::build(array(
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
+ 'Controller' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin'));
+
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'test_request_action')
+ );
+ $expected = 'This is a test';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'another_ra_test'),
+ array('pass' => array('5', '7'))
+ );
+ $expected = 12;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'tests_apps', 'action' => 'index'), array('return')
+ );
+ $expected = 'This is the TestsAppsController index view ';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(array('controller' => 'tests_apps', 'action' => 'some_method'));
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'normal_request_action')
+ );
+ $expected = 'Hello World';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'paginate_request_action')
+ );
+ $this->assertTrue($result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'paginate_request_action'),
+ array('pass' => array(5), 'named' => array('param' => 'value'))
+ );
+ $this->assertTrue($result);
+ }
+
+/**
+ * Test that requestAction() does not forward the 0 => return value.
+ *
+ * @return void
+ */
+ public function testRequestActionRemoveReturnParam() {
+ $result = $this->object->requestAction(
+ '/request_action/param_check', array('return')
+ );
+ $this->assertEquals('', $result, 'Return key was found');
+ }
+
+/**
+ * Test that requestAction() is populating $this->params properly
+ *
+ * @return void
+ */
+ public function testRequestActionParamParseAndPass() {
+ $result = $this->object->requestAction('/request_action/params_pass');
+ $this->assertEquals('request_action/params_pass', $result->url);
+ $this->assertEquals('request_action', $result['controller']);
+ $this->assertEquals('params_pass', $result['action']);
+ $this->assertEquals(null, $result['plugin']);
+
+ $result = $this->object->requestAction('/request_action/params_pass/sort:desc/limit:5');
+ $expected = array('sort' => 'desc', 'limit' => 5,);
+ $this->assertEquals($expected, $result['named']);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'params_pass'),
+ array('named' => array('sort' => 'desc', 'limit' => 5))
+ );
+ $this->assertEquals($expected, $result['named']);
+ }
+
+/**
+ * test that requestAction does not fish data out of the POST
+ * superglobal.
+ *
+ * @return void
+ */
+ public function testRequestActionNoPostPassing() {
+ $_tmp = $_POST;
+
+ $_POST = array('data' => array(
+ 'item' => 'value'
+ ));
+ $result = $this->object->requestAction(array('controller' => 'request_action', 'action' => 'post_pass'));
+ $expected = null;
+ $this->assertEmpty($result);
+
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'post_pass'),
+ array('data' => $_POST['data'])
+ );
+ $expected = $_POST['data'];
+ $this->assertEquals($expected, $result);
+
+ $result = $this->object->requestAction('/request_action/post_pass');
+ $expected = $_POST['data'];
+ $this->assertEquals($expected, $result);
+
+ $_POST = $_tmp;
+ }
+
+/**
+ * Test requestAction with post data.
+ *
+ * @return void
+ */
+ public function testRequestActionPostWithData() {
+ $data = array(
+ 'Post' => array('id' => 2)
+ );
+ $result = $this->object->requestAction(
+ array('controller' => 'request_action', 'action' => 'post_pass'),
+ array('data' => $data)
+ );
+ $this->assertEquals($data, $result);
+
+ $result = $this->object->requestAction(
+ '/request_action/post_pass',
+ array('data' => $data)
+ );
+ $this->assertEquals($data, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ErrorHandlerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ErrorHandlerTest.php
new file mode 100644
index 0000000..e4bd579
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ErrorHandlerTest.php
@@ -0,0 +1,296 @@
+<?php
+/**
+ * ErrorHandlerTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Error
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ErrorHandler', 'Error');
+App::uses('Controller', 'Controller');
+App::uses('Router', 'Routing');
+
+/**
+ * ErrorHandlerTest class
+ *
+ * @package Cake.Test.Case.Error
+ */
+class ErrorHandlerTest extends CakeTestCase {
+
+ protected $_restoreError = false;
+
+/**
+ * setup create a request object to get out of router later.
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'View' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
+ )
+ ), App::RESET);
+ Router::reload();
+
+ $request = new CakeRequest(null, false);
+ $request->base = '';
+ Router::setRequestInfo($request);
+ Configure::write('debug', 2);
+
+ CakeLog::disable('stdout');
+ CakeLog::disable('stderr');
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ if ($this->_restoreError) {
+ restore_error_handler();
+ }
+ CakeLog::enable('stdout');
+ CakeLog::enable('stderr');
+ }
+
+/**
+ * test error handling when debug is on, an error should be printed from Debugger.
+ *
+ * @return void
+ */
+ public function testHandleErrorDebugOn() {
+ set_error_handler('ErrorHandler::handleError');
+ $this->_restoreError = true;
+
+ ob_start();
+ $wrong .= '';
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/<pre class="cake-error">/', $result);
+ $this->assertRegExp('/<b>Notice<\/b>/', $result);
+ $this->assertRegExp('/variable:\s+wrong/', $result);
+ }
+
+/**
+ * provides errors for mapping tests.
+ *
+ * @return void
+ */
+ public static function errorProvider() {
+ return array(
+ array(E_USER_NOTICE, 'Notice'),
+ array(E_USER_WARNING, 'Warning'),
+ );
+ }
+
+/**
+ * test error mappings
+ *
+ * @dataProvider errorProvider
+ * @return void
+ */
+ public function testErrorMapping($error, $expected) {
+ set_error_handler('ErrorHandler::handleError');
+ $this->_restoreError = true;
+
+ ob_start();
+ trigger_error('Test error', $error);
+
+ $result = ob_get_clean();
+ $this->assertRegExp('/<b>' . $expected . '<\/b>/', $result);
+ }
+
+/**
+ * test error prepended by @
+ *
+ * @return void
+ */
+ public function testErrorSuppressed() {
+ set_error_handler('ErrorHandler::handleError');
+ $this->_restoreError = true;
+
+ ob_start();
+ @include 'invalid.file';
+ $result = ob_get_clean();
+ $this->assertTrue(empty($result));
+ }
+
+/**
+ * Test that errors go into CakeLog when debug = 0.
+ *
+ * @return void
+ */
+ public function testHandleErrorDebugOff() {
+ Configure::write('debug', 0);
+ Configure::write('Error.trace', false);
+ if (file_exists(LOGS . 'debug.log')) {
+ @unlink(LOGS . 'debug.log');
+ }
+
+ set_error_handler('ErrorHandler::handleError');
+ $this->_restoreError = true;
+
+ $out .= '';
+
+ $result = file(LOGS . 'debug.log');
+ $this->assertEquals(1, count($result));
+ $this->assertRegExp(
+ '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
+ $result[0]
+ );
+ @unlink(LOGS . 'debug.log');
+ }
+
+/**
+ * Test that errors going into CakeLog include traces.
+ *
+ * @return void
+ */
+ public function testHandleErrorLoggingTrace() {
+ Configure::write('debug', 0);
+ Configure::write('Error.trace', true);
+ if (file_exists(LOGS . 'debug.log')) {
+ @unlink(LOGS . 'debug.log');
+ }
+
+ set_error_handler('ErrorHandler::handleError');
+ $this->_restoreError = true;
+
+ $out .= '';
+
+ $result = file(LOGS . 'debug.log');
+ $this->assertRegExp(
+ '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
+ $result[0]
+ );
+ $this->assertRegExp('/^Trace:/', $result[1]);
+ $this->assertRegExp('/^ErrorHandlerTest\:\:testHandleErrorLoggingTrace\(\)/', $result[2]);
+ @unlink(LOGS . 'debug.log');
+ }
+
+/**
+ * test handleException generating a page.
+ *
+ * @return void
+ */
+ public function testHandleException() {
+ $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.');
+
+ $error = new NotFoundException('Kaboom!');
+ ob_start();
+ ErrorHandler::handleException($error);
+ $result = ob_get_clean();
+ $this->assertRegExp('/Kaboom!/', $result, 'message missing.');
+ }
+
+/**
+ * test handleException generating log.
+ *
+ * @return void
+ */
+ public function testHandleExceptionLog() {
+ $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.');
+
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ Configure::write('Exception.log', true);
+ $error = new NotFoundException('Kaboom!');
+
+ ob_start();
+ ErrorHandler::handleException($error);
+ $result = ob_get_clean();
+ $this->assertRegExp('/Kaboom!/', $result, 'message missing.');
+
+ $log = file(LOGS . 'error.log');
+ $this->assertRegExp('/\[NotFoundException\] Kaboom!/', $log[0], 'message missing.');
+ $this->assertRegExp('/\#0.*ErrorHandlerTest->testHandleExceptionLog/', $log[1], 'Stack trace missing.');
+ }
+
+/**
+ * tests it is possible to load a plugin exception renderer
+ *
+ * @return void
+ */
+ public function testLoadPluginHandler() {
+ App::build(array(
+ 'Plugin' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ )
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+ Configure::write('Exception.renderer', 'TestPlugin.TestPluginExceptionRenderer');
+ $error = new NotFoundException('Kaboom!');
+ ob_start();
+ ErrorHandler::handleException($error);
+ $result = ob_get_clean();
+ $this->assertEquals('Rendered by test plugin', $result);
+ CakePlugin::unload();
+ }
+
+/**
+ * test handleFatalError generating a page.
+ *
+ * @return void
+ */
+ public function testHandleFatalErrorPage() {
+ $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.');
+
+ $originalDebugLevel = Configure::read('debug');
+ $line = __LINE__;
+
+ ob_start();
+ Configure::write('debug', 1);
+ ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
+ $result = ob_get_clean();
+ $this->assertContains('Something wrong', $result, 'message missing.');
+ $this->assertContains(__FILE__, $result, 'filename missing.');
+ $this->assertContains((string)$line, $result, 'line missing.');
+
+ ob_start();
+ Configure::write('debug', 0);
+ ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
+ $result = ob_get_clean();
+ $this->assertNotContains('Something wrong', $result, 'message must not appear.');
+ $this->assertNotContains(__FILE__, $result, 'filename must not appear.');
+ $this->assertContains('An Internal Error Has Occurred', $result);
+
+ Configure::write('debug', $originalDebugLevel);
+ }
+
+/**
+ * test handleException generating log.
+ *
+ * @return void
+ */
+ public function testHandleFatalErrorLog() {
+ $this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.');
+
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+
+ ob_start();
+ ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, __LINE__);
+ ob_clean();
+
+ $log = file(LOGS . 'error.log');
+ $this->assertContains(__FILE__, $log[0], 'missing filename');
+ $this->assertContains('[FatalErrorException] Something wrong', $log[1], 'message missing.');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ExceptionRendererTest.php
new file mode 100644
index 0000000..956acec
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Error/ExceptionRendererTest.php
@@ -0,0 +1,776 @@
+<?php
+/**
+ * ExceptionRendererTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Error
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ExceptionRenderer', 'Error');
+App::uses('Controller', 'Controller');
+App::uses('AppController', 'Controller');
+App::uses('Component', 'Controller');
+App::uses('Router', 'Routing');
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Case.Error
+ */
+class AuthBlueberryUser extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'AuthBlueberryUser'
+ */
+ public $name = 'AuthBlueberryUser';
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = false;
+}
+
+/**
+ * BlueberryComponent class
+ *
+ * @package Cake.Test.Case.Error
+ */
+class BlueberryComponent extends Component {
+
+/**
+ * testName property
+ *
+ * @return void
+ */
+ public $testName = null;
+
+/**
+ * initialize method
+ *
+ * @return void
+ */
+ public function initialize(Controller $controller) {
+ $this->testName = 'BlueberryComponent';
+ }
+
+}
+
+/**
+ * TestErrorController class
+ *
+ * @package Cake.Test.Case.Error
+ */
+class TestErrorController extends Controller {
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * components property
+ *
+ * @return void
+ */
+ public $components = array('Blueberry');
+
+/**
+ * beforeRender method
+ *
+ * @return void
+ */
+ public function beforeRender() {
+ echo $this->Blueberry->testName;
+ }
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ $this->autoRender = false;
+ return 'what up';
+ }
+
+}
+
+/**
+ * MyCustomExceptionRenderer class
+ *
+ * @package Cake.Test.Case.Error
+ */
+class MyCustomExceptionRenderer extends ExceptionRenderer {
+
+/**
+ * custom error message type.
+ *
+ * @return void
+ */
+ public function missingWidgetThing() {
+ echo 'widget thing is missing';
+ }
+
+}
+
+/**
+ * Exception class for testing app error handlers and custom errors.
+ *
+ * @package Cake.Test.Case.Error
+ */
+class MissingWidgetThingException extends NotFoundException {
+}
+
+
+/**
+ * ExceptionRendererTest class
+ *
+ * @package Cake.Test.Case.Error
+ */
+class ExceptionRendererTest extends CakeTestCase {
+
+ protected $_restoreError = false;
+
+/**
+ * setup create a request object to get out of router later.
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'View' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
+ )
+ ), App::RESET);
+ Router::reload();
+
+ $request = new CakeRequest(null, false);
+ $request->base = '';
+ Router::setRequestInfo($request);
+ Configure::write('debug', 2);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ if ($this->_restoreError) {
+ restore_error_handler();
+ }
+ }
+
+/**
+ * Mocks out the response on the ExceptionRenderer object so headers aren't modified.
+ *
+ * @return void
+ */
+ protected function _mockResponse($error) {
+ $error->controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ return $error;
+ }
+
+/**
+ * test that methods declared in an ExceptionRenderer subclass are not converted
+ * into error400 when debug > 0
+ *
+ * @return void
+ */
+ public function testSubclassMethodsNotBeingConvertedToError() {
+ Configure::write('debug', 2);
+
+ $exception = new MissingWidgetThingException('Widget not found');
+ $ExceptionRenderer = $this->_mockResponse(new MyCustomExceptionRenderer($exception));
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertEquals('widget thing is missing', $result);
+ }
+
+/**
+ * test that subclass methods are not converted when debug = 0
+ *
+ * @return void
+ */
+ public function testSubclassMethodsNotBeingConvertedDebug0() {
+ Configure::write('debug', 0);
+ $exception = new MissingWidgetThingException('Widget not found');
+ $ExceptionRenderer = $this->_mockResponse(new MyCustomExceptionRenderer($exception));
+
+ $this->assertEquals('missingWidgetThing', $ExceptionRenderer->method);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertEquals('widget thing is missing', $result, 'Method declared in subclass converted to error400');
+ }
+
+/**
+ * test that ExceptionRenderer subclasses properly convert framework errors.
+ *
+ * @return void
+ */
+ public function testSubclassConvertingFrameworkErrors() {
+ Configure::write('debug', 0);
+
+ $exception = new MissingControllerException('PostsController');
+ $ExceptionRenderer = $this->_mockResponse(new MyCustomExceptionRenderer($exception));
+
+ $this->assertEquals('error400', $ExceptionRenderer->method);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/Not Found/', $result, 'Method declared in error handler not converted to error400. %s');
+ }
+
+/**
+ * test things in the constructor.
+ *
+ * @return void
+ */
+ public function testConstruction() {
+ $exception = new NotFoundException('Page not found');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+
+ $this->assertInstanceOf('CakeErrorController', $ExceptionRenderer->controller);
+ $this->assertEquals('error400', $ExceptionRenderer->method);
+ $this->assertEquals($exception, $ExceptionRenderer->error);
+ }
+
+/**
+ * test that method gets coerced when debug = 0
+ *
+ * @return void
+ */
+ public function testErrorMethodCoercion() {
+ Configure::write('debug', 0);
+ $exception = new MissingActionException('Page not found');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+
+ $this->assertInstanceOf('CakeErrorController', $ExceptionRenderer->controller);
+ $this->assertEquals('error400', $ExceptionRenderer->method);
+ $this->assertEquals($exception, $ExceptionRenderer->error);
+ }
+
+/**
+ * test that helpers in custom CakeErrorController are not lost
+ */
+ public function testCakeErrorHelpersNotLost() {
+ $testApp = CAKE . 'Test' . DS . 'test_app' . DS;
+ App::build(array(
+ 'Controller' => array(
+ $testApp . 'Controller' . DS
+ ),
+ 'View/Helper' => array(
+ $testApp . 'View' . DS . 'Helper' . DS
+ ),
+ 'View/Layouts' => array(
+ $testApp . 'View' . DS . 'Layouts' . DS
+ ),
+ 'Error' => array(
+ $testApp . 'Error' . DS
+ ),
+ ), App::RESET);
+
+ App::uses('TestAppsExceptionRenderer', 'Error');
+ $exception = new SocketException('socket exception');
+ $renderer = new TestAppsExceptionRenderer($exception);
+
+ ob_start();
+ $renderer->render();
+ $result = ob_get_clean();
+ $this->assertContains('<b>peeled</b>', $result);
+ }
+
+/**
+ * test that unknown exception types with valid status codes are treated correctly.
+ *
+ * @return void
+ */
+ public function testUnknownExceptionTypeWithExceptionThatHasA400Code() {
+ $exception = new MissingWidgetThingException('coding fail.');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(404);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertFalse(method_exists($ExceptionRenderer, 'missingWidgetThing'), 'no method should exist.');
+ $this->assertEquals('error400', $ExceptionRenderer->method, 'incorrect method coercion.');
+ $this->assertContains('coding fail', $result, 'Text should show up.');
+ }
+
+/**
+ * test that unknown exception types with valid status codes are treated correctly.
+ *
+ * @return void
+ */
+ public function testUnknownExceptionTypeWithNoCodeIsA500() {
+ $exception = new OutOfBoundsException('foul ball.');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())
+ ->method('statusCode')
+ ->with(500);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertEquals('error500', $ExceptionRenderer->method, 'incorrect method coercion.');
+ $this->assertContains('foul ball.', $result, 'Text should show up as its debug mode.');
+ }
+
+/**
+ * test that unknown exceptions have messages ignored.
+ *
+ * @return void
+ */
+ public function testUnknownExceptionInProduction() {
+ Configure::write('debug', 0);
+
+ $exception = new OutOfBoundsException('foul ball.');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())
+ ->method('statusCode')
+ ->with(500);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertEquals('error500', $ExceptionRenderer->method, 'incorrect method coercion.');
+ $this->assertNotContains('foul ball.', $result, 'Text should no show up.');
+ $this->assertContains('Internal Error', $result, 'Generic message only.');
+ }
+
+/**
+ * test that unknown exception types with valid status codes are treated correctly.
+ *
+ * @return void
+ */
+ public function testUnknownExceptionTypeWithCodeHigherThan500() {
+ $exception = new OutOfBoundsException('foul ball.', 501);
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(501);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertEquals('error500', $ExceptionRenderer->method, 'incorrect method coercion.');
+ $this->assertContains('foul ball.', $result, 'Text should show up as its debug mode.');
+ }
+
+/**
+ * testerror400 method
+ *
+ * @return void
+ */
+ public function testError400() {
+ Router::reload();
+
+ $request = new CakeRequest('posts/view/1000', false);
+ Router::setRequestInfo($request);
+
+ $exception = new NotFoundException('Custom message');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(404);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/<h2>Custom message<\/h2>/', $result);
+ $this->assertRegExp("/<strong>'.*?\/posts\/view\/1000'<\/strong>/", $result);
+ }
+
+/**
+ * test that error400 only modifies the messages on CakeExceptions.
+ *
+ * @return void
+ */
+ public function testerror400OnlyChangingCakeException() {
+ Configure::write('debug', 0);
+
+ $exception = new NotFoundException('Custom message');
+ $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception));
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+ $this->assertContains('Custom message', $result);
+
+ $exception = new MissingActionException(array('controller' => 'PostsController', 'action' => 'index'));
+ $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception));
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+ $this->assertContains('Not Found', $result);
+ }
+
+/**
+ * test that error400 doesn't expose XSS
+ *
+ * @return void
+ */
+ public function testError400NoInjection() {
+ Router::reload();
+
+ $request = new CakeRequest('pages/<span id=333>pink</span></id><script>document.body.style.background = t=document.getElementById(333).innerHTML;window.alert(t);</script>', false);
+ Router::setRequestInfo($request);
+
+ $exception = new NotFoundException('Custom message');
+ $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception));
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertNotRegExp('#<script>document#', $result);
+ $this->assertNotRegExp('#alert\(t\);</script>#', $result);
+ }
+
+/**
+ * testError500 method
+ *
+ * @return void
+ */
+ public function testError500Message() {
+ $exception = new InternalErrorException('An Internal Error Has Occurred');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(500);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/<h2>An Internal Error Has Occurred<\/h2>/', $result);
+ }
+
+/**
+ * testMissingController method
+ *
+ * @return void
+ */
+ public function testMissingController() {
+ $exception = new MissingControllerException(array('class' => 'PostsController'));
+ $ExceptionRenderer = $this->_mockResponse(new ExceptionRenderer($exception));
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/<h2>Missing Controller<\/h2>/', $result);
+ $this->assertRegExp('/<em>PostsController<\/em>/', $result);
+ }
+
+/**
+ * Returns an array of tests to run for the various CakeException classes.
+ *
+ * @return void
+ */
+ public static function testProvider() {
+ return array(
+ array(
+ new MissingActionException(array('controller' => 'PostsController', 'action' => 'index')),
+ array(
+ '/<h2>Missing Method in PostsController<\/h2>/',
+ '/<em>PostsController::<\/em><em>index\(\)<\/em>/'
+ ),
+ 404
+ ),
+ array(
+ new PrivateActionException(array('controller' => 'PostsController' , 'action' => '_secretSauce')),
+ array(
+ '/<h2>Private Method in PostsController<\/h2>/',
+ '/<em>PostsController::<\/em><em>_secretSauce\(\)<\/em>/'
+ ),
+ 404
+ ),
+ array(
+ new MissingTableException(array('table' => 'articles', 'class' => 'Article', 'ds' => 'test')),
+ array(
+ '/<h2>Missing Database Table<\/h2>/',
+ '/Table <em>articles<\/em> for model <em>Article<\/em> was not found in datasource <em>test<\/em>/'
+ ),
+ 500
+ ),
+ array(
+ new MissingDatabaseException(array('connection' => 'default')),
+ array(
+ '/<h2>Missing Database Connection<\/h2>/',
+ '/Confirm you have created the file/'
+ ),
+ 500
+ ),
+ array(
+ new MissingViewException(array('file' => '/posts/about.ctp')),
+ array(
+ "/posts\/about.ctp/"
+ ),
+ 500
+ ),
+ array(
+ new MissingLayoutException(array('file' => 'layouts/my_layout.ctp')),
+ array(
+ "/Missing Layout/",
+ "/layouts\/my_layout.ctp/"
+ ),
+ 500
+ ),
+ array(
+ new MissingConnectionException(array('class' => 'Article')),
+ array(
+ '/<h2>Missing Database Connection<\/h2>/',
+ '/Article requires a database connection/'
+ ),
+ 500
+ ),
+ array(
+ new MissingConnectionException(array('class' => 'Mysql', 'enabled' => false)),
+ array(
+ '/<h2>Missing Database Connection<\/h2>/',
+ '/Mysql requires a database connection/',
+ '/Mysql driver is NOT enabled/'
+ ),
+ 500
+ ),
+ array(
+ new MissingDatasourceConfigException(array('config' => 'default')),
+ array(
+ '/<h2>Missing Datasource Configuration<\/h2>/',
+ '/The datasource configuration <em>default<\/em> was not found in database.php/'
+ ),
+ 500
+ ),
+ array(
+ new MissingDatasourceException(array('class' => 'MyDatasource', 'plugin' => 'MyPlugin')),
+ array(
+ '/<h2>Missing Datasource<\/h2>/',
+ '/Datasource class <em>MyPlugin.MyDatasource<\/em> could not be found/'
+ ),
+ 500
+ ),
+ array(
+ new MissingHelperException(array('class' => 'MyCustomHelper')),
+ array(
+ '/<h2>Missing Helper<\/h2>/',
+ '/<em>MyCustomHelper<\/em> could not be found./',
+ '/Create the class <em>MyCustomHelper<\/em> below in file:/',
+ '/(\/|\\\)MyCustomHelper.php/'
+ ),
+ 500
+ ),
+ array(
+ new MissingBehaviorException(array('class' => 'MyCustomBehavior')),
+ array(
+ '/<h2>Missing Behavior<\/h2>/',
+ '/Create the class <em>MyCustomBehavior<\/em> below in file:/',
+ '/(\/|\\\)MyCustomBehavior.php/'
+ ),
+ 500
+ ),
+ array(
+ new MissingComponentException(array('class' => 'SideboxComponent')),
+ array(
+ '/<h2>Missing Component<\/h2>/',
+ '/Create the class <em>SideboxComponent<\/em> below in file:/',
+ '/(\/|\\\)SideboxComponent.php/'
+ ),
+ 500
+ ),
+ array(
+ new Exception('boom'),
+ array(
+ '/Internal Error/'
+ ),
+ 500
+ ),
+ array(
+ new RuntimeException('another boom'),
+ array(
+ '/Internal Error/'
+ ),
+ 500
+ ),
+ array(
+ new CakeException('base class'),
+ array('/Internal Error/'),
+ 500
+ ),
+ array(
+ new ConfigureException('No file'),
+ array('/Internal Error/'),
+ 500
+ )
+ );
+ }
+
+/**
+ * Test the various CakeException sub classes
+ *
+ * @dataProvider testProvider
+ * @return void
+ */
+ public function testCakeExceptionHandling($exception, $patterns, $code) {
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())
+ ->method('statusCode')
+ ->with($code);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ foreach ($patterns as $pattern) {
+ $this->assertRegExp($pattern, $result);
+ }
+ }
+
+/**
+ * Test exceptions being raised when helpers are missing.
+ *
+ * @return void
+ */
+ public function testMissingRenderSafe() {
+ $exception = new MissingHelperException(array('class' => 'Fail'));
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+
+ $ExceptionRenderer->controller = $this->getMock('Controller');
+ $ExceptionRenderer->controller->helpers = array('Fail', 'Boom');
+ $ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
+ $ExceptionRenderer->controller->expects($this->at(2))
+ ->method('render')
+ ->with('missingHelper')
+ ->will($this->throwException($exception));
+
+ $ExceptionRenderer->controller->expects($this->at(4))
+ ->method('render')
+ ->with('error500')
+ ->will($this->returnValue(true));
+
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse');
+ $ExceptionRenderer->render();
+ sort($ExceptionRenderer->controller->helpers);
+ $this->assertEquals(array('Form', 'Html', 'Session'), $ExceptionRenderer->controller->helpers);
+ }
+
+/**
+ * Test that missing subDir/layoutPath don't cause other fatal errors.
+ *
+ * @return void
+ */
+ public function testMissingSubdirRenderSafe() {
+ $exception = new NotFoundException();
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+
+ $ExceptionRenderer->controller = $this->getMock('Controller');
+ $ExceptionRenderer->controller->helpers = array('Fail', 'Boom');
+ $ExceptionRenderer->controller->layoutPath = 'json';
+ $ExceptionRenderer->controller->subDir = 'json';
+ $ExceptionRenderer->controller->viewClass = 'Json';
+ $ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
+
+ $ExceptionRenderer->controller->expects($this->at(1))
+ ->method('render')
+ ->with('error400')
+ ->will($this->throwException($exception));
+
+ $ExceptionRenderer->controller->expects($this->at(3))
+ ->method('render')
+ ->with('error500')
+ ->will($this->returnValue(true));
+
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse');
+ $ExceptionRenderer->controller->response->expects($this->once())
+ ->method('type')
+ ->with('html');
+
+ $ExceptionRenderer->render();
+ $this->assertEquals('', $ExceptionRenderer->controller->layoutPath);
+ $this->assertEquals('', $ExceptionRenderer->controller->subDir);
+ $this->assertEquals('View', $ExceptionRenderer->controller->viewClass);
+ $this->assertEquals('Errors/', $ExceptionRenderer->controller->viewPath);
+ }
+
+/**
+ * Test that exceptions can be rendered when an request hasn't been registered
+ * with Router
+ *
+ * @return void
+ */
+ public function testRenderWithNoRequest() {
+ Router::reload();
+ $this->assertNull(Router::getRequest(false));
+
+ $exception = new Exception('Terrible');
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())
+ ->method('statusCode')
+ ->with(500);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertContains('Internal Error', $result);
+ }
+
+/**
+ * Tests the output of rendering a PDOException
+ *
+ * @return void
+ */
+ public function testPDOException() {
+ $exception = new PDOException('There was an error in the SQL query');
+ $exception->queryString = 'SELECT * from poo_query < 5 and :seven';
+ $exception->params = array('seven' => 7);
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse', array('statusCode', '_sendHeader'));
+ $ExceptionRenderer->controller->response->expects($this->once())->method('statusCode')->with(500);
+
+ ob_start();
+ $ExceptionRenderer->render();
+ $result = ob_get_clean();
+
+ $this->assertContains('<h2>Database Error</h2>', $result);
+ $this->assertContains('There was an error in the SQL query', $result);
+ $this->assertContains('SELECT * from poo_query < 5 and :seven', $result);
+ $this->assertContains("'seven' => (int) 7", $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventManagerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventManagerTest.php
new file mode 100644
index 0000000..04a358a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventManagerTest.php
@@ -0,0 +1,406 @@
+<?php
+/**
+ * ControllerTestCaseTest file
+ *
+ * Test Case for ControllerTestCase class
+ *
+ * PHP version 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Event
+ * @since CakePHP v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeEvent', 'Event');
+App::uses('CakeEventManager', 'Event');
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * Mock class used to test event dispatching
+ *
+ * @package Cake.Test.Case.Event
+ */
+class CakeEventTestListener {
+
+ public $callStack = array();
+
+/**
+ * Test function to be used in event dispatching
+ *
+ * @return void
+ */
+ public function listenerFunction() {
+ $this->callStack[] = __FUNCTION__;
+ }
+
+/**
+ * Test function to be used in event dispatching
+ *
+ * @return void
+ */
+ public function secondListenerFunction() {
+ $this->callStack[] = __FUNCTION__;
+ }
+
+/**
+ * Auxiliary function to help in stopPropagation testing
+ *
+ * @param CakeEvent $event
+ * @return void
+ */
+ public function stopListener($event) {
+ $event->stopPropagation();
+ }
+
+}
+
+/**
+ * Mock used for testing the subscriber objects
+ *
+ * @package Cake.Test.Case.Event
+ */
+class CustomTestEventListerner extends CakeEventTestListener implements CakeEventListener {
+
+ public function implementedEvents() {
+ return array(
+ 'fake.event' => 'listenerFunction',
+ 'another.event' => array('callable' => 'secondListenerFunction', 'passParams' => true),
+ 'multiple.handlers' => array(
+ array('callable' => 'listenerFunction'),
+ array('callable' => 'thirdListenerFunction')
+ )
+ );
+ }
+
+/**
+ * Test function to be used in event dispatching
+ *
+ * @return void
+ */
+ public function thirdListenerFunction() {
+ $this->callStack[] = __FUNCTION__;
+ }
+
+}
+
+/**
+ * Tests the CakeEventManager class functionality
+ *
+ */
+class CakeEventManagerTest extends CakeTestCase {
+
+/**
+ * Tests the attach() method for a single event key in multiple queues
+ *
+ * @return void
+ */
+ public function testAttachListeners() {
+ $manager = new CakeEventManager;
+ $manager->attach('fakeFunction', 'fake.event');
+ $expected = array(
+ array('callable' => 'fakeFunction', 'passParams' => false)
+ );
+ $this->assertEquals($expected, $manager->listeners('fake.event'));
+
+ $manager->attach('fakeFunction2', 'fake.event');
+ $expected[] = array('callable' => 'fakeFunction2', 'passParams' => false);
+ $this->assertEquals($expected, $manager->listeners('fake.event'));
+
+ $manager->attach('inQ5', 'fake.event', array('priority' => 5));
+ $manager->attach('inQ1', 'fake.event', array('priority' => 1));
+ $manager->attach('otherInQ5', 'fake.event', array('priority' => 5));
+
+ $expected = array_merge(
+ array(
+ array('callable' => 'inQ1', 'passParams' => false),
+ array('callable' => 'inQ5', 'passParams' => false),
+ array('callable' => 'otherInQ5', 'passParams' => false)
+ ),
+ $expected
+ );
+ $this->assertEquals($expected, $manager->listeners('fake.event'));
+ }
+
+/**
+ * Tests the attach() method for multiple event key in multiple queues
+ *
+ * @return void
+ */
+ public function testAttachMultipleEventKeys() {
+ $manager = new CakeEventManager;
+ $manager->attach('fakeFunction', 'fake.event');
+ $manager->attach('fakeFunction2', 'another.event');
+ $manager->attach('fakeFunction3', 'another.event', array('priority' => 1, 'passParams' => true));
+ $expected = array(
+ array('callable' => 'fakeFunction', 'passParams' => false)
+ );
+ $this->assertEquals($expected, $manager->listeners('fake.event'));
+
+ $expected = array(
+ array('callable' => 'fakeFunction3', 'passParams' => true),
+ array('callable' => 'fakeFunction2', 'passParams' => false)
+ );
+ $this->assertEquals($expected, $manager->listeners('another.event'));
+ }
+
+/**
+ * Tests detaching an event from a event key queue
+ *
+ * @return void
+ */
+ public function testDetach() {
+ $manager = new CakeEventManager;
+ $manager->attach(array('AClass', 'aMethod'), 'fake.event');
+ $manager->attach(array('AClass', 'anotherMethod'), 'another.event');
+ $manager->attach('fakeFunction', 'another.event', array('priority' => 1));
+
+ $manager->detach(array('AClass', 'aMethod'), 'fake.event');
+ $this->assertEquals(array(), $manager->listeners('fake.event'));
+
+ $manager->detach(array('AClass', 'anotherMethod'), 'another.event');
+ $expected = array(
+ array('callable' => 'fakeFunction', 'passParams' => false)
+ );
+ $this->assertEquals($expected, $manager->listeners('another.event'));
+
+ $manager->detach('fakeFunction', 'another.event');
+ $this->assertEquals(array(), $manager->listeners('another.event'));
+ }
+
+/**
+ * Tests detaching an event from all event queues
+ *
+ * @return void
+ */
+ public function testDetachFromAll() {
+ $manager = new CakeEventManager;
+ $manager->attach(array('AClass', 'aMethod'), 'fake.event');
+ $manager->attach(array('AClass', 'aMethod'), 'another.event');
+ $manager->attach('fakeFunction', 'another.event', array('priority' => 1));
+
+ $manager->detach(array('AClass', 'aMethod'));
+ $expected = array(
+ array('callable' => 'fakeFunction', 'passParams' => false)
+ );
+ $this->assertEquals($expected, $manager->listeners('another.event'));
+ $this->assertEquals(array(), $manager->listeners('fake.event'));
+ }
+
+/**
+ * Tests event dispatching
+ *
+ * @return void
+ */
+ public function testDispatch() {
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CakeEventTestListener');
+ $anotherListener = $this->getMock('CakeEventTestListener');
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event');
+ $event = new CakeEvent('fake.event');
+
+ $listener->expects($this->once())->method('listenerFunction')->with($event);
+ $anotherListener->expects($this->once())->method('listenerFunction')->with($event);
+ $manager->dispatch($event);
+ }
+
+/**
+ * Tests event dispatching using event key name
+ *
+ * @return void
+ */
+ public function testDispatchWithKeyName() {
+ $manager = new CakeEventManager;
+ $listener = new CakeEventTestListener;
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $event = 'fake.event';
+ $manager->dispatch($event);
+
+ $expected = array('listenerFunction');
+ $this->assertEquals($expected, $listener->callStack);
+ }
+
+/**
+ * Tests event dispatching with a return value
+ *
+ * @return void
+ */
+ public function testDispatchReturnValue() {
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CakeEventTestListener');
+ $anotherListener = $this->getMock('CakeEventTestListener');
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event');
+ $event = new CakeEvent('fake.event');
+
+ $firstStep = clone $event;
+ $listener->expects($this->at(0))->method('listenerFunction')
+ ->with($firstStep)
+ ->will($this->returnValue('something special'));
+ $anotherListener->expects($this->at(0))->method('listenerFunction')->with($event);
+ $manager->dispatch($event);
+ $this->assertEquals('something special', $event->result);
+ }
+
+/**
+ * Tests that returning false in a callback stops the event
+ *
+ * @return void
+ */
+ public function testDispatchFalseStopsEvent() {
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CakeEventTestListener');
+ $anotherListener = $this->getMock('CakeEventTestListener');
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event');
+ $event = new CakeEvent('fake.event');
+
+ $originalEvent = clone $event;
+ $listener->expects($this->at(0))->method('listenerFunction')
+ ->with($originalEvent)
+ ->will($this->returnValue(false));
+ $anotherListener->expects($this->never())->method('listenerFunction');
+ $manager->dispatch($event);
+ $this->assertTrue($event->isStopped());
+ }
+
+/**
+ * Tests event dispatching using priorities
+ *
+ * @return void
+ */
+ public function testDispatchPrioritized() {
+ $manager = new CakeEventManager;
+ $listener = new CakeEventTestListener;
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $manager->attach(array($listener, 'secondListenerFunction'), 'fake.event', array('priority' => 5));
+ $event = new CakeEvent('fake.event');
+ $manager->dispatch($event);
+
+ $expected = array('secondListenerFunction', 'listenerFunction');
+ $this->assertEquals($expected, $listener->callStack);
+ }
+
+/**
+ * Tests event dispatching with passed params
+ *
+ * @return void
+ */
+ public function testDispatchPassingParams() {
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CakeEventTestListener');
+ $anotherListener = $this->getMock('CakeEventTestListener');
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $manager->attach(array($anotherListener, 'secondListenerFunction'), 'fake.event', array('passParams' => true));
+ $event = new CakeEvent('fake.event', $this, array('some' => 'data'));
+
+ $listener->expects($this->once())->method('listenerFunction')->with($event);
+ $anotherListener->expects($this->once())->method('secondListenerFunction')->with('data');
+ $manager->dispatch($event);
+ }
+
+/**
+ * Tests subscribing a listener object and firing the events it subscribed to
+ *
+ * @return void
+ */
+ public function testAttachSubscriber() {
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CustomTestEventListerner', array('secondListenerFunction'));
+ $manager->attach($listener);
+ $event = new CakeEvent('fake.event');
+
+ $manager->dispatch($event);
+
+ $expected = array('listenerFunction');
+ $this->assertEquals($expected, $listener->callStack);
+
+ $listener->expects($this->at(0))->method('secondListenerFunction')->with('data');
+ $event = new CakeEvent('another.event', $this, array('some' => 'data'));
+ $manager->dispatch($event);
+
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CustomTestEventListerner', array('listenerFunction', 'thirdListenerFunction'));
+ $manager->attach($listener);
+ $event = new CakeEvent('multiple.handlers');
+ $listener->expects($this->once())->method('listenerFunction')->with($event);
+ $listener->expects($this->once())->method('thirdListenerFunction')->with($event);
+ $manager->dispatch($event);
+ }
+
+/**
+ * Tests subscribing a listener object and firing the events it subscribed to
+ *
+ * @return void
+ */
+ public function testDetachSubscriber() {
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CustomTestEventListerner', array('secondListenerFunction'));
+ $manager->attach($listener);
+ $expected = array(
+ array('callable' => array($listener, 'secondListenerFunction'), 'passParams' => true)
+ );
+ $this->assertEquals($expected, $manager->listeners('another.event'));
+ $expected = array(
+ array('callable' => array($listener, 'listenerFunction'), 'passParams' => false)
+ );
+ $this->assertEquals($expected, $manager->listeners('fake.event'));
+ $manager->detach($listener);
+ $this->assertEquals(array(), $manager->listeners('fake.event'));
+ $this->assertEquals(array(), $manager->listeners('another.event'));
+ }
+
+/**
+ * Tests that it is possible to get/set the manager singleton
+ *
+ * @return void
+ */
+ public function testGlobalDispatcherGetter() {
+ $this->assertInstanceOf('CakeEventManager', CakeEventManager::instance());
+ $manager = new CakeEventManager;
+
+ CakeEventManager::instance($manager);
+ $this->assertSame($manager, CakeEventManager::instance());
+ }
+
+/**
+ * Tests that the global event manager gets the event too from any other manager
+ *
+ * @return void
+ */
+ public function testDispatchWithGlobal() {
+ $generalManager = $this->getMock('CakeEventManager', array('dispatch'));
+ $manager = new CakeEventManager;
+ $event = new CakeEvent('fake.event');
+ CakeEventManager::instance($generalManager);
+
+ $generalManager->expects($this->once())->method('dispatch')->with($event);
+ $manager->dispatch($event);
+ }
+
+/**
+ * Tests that stopping an event will not notify the rest of the listeners
+ *
+ * @return void
+ */
+ public function testStopPropagation() {
+ $manager = new CakeEventManager;
+ $listener = new CakeEventTestListener;
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $manager->attach(array($listener, 'stopListener'), 'fake.event', array('priority' => 8));
+ $manager->attach(array($listener, 'secondListenerFunction'), 'fake.event', array('priority' => 5));
+ $event = new CakeEvent('fake.event');
+ $manager->dispatch($event);
+
+ $expected = array('secondListenerFunction');
+ $this->assertEquals($expected, $listener->callStack);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventTest.php
new file mode 100644
index 0000000..592a93a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Event/CakeEventTest.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * ControllerTestCaseTest file
+ *
+ * Test Case for ControllerTestCase class
+ *
+ * PHP version 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Event
+ * @since CakePHP v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeEvent', 'Event');
+
+/**
+ * Tests the CakeEvent class functionality
+ *
+ */
+class CakeEventTest extends CakeTestCase {
+
+/**
+ * Tests the name() method
+ *
+ * @return void
+ */
+ public function testName() {
+ $event = new CakeEvent('fake.event');
+ $this->assertEquals('fake.event', $event->name());
+ }
+
+/**
+ * Tests the subject() method
+ *
+ * @return void
+ */
+ public function testSubject() {
+ $event = new CakeEvent('fake.event', $this);
+ $this->assertSame($this, $event->subject());
+
+ $event = new CakeEvent('fake.event');
+ $this->assertNull($event->subject());
+ }
+
+/**
+ * Tests the event propagation stopping property
+ *
+ * @return void
+ */
+ public function testPropagation() {
+ $event = new CakeEvent('fake.event');
+ $this->assertFalse($event->isStopped());
+ $event->stopPropagation();
+ $this->assertTrue($event->isStopped());
+ }
+
+/**
+ * Tests that it is possible to get/set custom data in a event
+ *
+ * @return void
+ */
+ public function testEventData() {
+ $event = new CakeEvent('fake.event', $this, array('some' => 'data'));
+ $this->assertEquals(array('some' => 'data'), $event->data);
+ }
+
+/**
+ * Tests that it is possible to get the name and subject directly
+ *
+ * @return void
+ */
+ public function testEventDirectPropertyAccess() {
+ $event = new CakeEvent('fake.event', $this);
+ $this->assertEquals($this, $event->subject);
+ $this->assertEquals('fake.event', $event->name);
+ }
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/I18nTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/I18nTest.php
new file mode 100644
index 0000000..e86628b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/I18nTest.php
@@ -0,0 +1,1952 @@
+<?php
+/**
+ * I18nTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.I18n
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('I18n', 'I18n');
+
+/**
+ * I18nTest class
+ *
+ * @package Cake.Test.Case.I18n
+ */
+class I18nTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ Cache::delete('object_map', '_cake_core_');
+ App::build(array(
+ 'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ Cache::delete('object_map', '_cake_core_');
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * testTranslationCaching method
+ *
+ * @return void
+ */
+ public function testTranslationCaching() {
+ Configure::write('Config.language', 'cache_test_po');
+
+ // reset internally stored entries
+ I18n::clear();
+
+ Cache::clear(false, '_cake_core_');
+ $lang = Configure::read('Config.language');
+
+ Cache::config('_cake_core_', Cache::config('default'));
+
+ // make some calls to translate using different domains
+ $this->assertEquals('Dom 1 Foo', I18n::translate('dom1.foo', false, 'dom1'));
+ $this->assertEquals('Dom 1 Bar', I18n::translate('dom1.bar', false, 'dom1'));
+ $domains = I18n::domains();
+ $this->assertEquals('Dom 1 Foo', $domains['dom1']['cache_test_po']['LC_MESSAGES']['dom1.foo']);
+
+ // reset internally stored entries
+ I18n::clear();
+
+ // now only dom1 should be in cache
+ $cachedDom1 = Cache::read('dom1_' . $lang, '_cake_core_');
+ $this->assertEquals('Dom 1 Foo', $cachedDom1['LC_MESSAGES']['dom1.foo']);
+ $this->assertEquals('Dom 1 Bar', $cachedDom1['LC_MESSAGES']['dom1.bar']);
+ // dom2 not in cache
+ $this->assertFalse(Cache::read('dom2_' . $lang, '_cake_core_'));
+
+ // translate a item of dom2 (adds dom2 to cache)
+ $this->assertEquals('Dom 2 Foo', I18n::translate('dom2.foo', false, 'dom2'));
+
+ // verify dom2 was cached through manual read from cache
+ $cachedDom2 = Cache::read('dom2_' . $lang, '_cake_core_');
+ $this->assertEquals('Dom 2 Foo', $cachedDom2['LC_MESSAGES']['dom2.foo']);
+ $this->assertEquals('Dom 2 Bar', $cachedDom2['LC_MESSAGES']['dom2.bar']);
+
+ // modify cache entry manually to verify that dom1 entries now will be read from cache
+ $cachedDom1['LC_MESSAGES']['dom1.foo'] = 'FOO';
+ Cache::write('dom1_' . $lang, $cachedDom1, '_cake_core_');
+ $this->assertEquals('FOO', I18n::translate('dom1.foo', false, 'dom1'));
+ }
+
+/**
+ * testDefaultStrings method
+ *
+ * @return void
+ */
+ public function testDefaultStrings() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 1', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('1 = 1', $plurals));
+ $this->assertTrue(in_array('2 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('3 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('4 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('5 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('6 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('7 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('8 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('9 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('10 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('11 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('12 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('13 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('14 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('15 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('16 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('17 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('18 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('19 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('20 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('21 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('22 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('23 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('24 = 0 or > 1', $plurals));
+ $this->assertTrue(in_array('25 = 0 or > 1', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 1 (from core)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('1 = 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('2 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('3 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('4 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('5 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('6 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('7 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('8 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('9 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('10 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('11 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('12 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('13 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('14 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('15 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('16 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('17 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('18 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('19 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('20 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('21 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('22 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('23 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('24 = 0 or > 1 (from core)', $corePlurals));
+ $this->assertTrue(in_array('25 = 0 or > 1 (from core)', $corePlurals));
+ }
+
+/**
+ * testPoRulesZero method
+ *
+ * @return void
+ */
+ public function testPoRulesZero() {
+ Configure::write('Config.language', 'rule_0_po');
+ $this->assertRulesZero();
+ }
+
+/**
+ * testMoRulesZero method
+ *
+ * @return void
+ */
+ public function testMoRulesZero() {
+ Configure::write('Config.language', 'rule_0_mo');
+ $this->assertRulesZero();
+ }
+
+/**
+ * Assertions for rules zero.
+ *
+ * @return
+ */
+ public function assertRulesZero() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 0 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('1 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('2 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('3 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('4 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('5 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('6 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('7 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('8 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('9 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('10 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('11 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('12 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('13 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('14 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('15 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('16 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('17 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('18 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('19 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('20 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('21 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('22 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('23 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('24 ends with any # (translated)', $plurals));
+ $this->assertTrue(in_array('25 ends with any # (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 0 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 ends with any # (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 ends with any # (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesOne method
+ *
+ * @return void
+ */
+ public function testPoRulesOne() {
+ Configure::write('Config.language', 'rule_1_po');
+ $this->assertRulesOne();
+ }
+
+/**
+ * testMoRulesOne method
+ *
+ * @return void
+ */
+ public function testMoRulesOne() {
+ Configure::write('Config.language', 'rule_1_mo');
+ $this->assertRulesOne();
+ }
+
+/**
+ * Assertions for plural rule one
+ *
+ * @return void
+ */
+ public function assertRulesOne() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 1 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('1 = 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('3 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('4 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('5 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('6 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('7 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('8 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('9 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('10 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('11 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('12 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('13 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('14 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('15 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('16 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('17 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('18 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('19 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('20 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('21 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('22 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('23 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('24 = 0 or > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('25 = 0 or > 1 (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 1 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 = 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 = 0 or > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 = 0 or > 1 (from core translated)', $corePlurals));
+ }
+
+/**
+ * testMoRulesTwo method
+ *
+ * @return void
+ */
+ public function testMoRulesTwo() {
+ Configure::write('Config.language', 'rule_2_mo');
+ $this->assertRulesTwo();
+ }
+
+/**
+ * testPoRulesTwo method
+ *
+ * @return void
+ */
+ public function testPoRulesTwo() {
+ Configure::write('Config.language', 'rule_2_po');
+ $this->assertRulesTwo();
+ }
+
+/**
+ * Assertions for rules Two
+ *
+ * @return void
+ */
+ public function assertRulesTwo() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 2 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 = 0 or 1 (translated)', $plurals));
+ $this->assertTrue(in_array('1 = 0 or 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('3 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('4 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('5 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('6 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('7 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('8 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('9 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('10 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('11 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('12 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('13 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('14 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('15 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('16 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('17 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('18 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('19 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('20 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('21 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('22 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('23 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('24 > 1 (translated)', $plurals));
+ $this->assertTrue(in_array('25 > 1 (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 2 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 = 0 or 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 = 0 or 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 > 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 > 1 (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesThree method
+ *
+ * @return void
+ */
+ public function testPoRulesThree() {
+ Configure::write('Config.language', 'rule_3_po');
+ $this->assertRulesThree();
+ }
+
+/**
+ * testMoRulesThree method
+ *
+ * @return void
+ */
+ public function testMoRulesThree() {
+ Configure::write('Config.language', 'rule_3_mo');
+ $this->assertRulesThree();
+ }
+
+/**
+ * Assert rules for plural three.
+ *
+ * @return void
+ */
+ public function assertRulesThree() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 3 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 = 0 (translated)', $plurals));
+ $this->assertTrue(in_array('1 ends 1 but not 11 (translated)', $plurals));
+ $this->assertTrue(in_array('2 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('3 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('4 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 ends 1 but not 11 (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 3 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 = 0 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 ends 1 but not 11 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 ends 1 but not 11 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesFour method
+ *
+ * @return void
+ */
+ public function testPoRulesFour() {
+ Configure::write('Config.language', 'rule_4_po');
+ $this->assertRulesFour();
+ }
+
+/**
+ * testMoRulesFour method
+ *
+ * @return void
+ */
+ public function testMoRulesFour() {
+ Configure::write('Config.language', 'rule_4_mo');
+ $this->assertRulesFour();
+ }
+
+/**
+ * Run the assertions for Rule 4 plurals.
+ *
+ * @return void
+ */
+ public function assertRulesFour() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 4 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('1 = 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 = 2 (translated)', $plurals));
+ $this->assertTrue(in_array('3 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('4 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 4 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 = 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 = 2 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesFive method
+ *
+ * @return void
+ */
+ public function testPoRulesFive() {
+ Configure::write('Config.language', 'rule_5_po');
+ $this->assertRulesFive();
+ }
+
+/**
+ * testMoRulesFive method
+ *
+ * @return void
+ */
+ public function testMoRulesFive() {
+ Configure::write('Config.language', 'rule_5_mo');
+ $this->assertRulesFive();
+ }
+
+/**
+ * Run the assertions for rule 5 plurals
+ *
+ * @return void
+ */
+ public function assertRulesFive() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 5 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('0 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('1 = 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('3 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('4 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('5 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('6 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('7 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('8 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('9 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('10 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('11 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('12 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('13 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('14 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('15 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('16 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('17 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('18 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('19 = 0 or ends in 01-19 (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 5 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('0 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 = 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 = 0 or ends in 01-19 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesSix method
+ *
+ * @return void
+ */
+ public function testPoRulesSix() {
+ Configure::write('Config.language', 'rule_6_po');
+ $this->assertRulesSix();
+ }
+
+/**
+ * testMoRulesSix method
+ *
+ * @return void
+ */
+ public function testMoRulesSix() {
+ Configure::write('Config.language', 'rule_6_mo');
+ $this->assertRulesSix();
+ }
+
+/**
+ * Assertions for the sixth plural rules.
+ *
+ * @return void
+ */
+ public function assertRulesSix() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 6 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('1 ends in 1, not 11 (translated)', $plurals));
+ $this->assertTrue(in_array('2 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('3 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('4 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('11 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('12 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('13 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('14 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('15 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('16 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('17 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('18 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('19 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('20 ends in 0 or ends in 10-20 (translated)', $plurals));
+ $this->assertTrue(in_array('21 ends in 1, not 11 (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 6 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 ends in 1, not 11 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 ends in 0 or ends in 10-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 ends in 1, not 11 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesSeven method
+ *
+ * @return void
+ */
+ public function testPoRulesSeven() {
+ Configure::write('Config.language', 'rule_7_po');
+ $this->assertRulesSeven();
+ }
+
+/**
+ * testMoRulesSeven method
+ *
+ * @return void
+ */
+ public function testMoRulesSeven() {
+ Configure::write('Config.language', 'rule_7_mo');
+ $this->assertRulesSeven();
+ }
+
+/**
+ * Run assertions for seventh plural rules
+ *
+ * @return void
+ */
+ public function assertRulesSeven() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 7 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('1 ends in 1, not 11 (translated)', $plurals));
+ $this->assertTrue(in_array('2 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('3 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('4 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 ends in 1, not 11 (translated)', $plurals));
+ $this->assertTrue(in_array('22 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('23 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('24 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 7 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 ends in 1, not 11 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 ends in 1, not 11 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesEight method
+ *
+ * @return void
+ */
+ public function testPoRulesEight() {
+ Configure::write('Config.language', 'rule_8_po');
+ $this->assertRulesEight();
+ }
+
+/**
+ * testMoRulesEight method
+ *
+ * @return void
+ */
+ public function testMoRulesEight() {
+ Configure::write('Config.language', 'rule_8_mo');
+ $this->assertRulesEight();
+ }
+
+/**
+ * Run assertions for the eighth plural rule.
+ *
+ * @return void
+ */
+ public function assertRulesEight() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 8 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('1 is 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 is 2-4 (translated)', $plurals));
+ $this->assertTrue(in_array('3 is 2-4 (translated)', $plurals));
+ $this->assertTrue(in_array('4 is 2-4 (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 8 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 is 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 is 2-4 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 is 2-4 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 is 2-4 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesNine method
+ *
+ * @return void
+ */
+ public function testPoRulesNine() {
+ Configure::write('Config.language', 'rule_9_po');
+ $this->assertRulesNine();
+ }
+
+/**
+ * testMoRulesNine method
+ *
+ * @return void
+ */
+ public function testMoRulesNine() {
+ Configure::write('Config.language', 'rule_9_mo');
+ $this->assertRulesNine();
+ }
+
+/**
+ * Assert plural rules nine
+ *
+ * @return void
+ */
+ public function assertRulesNine() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 9 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('1 is 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('3 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('4 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('23 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('24 ends in 2-4, not 12-14 (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 9 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 is 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 ends in 2-4, not 12-14 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesTen method
+ *
+ * @return void
+ */
+ public function testPoRulesTen() {
+ Configure::write('Config.language', 'rule_10_po');
+ $this->assertRulesTen();
+ }
+
+/**
+ * testMoRulesTen method
+ *
+ * @return void
+ */
+ public function testMoRulesTen() {
+ Configure::write('Config.language', 'rule_10_mo');
+ $this->assertRulesTen();
+ }
+
+/**
+ * Assertions for plural rules 10
+ *
+ * @return void
+ */
+ public function assertRulesTen() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 10 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('1 ends in 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 ends in 2 (translated)', $plurals));
+ $this->assertTrue(in_array('3 ends in 03-04 (translated)', $plurals));
+ $this->assertTrue(in_array('4 ends in 03-04 (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 10 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 ends in 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 ends in 2 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 ends in 03-04 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 ends in 03-04 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesEleven method
+ *
+ * @return void
+ */
+ public function testPoRulesEleven() {
+ Configure::write('Config.language', 'rule_11_po');
+ $this->assertRulesEleven();
+ }
+
+/**
+ * testMoRulesEleven method
+ *
+ * @return void
+ */
+ public function testMoRulesEleven() {
+ Configure::write('Config.language', 'rule_11_mo');
+ $this->assertRulesEleven();
+ }
+
+/**
+ * Assertions for plural rules eleven
+ *
+ * @return void
+ */
+ public function assertRulesEleven() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 11 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('1 is 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 is 2 (translated)', $plurals));
+ $this->assertTrue(in_array('3 is 3-6 (translated)', $plurals));
+ $this->assertTrue(in_array('4 is 3-6 (translated)', $plurals));
+ $this->assertTrue(in_array('5 is 3-6 (translated)', $plurals));
+ $this->assertTrue(in_array('6 is 3-6 (translated)', $plurals));
+ $this->assertTrue(in_array('7 is 7-10 (translated)', $plurals));
+ $this->assertTrue(in_array('8 is 7-10 (translated)', $plurals));
+ $this->assertTrue(in_array('9 is 7-10 (translated)', $plurals));
+ $this->assertTrue(in_array('10 is 7-10 (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 11 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 is 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 is 2 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 is 3-6 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 is 3-6 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 is 3-6 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 is 3-6 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 is 7-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 is 7-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 is 7-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 is 7-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPoRulesTwelve method
+ *
+ * @return void
+ */
+ public function testPoRulesTwelve() {
+ Configure::write('Config.language', 'rule_12_po');
+ $this->assertRulesTwelve();
+ }
+
+/**
+ * testMoRulesTwelve method
+ *
+ * @return void
+ */
+ public function testMoRulesTwelve() {
+ Configure::write('Config.language', 'rule_12_mo');
+ $this->assertRulesTwelve();
+ }
+
+/**
+ * Assertions for plural rules twelve
+ *
+ * @return void
+ */
+ public function assertRulesTwelve() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 12 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('1 is 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 is 2 (translated)', $plurals));
+ $this->assertTrue(in_array('3 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('4 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('5 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('6 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('7 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('8 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('9 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('10 is 0 or 3-10 (translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 12 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 is 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 is 2 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 is 0 or 3-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testMoRulesThirteen method
+ *
+ * @return void
+ */
+ public function testmoRulesThirteen() {
+ Configure::write('Config.language', 'rule_13_mo');
+ $this->assertRulesThirteen();
+ }
+
+/**
+ * testPoRulesThirteen method
+ *
+ * @return void
+ */
+ public function testPoRulesThirteen() {
+ Configure::write('Config.language', 'rule_13_po');
+ $this->assertRulesThirteen();
+ }
+
+/**
+ * Assertions for plural rules thirteen
+ *
+ * @return void
+ */
+ public function assertRulesThirteen() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 13 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('1 is 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('3 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('4 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('5 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('6 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('7 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('8 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('9 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('10 is 0 or ends in 01-10 (translated)', $plurals));
+ $this->assertTrue(in_array('11 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('12 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('13 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('14 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('15 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('16 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('17 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('18 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('19 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('20 ends in 11-20 (translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 13 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 is 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 is 0 or ends in 01-10 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 ends in 11-20 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testMoRulesFourteen method
+ *
+ * @return void
+ */
+ public function testMoRulesFourteen() {
+ Configure::write('Config.language', 'rule_14_mo');
+ $this->assertRulesFourteen();
+ }
+
+/**
+ * testPoRulesFourteen method
+ *
+ * @return void
+ */
+ public function testPoRulesFourteen() {
+ Configure::write('Config.language', 'rule_14_po');
+ $this->assertRulesFourteen();
+ }
+
+/**
+ * Assertions for plural rules fourteen
+ *
+ * @return void
+ */
+ public function assertRulesFourteen() {
+ $singular = $this->__singular();
+ $this->assertEquals('Plural Rule 14 (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('1 ends in 1 (translated)', $plurals));
+ $this->assertTrue(in_array('2 ends in 2 (translated)', $plurals));
+ $this->assertTrue(in_array('3 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('4 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('11 ends in 1 (translated)', $plurals));
+ $this->assertTrue(in_array('12 ends in 2 (translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('21 ends in 1 (translated)', $plurals));
+ $this->assertTrue(in_array('22 ends in 2 (translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (translated)', $plurals));
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertEquals('Plural Rule 14 (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertTrue(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('1 ends in 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('2 ends in 2 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('3 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('4 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('11 ends in 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('12 ends in 2 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('21 ends in 1 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('22 ends in 2 (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertTrue(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testSetLanguageWithSession method
+ *
+ * @return void
+ */
+ public function testSetLanguageWithSession() {
+ $_SESSION['Config']['language'] = 'po';
+ $singular = $this->__singular();
+ $this->assertEquals('Po (translated)', $singular);
+
+ $plurals = $this->__plural();
+ $this->assertTrue(in_array('0 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('1 is 1 (po translated)', $plurals));
+ $this->assertTrue(in_array('2 is 2-4 (po translated)', $plurals));
+ $this->assertTrue(in_array('3 is 2-4 (po translated)', $plurals));
+ $this->assertTrue(in_array('4 is 2-4 (po translated)', $plurals));
+ $this->assertTrue(in_array('5 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('6 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('7 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('8 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('9 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('10 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('11 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('12 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('13 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('14 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('15 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('16 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('17 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('18 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('19 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('20 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('21 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('22 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('23 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('24 everything else (po translated)', $plurals));
+ $this->assertTrue(in_array('25 everything else (po translated)', $plurals));
+ unset($_SESSION['Config']['language']);
+ }
+
+/**
+ * testNoCoreTranslation method
+ *
+ * @return void
+ */
+ public function testNoCoreTranslation() {
+ Configure::write('Config.language', 'po');
+ $singular = $this->__singular();
+ $this->assertEquals('Po (translated)', $singular);
+
+ $coreSingular = $this->__singularFromCore();
+ $this->assertNotEquals('Po (from core translated)', $coreSingular);
+
+ $corePlurals = $this->__pluralFromCore();
+ $this->assertFalse(in_array('0 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('1 is 1 (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('2 is 2-4 (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('3 is 2-4 (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('4 is 2-4 (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('5 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('6 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('7 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('8 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('9 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('10 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('11 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('12 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('13 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('14 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('15 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('16 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('17 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('18 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('19 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('20 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('21 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('22 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('23 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('24 everything else (from core translated)', $corePlurals));
+ $this->assertFalse(in_array('25 everything else (from core translated)', $corePlurals));
+ }
+
+/**
+ * testPluginTranslation method
+ *
+ * @return void
+ */
+ public function testPluginTranslation() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+
+ Configure::write('Config.language', 'po');
+ $singular = $this->__domainSingular();
+ $this->assertEquals('Plural Rule 1 (from plugin)', $singular);
+
+ $plurals = $this->__domainPlural();
+ $this->assertTrue(in_array('0 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('1 = 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('2 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('3 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('4 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('5 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('6 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('7 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('8 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('9 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('10 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('11 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('12 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('13 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('14 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('15 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('16 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('17 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('18 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('19 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('20 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('21 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('22 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('23 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('24 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('25 = 0 or > 1 (from plugin)', $plurals));
+ }
+
+/**
+ * testPoMultipleLineTranslation method
+ *
+ * @return void
+ */
+ public function testPoMultipleLineTranslation() {
+ Configure::write('Config.language', 'po');
+
+ $string = "This is a multiline translation\n";
+ $string .= "broken up over multiple lines.\n";
+ $string .= "This is the third line.\n";
+ $string .= "This is the forth line.";
+ $result = __($string);
+
+ $expected = "This is a multiline translation\n";
+ $expected .= "broken up over multiple lines.\n";
+ $expected .= "This is the third line.\n";
+ $expected .= "This is the forth line. (translated)";
+ $this->assertEquals($expected, $result);
+
+ // Windows Newline is \r\n
+ $string = "This is a multiline translation\r\n";
+ $string .= "broken up over multiple lines.\r\n";
+ $string .= "This is the third line.\r\n";
+ $string .= "This is the forth line.";
+ $result = __($string);
+ $this->assertEquals($expected, $result);
+
+ $singular = "valid\nsecond line";
+ $plural = "valids\nsecond line";
+
+ $result = __n($singular, $plural, 1);
+ $expected = "v\nsecond line";
+ $this->assertEquals($expected, $result);
+
+ $result = __n($singular, $plural, 2);
+ $expected = "vs\nsecond line";
+ $this->assertEquals($expected, $result);
+
+ $string = "This is a multiline translation\n";
+ $string .= "broken up over multiple lines.\n";
+ $string .= "This is the third line.\n";
+ $string .= "This is the forth line.";
+
+ $singular = "%d = 1\n" . $string;
+ $plural = "%d = 0 or > 1\n" . $string;
+
+ $result = __n($singular, $plural, 1);
+ $expected = "%d is 1\n" . $string;
+ $this->assertEquals($expected, $result);
+
+ $result = __n($singular, $plural, 2);
+ $expected = "%d is 2-4\n" . $string;
+ $this->assertEquals($expected, $result);
+
+ // Windows Newline is \r\n
+ $string = "This is a multiline translation\r\n";
+ $string .= "broken up over multiple lines.\r\n";
+ $string .= "This is the third line.\r\n";
+ $string .= "This is the forth line.";
+
+ $singular = "%d = 1\r\n" . $string;
+ $plural = "%d = 0 or > 1\r\n" . $string;
+
+ $result = __n($singular, $plural, 1);
+ $expected = "%d is 1\n" . str_replace("\r\n", "\n", $string);
+ $this->assertEquals($expected, $result);
+
+ $result = __n($singular, $plural, 2);
+ $expected = "%d is 2-4\n" . str_replace("\r\n", "\n", $string);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testPoNoTranslationNeeded method
+ *
+ * @return void
+ */
+ public function testPoNoTranslationNeeded() {
+ Configure::write('Config.language', 'po');
+ $result = __('No Translation needed');
+ $this->assertEquals('No Translation needed', $result);
+ }
+
+/**
+ * testPoQuotedString method
+ *
+ * @return void
+ */
+ public function testPoQuotedString() {
+ Configure::write('Config.language', 'po');
+ $expected = 'this is a "quoted string" (translated)';
+ $this->assertEquals($expected, __('this is a "quoted string"'));
+ }
+
+/**
+ * testFloatValue method
+ *
+ * @return void
+ */
+ public function testFloatValue() {
+ Configure::write('Config.language', 'rule_9_po');
+
+ $result = __n('%d = 1', '%d = 0 or > 1', (float)1);
+ $expected = '%d is 1 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = __n('%d = 1', '%d = 0 or > 1', (float)2);
+ $expected = "%d ends in 2-4, not 12-14 (translated)";
+ $this->assertEquals($expected, $result);
+
+ $result = __n('%d = 1', '%d = 0 or > 1', (float)5);
+ $expected = "%d everything else (translated)";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCategory method
+ *
+ * @return void
+ */
+ public function testCategory() {
+ Configure::write('Config.language', 'po');
+ $category = $this->__category();
+ $this->assertEquals('Monetary Po (translated)', $category);
+ }
+
+/**
+ * testPluginCategory method
+ *
+ * @return void
+ */
+ public function testPluginCategory() {
+ Configure::write('Config.language', 'po');
+
+ $singular = $this->__domainCategorySingular();
+ $this->assertEquals('Monetary Plural Rule 1 (from plugin)', $singular);
+
+ $plurals = $this->__domainCategoryPlural();
+ $this->assertTrue(in_array('Monetary 0 = 0 or > 1 (from plugin)', $plurals));
+ $this->assertTrue(in_array('Monetary 1 = 1 (from plugin)', $plurals));
+ }
+
+/**
+ * testCategoryThenSingular method
+ *
+ * @return void
+ */
+ public function testCategoryThenSingular() {
+ Configure::write('Config.language', 'po');
+ $category = $this->__category();
+ $this->assertEquals('Monetary Po (translated)', $category);
+
+ $singular = $this->__singular();
+ $this->assertEquals('Po (translated)', $singular);
+ }
+
+/**
+ * testTimeDefinition method
+ *
+ * @return void
+ */
+ public function testTimeDefinition() {
+ Configure::write('Config.language', 'po');
+ $result = __c('d_fmt', 5);
+ $expected = '%m/%d/%Y';
+ $this->assertEquals($expected, $result);
+
+ $result = __c('am_pm', 5);
+ $expected = array('AM', 'PM');
+ $this->assertEquals($expected, $result);
+
+ $result = __c('abmon', 5);
+ $expected = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testTimeDefinitionJapanese method
+ *
+ * @return void
+ */
+ public function testTimeDefinitionJapanese() {
+ Configure::write('Config.language', 'ja_jp');
+ $result = __c('d_fmt', 5);
+
+ $expected = "%Y年%m月%d日";
+
+ $this->assertEquals($expected, $result);
+
+ $result = __c('am_pm', 5);
+ $expected = array("午前", "午後");
+ $this->assertEquals($expected, $result);
+
+ $result = __c('abmon', 5);
+ $expected = array(" 1月", " 2月", " 3月", " 4月", " 5月", " 6月", " 7月", " 8月", " 9月", "10月", "11月", "12月");
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testTranslateLanguageParam method
+ *
+ * @return void
+ */
+ public function testTranslateLanguageParam() {
+ Configure::write('Config.language', 'rule_0_po');
+
+ $result = I18n::translate('Plural Rule 1', null, null, 6);
+ $expected = 'Plural Rule 0 (translated)';
+ $this->assertEquals($expected, $result);
+
+ $result = I18n::translate('Plural Rule 1', null, null, 6, null, 'rule_1_po');
+ $expected = 'Plural Rule 1 (translated)';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Singular method
+ *
+ * @return void
+ */
+ private function __domainCategorySingular($domain = 'test_plugin', $category = 3) {
+ $singular = __dc($domain, 'Plural Rule 1', $category);
+ return $singular;
+ }
+
+/**
+ * Plural method
+ *
+ * @return void
+ */
+ private function __domainCategoryPlural($domain = 'test_plugin', $category = 3) {
+ $plurals = array();
+ for ($number = 0; $number <= 25; $number++) {
+ $plurals[] = sprintf(__dcn($domain, '%d = 1', '%d = 0 or > 1', (float)$number, $category), (float)$number);
+ }
+ return $plurals;
+ }
+
+/**
+ * Singular method
+ *
+ * @return void
+ */
+ private function __domainSingular($domain = 'test_plugin') {
+ $singular = __d($domain, 'Plural Rule 1');
+ return $singular;
+ }
+
+/**
+ * Plural method
+ *
+ * @return void
+ */
+ private function __domainPlural($domain = 'test_plugin') {
+ $plurals = array();
+ for ($number = 0; $number <= 25; $number++) {
+ $plurals[] = sprintf(__dn($domain, '%d = 1', '%d = 0 or > 1', (float)$number), (float)$number );
+ }
+ return $plurals;
+ }
+
+/**
+ * category method
+ *
+ * @return void
+ */
+ private function __category($category = 3) {
+ $singular = __c('Plural Rule 1', $category);
+ return $singular;
+ }
+
+/**
+ * Singular method
+ *
+ * @return void
+ */
+ private function __singular() {
+ $singular = __('Plural Rule 1');
+ return $singular;
+ }
+
+/**
+ * Plural method
+ *
+ * @return void
+ */
+ private function __plural() {
+ $plurals = array();
+ for ($number = 0; $number <= 25; $number++) {
+ $plurals[] = sprintf(__n('%d = 1', '%d = 0 or > 1', (float)$number), (float)$number);
+ }
+ return $plurals;
+ }
+
+/**
+ * singularFromCore method
+ *
+ * @return void
+ */
+ private function __singularFromCore() {
+ $singular = __('Plural Rule 1 (from core)');
+ return $singular;
+ }
+
+/**
+ * pluralFromCore method
+ *
+ * @return void
+ */
+ private function __pluralFromCore() {
+ $plurals = array();
+ for ($number = 0; $number <= 25; $number++) {
+ $plurals[] = sprintf(__n('%d = 1 (from core)', '%d = 0 or > 1 (from core)', (float)$number), (float)$number );
+ }
+ return $plurals;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/L10nTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/L10nTest.php
new file mode 100644
index 0000000..d52c3a6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/L10nTest.php
@@ -0,0 +1,955 @@
+<?php
+/**
+ * L10nTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.I18n
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('L10n', 'I18n');
+
+/**
+ * L10nTest class
+ *
+ * @package Cake.Test.Case.I18n
+ */
+class L10nTest extends CakeTestCase {
+
+/**
+ * testGet method
+ *
+ * @return void
+ */
+ public function testGet() {
+ $localize = new L10n();
+
+ // Catalog Entry
+ $lang = $localize->get('en');
+
+ $this->assertEquals('en', $lang);
+ $this->assertEquals('English', $localize->language);
+ $this->assertEquals(array('eng', 'eng'), $localize->languagePath);
+ $this->assertEquals('eng', $localize->locale);
+
+ // Map Entry
+ $localize->get('eng');
+
+ $this->assertEquals('English', $localize->language);
+ $this->assertEquals(array('eng', 'eng'), $localize->languagePath);
+ $this->assertEquals('eng', $localize->locale);
+
+ // Catalog Entry
+ $localize->get('en-ca');
+
+ $this->assertEquals('English (Canadian)', $localize->language);
+ $this->assertEquals(array('en_ca', 'eng'), $localize->languagePath);
+ $this->assertEquals('en_ca', $localize->locale);
+
+ // Default Entry
+ define('DEFAULT_LANGUAGE', 'en-us');
+
+ $lang = $localize->get('use_default');
+
+ $this->assertEquals('en-us', $lang);
+ $this->assertEquals('English (United States)', $localize->language);
+ $this->assertEquals(array('en_us', 'eng'), $localize->languagePath);
+ $this->assertEquals('en_us', $localize->locale);
+
+ $localize->get('es');
+ $localize->get('');
+ $this->assertEquals('en-us', $localize->lang);
+
+ // Using $this->default
+ $localize = new L10n();
+
+ $localize->get('use_default');
+ $this->assertEquals('English (United States)', $localize->language);
+ $this->assertEquals(array('en_us', 'eng', 'eng'), $localize->languagePath);
+ $this->assertEquals('en_us', $localize->locale);
+ }
+
+/**
+ * testGetAutoLanguage method
+ *
+ * @return void
+ */
+ public function testGetAutoLanguage() {
+ $serverBackup = $_SERVER;
+ $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'inexistent,en-ca';
+
+ $localize = new L10n();
+ $lang = $localize->get();
+
+ $this->assertEquals('en-ca', $lang);
+ $this->assertEquals('English (Canadian)', $localize->language);
+ $this->assertEquals(array('en_ca', 'eng', 'eng'), $localize->languagePath);
+ $this->assertEquals('en_ca', $localize->locale);
+
+ $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'es_mx';
+ $lang = $localize->get();
+
+ $this->assertEquals('es-mx', $lang);
+ $this->assertEquals('Spanish (Mexican)', $localize->language);
+ $this->assertEquals(array('es_mx', 'spa', 'eng'), $localize->languagePath);
+ $this->assertEquals('es_mx', $localize->locale);
+
+ $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'en_xy,en_ca';
+ $localize->get();
+
+ $this->assertEquals('English', $localize->language);
+ $this->assertEquals(array('eng', 'eng', 'eng'), $localize->languagePath);
+ $this->assertEquals('eng', $localize->locale);
+
+ $_SERVER = $serverBackup;
+ }
+
+/**
+ * testMap method
+ *
+ * @return void
+ */
+ public function testMap() {
+ $localize = new L10n();
+
+ $result = $localize->map(array('afr', 'af'));
+ $expected = array('afr' => 'af', 'af' => 'afr');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('alb', 'sq'));
+ $expected = array('alb' => 'sq', 'sq' => 'alb');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ara', 'ar'));
+ $expected = array('ara' => 'ar', 'ar' => 'ara');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('hye', 'hy'));
+ $expected = array('hye' => 'hy', 'hy' => 'hye');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('baq', 'eu'));
+ $expected = array('baq' => 'eu', 'eu' => 'baq');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('baq', 'eu'));
+ $expected = array('baq' => 'eu', 'eu' => 'baq');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('bos', 'bs'));
+ $expected = array('bos' => 'bs', 'bs' => 'bos');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('bul', 'bg'));
+ $expected = array('bul' => 'bg', 'bg' => 'bul');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('bel', 'be'));
+ $expected = array('bel' => 'be', 'be' => 'bel');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('cat', 'ca'));
+ $expected = array('cat' => 'ca', 'ca' => 'cat');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('chi', 'zh'));
+ $expected = array('chi' => 'zh', 'zh' => 'chi');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('zho', 'zh'));
+ $expected = array('zho' => 'zh', 'zh' => 'chi');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('hrv', 'hr'));
+ $expected = array('hrv' => 'hr', 'hr' => 'hrv');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ces', 'cs'));
+ $expected = array('ces' => 'cs', 'cs' => 'cze');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('cze', 'cs'));
+ $expected = array('cze' => 'cs', 'cs' => 'cze');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('dan', 'da'));
+ $expected = array('dan' => 'da', 'da' => 'dan');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('dut', 'nl'));
+ $expected = array('dut' => 'nl', 'nl' => 'dut');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('nld', 'nl'));
+ $expected = array('nld' => 'nl', 'nl' => 'dut');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('nld'));
+ $expected = array('nld' => 'nl');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('eng', 'en'));
+ $expected = array('eng' => 'en', 'en' => 'eng');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('est', 'et'));
+ $expected = array('est' => 'et', 'et' => 'est');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('fao', 'fo'));
+ $expected = array('fao' => 'fo', 'fo' => 'fao');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('fas', 'fa'));
+ $expected = array('fas' => 'fa', 'fa' => 'fas');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('per', 'fa'));
+ $expected = array('per' => 'fa', 'fa' => 'fas');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('fin', 'fi'));
+ $expected = array('fin' => 'fi', 'fi' => 'fin');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('fra', 'fr'));
+ $expected = array('fra' => 'fr', 'fr' => 'fre');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('fre', 'fr'));
+ $expected = array('fre' => 'fr', 'fr' => 'fre');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('gla', 'gd'));
+ $expected = array('gla' => 'gd', 'gd' => 'gla');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('glg', 'gl'));
+ $expected = array('glg' => 'gl', 'gl' => 'glg');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('deu', 'de'));
+ $expected = array('deu' => 'de', 'de' => 'deu');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ger', 'de'));
+ $expected = array('ger' => 'de', 'de' => 'deu');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ell', 'el'));
+ $expected = array('ell' => 'el', 'el' => 'gre');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('gre', 'el'));
+ $expected = array('gre' => 'el', 'el' => 'gre');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('heb', 'he'));
+ $expected = array('heb' => 'he', 'he' => 'heb');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('hin', 'hi'));
+ $expected = array('hin' => 'hi', 'hi' => 'hin');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('hun', 'hu'));
+ $expected = array('hun' => 'hu', 'hu' => 'hun');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ice', 'is'));
+ $expected = array('ice' => 'is', 'is' => 'ice');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('isl', 'is'));
+ $expected = array('isl' => 'is', 'is' => 'ice');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ind', 'id'));
+ $expected = array('ind' => 'id', 'id' => 'ind');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('gle', 'ga'));
+ $expected = array('gle' => 'ga', 'ga' => 'gle');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ita', 'it'));
+ $expected = array('ita' => 'it', 'it' => 'ita');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('jpn', 'ja'));
+ $expected = array('jpn' => 'ja', 'ja' => 'jpn');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('kor', 'ko'));
+ $expected = array('kor' => 'ko', 'ko' => 'kor');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('lav', 'lv'));
+ $expected = array('lav' => 'lv', 'lv' => 'lav');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('lit', 'lt'));
+ $expected = array('lit' => 'lt', 'lt' => 'lit');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('mac', 'mk'));
+ $expected = array('mac' => 'mk', 'mk' => 'mac');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('mkd', 'mk'));
+ $expected = array('mkd' => 'mk', 'mk' => 'mac');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('may', 'ms'));
+ $expected = array('may' => 'ms', 'ms' => 'may');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('msa', 'ms'));
+ $expected = array('msa' => 'ms', 'ms' => 'may');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('mlt', 'mt'));
+ $expected = array('mlt' => 'mt', 'mt' => 'mlt');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('nor', 'no'));
+ $expected = array('nor' => 'no', 'no' => 'nor');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('nob', 'nb'));
+ $expected = array('nob' => 'nb', 'nb' => 'nob');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('nno', 'nn'));
+ $expected = array('nno' => 'nn', 'nn' => 'nno');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('pol', 'pl'));
+ $expected = array('pol' => 'pl', 'pl' => 'pol');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('por', 'pt'));
+ $expected = array('por' => 'pt', 'pt' => 'por');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('roh', 'rm'));
+ $expected = array('roh' => 'rm', 'rm' => 'roh');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ron', 'ro'));
+ $expected = array('ron' => 'ro', 'ro' => 'rum');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('rum', 'ro'));
+ $expected = array('rum' => 'ro', 'ro' => 'rum');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('rus', 'ru'));
+ $expected = array('rus' => 'ru', 'ru' => 'rus');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('smi', 'sz'));
+ $expected = array('smi' => 'sz', 'sz' => 'smi');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('scc', 'sr'));
+ $expected = array('scc' => 'sr', 'sr' => 'scc');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('srp', 'sr'));
+ $expected = array('srp' => 'sr', 'sr' => 'scc');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('slk', 'sk'));
+ $expected = array('slk' => 'sk', 'sk' => 'slo');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('slo', 'sk'));
+ $expected = array('slo' => 'sk', 'sk' => 'slo');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('slv', 'sl'));
+ $expected = array('slv' => 'sl', 'sl' => 'slv');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('wen', 'sb'));
+ $expected = array('wen' => 'sb', 'sb' => 'wen');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('spa', 'es'));
+ $expected = array('spa' => 'es', 'es' => 'spa');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('swe', 'sv'));
+ $expected = array('swe' => 'sv', 'sv' => 'swe');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('tha', 'th'));
+ $expected = array('tha' => 'th', 'th' => 'tha');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('tso', 'ts'));
+ $expected = array('tso' => 'ts', 'ts' => 'tso');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('tsn', 'tn'));
+ $expected = array('tsn' => 'tn', 'tn' => 'tsn');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('tur', 'tr'));
+ $expected = array('tur' => 'tr', 'tr' => 'tur');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ukr', 'uk'));
+ $expected = array('ukr' => 'uk', 'uk' => 'ukr');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('urd', 'ur'));
+ $expected = array('urd' => 'ur', 'ur' => 'urd');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('ven', 've'));
+ $expected = array('ven' => 've', 've' => 'ven');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('vie', 'vi'));
+ $expected = array('vie' => 'vi', 'vi' => 'vie');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('xho', 'xh'));
+ $expected = array('xho' => 'xh', 'xh' => 'xho');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('cy', 'cym'));
+ $expected = array('cym' => 'cy', 'cy' => 'cym');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('yid', 'yi'));
+ $expected = array('yid' => 'yi', 'yi' => 'yid');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->map(array('zul', 'zu'));
+ $expected = array('zul' => 'zu', 'zu' => 'zul');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCatalog method
+ *
+ * @return void
+ */
+ public function testCatalog() {
+ $localize = new L10n();
+
+ $result = $localize->catalog(array('af'));
+ $expected = array(
+ 'af' => array('language' => 'Afrikaans', 'locale' => 'afr', 'localeFallback' => 'afr', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ar', 'ar-ae', 'ar-bh', 'ar-dz', 'ar-eg', 'ar-iq', 'ar-jo', 'ar-kw', 'ar-lb', 'ar-ly', 'ar-ma',
+ 'ar-om', 'ar-qa', 'ar-sa', 'ar-sy', 'ar-tn', 'ar-ye'));
+ $expected = array(
+ 'ar' => array('language' => 'Arabic', 'locale' => 'ara', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ae' => array('language' => 'Arabic (U.A.E.)', 'locale' => 'ar_ae', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-bh' => array('language' => 'Arabic (Bahrain)', 'locale' => 'ar_bh', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-dz' => array('language' => 'Arabic (Algeria)', 'locale' => 'ar_dz', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-eg' => array('language' => 'Arabic (Egypt)', 'locale' => 'ar_eg', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-iq' => array('language' => 'Arabic (Iraq)', 'locale' => 'ar_iq', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-jo' => array('language' => 'Arabic (Jordan)', 'locale' => 'ar_jo', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-kw' => array('language' => 'Arabic (Kuwait)', 'locale' => 'ar_kw', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-lb' => array('language' => 'Arabic (Lebanon)', 'locale' => 'ar_lb', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ly' => array('language' => 'Arabic (Libya)', 'locale' => 'ar_ly', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ma' => array('language' => 'Arabic (Morocco)', 'locale' => 'ar_ma', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-om' => array('language' => 'Arabic (Oman)', 'locale' => 'ar_om', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-qa' => array('language' => 'Arabic (Qatar)', 'locale' => 'ar_qa', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-sa' => array('language' => 'Arabic (Saudi Arabia)', 'locale' => 'ar_sa', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-sy' => array('language' => 'Arabic (Syria)', 'locale' => 'ar_sy', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-tn' => array('language' => 'Arabic (Tunisia)', 'locale' => 'ar_tn', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'ar-ye' => array('language' => 'Arabic (Yemen)', 'locale' => 'ar_ye', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('be'));
+ $expected = array(
+ 'be' => array('language' => 'Byelorussian', 'locale' => 'bel', 'localeFallback' => 'bel', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('bg'));
+ $expected = array(
+ 'bg' => array('language' => 'Bulgarian', 'locale' => 'bul', 'localeFallback' => 'bul', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('bs'));
+ $expected = array(
+ 'bs' => array('language' => 'Bosnian', 'locale' => 'bos', 'localeFallback' => 'bos', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ca'));
+ $expected = array(
+ 'ca' => array('language' => 'Catalan', 'locale' => 'cat', 'localeFallback' => 'cat', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('cs'));
+ $expected = array(
+ 'cs' => array('language' => 'Czech', 'locale' => 'cze', 'localeFallback' => 'cze', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('da'));
+ $expected = array(
+ 'da' => array('language' => 'Danish', 'locale' => 'dan', 'localeFallback' => 'dan', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('de', 'de-at', 'de-ch', 'de-de', 'de-li', 'de-lu'));
+ $expected = array(
+ 'de' => array('language' => 'German (Standard)', 'locale' => 'deu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-at' => array('language' => 'German (Austria)', 'locale' => 'de_at', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-ch' => array('language' => 'German (Swiss)', 'locale' => 'de_ch', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-de' => array('language' => 'German (Germany)', 'locale' => 'de_de', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-li' => array('language' => 'German (Liechtenstein)', 'locale' => 'de_li', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'de-lu' => array('language' => 'German (Luxembourg)', 'locale' => 'de_lu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('e', 'el'));
+ $expected = array(
+ 'e' => array('language' => 'Greek', 'locale' => 'gre', 'localeFallback' => 'gre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'el' => array('language' => 'Greek', 'locale' => 'gre', 'localeFallback' => 'gre', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('en', 'en-au', 'en-bz', 'en-ca', 'en-gb', 'en-ie', 'en-jm', 'en-nz', 'en-tt', 'en-us', 'en-za'));
+ $expected = array(
+ 'en' => array('language' => 'English', 'locale' => 'eng', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-au' => array('language' => 'English (Australian)', 'locale' => 'en_au', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-bz' => array('language' => 'English (Belize)', 'locale' => 'en_bz', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-ca' => array('language' => 'English (Canadian)', 'locale' => 'en_ca', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-gb' => array('language' => 'English (British)', 'locale' => 'en_gb', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-ie' => array('language' => 'English (Ireland)', 'locale' => 'en_ie', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-jm' => array('language' => 'English (Jamaica)', 'locale' => 'en_jm', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-nz' => array('language' => 'English (New Zealand)', 'locale' => 'en_nz', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-tt' => array('language' => 'English (Trinidad)', 'locale' => 'en_tt', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-us' => array('language' => 'English (United States)', 'locale' => 'en_us', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'en-za' => array('language' => 'English (South Africa)', 'locale' => 'en_za', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('es', 'es-ar', 'es-bo', 'es-cl', 'es-co', 'es-cr', 'es-do', 'es-ec', 'es-es', 'es-gt', 'es-hn',
+ 'es-mx', 'es-ni', 'es-pa', 'es-pe', 'es-pr', 'es-py', 'es-sv', 'es-uy', 'es-ve'));
+ $expected = array(
+ 'es' => array('language' => 'Spanish (Spain - Traditional)', 'locale' => 'spa', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ar' => array('language' => 'Spanish (Argentina)', 'locale' => 'es_ar', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-bo' => array('language' => 'Spanish (Bolivia)', 'locale' => 'es_bo', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-cl' => array('language' => 'Spanish (Chile)', 'locale' => 'es_cl', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-co' => array('language' => 'Spanish (Colombia)', 'locale' => 'es_co', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-cr' => array('language' => 'Spanish (Costa Rica)', 'locale' => 'es_cr', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-do' => array('language' => 'Spanish (Dominican Republic)', 'locale' => 'es_do', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ec' => array('language' => 'Spanish (Ecuador)', 'locale' => 'es_ec', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-es' => array('language' => 'Spanish (Spain)', 'locale' => 'es_es', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-gt' => array('language' => 'Spanish (Guatemala)', 'locale' => 'es_gt', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-hn' => array('language' => 'Spanish (Honduras)', 'locale' => 'es_hn', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-mx' => array('language' => 'Spanish (Mexican)', 'locale' => 'es_mx', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ni' => array('language' => 'Spanish (Nicaragua)', 'locale' => 'es_ni', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-pa' => array('language' => 'Spanish (Panama)', 'locale' => 'es_pa', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-pe' => array('language' => 'Spanish (Peru)', 'locale' => 'es_pe', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-pr' => array('language' => 'Spanish (Puerto Rico)', 'locale' => 'es_pr', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-py' => array('language' => 'Spanish (Paraguay)', 'locale' => 'es_py', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-sv' => array('language' => 'Spanish (El Salvador)', 'locale' => 'es_sv', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-uy' => array('language' => 'Spanish (Uruguay)', 'locale' => 'es_uy', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-ve' => array('language' => 'Spanish (Venezuela)', 'locale' => 'es_ve', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('et'));
+ $expected = array(
+ 'et' => array('language' => 'Estonian', 'locale' => 'est', 'localeFallback' => 'est', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('eu'));
+ $expected = array(
+ 'eu' => array('language' => 'Basque', 'locale' => 'baq', 'localeFallback' => 'baq', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('fa'));
+ $expected = array(
+ 'fa' => array('language' => 'Farsi', 'locale' => 'per', 'localeFallback' => 'per', 'charset' => 'utf-8', 'direction' => 'rtl')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('fi'));
+ $expected = array(
+ 'fi' => array('language' => 'Finnish', 'locale' => 'fin', 'localeFallback' => 'fin', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('fo'));
+ $expected = array(
+ 'fo' => array('language' => 'Faeroese', 'locale' => 'fao', 'localeFallback' => 'fao', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('fr', 'fr-be', 'fr-ca', 'fr-ch', 'fr-fr', 'fr-lu'));
+ $expected = array(
+ 'fr' => array('language' => 'French (Standard)', 'locale' => 'fre', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-be' => array('language' => 'French (Belgium)', 'locale' => 'fr_be', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-ca' => array('language' => 'French (Canadian)', 'locale' => 'fr_ca', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-ch' => array('language' => 'French (Swiss)', 'locale' => 'fr_ch', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-fr' => array('language' => 'French (France)', 'locale' => 'fr_fr', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'fr-lu' => array('language' => 'French (Luxembourg)', 'locale' => 'fr_lu', 'localeFallback' => 'fre', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ga'));
+ $expected = array(
+ 'ga' => array('language' => 'Irish', 'locale' => 'gle', 'localeFallback' => 'gle', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('gd', 'gd-ie'));
+ $expected = array(
+ 'gd' => array('language' => 'Gaelic (Scots)', 'locale' => 'gla', 'localeFallback' => 'gla', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'gd-ie' => array('language' => 'Gaelic (Irish)', 'locale' => 'gd_ie', 'localeFallback' => 'gla', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('gl'));
+ $expected = array(
+ 'gl' => array('language' => 'Galician', 'locale' => 'glg', 'localeFallback' => 'glg', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('he'));
+ $expected = array(
+ 'he' => array('language' => 'Hebrew', 'locale' => 'heb', 'localeFallback' => 'heb', 'charset' => 'utf-8', 'direction' => 'rtl')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('hi'));
+ $expected = array(
+ 'hi' => array('language' => 'Hindi', 'locale' => 'hin', 'localeFallback' => 'hin', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('hr'));
+ $expected = array(
+ 'hr' => array('language' => 'Croatian', 'locale' => 'hrv', 'localeFallback' => 'hrv', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('hu'));
+ $expected = array(
+ 'hu' => array('language' => 'Hungarian', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('hy'));
+ $expected = array(
+ 'hy' => array('language' => 'Armenian - Armenia', 'locale' => 'hye', 'localeFallback' => 'hye', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('id', 'in'));
+ $expected = array(
+ 'id' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'in' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('is'));
+ $expected = array(
+ 'is' => array('language' => 'Icelandic', 'locale' => 'ice', 'localeFallback' => 'ice', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('it', 'it-ch'));
+ $expected = array(
+ 'it' => array('language' => 'Italian', 'locale' => 'ita', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'it-ch' => array('language' => 'Italian (Swiss) ', 'locale' => 'it_ch', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ja'));
+ $expected = array(
+ 'ja' => array('language' => 'Japanese', 'locale' => 'jpn', 'localeFallback' => 'jpn', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ko', 'ko-kp', 'ko-kr'));
+ $expected = array(
+ 'ko' => array('language' => 'Korean', 'locale' => 'kor', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
+ 'ko-kp' => array('language' => 'Korea (North)', 'locale' => 'ko_kp', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
+ 'ko-kr' => array('language' => 'Korea (South)', 'locale' => 'ko_kr', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('koi8-r', 'ru', 'ru-mo'));
+ $expected = array(
+ 'koi8-r' => array('language' => 'Russian', 'locale' => 'koi8_r', 'localeFallback' => 'rus', 'charset' => 'koi8-r', 'direction' => 'ltr'),
+ 'ru' => array('language' => 'Russian', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ru-mo' => array('language' => 'Russian (Moldavia)', 'locale' => 'ru_mo', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('lt'));
+ $expected = array(
+ 'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('lv'));
+ $expected = array(
+ 'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('mk', 'mk-mk'));
+ $expected = array(
+ 'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mk', 'localeFallback' => 'mac', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'mk-mk' => array('language' => 'Macedonian', 'locale' => 'mk_mk', 'localeFallback' => 'mac', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ms'));
+ $expected = array(
+ 'ms' => array('language' => 'Malaysian', 'locale' => 'may', 'localeFallback' => 'may', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('mt'));
+ $expected = array(
+ 'mt' => array('language' => 'Maltese', 'locale' => 'mlt', 'localeFallback' => 'mlt', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('n', 'nl', 'nl-be'));
+ $expected = array(
+ 'n' => array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'nl' => array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'nl-be' => array('language' => 'Dutch (Belgium)', 'locale' => 'nl_be', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog('nl');
+ $expected = array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog('nld');
+ $expected = array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog('dut');
+ $expected = array('language' => 'Dutch (Standard)', 'locale' => 'dut', 'localeFallback' => 'dut', 'charset' => 'utf-8', 'direction' => 'ltr');
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('nb'));
+ $expected = array(
+ 'nb' => array('language' => 'Norwegian Bokmal', 'locale' => 'nob', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('nn', 'no'));
+ $expected = array(
+ 'nn' => array('language' => 'Norwegian Nynorsk', 'locale' => 'nno', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'no' => array('language' => 'Norwegian', 'locale' => 'nor', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('p', 'pl'));
+ $expected = array(
+ 'p' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'pl' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('pt', 'pt-br'));
+ $expected = array(
+ 'pt' => array('language' => 'Portuguese (Portugal)', 'locale' => 'por', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'pt-br' => array('language' => 'Portuguese (Brazil)', 'locale' => 'pt_br', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('rm'));
+ $expected = array(
+ 'rm' => array('language' => 'Rhaeto-Romanic', 'locale' => 'roh', 'localeFallback' => 'roh', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ro', 'ro-mo'));
+ $expected = array(
+ 'ro' => array('language' => 'Romanian', 'locale' => 'rum', 'localeFallback' => 'rum', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ro-mo' => array('language' => 'Romanian (Moldavia)', 'locale' => 'ro_mo', 'localeFallback' => 'rum', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sb'));
+ $expected = array(
+ 'sb' => array('language' => 'Sorbian', 'locale' => 'wen', 'localeFallback' => 'wen', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sk'));
+ $expected = array(
+ 'sk' => array('language' => 'Slovak', 'locale' => 'slo', 'localeFallback' => 'slo', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sl'));
+ $expected = array(
+ 'sl' => array('language' => 'Slovenian', 'locale' => 'slv', 'localeFallback' => 'slv', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sq'));
+ $expected = array(
+ 'sq' => array('language' => 'Albanian', 'locale' => 'alb', 'localeFallback' => 'alb', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sr'));
+ $expected = array(
+ 'sr' => array('language' => 'Serbian', 'locale' => 'scc', 'localeFallback' => 'scc', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sv', 'sv-fi'));
+ $expected = array(
+ 'sv' => array('language' => 'Swedish', 'locale' => 'swe', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sv-fi' => array('language' => 'Swedish (Finland)', 'locale' => 'sv_fi', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sx'));
+ $expected = array(
+ 'sx' => array('language' => 'Sutu', 'locale' => 'sx', 'localeFallback' => 'sx', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('sz'));
+ $expected = array(
+ 'sz' => array('language' => 'Sami (Lappish)', 'locale' => 'smi', 'localeFallback' => 'smi', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('th'));
+ $expected = array(
+ 'th' => array('language' => 'Thai', 'locale' => 'tha', 'localeFallback' => 'tha', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('tn'));
+ $expected = array(
+ 'tn' => array('language' => 'Tswana', 'locale' => 'tsn', 'localeFallback' => 'tsn', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('tr'));
+ $expected = array(
+ 'tr' => array('language' => 'Turkish', 'locale' => 'tur', 'localeFallback' => 'tur', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ts'));
+ $expected = array(
+ 'ts' => array('language' => 'Tsonga', 'locale' => 'tso', 'localeFallback' => 'tso', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('uk'));
+ $expected = array(
+ 'uk' => array('language' => 'Ukrainian', 'locale' => 'ukr', 'localeFallback' => 'ukr', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ur'));
+ $expected = array(
+ 'ur' => array('language' => 'Urdu', 'locale' => 'urd', 'localeFallback' => 'urd', 'charset' => 'utf-8', 'direction' => 'rtl')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('ve'));
+ $expected = array(
+ 've' => array('language' => 'Venda', 'locale' => 'ven', 'localeFallback' => 'ven', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('vi'));
+ $expected = array(
+ 'vi' => array('language' => 'Vietnamese', 'locale' => 'vie', 'localeFallback' => 'vie', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('cy'));
+ $expected = array(
+ 'cy' => array('language' => 'Welsh', 'locale' => 'cym', 'localeFallback' => 'cym', 'charset' => 'utf-8',
+ 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('xh'));
+ $expected = array(
+ 'xh' => array('language' => 'Xhosa', 'locale' => 'xho', 'localeFallback' => 'xho', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('yi'));
+ $expected = array(
+ 'yi' => array('language' => 'Yiddish', 'locale' => 'yid', 'localeFallback' => 'yid', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('zh', 'zh-cn', 'zh-hk', 'zh-sg', 'zh-tw'));
+ $expected = array(
+ 'zh' => array('language' => 'Chinese', 'locale' => 'chi', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zh-cn' => array('language' => 'Chinese (PRC)', 'locale' => 'zh_cn', 'localeFallback' => 'chi', 'charset' => 'GB2312', 'direction' => 'ltr'),
+ 'zh-hk' => array('language' => 'Chinese (Hong Kong)', 'locale' => 'zh_hk', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zh-sg' => array('language' => 'Chinese (Singapore)', 'locale' => 'zh_sg', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zh-tw' => array('language' => 'Chinese (Taiwan)', 'locale' => 'zh_tw', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('zu'));
+ $expected = array(
+ 'zu' => array('language' => 'Zulu', 'locale' => 'zul', 'localeFallback' => 'zul', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('en-nz', 'es-do', 'sz', 'ar-lb', 'zh-hk', 'pt-br'));
+ $expected = array(
+ 'en-nz' => array('language' => 'English (New Zealand)', 'locale' => 'en_nz', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'es-do' => array('language' => 'Spanish (Dominican Republic)', 'locale' => 'es_do', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'sz' => array('language' => 'Sami (Lappish)', 'locale' => 'smi', 'localeFallback' => 'smi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'ar-lb' => array('language' => 'Arabic (Lebanon)', 'locale' => 'ar_lb', 'localeFallback' => 'ara', 'charset' => 'utf-8', 'direction' => 'rtl'),
+ 'zh-hk' => array('language' => 'Chinese (Hong Kong)', 'locale' => 'zh_hk', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'pt-br' => array('language' => 'Portuguese (Brazil)', 'locale' => 'pt_br', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $localize->catalog(array('eng', 'deu', 'zho', 'rum', 'zul', 'yid'));
+ $expected = array(
+ 'eng' => array('language' => 'English', 'locale' => 'eng', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'deu' => array('language' => 'German (Standard)', 'locale' => 'deu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zho' => array('language' => 'Chinese', 'locale' => 'chi', 'localeFallback' => 'chi', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'rum' => array('language' => 'Romanian', 'locale' => 'rum', 'localeFallback' => 'rum', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'zul' => array('language' => 'Zulu', 'locale' => 'zul', 'localeFallback' => 'zul', 'charset' => 'utf-8', 'direction' => 'ltr'),
+ 'yid' => array('language' => 'Yiddish', 'locale' => 'yid', 'localeFallback' => 'yid', 'charset' => 'utf-8', 'direction' => 'ltr')
+ );
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/MultibyteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/MultibyteTest.php
new file mode 100644
index 0000000..927b844
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/I18n/MultibyteTest.php
@@ -0,0 +1,9228 @@
+<?php
+/**
+ * MultibyteTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.I18n
+ * @since CakePHP(tm) v 1.2.0.6833
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Multibyte', 'I18n');
+
+/**
+ * MultibyteTest class
+ *
+ * @package Cake.Test.Case.I18n
+ */
+class MultibyteTest extends CakeTestCase {
+
+/**
+ * testUtf8 method
+ *
+ * @return void
+ */
+ public function testUtf8() {
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = Multibyte::utf8($string);
+ $expected = array(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126);
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $result = Multibyte::utf8($string);
+ $expected = array(161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $result = Multibyte::utf8($string);
+ $expected = array(201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
+ 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263,
+ 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $result = Multibyte::utf8($string);
+ $expected = array(301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321,
+ 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363,
+ 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $result = Multibyte::utf8($string);
+ $expected = array(401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421,
+ 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442,
+ 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463,
+ 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484,
+ 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500);
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $result = Multibyte::utf8($string);
+ $expected = array(601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621,
+ 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642,
+ 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663,
+ 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+ 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $result = Multibyte::utf8($string);
+ $expected = array(1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041,
+ 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051);
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $result = Multibyte::utf8($string);
+ $expected = array(1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069,
+ 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087,
+ 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100);
+ $this->assertEquals($expected, $result);
+
+ $string = 'չպջռսվտ';
+ $result = Multibyte::utf8($string);
+ $expected = array(1401, 1402, 1403, 1404, 1405, 1406, 1407);
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $result = Multibyte::utf8($string);
+ $expected = array(1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615);
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $result = Multibyte::utf8($string);
+ $expected = array(10032, 10033, 10034, 10035, 10036, 10037, 10038, 10039, 10040, 10041, 10042, 10043, 10044,
+ 10045, 10046, 10047, 10048, 10049, 10050, 10051, 10052, 10053, 10054, 10055, 10056, 10057,
+ 10058, 10059, 10060, 10061, 10062, 10063, 10064, 10065, 10066, 10067, 10068, 10069, 10070,
+ 10071, 10072, 10073, 10074, 10075, 10076, 10077, 10078);
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $result = Multibyte::utf8($string);
+ $expected = array(11904, 11905, 11906, 11907, 11908, 11909, 11910, 11911, 11912, 11913, 11914, 11915, 11916, 11917, 11918, 11919,
+ 11920, 11921, 11922, 11923, 11924, 11925, 11926, 11927, 11928, 11929, 11931, 11932, 11933, 11934, 11935, 11936,
+ 11937, 11938, 11939, 11940, 11941, 11942, 11943, 11944, 11945, 11946, 11947, 11948, 11949, 11950, 11951, 11952,
+ 11953, 11954, 11955, 11956, 11957, 11958, 11959, 11960, 11961, 11962, 11963, 11964, 11965, 11966, 11967, 11968,
+ 11969, 11970, 11971, 11972, 11973, 11974, 11975, 11976, 11977, 11978, 11979, 11980, 11981, 11982, 11983, 11984,
+ 11985, 11986, 11987, 11988, 11989, 11990, 11991, 11992, 11993, 11994, 11995, 11996, 11997, 11998, 11999, 12000);
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $result = Multibyte::utf8($string);
+ $expected = array(12101, 12102, 12103, 12104, 12105, 12106, 12107, 12108, 12109, 12110, 12111, 12112, 12113, 12114, 12115, 12116,
+ 12117, 12118, 12119, 12120, 12121, 12122, 12123, 12124, 12125, 12126, 12127, 12128, 12129, 12130, 12131, 12132,
+ 12133, 12134, 12135, 12136, 12137, 12138, 12139, 12140, 12141, 12142, 12143, 12144, 12145, 12146, 12147, 12148,
+ 12149, 12150, 12151, 12152, 12153, 12154, 12155, 12156, 12157, 12158, 12159);
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $result = Multibyte::utf8($string);
+ $expected = array(45601, 45602, 45603, 45604, 45605, 45606, 45607, 45608, 45609, 45610, 45611, 45612, 45613, 45614, 45615, 45616,
+ 45617, 45618, 45619, 45620, 45621, 45622, 45623, 45624, 45625, 45626, 45627, 45628, 45629, 45630, 45631, 45632,
+ 45633, 45634, 45635, 45636, 45637, 45638, 45639, 45640, 45641, 45642, 45643, 45644, 45645, 45646, 45647, 45648,
+ 45649, 45650, 45651, 45652, 45653, 45654, 45655, 45656, 45657, 45658, 45659, 45660, 45661, 45662, 45663, 45664,
+ 45665, 45666, 45667, 45668, 45669, 45670, 45671, 45672, 45673, 45674, 45675, 45676, 45677, 45678, 45679, 45680,
+ 45681, 45682, 45683, 45684, 45685, 45686, 45687, 45688, 45689, 45690, 45691, 45692, 45693, 45694, 45695, 45696,
+ 45697, 45698, 45699, 45700);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $result = Multibyte::utf8($string);
+ $expected = array(65136, 65137, 65138, 65139, 65140, 65141, 65142, 65143, 65144, 65145, 65146, 65147, 65148, 65149, 65150, 65151,
+ 65152, 65153, 65154, 65155, 65156, 65157, 65158, 65159, 65160, 65161, 65162, 65163, 65164, 65165, 65166, 65167,
+ 65168, 65169, 65170, 65171, 65172, 65173, 65174, 65175, 65176, 65177, 65178, 65179, 65180, 65181, 65182, 65183,
+ 65184, 65185, 65186, 65187, 65188, 65189, 65190, 65191, 65192, 65193, 65194, 65195, 65196, 65197, 65198, 65199,
+ 65200);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $result = Multibyte::utf8($string);
+ $expected = array(65201, 65202, 65203, 65204, 65205, 65206, 65207, 65208, 65209, 65210, 65211, 65212, 65213, 65214, 65215, 65216,
+ 65217, 65218, 65219, 65220, 65221, 65222, 65223, 65224, 65225, 65226, 65227, 65228, 65229, 65230, 65231, 65232,
+ 65233, 65234, 65235, 65236, 65237, 65238, 65239, 65240, 65241, 65242, 65243, 65244, 65245, 65246, 65247, 65248,
+ 65249, 65250, 65251, 65252, 65253, 65254, 65255, 65256, 65257, 65258, 65259, 65260, 65261, 65262, 65263, 65264,
+ 65265, 65266, 65267, 65268, 65269, 65270, 65271, 65272, 65273, 65274, 65275, 65276);
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $result = Multibyte::utf8($string);
+ $expected = array(65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360,
+ 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370);
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $result = Multibyte::utf8($string);
+ $expected = array(65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392,
+ 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $result = Multibyte::utf8($string);
+ $expected = array(65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416,
+ 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432,
+ 65433, 65434, 65435, 65436, 65437, 65438);
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = Multibyte::utf8($string);
+ $expected = array(292, 275, 314, 316, 335, 44, 32, 372, 337, 345, 316, 271, 33);
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $result = Multibyte::utf8($string);
+ $expected = array(72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33);
+ $this->assertEquals($expected, $result);
+
+ $string = '¨';
+ $result = Multibyte::utf8($string);
+ $expected = array(168);
+ $this->assertEquals($expected, $result);
+
+ $string = '¿';
+ $result = Multibyte::utf8($string);
+ $expected = array(191);
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $result = Multibyte::utf8($string);
+ $expected = array(269, 105, 110, 105);
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $result = Multibyte::utf8($string);
+ $expected = array(109, 111, 263, 105);
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $result = Multibyte::utf8($string);
+ $expected = array(100, 114, 382, 97, 118, 110, 105);
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $result = Multibyte::utf8($string);
+ $expected = array(25226, 30334, 24230, 35774, 20026, 39318, 39029);
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = Multibyte::utf8($string);
+ $expected = array(19968, 20108, 19977, 21608, 27704, 40845);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ԀԂԄԆԈԊԌԎԐԒ';
+ $result = Multibyte::utf8($string);
+ $expected = array(1280, 1282, 1284, 1286, 1288, 1290, 1292, 1294, 1296, 1298);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ԁԃԅԇԉԋԍԏԐԒ';
+ $result = Multibyte::utf8($string);
+ $expected = array(1281, 1283, 1285, 1287, 1289, 1291, 1293, 1295, 1296, 1298);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖև';
+ $result = Multibyte::utf8($string);
+ $expected = array(1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346,
+ 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364,
+ 1365, 1366, 1415);
+ $this->assertEquals($expected, $result);
+
+ $string = 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև';
+ $result = Multibyte::utf8($string);
+ $expected = array(1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394,
+ 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412,
+ 1413, 1414, 1415);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $result = Multibyte::utf8($string);
+ $expected = array(4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273,
+ 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291,
+ 4292, 4293);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẖẗẘẙẚẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸ';
+ $result = Multibyte::utf8($string);
+ $expected = array(7680, 7682, 7684, 7686, 7688, 7690, 7692, 7694, 7696, 7698, 7700, 7702, 7704, 7706, 7708, 7710, 7712, 7714,
+ 7716, 7718, 7720, 7722, 7724, 7726, 7728, 7730, 7732, 7734, 7736, 7738, 7740, 7742, 7744, 7746, 7748, 7750,
+ 7752, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, 7786,
+ 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822,
+ 7824, 7826, 7828, 7830, 7831, 7832, 7833, 7834, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, 7856,
+ 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, 7892,
+ 7894, 7896, 7898, 7900, 7902, 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, 7928);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ';
+ $result = Multibyte::utf8($string);
+ $expected = array(7681, 7683, 7685, 7687, 7689, 7691, 7693, 7695, 7697, 7699, 7701, 7703, 7705, 7707, 7709, 7711, 7713, 7715,
+ 7717, 7719, 7721, 7723, 7725, 7727, 7729, 7731, 7733, 7735, 7737, 7739, 7741, 7743, 7745, 7747, 7749, 7751,
+ 7753, 7755, 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 7781, 7783, 7785, 7787,
+ 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 7805, 7807, 7809, 7811, 7813, 7815, 7817, 7819, 7821, 7823,
+ 7825, 7827, 7829, 7830, 7831, 7832, 7833, 7834, 7841, 7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859,
+ 7861, 7863, 7865, 7867, 7869, 7871, 7873, 7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889, 7891, 7893, 7895,
+ 7897, 7899, 7901, 7903, 7905, 7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921, 7923, 7925, 7927, 7929);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ΩKÅℲ';
+ $result = Multibyte::utf8($string);
+ $expected = array(8486, 8490, 8491, 8498);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ωkåⅎ';
+ $result = Multibyte::utf8($string);
+ $expected = array(969, 107, 229, 8526);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯↃ';
+ $result = Multibyte::utf8($string);
+ $expected = array(8544, 8545, 8546, 8547, 8548, 8549, 8550, 8551, 8552, 8553, 8554, 8555, 8556, 8557, 8558, 8559, 8579);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↄ';
+ $result = Multibyte::utf8($string);
+ $expected = array(8560, 8561, 8562, 8563, 8564, 8565, 8566, 8567, 8568, 8569, 8570, 8571, 8572, 8573, 8574, 8575, 8580);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ';
+ $result = Multibyte::utf8($string);
+ $expected = array(9398, 9399, 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413, 9414,
+ 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ';
+ $result = Multibyte::utf8($string);
+ $expected = array(9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, 9432, 9433, 9434, 9435, 9436, 9437, 9438, 9439, 9440, 9441,
+ 9442, 9443, 9444, 9445, 9446, 9447, 9448, 9449);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⰀⰁⰂⰃⰄⰅⰆⰇⰈⰉⰊⰋⰌⰍⰎⰏⰐⰑⰒⰓⰔⰕⰖⰗⰘⰙⰚⰛⰜⰝⰞⰟⰠⰡⰢⰣⰤⰥⰦⰧⰨⰩⰪⰫⰬⰭⰮ';
+ $result = Multibyte::utf8($string);
+ $expected = array(11264, 11265, 11266, 11267, 11268, 11269, 11270, 11271, 11272, 11273, 11274, 11275, 11276, 11277, 11278,
+ 11279, 11280, 11281, 11282, 11283, 11284, 11285, 11286, 11287, 11288, 11289, 11290, 11291, 11292, 11293,
+ 11294, 11295, 11296, 11297, 11298, 11299, 11300, 11301, 11302, 11303, 11304, 11305, 11306, 11307, 11308,
+ 11309, 11310);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⰰⰱⰲⰳⰴⰵⰶⰷⰸⰹⰺⰻⰼⰽⰾⰿⱀⱁⱂⱃⱄⱅⱆⱇⱈⱉⱊⱋⱌⱍⱎⱏⱐⱑⱒⱓⱔⱕⱖⱗⱘⱙⱚⱛⱜⱝⱞ';
+ $result = Multibyte::utf8($string);
+ $expected = array(11312, 11313, 11314, 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326, 11327,
+ 11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, 11342, 11343,
+ 11344, 11345, 11346, 11347, 11348, 11349, 11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⲀⲂⲄⲆⲈⲊⲌⲎⲐⲒⲔⲖⲘⲚⲜⲞⲠⲢⲤⲦⲨⲪⲬⲮⲰⲲⲴⲶⲸⲺⲼⲾⳀⳂⳄⳆⳈⳊⳌⳎⳐⳒⳔⳖⳘⳚⳜⳞⳠⳢ';
+ $result = Multibyte::utf8($string);
+ $expected = array(11392, 11394, 11396, 11398, 11400, 11402, 11404, 11406, 11408, 11410, 11412, 11414, 11416, 11418, 11420,
+ 11422, 11424, 11426, 11428, 11430, 11432, 11434, 11436, 11438, 11440, 11442, 11444, 11446, 11448, 11450,
+ 11452, 11454, 11456, 11458, 11460, 11462, 11464, 11466, 11468, 11470, 11472, 11474, 11476, 11478, 11480,
+ 11482, 11484, 11486, 11488, 11490);
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣ';
+ $result = Multibyte::utf8($string);
+ $expected = array(11393, 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, 11421, 11423,
+ 11425, 11427, 11429, 11431, 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, 11453, 11455,
+ 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, 11473, 11475, 11477, 11479, 11481, 11483, 11485, 11487,
+ 11489, 11491);
+ $this->assertEquals($expected, $result);
+
+ $string = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $result = Multibyte::utf8($string);
+ $expected = array(64256, 64257, 64258, 64259, 64260, 64261, 64262, 64275, 64276, 64277, 64278, 64279);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testAscii method
+ *
+ * @return void
+ */
+ public function testAscii() {
+ $input = array(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126);
+ $result = Multibyte::ascii($input);
+
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $input = array(161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200);
+ $result = Multibyte::ascii($input);
+
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
+ 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263,
+ 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300);
+ $result = Multibyte::ascii($input);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321,
+ 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+ 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363,
+ 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421,
+ 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442,
+ 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463,
+ 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484,
+ 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621,
+ 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642,
+ 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663,
+ 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
+ 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041,
+ 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051);
+ $expected = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069,
+ 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087,
+ 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100);
+ $expected = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(1401, 1402, 1403, 1404, 1405, 1406, 1407);
+ $expected = 'չպջռսվտ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615);
+ $expected = 'فقكلمنهوىيًٌٍَُ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(10032, 10033, 10034, 10035, 10036, 10037, 10038, 10039, 10040, 10041, 10042, 10043, 10044,
+ 10045, 10046, 10047, 10048, 10049, 10050, 10051, 10052, 10053, 10054, 10055, 10056, 10057,
+ 10058, 10059, 10060, 10061, 10062, 10063, 10064, 10065, 10066, 10067, 10068, 10069, 10070,
+ 10071, 10072, 10073, 10074, 10075, 10076, 10077, 10078);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(11904, 11905, 11906, 11907, 11908, 11909, 11910, 11911, 11912, 11913, 11914, 11915, 11916, 11917, 11918, 11919,
+ 11920, 11921, 11922, 11923, 11924, 11925, 11926, 11927, 11928, 11929, 11931, 11932, 11933, 11934, 11935, 11936,
+ 11937, 11938, 11939, 11940, 11941, 11942, 11943, 11944, 11945, 11946, 11947, 11948, 11949, 11950, 11951, 11952,
+ 11953, 11954, 11955, 11956, 11957, 11958, 11959, 11960, 11961, 11962, 11963, 11964, 11965, 11966, 11967, 11968,
+ 11969, 11970, 11971, 11972, 11973, 11974, 11975, 11976, 11977, 11978, 11979, 11980, 11981, 11982, 11983, 11984,
+ 11985, 11986, 11987, 11988, 11989, 11990, 11991, 11992, 11993, 11994, 11995, 11996, 11997, 11998, 11999, 12000);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(12101, 12102, 12103, 12104, 12105, 12106, 12107, 12108, 12109, 12110, 12111, 12112, 12113, 12114, 12115, 12116,
+ 12117, 12118, 12119, 12120, 12121, 12122, 12123, 12124, 12125, 12126, 12127, 12128, 12129, 12130, 12131, 12132,
+ 12133, 12134, 12135, 12136, 12137, 12138, 12139, 12140, 12141, 12142, 12143, 12144, 12145, 12146, 12147, 12148,
+ 12149, 12150, 12151, 12152, 12153, 12154, 12155, 12156, 12157, 12158, 12159);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(45601, 45602, 45603, 45604, 45605, 45606, 45607, 45608, 45609, 45610, 45611, 45612, 45613, 45614, 45615, 45616,
+ 45617, 45618, 45619, 45620, 45621, 45622, 45623, 45624, 45625, 45626, 45627, 45628, 45629, 45630, 45631, 45632,
+ 45633, 45634, 45635, 45636, 45637, 45638, 45639, 45640, 45641, 45642, 45643, 45644, 45645, 45646, 45647, 45648,
+ 45649, 45650, 45651, 45652, 45653, 45654, 45655, 45656, 45657, 45658, 45659, 45660, 45661, 45662, 45663, 45664,
+ 45665, 45666, 45667, 45668, 45669, 45670, 45671, 45672, 45673, 45674, 45675, 45676, 45677, 45678, 45679, 45680,
+ 45681, 45682, 45683, 45684, 45685, 45686, 45687, 45688, 45689, 45690, 45691, 45692, 45693, 45694, 45695, 45696,
+ 45697, 45698, 45699, 45700);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(65136, 65137, 65138, 65139, 65140, 65141, 65142, 65143, 65144, 65145, 65146, 65147, 65148, 65149, 65150, 65151,
+ 65152, 65153, 65154, 65155, 65156, 65157, 65158, 65159, 65160, 65161, 65162, 65163, 65164, 65165, 65166, 65167,
+ 65168, 65169, 65170, 65171, 65172, 65173, 65174, 65175, 65176, 65177, 65178, 65179, 65180, 65181, 65182, 65183,
+ 65184, 65185, 65186, 65187, 65188, 65189, 65190, 65191, 65192, 65193, 65194, 65195, 65196, 65197, 65198, 65199,
+ 65200);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(65201, 65202, 65203, 65204, 65205, 65206, 65207, 65208, 65209, 65210, 65211, 65212, 65213, 65214, 65215, 65216,
+ 65217, 65218, 65219, 65220, 65221, 65222, 65223, 65224, 65225, 65226, 65227, 65228, 65229, 65230, 65231, 65232,
+ 65233, 65234, 65235, 65236, 65237, 65238, 65239, 65240, 65241, 65242, 65243, 65244, 65245, 65246, 65247, 65248,
+ 65249, 65250, 65251, 65252, 65253, 65254, 65255, 65256, 65257, 65258, 65259, 65260, 65261, 65262, 65263, 65264,
+ 65265, 65266, 65267, 65268, 65269, 65270, 65271, 65272, 65273, 65274, 65275, 65276);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360,
+ 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370);
+ $expected = 'abcdefghijklmnopqrstuvwxyz';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392,
+ 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400);
+ $expected = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416,
+ 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432,
+ 65433, 65434, 65435, 65436, 65437, 65438);
+ $expected = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(292, 275, 314, 316, 335, 44, 32, 372, 337, 345, 316, 271, 33);
+ $expected = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33);
+ $expected = 'Hello, World!';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(168);
+ $expected = '¨';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(191);
+ $expected = '¿';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(269, 105, 110, 105);
+ $expected = 'čini';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(109, 111, 263, 105);
+ $expected = 'moći';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(100, 114, 382, 97, 118, 110, 105);
+ $expected = 'državni';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(25226, 30334, 24230, 35774, 20026, 39318, 39029);
+ $expected = '把百度设为首页';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(19968, 20108, 19977, 21608, 27704, 40845);
+ $expected = '一二三周永龍';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(1280, 1282, 1284, 1286, 1288, 1290, 1292, 1294, 1296, 1298);
+ $expected = 'ԀԂԄԆԈԊԌԎԐԒ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(1281, 1283, 1285, 1287, 1289, 1291, 1293, 1295, 1296, 1298);
+ $expected = 'ԁԃԅԇԉԋԍԏԐԒ';
+ $result = Multibyte::ascii($input);
+ $this->assertEquals($expected, $result);
+
+ $input = array(1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347,
+ 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365,
+ 1366, 1415);
+ $result = Multibyte::ascii($input);
+ $expected = 'ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖև';
+ $this->assertEquals($expected, $result);
+
+ $input = array(1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394,
+ 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412,
+ 1413, 1414, 1415);
+ $result = Multibyte::ascii($input);
+ $expected = 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև';
+ $this->assertEquals($expected, $result);
+
+ $input = array(4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274,
+ 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291, 4292, 4293);
+ $result = Multibyte::ascii($input);
+ $expected = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(7680, 7682, 7684, 7686, 7688, 7690, 7692, 7694, 7696, 7698, 7700, 7702, 7704, 7706, 7708, 7710, 7712, 7714,
+ 7716, 7718, 7720, 7722, 7724, 7726, 7728, 7730, 7732, 7734, 7736, 7738, 7740, 7742, 7744, 7746, 7748, 7750,
+ 7752, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, 7786,
+ 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822,
+ 7824, 7826, 7828, 7830, 7831, 7832, 7833, 7834, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, 7856,
+ 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, 7892,
+ 7894, 7896, 7898, 7900, 7902, 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, 7928);
+ $result = Multibyte::ascii($input);
+ $expected = 'ḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẖẗẘẙẚẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(7681, 7683, 7685, 7687, 7689, 7691, 7693, 7695, 7697, 7699, 7701, 7703, 7705, 7707, 7709, 7711, 7713, 7715,
+ 7717, 7719, 7721, 7723, 7725, 7727, 7729, 7731, 7733, 7735, 7737, 7739, 7741, 7743, 7745, 7747, 7749, 7751,
+ 7753, 7755, 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 7781, 7783, 7785, 7787,
+ 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 7805, 7807, 7809, 7811, 7813, 7815, 7817, 7819, 7821, 7823,
+ 7825, 7827, 7829, 7830, 7831, 7832, 7833, 7834, 7841, 7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859,
+ 7861, 7863, 7865, 7867, 7869, 7871, 7873, 7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889, 7891, 7893, 7895,
+ 7897, 7899, 7901, 7903, 7905, 7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921, 7923, 7925, 7927, 7929);
+ $result = Multibyte::ascii($input);
+ $expected = 'ḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(8486, 8490, 8491, 8498);
+ $result = Multibyte::ascii($input);
+ $expected = 'ΩKÅℲ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(969, 107, 229, 8526);
+ $result = Multibyte::ascii($input);
+ $expected = 'ωkåⅎ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(8544, 8545, 8546, 8547, 8548, 8549, 8550, 8551, 8552, 8553, 8554, 8555, 8556, 8557, 8558, 8559, 8579);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯↃ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(8560, 8561, 8562, 8563, 8564, 8565, 8566, 8567, 8568, 8569, 8570, 8571, 8572, 8573, 8574, 8575, 8580);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↄ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(9398, 9399, 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413, 9414,
+ 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, 9432, 9433, 9434, 9435, 9436, 9437, 9438, 9439, 9440, 9441,
+ 9442, 9443, 9444, 9445, 9446, 9447, 9448, 9449);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(11264, 11265, 11266, 11267, 11268, 11269, 11270, 11271, 11272, 11273, 11274, 11275, 11276, 11277, 11278, 11279,
+ 11280, 11281, 11282, 11283, 11284, 11285, 11286, 11287, 11288, 11289, 11290, 11291, 11292, 11293, 11294, 11295,
+ 11296, 11297, 11298, 11299, 11300, 11301, 11302, 11303, 11304, 11305, 11306, 11307, 11308, 11309, 11310);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⰀⰁⰂⰃⰄⰅⰆⰇⰈⰉⰊⰋⰌⰍⰎⰏⰐⰑⰒⰓⰔⰕⰖⰗⰘⰙⰚⰛⰜⰝⰞⰟⰠⰡⰢⰣⰤⰥⰦⰧⰨⰩⰪⰫⰬⰭⰮ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(11312, 11313, 11314, 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326, 11327,
+ 11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, 11342, 11343,
+ 11344, 11345, 11346, 11347, 11348, 11349, 11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⰰⰱⰲⰳⰴⰵⰶⰷⰸⰹⰺⰻⰼⰽⰾⰿⱀⱁⱂⱃⱄⱅⱆⱇⱈⱉⱊⱋⱌⱍⱎⱏⱐⱑⱒⱓⱔⱕⱖⱗⱘⱙⱚⱛⱜⱝⱞ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(11392, 11394, 11396, 11398, 11400, 11402, 11404, 11406, 11408, 11410, 11412, 11414, 11416, 11418, 11420,
+ 11422, 11424, 11426, 11428, 11430, 11432, 11434, 11436, 11438, 11440, 11442, 11444, 11446, 11448, 11450,
+ 11452, 11454, 11456, 11458, 11460, 11462, 11464, 11466, 11468, 11470, 11472, 11474, 11476, 11478, 11480,
+ 11482, 11484, 11486, 11488, 11490);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⲀⲂⲄⲆⲈⲊⲌⲎⲐⲒⲔⲖⲘⲚⲜⲞⲠⲢⲤⲦⲨⲪⲬⲮⲰⲲⲴⲶⲸⲺⲼⲾⳀⳂⳄⳆⳈⳊⳌⳎⳐⳒⳔⳖⳘⳚⳜⳞⳠⳢ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(11393, 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, 11413, 11415, 11417, 11419, 11421, 11423,
+ 11425, 11427, 11429, 11431, 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, 11453, 11455,
+ 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, 11473, 11475, 11477, 11479, 11481, 11483, 11485, 11487,
+ 11489, 11491);
+ $result = Multibyte::ascii($input);
+ $expected = 'ⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣ';
+ $this->assertEquals($expected, $result);
+
+ $input = array(64256, 64257, 64258, 64259, 64260, 64261, 64262, 64275, 64276, 64277, 64278, 64279);
+ $result = Multibyte::ascii($input);
+ $expected = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStripos method
+ *
+ * @return void
+ */
+ public function testUsingMbStripos() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = mb_stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = mb_stripos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = mb_stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = mb_stripos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = mb_stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = mb_stripos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'f';
+ $result = mb_stripos($string, $find);
+ $expected = 37;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'Μ';
+ $result = mb_stripos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'É';
+ $result = mb_stripos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_stripos($string, $find);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_stripos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_stripos($string, $find, 40);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'Ʀ';
+ $result = mb_stripos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'ї';
+ $result = mb_stripos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_stripos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_stripos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_stripos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_stripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_stripos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_stripos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_stripos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_stripos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_stripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = mb_stripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_stripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_stripos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_stripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'Ő';
+ $result = mb_stripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'O';
+ $result = mb_stripos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_stripos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'N';
+ $result = mb_stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'Ć';
+ $result = mb_stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'Ž';
+ $result = mb_stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_stripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_stripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'DŽ';
+ $result = mb_stripos($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStripos method
+ *
+ * @return void
+ */
+ public function testMultibyteStripos() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = Multibyte::stripos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = Multibyte::stripos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = Multibyte::stripos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'f';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 37;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'Μ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'É';
+ $result = Multibyte::stripos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::stripos($string, $find, 40);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'Ʀ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'ї';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::stripos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'Ő';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'O';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'N';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'Ć';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'Ž';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::stripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'DŽ';
+ $result = Multibyte::stripos($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStristr method
+ *
+ * @return void
+ */
+ public function testUsingMbStristr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = mb_stristr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = mb_stristr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = mb_stristr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'f';
+ $result = mb_stristr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'f';
+ $result = mb_stristr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'Μ';
+ $result = mb_stristr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'Μ';
+ $result = mb_stristr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'þ';
+ $result = mb_stristr($string, $find);
+ $expected = 'Þßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'þ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_stristr($string, $find);
+ $expected = 'ŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_stristr($string, $find);
+ $expected = 'ƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'Ʀ';
+ $result = mb_stristr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'Ʀ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'ї';
+ $result = mb_stristr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'ї';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_stristr($string, $find);
+ $expected = 'РСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_stristr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_stristr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_stristr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_stristr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_stristr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_stristr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_stristr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_stristr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_stristr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_stristr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_stristr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = mb_stristr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_stristr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_stristr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_stristr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'Ő';
+ $result = mb_stristr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'Ő';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ĺļ';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'Ĥē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'O';
+ $result = mb_stristr($string, $find);
+ $expected = 'o, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'O';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'Hell';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_stristr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_stristr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_stristr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'N';
+ $result = mb_stristr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'N';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'Ć';
+ $result = mb_stristr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'Ć';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'Ž';
+ $result = mb_stristr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'Ž';
+ $result = mb_stristr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_stristr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_stristr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_stristr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_stristr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '二周';
+ $result = mb_stristr($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStristr method
+ *
+ * @return void
+ */
+ public function testMultibyteStristr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'f';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'å';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'ċ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'f';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'f';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'Μ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'Μ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'þ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'Þßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'þ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'Ʀ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'Ʀ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'ї';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'ї';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'РСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::stristr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::stristr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::stristr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::stristr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'Ő';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'Ő';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ĺļ';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'Ĥē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'O';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'o, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'O';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'Hell';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'N';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'N';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'Ć';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'Ć';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'Ž';
+ $result = Multibyte::stristr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'Ž';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::stristr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::stristr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::stristr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '二周';
+ $result = Multibyte::stristr($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrlen method
+ *
+ * @return void
+ */
+ public function testUsingMbStrlen() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $result = mb_strlen($string);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $result = mb_strlen($string);
+ $expected = 30;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $result = mb_strlen($string);
+ $expected = 61;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = mb_strlen($string);
+ $expected = 94;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $result = mb_strlen($string);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $result = mb_strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $result = mb_strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $result = mb_strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $result = mb_strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $result = mb_strlen($string);
+ $expected = 28;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $result = mb_strlen($string);
+ $expected = 49;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $result = mb_strlen($string);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $result = mb_strlen($string);
+ $expected = 47;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $result = mb_strlen($string);
+ $expected = 96;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $result = mb_strlen($string);
+ $expected = 59;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $result = mb_strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $result = mb_strlen($string);
+ $expected = 65;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $result = mb_strlen($string);
+ $expected = 76;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $result = mb_strlen($string);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $result = mb_strlen($string);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $result = mb_strlen($string);
+ $expected = 38;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = mb_strlen($string);
+ $expected = 13;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $result = mb_strlen($string);
+ $expected = 13;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $result = mb_strlen($string);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $result = mb_strlen($string);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $result = mb_strlen($string);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $result = mb_strlen($string);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = mb_strlen($string);
+ $expected = 6;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrlen method
+ *
+ * @return void
+ */
+ public function testMultibyteStrlen() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $result = Multibyte::strlen($string);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $result = Multibyte::strlen($string);
+ $expected = 30;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $result = Multibyte::strlen($string);
+ $expected = 61;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = Multibyte::strlen($string);
+ $expected = 94;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $result = Multibyte::strlen($string);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $result = Multibyte::strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $result = Multibyte::strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $result = Multibyte::strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $result = Multibyte::strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $result = Multibyte::strlen($string);
+ $expected = 28;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $result = Multibyte::strlen($string);
+ $expected = 49;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $result = Multibyte::strlen($string);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $result = Multibyte::strlen($string);
+ $expected = 47;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $result = Multibyte::strlen($string);
+ $expected = 96;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $result = Multibyte::strlen($string);
+ $expected = 59;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $result = Multibyte::strlen($string);
+ $expected = 100;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $result = Multibyte::strlen($string);
+ $expected = 65;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $result = Multibyte::strlen($string);
+ $expected = 76;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $result = Multibyte::strlen($string);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $result = Multibyte::strlen($string);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $result = Multibyte::strlen($string);
+ $expected = 38;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = Multibyte::strlen($string);
+ $expected = 13;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $result = Multibyte::strlen($string);
+ $expected = 13;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $result = Multibyte::strlen($string);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $result = Multibyte::strlen($string);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $result = Multibyte::strlen($string);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $result = Multibyte::strlen($string);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = Multibyte::strlen($string);
+ $expected = 6;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrpos method
+ *
+ * @return void
+ */
+ public function testUsingMbStrpos() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strpos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strpos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strpos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strpos($string, $find);
+ $expected = 37;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strpos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'é';
+ $result = mb_strpos($string, $find);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strpos($string, $find);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_strpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = mb_strpos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strpos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strpos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'р';
+ $result = mb_strpos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strpos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strpos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strpos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strpos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strpos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strpos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'őř';
+ $result = mb_strpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strpos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strpos($string, $find, 5);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '一周';
+ $result = mb_strpos($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrpos method
+ *
+ * @return void
+ */
+ public function testMultibyteStrpos() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strpos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strpos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strpos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 37;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'é';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'р';
+ $result = Multibyte::strpos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'őř';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strpos($string, $find, 5);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '一周';
+ $result = Multibyte::strpos($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrrchr method
+ *
+ * @return void
+ */
+ public function testUsingMbStrrchr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strrchr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strrchr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'Þßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strrchr($string, $find);
+ $expected = 'РСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strrchr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strrchr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strrchr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strrchr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strrchr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strrchr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strrchr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strrchr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strrchr($string, $find);
+ $expected = 'orld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'Hello, W';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_strrchr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_strrchr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_strrchr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strrchr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strrchr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strrchr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strrchr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strrchr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strrchr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周龍';
+ $result = mb_strrchr($string, $find, true);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrrchr method
+ *
+ * @return void
+ */
+ public function testMultibyteStrrchr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'Þßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'РСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'orld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'Hello, W';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strrchr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周龍';
+ $result = Multibyte::strrchr($string, $find, true);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrrichr method
+ *
+ * @return void
+ */
+ public function testUsingMbStrrichr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strrichr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strrichr($string, $find);
+ $expected = 'fghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcde';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'þÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüý';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strrichr($string, $find);
+ $expected = 'рстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп';
+ $find = 'Р';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strrichr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strrichr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strrichr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strrichr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strrichr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strrichr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strrichr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strrichr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strrichr($string, $find);
+ $expected = 'orld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'Hello, W';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_strrichr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_strrichr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_strrichr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strrichr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strrichr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strrichr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strrichr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strrichr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strrichr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '百设';
+ $result = mb_strrichr($string, $find, true);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrrichr method
+ *
+ * @return void
+ */
+ public function testMultibyteStrrichr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'fghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcde';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'þÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüý';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'рстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп';
+ $find = 'Р';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'orld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'Hello, W';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strrichr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '百设';
+ $result = Multibyte::strrichr($string, $find, true);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrripos method
+ *
+ * @return void
+ */
+ public function testUsingMbStrripos() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strripos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strripos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'ÓÔ';
+ $result = mb_strripos($string, $find);
+ $expected = 19;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strripos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strripos($string, $find);
+ $expected = 69;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strripos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'é';
+ $result = mb_strripos($string, $find);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strripos($string, $find);
+ $expected = 25;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_strripos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = mb_strripos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strripos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strripos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strripos($string, $find);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'р';
+ $result = mb_strripos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strripos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strripos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strripos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strripos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strripos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnoppqrstuvwxyz';
+ $find = 'pp';
+ $result = mb_strripos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strripos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strripos($string, $find, 5);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'dž';
+ $result = mb_strripos($string, $find);
+ $this->assertFalse($result);
+ }
+
+/**
+ * testMultibyteStrripos method
+ *
+ * @return void
+ */
+ public function testMultibyteStrripos() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strripos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strripos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'ÓÔ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 19;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strripos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 69;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'é';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 25;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'р';
+ $result = Multibyte::strripos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnoppqrstuvwxyz';
+ $find = 'pp';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strripos($string, $find, 5);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'dž';
+ $result = Multibyte::strripos($string, $find);
+ $expected = 0;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrrpos method
+ *
+ * @return void
+ */
+ public function testUsingMbStrrpos() {
+ $this->skipIf(extension_loaded('mbstring') && version_compare(PHP_VERSION, '5.2.0', '<'), 'PHP version does not support $offset parameter in mb_strrpos().');
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strrpos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'ÙÚ';
+ $result = mb_strrpos($string, $find);
+ $expected = 25;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strrpos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strrpos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strrpos($string, $find);
+ $expected = 37;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strrpos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'é';
+ $result = mb_strrpos($string, $find);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strrpos($string, $find);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_strrpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = mb_strrpos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strrpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strrpos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strrpos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'р';
+ $result = mb_strrpos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strrpos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strrpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strrpos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strrpos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strrpos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strrpos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strrpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strrpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnoppqrstuvwxyz';
+ $find = 'pp';
+ $result = mb_strrpos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strrpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strrpos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strrpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strrpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strrpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strrpos($string, $find, 5);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strrpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strrpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'H';
+ $result = mb_strrpos($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrrpos method
+ *
+ * @return void
+ */
+ public function testMultibyteStrrpos() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strrpos($string, $find, 6);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strrpos($string, $find, 6);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞ';
+ $find = 'ÙÚ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 25;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strrpos($string, $find, 6);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 37;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 20;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'é';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 32;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 24;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 40;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 39;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'р';
+ $result = Multibyte::strrpos($string, $find, 5);
+ $expected = 36;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 31;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 26;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 46;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 45;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 10;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnoppqrstuvwxyz';
+ $find = 'pp';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 16;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 17;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strrpos($string, $find, 5);
+ $expected = 8;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'H';
+ $result = Multibyte::strrpos($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrstr method
+ *
+ * @return void
+ */
+ public function testUsingMbStrstr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strstr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strstr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strstr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strstr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = mb_strstr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strstr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = mb_strstr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = mb_strstr($string, $find);
+ $expected = 'Þßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strstr($string, $find);
+ $expected = 'ŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_strstr($string, $find);
+ $expected = 'ƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strstr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strstr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strstr($string, $find);
+ $expected = 'РСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strstr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strstr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_strstr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strstr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_strstr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strstr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_strstr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strstr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = mb_strstr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strstr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strstr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strstr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = mb_strstr($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strstr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_strstr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strstr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strstr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ĺļ';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'Ĥē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strstr($string, $find);
+ $expected = 'o, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'Hell';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_strstr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_strstr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_strstr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strstr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strstr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strstr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_strstr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strstr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_strstr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strstr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_strstr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '二周';
+ $result = mb_strstr($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrstr method
+ *
+ * @return void
+ */
+ public function testMultibyteStrstr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ÀÁÂÃÄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ĀĂĄĆĈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDE';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $find = 'µ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'Þßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $find = 'Þ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'Ņ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $find = 'Ƹ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ЀЁЂЃЄЅІ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'РСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'МНОП';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'نهوىيًٌٍَُ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'فقكلم';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strstr($string, $find);
+ $expected = '✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strstr($string, $find);
+ $expected = '⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strstr($string, $find);
+ $expected = '⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strstr($string, $find);
+ $expected = '눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눻';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'klmnopqrstuvwxyz';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'k';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'abcdefghij';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $find = 'K';
+ $result = Multibyte::strstr($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'アイウエオカキク';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '。「」、・ヲァィゥェォャュョッー';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'ケコサシスセソタチツテトナニヌネノ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'őřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'Ĥēĺļŏ, Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ĺļ';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'Ĥē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'o, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'Hell';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'Wo';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'Hello, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'llo, World!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'll';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'He';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'rld!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rld';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'Hello, Wo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'či';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'ći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'mo';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strstr($string, $find);
+ $expected = 'žavni';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strstr($string, $find);
+ $expected = '设为首页';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '把百度';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strstr($string, $find);
+ $expected = '周永龍';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::strstr($string, $find, true);
+ $expected = '一二三';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '二周';
+ $result = Multibyte::strstr($string, $find);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrtolower method
+ *
+ * @return void
+ */
+ public function testUsingMbStrtolower() {
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~';
+ $result = mb_strtolower($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $result = mb_strtolower($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $this->assertEquals($expected, $result);
+
+ $string = 'À';
+ $result = mb_strtolower($string);
+ $expected = 'à';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Á';
+ $result = mb_strtolower($string);
+ $expected = 'á';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Â';
+ $result = mb_strtolower($string);
+ $expected = 'â';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ã';
+ $result = mb_strtolower($string);
+ $expected = 'ã';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ä';
+ $result = mb_strtolower($string);
+ $expected = 'ä';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Å';
+ $result = mb_strtolower($string);
+ $expected = 'å';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Æ';
+ $result = mb_strtolower($string);
+ $expected = 'æ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ç';
+ $result = mb_strtolower($string);
+ $expected = 'ç';
+ $this->assertEquals($expected, $result);
+
+ $string = 'È';
+ $result = mb_strtolower($string);
+ $expected = 'è';
+ $this->assertEquals($expected, $result);
+
+ $string = 'É';
+ $result = mb_strtolower($string);
+ $expected = 'é';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ê';
+ $result = mb_strtolower($string);
+ $expected = 'ê';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ë';
+ $result = mb_strtolower($string);
+ $expected = 'ë';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ì';
+ $result = mb_strtolower($string);
+ $expected = 'ì';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Í';
+ $result = mb_strtolower($string);
+ $expected = 'í';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Î';
+ $result = mb_strtolower($string);
+ $expected = 'î';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ï';
+ $result = mb_strtolower($string);
+ $expected = 'ï';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ð';
+ $result = mb_strtolower($string);
+ $expected = 'ð';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ñ';
+ $result = mb_strtolower($string);
+ $expected = 'ñ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ò';
+ $result = mb_strtolower($string);
+ $expected = 'ò';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ó';
+ $result = mb_strtolower($string);
+ $expected = 'ó';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ô';
+ $result = mb_strtolower($string);
+ $expected = 'ô';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Õ';
+ $result = mb_strtolower($string);
+ $expected = 'õ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ö';
+ $result = mb_strtolower($string);
+ $expected = 'ö';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ø';
+ $result = mb_strtolower($string);
+ $expected = 'ø';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ù';
+ $result = mb_strtolower($string);
+ $expected = 'ù';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ú';
+ $result = mb_strtolower($string);
+ $expected = 'ú';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Û';
+ $result = mb_strtolower($string);
+ $expected = 'û';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ü';
+ $result = mb_strtolower($string);
+ $expected = 'ü';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ý';
+ $result = mb_strtolower($string);
+ $expected = 'ý';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Þ';
+ $result = mb_strtolower($string);
+ $expected = 'þ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $result = mb_strtolower($string);
+ $expected = 'àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ā';
+ $result = mb_strtolower($string);
+ $expected = 'ā';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ă';
+ $result = mb_strtolower($string);
+ $expected = 'ă';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ą';
+ $result = mb_strtolower($string);
+ $expected = 'ą';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ć';
+ $result = mb_strtolower($string);
+ $expected = 'ć';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĉ';
+ $result = mb_strtolower($string);
+ $expected = 'ĉ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ċ';
+ $result = mb_strtolower($string);
+ $expected = 'ċ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Č';
+ $result = mb_strtolower($string);
+ $expected = 'č';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ď';
+ $result = mb_strtolower($string);
+ $expected = 'ď';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Đ';
+ $result = mb_strtolower($string);
+ $expected = 'đ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ē';
+ $result = mb_strtolower($string);
+ $expected = 'ē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĕ';
+ $result = mb_strtolower($string);
+ $expected = 'ĕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ė';
+ $result = mb_strtolower($string);
+ $expected = 'ė';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ę';
+ $result = mb_strtolower($string);
+ $expected = 'ę';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ě';
+ $result = mb_strtolower($string);
+ $expected = 'ě';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĝ';
+ $result = mb_strtolower($string);
+ $expected = 'ĝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ğ';
+ $result = mb_strtolower($string);
+ $expected = 'ğ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ġ';
+ $result = mb_strtolower($string);
+ $expected = 'ġ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ģ';
+ $result = mb_strtolower($string);
+ $expected = 'ģ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥ';
+ $result = mb_strtolower($string);
+ $expected = 'ĥ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ħ';
+ $result = mb_strtolower($string);
+ $expected = 'ħ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĩ';
+ $result = mb_strtolower($string);
+ $expected = 'ĩ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ī';
+ $result = mb_strtolower($string);
+ $expected = 'ī';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĭ';
+ $result = mb_strtolower($string);
+ $expected = 'ĭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Į';
+ $result = mb_strtolower($string);
+ $expected = 'į';
+ $this->assertEquals($expected, $result);
+
+ $string = 'IJ';
+ $result = mb_strtolower($string);
+ $expected = 'ij';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĵ';
+ $result = mb_strtolower($string);
+ $expected = 'ĵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ķ';
+ $result = mb_strtolower($string);
+ $expected = 'ķ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĺ';
+ $result = mb_strtolower($string);
+ $expected = 'ĺ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ļ';
+ $result = mb_strtolower($string);
+ $expected = 'ļ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ľ';
+ $result = mb_strtolower($string);
+ $expected = 'ľ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŀ';
+ $result = mb_strtolower($string);
+ $expected = 'ŀ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ł';
+ $result = mb_strtolower($string);
+ $expected = 'ł';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ń';
+ $result = mb_strtolower($string);
+ $expected = 'ń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ņ';
+ $result = mb_strtolower($string);
+ $expected = 'ņ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ň';
+ $result = mb_strtolower($string);
+ $expected = 'ň';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŋ';
+ $result = mb_strtolower($string);
+ $expected = 'ŋ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ō';
+ $result = mb_strtolower($string);
+ $expected = 'ō';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŏ';
+ $result = mb_strtolower($string);
+ $expected = 'ŏ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ő';
+ $result = mb_strtolower($string);
+ $expected = 'ő';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Œ';
+ $result = mb_strtolower($string);
+ $expected = 'œ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŕ';
+ $result = mb_strtolower($string);
+ $expected = 'ŕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŗ';
+ $result = mb_strtolower($string);
+ $expected = 'ŗ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ř';
+ $result = mb_strtolower($string);
+ $expected = 'ř';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ś';
+ $result = mb_strtolower($string);
+ $expected = 'ś';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŝ';
+ $result = mb_strtolower($string);
+ $expected = 'ŝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ş';
+ $result = mb_strtolower($string);
+ $expected = 'ş';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Š';
+ $result = mb_strtolower($string);
+ $expected = 'š';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ţ';
+ $result = mb_strtolower($string);
+ $expected = 'ţ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ť';
+ $result = mb_strtolower($string);
+ $expected = 'ť';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŧ';
+ $result = mb_strtolower($string);
+ $expected = 'ŧ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ũ';
+ $result = mb_strtolower($string);
+ $expected = 'ũ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ū';
+ $result = mb_strtolower($string);
+ $expected = 'ū';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŭ';
+ $result = mb_strtolower($string);
+ $expected = 'ŭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ů';
+ $result = mb_strtolower($string);
+ $expected = 'ů';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ű';
+ $result = mb_strtolower($string);
+ $expected = 'ű';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ų';
+ $result = mb_strtolower($string);
+ $expected = 'ų';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŵ';
+ $result = mb_strtolower($string);
+ $expected = 'ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŷ';
+ $result = mb_strtolower($string);
+ $expected = 'ŷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ź';
+ $result = mb_strtolower($string);
+ $expected = 'ź';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ż';
+ $result = mb_strtolower($string);
+ $expected = 'ż';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ž';
+ $result = mb_strtolower($string);
+ $expected = 'ž';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $result = mb_strtolower($string);
+ $expected = 'āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįijĵķĺļľŀłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĤĒĹĻŎ, ŴŐŘĻĎ!';
+ $result = mb_strtolower($string);
+ $expected = 'ĥēĺļŏ, ŵőřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĥēĺļŏ, ŵőřļď!';
+ $result = mb_strtolower($string);
+ $expected = 'ĥēĺļŏ, ŵőřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ἈΙ';
+ $result = mb_strtolower($string);
+ $expected = 'ἀι';
+ $this->assertEquals($expected, $result);
+
+ $string = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $result = mb_strtolower($string);
+ $expected = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrtolower method
+ *
+ * @return void
+ */
+ public function testMultibyteStrtolower() {
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~';
+ $result = Multibyte::strtolower($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $result = Multibyte::strtolower($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $this->assertEquals($expected, $result);
+
+ $string = 'À';
+ $result = Multibyte::strtolower($string);
+ $expected = 'à';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Á';
+ $result = Multibyte::strtolower($string);
+ $expected = 'á';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Â';
+ $result = Multibyte::strtolower($string);
+ $expected = 'â';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ã';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ã';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ä';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ä';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Å';
+ $result = Multibyte::strtolower($string);
+ $expected = 'å';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Æ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'æ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ç';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ç';
+ $this->assertEquals($expected, $result);
+
+ $string = 'È';
+ $result = Multibyte::strtolower($string);
+ $expected = 'è';
+ $this->assertEquals($expected, $result);
+
+ $string = 'É';
+ $result = Multibyte::strtolower($string);
+ $expected = 'é';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ê';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ê';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ë';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ë';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ì';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ì';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Í';
+ $result = Multibyte::strtolower($string);
+ $expected = 'í';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Î';
+ $result = Multibyte::strtolower($string);
+ $expected = 'î';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ï';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ï';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ð';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ð';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ñ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ñ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ò';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ò';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ó';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ó';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ô';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ô';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Õ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'õ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ö';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ö';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ø';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ø';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ù';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ù';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ú';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ú';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Û';
+ $result = Multibyte::strtolower($string);
+ $expected = 'û';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ü';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ü';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ý';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ý';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Þ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'þ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ā';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ā';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ă';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ă';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ą';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ą';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ć';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ć';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĉ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĉ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ċ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ċ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Č';
+ $result = Multibyte::strtolower($string);
+ $expected = 'č';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ď';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ď';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Đ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'đ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ē';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĕ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ė';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ė';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ę';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ę';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ě';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ě';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĝ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ğ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ğ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ġ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ġ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ģ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ģ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĥ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ħ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ħ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĩ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĩ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ī';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ī';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĭ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Į';
+ $result = Multibyte::strtolower($string);
+ $expected = 'į';
+ $this->assertEquals($expected, $result);
+
+ $string = 'IJ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ij';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĵ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ķ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ķ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĺ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĺ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ļ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ļ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ľ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ľ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŀ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŀ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ł';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ł';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ń';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ņ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ņ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ň';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ň';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŋ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŋ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ō';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ō';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŏ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŏ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ő';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ő';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Œ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'œ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŕ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŗ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŗ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ř';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ř';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ś';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ś';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŝ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ş';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ş';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Š';
+ $result = Multibyte::strtolower($string);
+ $expected = 'š';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ţ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ţ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ť';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ť';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŧ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŧ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ũ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ũ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ū';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ū';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŭ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ů';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ů';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ű';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ű';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ų';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ų';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŵ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ŷ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ŷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ź';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ź';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ż';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ż';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ž';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ž';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįijĵķĺļľŀłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĤĒĹĻŎ, ŴŐŘĻĎ!';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĥēĺļŏ, ŵőřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĥēĺļŏ, ŵőřļď!';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ĥēĺļŏ, ŵőřļď!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ἈΙ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ἀι';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ԀԂԄԆԈԊԌԎԐԒ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ԁԃԅԇԉԋԍԏԑԓ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖև';
+ $result = Multibyte::strtolower($string);
+ $expected = 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẖẗẘẙẚẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ΩKÅℲ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ωkåⅎ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ΩKÅ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ωkå';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ΩKÅ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ωkå';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯↃ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↄ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⰀⰁⰂⰃⰄⰅⰆⰇⰈⰉⰊⰋⰌⰍⰎⰏⰐⰑⰒⰓⰔⰕⰖⰗⰘⰙⰚⰛⰜⰝⰞⰟⰠⰡⰢⰣⰤⰥⰦⰧⰨⰩⰪⰫⰬⰭⰮ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ⰰⰱⰲⰳⰴⰵⰶⰷⰸⰹⰺⰻⰼⰽⰾⰿⱀⱁⱂⱃⱄⱅⱆⱇⱈⱉⱊⱋⱌⱍⱎⱏⱐⱑⱒⱓⱔⱕⱖⱗⱘⱙⱚⱛⱜⱝⱞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⲀⲂⲄⲆⲈⲊⲌⲎⲐⲒⲔⲖⲘⲚⲜⲞⲠⲢⲤⲦⲨⲪⲬⲮⲰⲲⲴⲶⲸⲺⲼⲾⳀⳂⳄⳆⳈⳊⳌⳎⳐⳒⳔⳖⳘⳚⳜⳞⳠⳢ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'ⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $result = Multibyte::strtolower($string);
+ $expected = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbStrtoupper method
+ *
+ * @return void
+ */
+ public function testUsingMbStrtoupper() {
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = mb_strtoupper($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $result = mb_strtoupper($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $this->assertEquals($expected, $result);
+
+ $string = 'à';
+ $result = mb_strtoupper($string);
+ $expected = 'À';
+ $this->assertEquals($expected, $result);
+
+ $string = 'á';
+ $result = mb_strtoupper($string);
+ $expected = 'Á';
+ $this->assertEquals($expected, $result);
+
+ $string = 'â';
+ $result = mb_strtoupper($string);
+ $expected = 'Â';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ã';
+ $result = mb_strtoupper($string);
+ $expected = 'Ã';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ä';
+ $result = mb_strtoupper($string);
+ $expected = 'Ä';
+ $this->assertEquals($expected, $result);
+
+ $string = 'å';
+ $result = mb_strtoupper($string);
+ $expected = 'Å';
+ $this->assertEquals($expected, $result);
+
+ $string = 'æ';
+ $result = mb_strtoupper($string);
+ $expected = 'Æ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ç';
+ $result = mb_strtoupper($string);
+ $expected = 'Ç';
+ $this->assertEquals($expected, $result);
+
+ $string = 'è';
+ $result = mb_strtoupper($string);
+ $expected = 'È';
+ $this->assertEquals($expected, $result);
+
+ $string = 'é';
+ $result = mb_strtoupper($string);
+ $expected = 'É';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ê';
+ $result = mb_strtoupper($string);
+ $expected = 'Ê';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ë';
+ $result = mb_strtoupper($string);
+ $expected = 'Ë';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ì';
+ $result = mb_strtoupper($string);
+ $expected = 'Ì';
+ $this->assertEquals($expected, $result);
+
+ $string = 'í';
+ $result = mb_strtoupper($string);
+ $expected = 'Í';
+ $this->assertEquals($expected, $result);
+
+ $string = 'î';
+ $result = mb_strtoupper($string);
+ $expected = 'Î';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ï';
+ $result = mb_strtoupper($string);
+ $expected = 'Ï';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ð';
+ $result = mb_strtoupper($string);
+ $expected = 'Ð';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ñ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ñ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ò';
+ $result = mb_strtoupper($string);
+ $expected = 'Ò';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ó';
+ $result = mb_strtoupper($string);
+ $expected = 'Ó';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ô';
+ $result = mb_strtoupper($string);
+ $expected = 'Ô';
+ $this->assertEquals($expected, $result);
+
+ $string = 'õ';
+ $result = mb_strtoupper($string);
+ $expected = 'Õ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ö';
+ $result = mb_strtoupper($string);
+ $expected = 'Ö';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ø';
+ $result = mb_strtoupper($string);
+ $expected = 'Ø';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ù';
+ $result = mb_strtoupper($string);
+ $expected = 'Ù';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ú';
+ $result = mb_strtoupper($string);
+ $expected = 'Ú';
+ $this->assertEquals($expected, $result);
+
+ $string = 'û';
+ $result = mb_strtoupper($string);
+ $expected = 'Û';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ü';
+ $result = mb_strtoupper($string);
+ $expected = 'Ü';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ý';
+ $result = mb_strtoupper($string);
+ $expected = 'Ý';
+ $this->assertEquals($expected, $result);
+
+ $string = 'þ';
+ $result = mb_strtoupper($string);
+ $expected = 'Þ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ';
+ $result = mb_strtoupper($string);
+ $expected = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ā';
+ $result = mb_strtoupper($string);
+ $expected = 'Ā';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ă';
+ $result = mb_strtoupper($string);
+ $expected = 'Ă';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ą';
+ $result = mb_strtoupper($string);
+ $expected = 'Ą';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ć';
+ $result = mb_strtoupper($string);
+ $expected = 'Ć';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĉ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĉ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ċ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ċ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'č';
+ $result = mb_strtoupper($string);
+ $expected = 'Č';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ď';
+ $result = mb_strtoupper($string);
+ $expected = 'Ď';
+ $this->assertEquals($expected, $result);
+
+ $string = 'đ';
+ $result = mb_strtoupper($string);
+ $expected = 'Đ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ē';
+ $result = mb_strtoupper($string);
+ $expected = 'Ē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĕ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ė';
+ $result = mb_strtoupper($string);
+ $expected = 'Ė';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ę';
+ $result = mb_strtoupper($string);
+ $expected = 'Ę';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ě';
+ $result = mb_strtoupper($string);
+ $expected = 'Ě';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĝ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ğ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ğ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ġ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ġ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ģ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ģ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĥ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĥ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ħ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ħ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĩ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĩ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ī';
+ $result = mb_strtoupper($string);
+ $expected = 'Ī';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'į';
+ $result = mb_strtoupper($string);
+ $expected = 'Į';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ij';
+ $result = mb_strtoupper($string);
+ $expected = 'IJ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĵ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ķ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ķ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĺ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ĺ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ļ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ļ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ľ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ľ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŀ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŀ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ł';
+ $result = mb_strtoupper($string);
+ $expected = 'Ł';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ń';
+ $result = mb_strtoupper($string);
+ $expected = 'Ń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ņ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ņ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ň';
+ $result = mb_strtoupper($string);
+ $expected = 'Ň';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŋ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŋ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ō';
+ $result = mb_strtoupper($string);
+ $expected = 'Ō';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŏ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŏ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ő';
+ $result = mb_strtoupper($string);
+ $expected = 'Ő';
+ $this->assertEquals($expected, $result);
+
+ $string = 'œ';
+ $result = mb_strtoupper($string);
+ $expected = 'Œ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŕ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŗ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŗ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ř';
+ $result = mb_strtoupper($string);
+ $expected = 'Ř';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ś';
+ $result = mb_strtoupper($string);
+ $expected = 'Ś';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŝ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ş';
+ $result = mb_strtoupper($string);
+ $expected = 'Ş';
+ $this->assertEquals($expected, $result);
+
+ $string = 'š';
+ $result = mb_strtoupper($string);
+ $expected = 'Š';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ţ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ţ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ť';
+ $result = mb_strtoupper($string);
+ $expected = 'Ť';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŧ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŧ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ũ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ũ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ū';
+ $result = mb_strtoupper($string);
+ $expected = 'Ū';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŭ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ů';
+ $result = mb_strtoupper($string);
+ $expected = 'Ů';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ű';
+ $result = mb_strtoupper($string);
+ $expected = 'Ű';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ų';
+ $result = mb_strtoupper($string);
+ $expected = 'Ų';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŵ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŷ';
+ $result = mb_strtoupper($string);
+ $expected = 'Ŷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ź';
+ $result = mb_strtoupper($string);
+ $expected = 'Ź';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ż';
+ $result = mb_strtoupper($string);
+ $expected = 'Ż';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ž';
+ $result = mb_strtoupper($string);
+ $expected = 'Ž';
+ $this->assertEquals($expected, $result);
+
+ $string = 'āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįijĵķĺļľŀłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž';
+ $result = mb_strtoupper($string);
+ $expected = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = mb_strtoupper($string);
+ $expected = 'ĤĒĹĻŎ, ŴŐŘĻĎ!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ἀι';
+ $result = mb_strtoupper($string);
+ $expected = 'ἈΙ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ԁԃԅԇԉԋԍԏԐԒ';
+ $result = mb_strtoupper($string);
+ $expected = 'ԀԂԄԆԈԊԌԎԐԒ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև';
+ $result = mb_strtoupper($string);
+ $expected = 'ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖև';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $result = mb_strtoupper($string);
+ $expected = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ';
+ $result = mb_strtoupper($string);
+ $expected = 'ḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẖẗẘẙẚẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ωkå';
+ $result = mb_strtoupper($string);
+ $expected = 'ΩKÅ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $result = mb_strtoupper($string);
+ $expected = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteStrtoupper method
+ *
+ * @return void
+ */
+ public function testMultibyteStrtoupper() {
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = Multibyte::strtoupper($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $result = Multibyte::strtoupper($string);
+ $expected = '!"#$%&\'()*+,-./0123456789:;<=>?@';
+ $this->assertEquals($expected, $result);
+
+ $string = 'à';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'À';
+ $this->assertEquals($expected, $result);
+
+ $string = 'á';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Á';
+ $this->assertEquals($expected, $result);
+
+ $string = 'â';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Â';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ã';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ã';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ä';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ä';
+ $this->assertEquals($expected, $result);
+
+ $string = 'å';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Å';
+ $this->assertEquals($expected, $result);
+
+ $string = 'æ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Æ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ç';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ç';
+ $this->assertEquals($expected, $result);
+
+ $string = 'è';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'È';
+ $this->assertEquals($expected, $result);
+
+ $string = 'é';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'É';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ê';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ê';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ë';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ë';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ì';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ì';
+ $this->assertEquals($expected, $result);
+
+ $string = 'í';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Í';
+ $this->assertEquals($expected, $result);
+
+ $string = 'î';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Î';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ï';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ï';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ð';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ð';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ñ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ñ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ò';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ò';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ó';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ó';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ô';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ô';
+ $this->assertEquals($expected, $result);
+
+ $string = 'õ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Õ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ö';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ö';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ø';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ø';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ù';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ù';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ú';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ú';
+ $this->assertEquals($expected, $result);
+
+ $string = 'û';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Û';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ü';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ü';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ý';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ý';
+ $this->assertEquals($expected, $result);
+
+ $string = 'þ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Þ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ā';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ā';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ă';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ă';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ą';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ą';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ć';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ć';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĉ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĉ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ċ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ċ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'č';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Č';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ď';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ď';
+ $this->assertEquals($expected, $result);
+
+ $string = 'đ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Đ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ē';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ē';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĕ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ė';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ė';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ę';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ę';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ě';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ě';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĝ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ğ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ğ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ġ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ġ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ģ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ģ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĥ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĥ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ħ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ħ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĩ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĩ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ī';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ī';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'į';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Į';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ij';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'IJ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĵ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ķ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ķ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĺ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ĺ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ļ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ļ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ľ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ľ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŀ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŀ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ł';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ł';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ń';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ń';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ņ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ņ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ň';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ň';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŋ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŋ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ō';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ō';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŏ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŏ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ő';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ő';
+ $this->assertEquals($expected, $result);
+
+ $string = 'œ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Œ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŕ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŕ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŗ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŗ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ř';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ř';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ś';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ś';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŝ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŝ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ş';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ş';
+ $this->assertEquals($expected, $result);
+
+ $string = 'š';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Š';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ţ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ţ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ť';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ť';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŧ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŧ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ũ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ũ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ū';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ū';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŭ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŭ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ů';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ů';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ű';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ű';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ų';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ų';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŵ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŵ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ŷ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ŷ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ź';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ź';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ż';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ż';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ž';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'Ž';
+ $this->assertEquals($expected, $result);
+
+ $string = 'āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįijĵķĺļľŀłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźżž';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ĤĒĹĻŎ, ŴŐŘĻĎ!';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ἀι';
+ $result = mb_strtoupper($string);
+ $expected = 'ἈΙ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ἀι';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ἈΙ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ԁԃԅԇԉԋԍԏԐԒ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ԀԂԄԆԈԊԌԎԐԒ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'աբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆև';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖև';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ḁḃḅḇḉḋḍḏḑḓḕḗḙḛḝḟḡḣḥḧḩḫḭḯḱḳḵḷḹḻḽḿṁṃṅṇṉṋṍṏṑṓṕṗṙṛṝṟṡṣṥṧṩṫṭṯṱṳṵṷṹṻṽṿẁẃẅẇẉẋẍẏẑẓẕẖẗẘẙẚạảấầẩẫậắằẳẵặẹẻẽếềểễệỉịọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ḀḂḄḆḈḊḌḎḐḒḔḖḘḚḜḞḠḢḤḦḨḪḬḮḰḲḴḶḸḺḼḾṀṂṄṆṈṊṌṎṐṒṔṖṘṚṜṞṠṢṤṦṨṪṬṮṰṲṴṶṸṺṼṾẀẂẄẆẈẊẌẎẐẒẔẖẗẘẙẚẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼẾỀỂỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪỬỮỰỲỴỶỸ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ωkåⅎ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ΩKÅℲ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ωkå';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ΩKÅ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↄ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯↃ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⰰⰱⰲⰳⰴⰵⰶⰷⰸⰹⰺⰻⰼⰽⰾⰿⱀⱁⱂⱃⱄⱅⱆⱇⱈⱉⱊⱋⱌⱍⱎⱏⱐⱑⱒⱓⱔⱕⱖⱗⱘⱙⱚⱛⱜⱝⱞ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ⰀⰁⰂⰃⰄⰅⰆⰇⰈⰉⰊⰋⰌⰍⰎⰏⰐⰑⰒⰓⰔⰕⰖⰗⰘⰙⰚⰛⰜⰝⰞⰟⰠⰡⰢⰣⰤⰥⰦⰧⰨⰩⰪⰫⰬⰭⰮ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ⲁⲃⲅⲇⲉⲋⲍⲏⲑⲓⲕⲗⲙⲛⲝⲟⲡⲣⲥⲧⲩⲫⲭⲯⲱⲳⲵⲷⲹⲻⲽⲿⳁⳃⳅⳇⳉⳋⳍⳏⳑⳓⳕⳗⳙⳛⳝⳟⳡⳣ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'ⲀⲂⲄⲆⲈⲊⲌⲎⲐⲒⲔⲖⲘⲚⲜⲞⲠⲢⲤⲦⲨⲪⲬⲮⲰⲲⲴⲶⲸⲺⲼⲾⳀⳂⳄⳆⳈⳊⳌⳎⳐⳒⳔⳖⳘⳚⳜⳞⳠⳢ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $result = Multibyte::strtoupper($string);
+ $expected = 'fffiflffifflſtstﬓﬔﬕﬖﬗ';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbSubstrCount method
+ *
+ * @return void
+ */
+ public function testUsingMbSubstrCount() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSFTUVWXYZ0F12345F6789';
+ $find = 'F';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÅÊËÌÍÎÏÐÑÒÓÔÅÕÖØÅÙÚÛÅÜÝÞ';
+ $find = 'Å';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÙÚÂÃÄÅÆÇÈÙÚÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞÙÚ';
+ $find = 'ÙÚ';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊÅËÌÍÎÏÐÑÒÓÔÕÅÖØÅÙÚÅÛÜÅÝÞÅ';
+ $find = 'Å';
+ $result = mb_substr_count($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĊĀĂĄĆĈĊČĎĐĒĔĖĊĘĚĜĞĠĢĤĦĨĪĬĮĊIJĴĶĹĻĽĿŁŃŅŇŊŌĊŎŐŒŔŖŘŚŜŞŠŢĊŤŦŨŪŬŮŰĊŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_substr_count($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĊĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅĊŇŊŌŎŐŒŔŖĊŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./012F34567F89:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghiFjklmnopqFrstuvwFxyz{|}~';
+ $find = 'F';
+ $result = mb_substr_count($string, $find);
+ $expected = 6;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥µ¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁµÂõÄÅÆǵÈ';
+ $find = 'µ';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôÕÖõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉÕÖĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝÕÖĞğĠġĢģĤĥĦÕÖħĨĩĪīĬ';
+ $find = 'ÕÖ';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōĵĶķĸĹŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšĵĶķĸĹŢţŤťŦŧŨũŪūŬŭŮůŰűŲųĵĶķĸĹŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'ĵĶķĸĹ';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƸƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJƸNjnjǍǎǏǐǑǒǓƸǔǕǖǗǘǙǚƸǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƹƠơƢƣƤƥƦƧƨƩƹƪƫƬƭƮƯưƱƲƳƴƹƵƶƷƸƹƺƻƼƽƾƿǀǁǂƹǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞʀɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʀʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʀʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʀʻʼ';
+ $find = 'ʀ';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЇЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = mb_substr_count($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСРТУФХЦЧШЩЪЫЬРЭЮЯабРвгдежзийклРмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСрТУФХЦЧШЩЪЫрЬЭЮЯабвгдежзийклмнопррстуфхцчшщъыь';
+ $find = 'р';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فنقكلنمنهونىينًٌٍَُ';
+ $find = 'ن';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✿✴✵✶✷✸✿✹✺✻✼✽✾✿❀❁❂❃❄❅❆✿❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺐⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺐⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⺐⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽤⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽤⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = mb_substr_count($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눺눻눼눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕눺눻눼뉖뉗뉘뉙뉚뉛뉜뉝눺눻눼뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눺눻눼';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺞﺟﺠﺡﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺞﺟﺠﺡﺆﺇﺞﺟﺠﺡﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞﺟﺠﺡ';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﻞﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻞﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻞﻸﻹﻺﻞﻻﻼ';
+ $find = 'ﻞ';
+ $result = mb_substr_count($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdkefghijklmnopqrstuvwxkyz';
+ $find = 'k';
+ $result = mb_substr_count($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abklmcdefghijklmnopqrstuvklmwxyz';
+ $find = 'klm';
+ $result = mb_substr_count($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdppefghijklmnoppqrstuvwxyz';
+ $find = 'ppe';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ĺļ';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = mb_substr_count($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rl';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ničiničiini';
+ $find = 'n';
+ $result = mb_substr_count($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moćimoćimoćmćioći';
+ $find = 'ći';
+ $result = mb_substr_count($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = mb_substr_count($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'H';
+ $result = mb_substr_count($string, $find);
+ $expected = 0;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteSubstrCount method
+ *
+ * @return void
+ */
+ public function testMultibyteSubstrCount() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $find = 'F';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ABCDEFGHIJKLMNOPQFRSFTUVWXYZ0F12345F6789';
+ $find = 'F';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÅÊËÌÍÎÏÐÑÒÓÔÅÕÖØÅÙÚÛÅÜÝÞ';
+ $find = 'Å';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÙÚÂÃÄÅÆÇÈÙÚÉÊËÌÍÎÏÐÑÒÓÔÕÖØÅÙÚÛÜÝÞÙÚ';
+ $find = 'ÙÚ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊÅËÌÍÎÏÐÑÒÓÔÕÅÖØÅÙÚÅÛÜÅÝÞÅ';
+ $find = 'Å';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĊĀĂĄĆĈĊČĎĐĒĔĖĊĘĚĜĞĠĢĤĦĨĪĬĮĊIJĴĶĹĻĽĿŁŃŅŇŊŌĊŎŐŒŔŖŘŚŜŞŠŢĊŤŦŨŪŬŮŰĊŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 7;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĊĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁĊŃŅĊŇŊŌŎŐŒŔŖĊŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $find = 'Ċ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./012F34567F89:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghiFjklmnopqFrstuvwFxyz{|}~';
+ $find = 'F';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 6;
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥µ¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁµÂõÄÅÆǵÈ';
+ $find = 'µ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôÕÖõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉÕÖĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝÕÖĞğĠġĢģĤĥĦÕÖħĨĩĪīĬ';
+ $find = 'ÕÖ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōĵĶķĸĹŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšĵĶķĸĹŢţŤťŦŧŨũŪūŬŭŮůŰűŲųĵĶķĸĹŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $find = 'ĵĶķĸĹ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƸƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJƸNjnjǍǎǏǐǑǒǓƸǔǕǖǗǘǙǚƸǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'Ƹ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƹƠơƢƣƤƥƦƧƨƩƹƪƫƬƭƮƯưƱƲƳƴƹƵƶƷƸƹƺƻƼƽƾƿǀǁǂƹǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $find = 'ƹ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞʀɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʀʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʀʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʀʻʼ';
+ $find = 'ʀ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЇЎЏАБВГДЕЖЗИЙКЛ';
+ $find = 'Ї';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСРТУФХЦЧШЩЪЫЬРЭЮЯабРвгдежзийклРмнопрстуфхцчшщъыь';
+ $find = 'Р';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСрТУФХЦЧШЩЪЫрЬЭЮЯабвгдежзийклмнопррстуфхцчшщъыь';
+ $find = 'р';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'فنقكلنمنهونىينًٌٍَُ';
+ $find = 'ن';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✿✴✵✶✷✸✿✹✺✻✼✽✾✿❀❁❂❃❄❅❆✿❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $find = '✿';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺐⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺐⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⺐⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $find = '⺐';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽤⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽤⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $find = '⽤';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눺눻눼눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕눺눻눼뉖뉗뉘뉙뉚뉛뉜뉝눺눻눼뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $find = '눺눻눼';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺞﺟﺠﺡﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺞﺟﺠﺡﺆﺇﺞﺟﺠﺡﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $find = 'ﺞﺟﺠﺡ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﻞﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻞﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻞﻸﻹﻺﻞﻻﻼ';
+ $find = 'ﻞ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdkefghijklmnopqrstuvwxkyz';
+ $find = 'k';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abklmcdefghijklmnopqrstuvklmwxyz';
+ $find = 'klm';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdppefghijklmnoppqrstuvwxyz';
+ $find = 'ppe';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $find = 'ア';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $find = 'ハ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ő';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'ĺļ';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'o';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $find = 'rl';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $find = 'n';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'ničiničiini';
+ $find = 'n';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $find = 'ć';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'moćimoćimoćmćioći';
+ $find = 'ći';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $find = 'ž';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $find = '设';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $find = '周';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $find = 'H';
+ $result = Multibyte::substrCount($string, $find);
+ $expected = 0;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUsingMbSubstr method
+ *
+ * @return void
+ */
+ public function testUsingMbSubstr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $result = mb_substr($string, 4, 7);
+ $expected = 'EFGHIJK';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $result = mb_substr($string, 4, 7);
+ $expected = 'ÄÅÆÇÈÉÊ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $result = mb_substr($string, 4, 7);
+ $expected = 'ĈĊČĎĐĒĔ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = mb_substr($string, 4, 7);
+ $expected = '%&\'()*+';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $result = mb_substr($string, 4);
+ $expected = '¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $result = mb_substr($string, 4, 7);
+ $expected = 'ÍÎÏÐÑÒÓ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $result = mb_substr($string, 4, 7);
+ $expected = 'ıIJijĴĵĶķ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $result = mb_substr($string, 25);
+ $expected = 'ƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $result = mb_substr($string, 3);
+ $expected = 'ɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $result = mb_substr($string, 3);
+ $expected = 'ЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $result = mb_substr($string, 3, 16);
+ $expected = 'ПРСТУФХЦЧШЩЪЫЬЭЮ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $result = mb_substr($string, 3, 6);
+ $expected = 'لمنهوى';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $result = mb_substr($string, 6, 14);
+ $expected = '✶✷✸✹✺✻✼✽✾✿❀❁❂❃';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $result = mb_substr($string, 8, 13);
+ $expected = '⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $result = mb_substr($string, 12, 24);
+ $expected = '⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $result = mb_substr($string, 12, 24);
+ $expected = '눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $result = mb_substr($string, 12);
+ $expected = 'ﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $result = mb_substr($string, 24, 12);
+ $expected = 'ﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $result = mb_substr($string, 11, 2);
+ $expected = 'lm';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $result = mb_substr($string, 7, 11);
+ $expected = 'ィゥェォャュョッーアイ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $result = mb_substr($string, 13, 13);
+ $expected = 'ニヌネノハヒフヘホマミムメ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = mb_substr($string, 3, 4);
+ $expected = 'ļŏ, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $result = mb_substr($string, 3, 4);
+ $expected = 'lo, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $result = mb_substr($string, 3);
+ $expected = 'i';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $result = mb_substr($string, 1);
+ $expected = 'oći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $result = mb_substr($string, 0, 2);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $result = mb_substr($string, 3, 3);
+ $expected = '设为首';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = mb_substr($string, 0, 1);
+ $expected = '一';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = mb_substr($string, 6);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = mb_substr($string, 0);
+ $expected = '一二三周永龍';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteSubstr method
+ *
+ * @return void
+ */
+ public function testMultibyteSubstr() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $result = Multibyte::substr($string, 4, 7);
+ $expected = 'EFGHIJK';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $result = Multibyte::substr($string, 4, 7);
+ $expected = 'ÄÅÆÇÈÉÊ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $result = Multibyte::substr($string, 4, 7);
+ $expected = 'ĈĊČĎĐĒĔ';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = Multibyte::substr($string, 4, 7);
+ $expected = '%&\'()*+';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $result = Multibyte::substr($string, 4);
+ $expected = '¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $result = Multibyte::substr($string, 4, 7);
+ $expected = 'ÍÎÏÐÑÒÓ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $result = Multibyte::substr($string, 4, 7);
+ $expected = 'ıIJijĴĵĶķ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $result = Multibyte::substr($string, 25);
+ $expected = 'ƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $result = Multibyte::substr($string, 3);
+ $expected = 'ɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $result = Multibyte::substr($string, 3);
+ $expected = 'ЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $result = Multibyte::substr($string, 3, 16);
+ $expected = 'ПРСТУФХЦЧШЩЪЫЬЭЮ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $result = Multibyte::substr($string, 3, 6);
+ $expected = 'لمنهوى';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $result = Multibyte::substr($string, 6, 14);
+ $expected = '✶✷✸✹✺✻✼✽✾✿❀❁❂❃';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $result = Multibyte::substr($string, 8, 13);
+ $expected = '⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $result = Multibyte::substr($string, 12, 24);
+ $expected = '⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $result = Multibyte::substr($string, 12, 24);
+ $expected = '눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $result = Multibyte::substr($string, 12);
+ $expected = 'ﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $result = Multibyte::substr($string, 24, 12);
+ $expected = 'ﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $result = Multibyte::substr($string, 11, 2);
+ $expected = 'lm';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $result = Multibyte::substr($string, 7, 11);
+ $expected = 'ィゥェォャュョッーアイ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $result = Multibyte::substr($string, 13, 13);
+ $expected = 'ニヌネノハヒフヘホマミムメ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = Multibyte::substr($string, 3, 4);
+ $expected = 'ļŏ, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $result = Multibyte::substr($string, 3, 4);
+ $expected = 'lo, ';
+ $this->assertEquals($expected, $result);
+
+ $string = 'čini';
+ $result = Multibyte::substr($string, 3);
+ $expected = 'i';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $result = Multibyte::substr($string, 1);
+ $expected = 'oći';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $result = Multibyte::substr($string, 0, 2);
+ $expected = 'dr';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $result = Multibyte::substr($string, 3, 3);
+ $expected = '设为首';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = Multibyte::substr($string, 0, 1);
+ $expected = '一';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = Multibyte::substr($string, 6);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = Multibyte::substr($string, 0);
+ $expected = '一二三周永龍';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteSubstr method
+ *
+ * @return void
+ */
+ public function testMultibyteMimeEncode() {
+ $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $result = Multibyte::mimeEncode($string);
+ $this->assertEquals($string, $result);
+
+ $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?w4DDgcOCw4PDhMOFw4bDh8OIw4nDisOLw4zDjcOOw4/DkMORw5LDk8OUw5U=?=' . "\r\n" .
+ ' =?UTF-8?B?w5bDmMOZw5rDm8Ocw53Dng==?=';
+ $this->assertEquals($expected, $result);
+ $result = Multibyte::mimeEncode($string, null, "\n");
+ $expected = '=?UTF-8?B?w4DDgcOCw4PDhMOFw4bDh8OIw4nDisOLw4zDjcOOw4/DkMORw5LDk8OUw5U=?=' . "\n" .
+ ' =?UTF-8?B?w5bDmMOZw5rDm8Ocw53Dng==?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?xIDEgsSExIbEiMSKxIzEjsSQxJLElMSWxJjEmsScxJ7EoMSixKTEpsSoxKo=?=' . "\r\n" .
+ ' =?UTF-8?B?xKzErsSyxLTEtsS5xLvEvcS/xYHFg8WFxYfFisWMxY7FkMWSxZTFlsWYxZo=?=' . "\r\n" .
+ ' =?UTF-8?B?xZzFnsWgxaLFpMWmxajFqsWsxa7FsMWyxbTFtsW5xbvFvQ==?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?ISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xN?=' . "\r\n" .
+ ' =?UTF-8?B?Tk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6?=' . "\r\n" .
+ ' =?UTF-8?B?e3x9fg==?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?wqHCosKjwqTCpcKmwqfCqMKpwqrCq8Kswq3CrsKvwrDCscKywrPCtMK1wrY=?=' . "\r\n" .
+ ' =?UTF-8?B?wrfCuMK5wrrCu8K8wr3CvsK/w4DDgcOCw4PDhMOFw4bDh8OI?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?w4nDisOLw4zDjcOOw4/DkMORw5LDk8OUw5XDlsOXw5jDmcOaw5vDnMOdw54=?=' . "\r\n" .
+ ' =?UTF-8?B?w5/DoMOhw6LDo8Okw6XDpsOnw6jDqcOqw6vDrMOtw67Dr8Oww7HDssOzw7Q=?=' . "\r\n" .
+ ' =?UTF-8?B?w7XDtsO3w7jDucO6w7vDvMO9w77Dv8SAxIHEgsSDxITEhcSGxIfEiMSJxIo=?=' . "\r\n" .
+ ' =?UTF-8?B?xIvEjMSNxI7Ej8SQxJHEksSTxJTElcSWxJfEmMSZxJrEm8ScxJ3EnsSfxKA=?=' . "\r\n" .
+ ' =?UTF-8?B?xKHEosSjxKTEpcSmxKfEqMSpxKrEq8Ss?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?xK3ErsSvxLDEscSyxLPEtMS1xLbEt8S4xLnEusS7xLzEvcS+xL/FgMWBxYI=?=' . "\r\n" .
+ ' =?UTF-8?B?xYPFhMWFxYbFh8WIxYnFisWLxYzFjcWOxY/FkMWRxZLFk8WUxZXFlsWXxZg=?=' . "\r\n" .
+ ' =?UTF-8?B?xZnFmsWbxZzFncWexZ/FoMWhxaLFo8WkxaXFpsWnxajFqcWqxavFrMWtxa4=?=' . "\r\n" .
+ ' =?UTF-8?B?xa/FsMWxxbLFs8W0xbXFtsW3xbjFucW6xbvFvMW9xb7Fv8aAxoHGgsaDxoQ=?=' . "\r\n" .
+ ' =?UTF-8?B?xoXGhsaHxojGicaKxovGjMaNxo7Gj8aQ?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?xpHGksaTxpTGlcaWxpfGmMaZxprGm8acxp3GnsafxqDGocaixqPGpMalxqY=?=' . "\r\n" .
+ ' =?UTF-8?B?xqfGqMapxqrGq8asxq3GrsavxrDGscayxrPGtMa1xrbGt8a4xrnGusa7xrw=?=' . "\r\n" .
+ ' =?UTF-8?B?xr3Gvsa/x4DHgceCx4PHhMeFx4bHh8eIx4nHiseLx4zHjceOx4/HkMeRx5I=?=' . "\r\n" .
+ ' =?UTF-8?B?x5PHlMeVx5bHl8eYx5nHmsebx5zHnceex5/HoMehx6LHo8ekx6XHpsenx6g=?=' . "\r\n" .
+ ' =?UTF-8?B?x6nHqserx6zHrceux6/HsMexx7LHs8e0?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?yZnJmsmbyZzJncmeyZ/JoMmhyaLJo8mkyaXJpsmnyajJqcmqyavJrMmtya4=?=' . "\r\n" .
+ ' =?UTF-8?B?ya/JsMmxybLJs8m0ybXJtsm3ybjJucm6ybvJvMm9yb7Jv8qAyoHKgsqDyoQ=?=' . "\r\n" .
+ ' =?UTF-8?B?yoXKhsqHyojKicqKyovKjMqNyo7Kj8qQypHKksqTypTKlcqWypfKmMqZypo=?=' . "\r\n" .
+ ' =?UTF-8?B?ypvKnMqdyp7Kn8qgyqHKosqjyqTKpcqmyqfKqMqpyqrKq8qsyq3KrsqvyrA=?=' . "\r\n" .
+ ' =?UTF-8?B?yrHKssqzyrTKtcq2yrfKuMq5yrrKu8q8?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?0IDQgdCC0IPQhNCF0IbQh9CI0InQitCL0IzQjdCO0I/QkNCR0JLQk9CU0JU=?=' . "\r\n" .
+ ' =?UTF-8?B?0JbQl9CY0JnQmtCb?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?0JzQndCe0J/QoNCh0KLQo9Ck0KXQptCn0KjQqdCq0KvQrNCt0K7Qr9Cw0LE=?=' . "\r\n" .
+ ' =?UTF-8?B?0LLQs9C00LXQttC30LjQudC60LvQvNC90L7Qv9GA0YHRgtGD0YTRhdGG0Yc=?=' . "\r\n" .
+ ' =?UTF-8?B?0YjRidGK0YvRjA==?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'فقكلمنهوىيًٌٍَُ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?2YHZgtmD2YTZhdmG2YfZiNmJ2YrZi9mM2Y3ZjtmP?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?4pyw4pyx4pyy4pyz4py04py14py24py34py44py54py64py74py84py94py+?=' . "\r\n" .
+ ' =?UTF-8?B?4py/4p2A4p2B4p2C4p2D4p2E4p2F4p2G4p2H4p2I4p2J4p2K4p2L4p2M4p2N?=' . "\r\n" .
+ ' =?UTF-8?B?4p2O4p2P4p2Q4p2R4p2S4p2T4p2U4p2V4p2W4p2X4p2Y4p2Z4p2a4p2b4p2c?=' . "\r\n" .
+ ' =?UTF-8?B?4p2d4p2e?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?4rqA4rqB4rqC4rqD4rqE4rqF4rqG4rqH4rqI4rqJ4rqK4rqL4rqM4rqN4rqO?=' . "\r\n" .
+ ' =?UTF-8?B?4rqP4rqQ4rqR4rqS4rqT4rqU4rqV4rqW4rqX4rqY4rqZ4rqb4rqc4rqd4rqe?=' . "\r\n" .
+ ' =?UTF-8?B?4rqf4rqg4rqh4rqi4rqj4rqk4rql4rqm4rqn4rqo4rqp4rqq4rqr4rqs4rqt?=' . "\r\n" .
+ ' =?UTF-8?B?4rqu4rqv4rqw4rqx4rqy4rqz4rq04rq14rq24rq34rq44rq54rq64rq74rq8?=' . "\r\n" .
+ ' =?UTF-8?B?4rq94rq+4rq/4ruA4ruB4ruC4ruD4ruE4ruF4ruG4ruH4ruI4ruJ4ruK4ruL?=' . "\r\n" .
+ ' =?UTF-8?B?4ruM4ruN4ruO4ruP4ruQ4ruR4ruS4ruT4ruU4ruV4ruW4ruX4ruY4ruZ4rua?=' . "\r\n" .
+ ' =?UTF-8?B?4rub4ruc4rud4rue4ruf4rug?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?4r2F4r2G4r2H4r2I4r2J4r2K4r2L4r2M4r2N4r2O4r2P4r2Q4r2R4r2S4r2T?=' . "\r\n" .
+ ' =?UTF-8?B?4r2U4r2V4r2W4r2X4r2Y4r2Z4r2a4r2b4r2c4r2d4r2e4r2f4r2g4r2h4r2i?=' . "\r\n" .
+ ' =?UTF-8?B?4r2j4r2k4r2l4r2m4r2n4r2o4r2p4r2q4r2r4r2s4r2t4r2u4r2v4r2w4r2x?=' . "\r\n" .
+ ' =?UTF-8?B?4r2y4r2z4r204r214r224r234r244r254r264r274r284r294r2+4r2/?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?64ih64ii64ij64ik64il64im64in64io64ip64iq64ir64is64it64iu64iv?=' . "\r\n" .
+ ' =?UTF-8?B?64iw64ix64iy64iz64i064i164i264i364i464i564i664i764i864i964i+?=' . "\r\n" .
+ ' =?UTF-8?B?64i/64mA64mB64mC64mD64mE64mF64mG64mH64mI64mJ64mK64mL64mM64mN?=' . "\r\n" .
+ ' =?UTF-8?B?64mO64mP64mQ64mR64mS64mT64mU64mV64mW64mX64mY64mZ64ma64mb64mc?=' . "\r\n" .
+ ' =?UTF-8?B?64md64me64mf64mg64mh64mi64mj64mk64ml64mm64mn64mo64mp64mq64mr?=' . "\r\n" .
+ ' =?UTF-8?B?64ms64mt64mu64mv64mw64mx64my64mz64m064m164m264m364m464m564m6?=' . "\r\n" .
+ ' =?UTF-8?B?64m764m864m964m+64m/64qA64qB64qC64qD64qE?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?77mw77mx77my77mz77m077m177m277m377m477m577m677m777m877m977m+?=' . "\r\n" .
+ ' =?UTF-8?B?77m/77qA77qB77qC77qD77qE77qF77qG77qH77qI77qJ77qK77qL77qM77qN?=' . "\r\n" .
+ ' =?UTF-8?B?77qO77qP77qQ77qR77qS77qT77qU77qV77qW77qX77qY77qZ77qa77qb77qc?=' . "\r\n" .
+ ' =?UTF-8?B?77qd77qe77qf77qg77qh77qi77qj77qk77ql77qm77qn77qo77qp77qq77qr?=' . "\r\n" .
+ ' =?UTF-8?B?77qs77qt77qu77qv77qw?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?77qx77qy77qz77q077q177q277q377q477q577q677q777q877q977q+77q/?=' . "\r\n" .
+ ' =?UTF-8?B?77uA77uB77uC77uD77uE77uF77uG77uH77uI77uJ77uK77uL77uM77uN77uO?=' . "\r\n" .
+ ' =?UTF-8?B?77uP77uQ77uR77uS77uT77uU77uV77uW77uX77uY77uZ77ua77ub77uc77ud?=' . "\r\n" .
+ ' =?UTF-8?B?77ue77uf77ug77uh77ui77uj77uk77ul77um77un77uo77up77uq77ur77us?=' . "\r\n" .
+ ' =?UTF-8?B?77ut77uu77uv77uw77ux77uy77uz77u077u177u277u377u477u577u677u7?=' . "\r\n" .
+ ' =?UTF-8?B?77u8?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'abcdefghijklmnopqrstuvwxyz';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?772B772C772D772E772F772G772H772I772J772K772L772M772N772O772P?=' . "\r\n" .
+ ' =?UTF-8?B?772Q772R772S772T772U772V772W772X772Y772Z772a?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?772h772i772j772k772l772m772n772o772p772q772r772s772t772u772v?=' . "\r\n" .
+ ' =?UTF-8?B?772w772x772y772z77207721772277237724?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?77257726772777287729772+772/776A776B776C776D776E776F776G776H?=' . "\r\n" .
+ ' =?UTF-8?B?776I776J776K776L776M776N776O776P776Q776R776S776T776U776V776W?=' . "\r\n" .
+ ' =?UTF-8?B?776X776Y776Z776a776b776c776d776e?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Ĥēĺļŏ, Ŵőřļď!';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?xKTEk8S6xLzFjywgxbTFkcWZxLzEjyE=?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'Hello, World!';
+ $result = Multibyte::mimeEncode($string);
+ $this->assertEquals($string, $result);
+
+ $string = 'čini';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?xI1pbmk=?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'moći';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?bW/Eh2k=?=';
+ $this->assertEquals($expected, $result);
+
+ $string = 'državni';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?ZHLFvmF2bmk=?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '把百度设为首页';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?5oqK55m+5bqm6K6+5Li66aaW6aG1?=';
+ $this->assertEquals($expected, $result);
+
+ $string = '一二三周永龍';
+ $result = Multibyte::mimeEncode($string);
+ $expected = '=?UTF-8?B?5LiA5LqM5LiJ5ZGo5rC46b6N?=';
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/CakeLogTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/CakeLogTest.php
new file mode 100644
index 0000000..7e0f05a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/CakeLogTest.php
@@ -0,0 +1,676 @@
+<?php
+/**
+ * CakeLogTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Log
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeLog', 'Log');
+App::uses('FileLog', 'Log/Engine');
+
+/**
+ * CakeLogTest class
+ *
+ * @package Cake.Test.Case.Log
+ */
+class CakeLogTest extends CakeTestCase {
+
+/**
+ * Start test callback, clears all streams enabled.
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $streams = CakeLog::configured();
+ foreach ($streams as $stream) {
+ CakeLog::drop($stream);
+ }
+ }
+
+/**
+ * test importing loggers from app/libs and plugins.
+ *
+ * @return void
+ */
+ public function testImportingLoggers() {
+ App::build(array(
+ 'Lib' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Lib' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+
+ $result = CakeLog::config('libtest', array(
+ 'engine' => 'TestAppLog'
+ ));
+ $this->assertTrue($result);
+ $this->assertEquals(CakeLog::configured(), array('libtest'));
+
+ $result = CakeLog::config('plugintest', array(
+ 'engine' => 'TestPlugin.TestPluginLog'
+ ));
+ $this->assertTrue($result);
+ $this->assertEquals(CakeLog::configured(), array('libtest', 'plugintest'));
+
+ CakeLog::write(LOG_INFO, 'TestPluginLog is not a BaseLog descendant');
+
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * test all the errors from failed logger imports
+ *
+ * @expectedException CakeLogException
+ * @return void
+ */
+ public function testImportingLoggerFailure() {
+ CakeLog::config('fail', array());
+ }
+
+/**
+ * test config() with valid key name
+ *
+ * @return void
+ */
+ public function testValidKeyName() {
+ CakeLog::config('valid', array('engine' => 'FileLog'));
+ $stream = CakeLog::stream('valid');
+ $this->assertInstanceOf('FileLog', $stream);
+ CakeLog::drop('valid');
+ }
+
+/**
+ * test config() with invalid key name
+ *
+ * @expectedException CakeLogException
+ * @return void
+ */
+ public function testInvalidKeyName() {
+ CakeLog::config('1nv', array('engine' => 'FileLog'));
+ }
+
+/**
+ * test that loggers have to implement the correct interface.
+ *
+ * @expectedException CakeLogException
+ * @return void
+ */
+ public function testNotImplementingInterface() {
+ CakeLog::config('fail', array('engine' => 'stdClass'));
+ }
+
+/**
+ * Test that CakeLog autoconfigures itself to use a FileLogger with the LOGS dir.
+ * When no streams are there.
+ *
+ * @return void
+ */
+ public function testAutoConfig() {
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ CakeLog::write(LOG_WARNING, 'Test warning');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+
+ $result = CakeLog::configured();
+ $this->assertEquals(array('default'), $result);
+
+ $testMessage = 'custom message';
+ CakeLog::write('custom', $testMessage);
+ $content = file_get_contents(LOGS . 'custom.log');
+ $this->assertContains($testMessage, $content);
+ unlink(LOGS . 'error.log');
+ unlink(LOGS . 'custom.log');
+ }
+
+/**
+ * test configuring log streams
+ *
+ * @return void
+ */
+ public function testConfig() {
+ CakeLog::config('file', array(
+ 'engine' => 'FileLog',
+ 'path' => LOGS
+ ));
+ $result = CakeLog::configured();
+ $this->assertEquals(array('file'), $result);
+
+ if (file_exists(LOGS . 'error.log')) {
+ @unlink(LOGS . 'error.log');
+ }
+ CakeLog::write(LOG_WARNING, 'Test warning');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+
+ $result = file_get_contents(LOGS . 'error.log');
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning/', $result);
+ unlink(LOGS . 'error.log');
+ }
+
+/**
+ * explicit tests for drop()
+ *
+ * @return void
+ **/
+ public function testDrop() {
+ CakeLog::config('file', array(
+ 'engine' => 'FileLog',
+ 'path' => LOGS
+ ));
+ $result = CakeLog::configured();
+ $this->assertEquals(array('file'), $result);
+
+ CakeLog::drop('file');
+ $result = CakeLog::configured();
+ $this->assertEquals(array(), $result);
+ }
+
+/**
+ * testLogFileWriting method
+ *
+ * @return void
+ */
+ public function testLogFileWriting() {
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ $result = CakeLog::write(LOG_WARNING, 'Test warning');
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ unlink(LOGS . 'error.log');
+
+ CakeLog::write(LOG_WARNING, 'Test warning 1');
+ CakeLog::write(LOG_WARNING, 'Test warning 2');
+ $result = file_get_contents(LOGS . 'error.log');
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning 1/', $result);
+ $this->assertRegExp('/2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning 2$/', $result);
+ unlink(LOGS . 'error.log');
+ }
+
+/**
+ * test selective logging by level/type
+ *
+ * @return void
+ */
+ public function testSelectiveLoggingByLevel() {
+ if (file_exists(LOGS . 'spam.log')) {
+ unlink(LOGS . 'spam.log');
+ }
+ if (file_exists(LOGS . 'eggs.log')) {
+ unlink(LOGS . 'eggs.log');
+ }
+ CakeLog::config('spam', array(
+ 'engine' => 'FileLog',
+ 'types' => 'info',
+ 'file' => 'spam',
+ ));
+ CakeLog::config('eggs', array(
+ 'engine' => 'FileLog',
+ 'types' => array('eggs', 'info', 'error', 'warning'),
+ 'file' => 'eggs',
+ ));
+
+ $testMessage = 'selective logging';
+ CakeLog::write(LOG_WARNING, $testMessage);
+
+ $this->assertTrue(file_exists(LOGS . 'eggs.log'));
+ $this->assertFalse(file_exists(LOGS . 'spam.log'));
+
+ CakeLog::write(LOG_INFO, $testMessage);
+ $this->assertTrue(file_exists(LOGS . 'spam.log'));
+
+ $contents = file_get_contents(LOGS . 'spam.log');
+ $this->assertContains('Info: ' . $testMessage, $contents);
+ $contents = file_get_contents(LOGS . 'eggs.log');
+ $this->assertContains('Info: ' . $testMessage, $contents);
+
+ if (file_exists(LOGS . 'spam.log')) {
+ unlink(LOGS . 'spam.log');
+ }
+ if (file_exists(LOGS . 'eggs.log')) {
+ unlink(LOGS . 'eggs.log');
+ }
+ }
+
+/**
+ * test enable
+ *
+ * @expectedException CakeLogException
+ */
+ public function testStreamEnable() {
+ CakeLog::config('spam', array(
+ 'engine' => 'FileLog',
+ 'file' => 'spam',
+ ));
+ $this->assertTrue(CakeLog::enabled('spam'));
+ CakeLog::drop('spam');
+ CakeLog::enable('bogus_stream');
+ }
+
+/**
+ * test disable
+ *
+ * @expectedException CakeLogException
+ */
+ public function testStreamDisable() {
+ CakeLog::config('spam', array(
+ 'engine' => 'FileLog',
+ 'file' => 'spam',
+ ));
+ $this->assertTrue(CakeLog::enabled('spam'));
+ CakeLog::disable('spam');
+ $this->assertFalse(CakeLog::enabled('spam'));
+ CakeLog::drop('spam');
+ CakeLog::enable('bogus_stream');
+ }
+
+/**
+ * test enabled() invalid stream
+ *
+ * @expectedException CakeLogException
+ */
+ public function testStreamEnabledInvalid() {
+ CakeLog::enabled('bogus_stream');
+ }
+
+/**
+ * test disable invalid stream
+ *
+ * @expectedException CakeLogException
+ */
+ public function testStreamDisableInvalid() {
+ CakeLog::disable('bogus_stream');
+ }
+
+ protected function _resetLogConfig() {
+ CakeLog::config('debug', array(
+ 'engine' => 'FileLog',
+ 'types' => array('notice', 'info', 'debug'),
+ 'file' => 'debug',
+ ));
+ CakeLog::config('error', array(
+ 'engine' => 'FileLog',
+ 'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
+ 'file' => 'error',
+ ));
+ }
+
+ protected function _deleteLogs() {
+ if (file_exists(LOGS . 'shops.log')) {
+ unlink(LOGS . 'shops.log');
+ }
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ if (file_exists(LOGS . 'debug.log')) {
+ unlink(LOGS . 'debug.log');
+ }
+ if (file_exists(LOGS . 'bogus.log')) {
+ unlink(LOGS . 'bogus.log');
+ }
+ if (file_exists(LOGS . 'spam.log')) {
+ unlink(LOGS . 'spam.log');
+ }
+ if (file_exists(LOGS . 'eggs.log')) {
+ unlink(LOGS . 'eggs.log');
+ }
+ }
+
+/**
+ * test backward compatible scoped logging
+ */
+ public function testScopedLoggingBC() {
+ $this->_deleteLogs();
+
+ $this->_resetLogConfig();
+ CakeLog::config('shops', array(
+ 'engine' => 'FileLog',
+ 'types' => array('info', 'notice', 'warning'),
+ 'scopes' => array('transactions', 'orders'),
+ 'file' => 'shops',
+ ));
+
+ CakeLog::write('info', 'info message');
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertTrue(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('transactions', 'transaction message');
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertFalse(file_exists(LOGS . 'transactions.log'));
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('error', 'error message');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->assertFalse(file_exists(LOGS . 'shops.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('orders', 'order message');
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->assertFalse(file_exists(LOGS . 'orders.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('warning', 'warning message');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::drop('shops');
+ }
+
+/**
+ * test scoped logging
+ *
+ * @return void
+ */
+ public function testScopedLogging() {
+ if (file_exists(LOGS . 'shops.log')) {
+ unlink(LOGS . 'shops.log');
+ }
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ if (file_exists(LOGS . 'debug.log')) {
+ unlink(LOGS . 'debug.log');
+ }
+
+ $this->_resetLogConfig();
+ CakeLog::config('shops', array(
+ 'engine' => 'FileLog',
+ 'types' => array('info', 'notice', 'warning'),
+ 'scopes' => array('transactions', 'orders'),
+ 'file' => 'shops',
+ ));
+
+ CakeLog::write('info', 'info message', 'transactions');
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertTrue(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('transactions', 'transaction message', 'orders');
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertFalse(file_exists(LOGS . 'transactions.log'));
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('error', 'error message', 'orders');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->assertFalse(file_exists(LOGS . 'shops.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('orders', 'order message', 'transactions');
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->assertFalse(file_exists(LOGS . 'orders.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::write('warning', 'warning message', 'orders');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::drop('shops');
+ }
+
+/**
+ * test bogus type and scope
+ *
+ */
+ public function testBogusTypeAndScope() {
+ $this->_resetLogConfig();
+ $this->_deleteLogs();
+
+ CakeLog::write('bogus', 'bogus message');
+ $this->assertTrue(file_exists(LOGS . 'bogus.log'));
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+
+ CakeLog::write('bogus', 'bogus message', 'bogus');
+ $this->assertTrue(file_exists(LOGS . 'bogus.log'));
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+
+ CakeLog::write('error', 'bogus message', 'bogus');
+ $this->assertFalse(file_exists(LOGS . 'bogus.log'));
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+ }
+
+/**
+ * test scoped logging with convenience methods
+ */
+ public function testConvenienceScopedLogging() {
+ if (file_exists(LOGS . 'shops.log')) {
+ unlink(LOGS . 'shops.log');
+ }
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ if (file_exists(LOGS . 'debug.log')) {
+ unlink(LOGS . 'debug.log');
+ }
+
+ $this->_resetLogConfig();
+ CakeLog::config('shops', array(
+ 'engine' => 'FileLog',
+ 'types' => array('info', 'notice', 'warning'),
+ 'scopes' => array('transactions', 'orders'),
+ 'file' => 'shops',
+ ));
+
+ CakeLog::info('info message', 'transactions');
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertTrue(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::error('error message', 'orders');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->assertFalse(file_exists(LOGS . 'shops.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::warning('warning message', 'orders');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $this->assertTrue(file_exists(LOGS . 'shops.log'));
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+
+ $this->_deleteLogs();
+
+ CakeLog::drop('shops');
+ }
+
+/**
+ * test convenience methods
+ */
+ public function testConvenienceMethods() {
+ $this->_deleteLogs();
+
+ CakeLog::config('debug', array(
+ 'engine' => 'FileLog',
+ 'types' => array('notice', 'info', 'debug'),
+ 'file' => 'debug',
+ ));
+ CakeLog::config('error', array(
+ 'engine' => 'FileLog',
+ 'types' => array('emergency', 'alert', 'critical', 'error', 'warning'),
+ 'file' => 'error',
+ ));
+
+ $testMessage = 'emergency message';
+ CakeLog::emergency($testMessage);
+ $contents = file_get_contents(LOGS . 'error.log');
+ $this->assertContains('Emergency: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+
+ $testMessage = 'alert message';
+ CakeLog::alert($testMessage);
+ $contents = file_get_contents(LOGS . 'error.log');
+ $this->assertContains('Alert: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+
+ $testMessage = 'critical message';
+ CakeLog::critical($testMessage);
+ $contents = file_get_contents(LOGS . 'error.log');
+ $this->assertContains('Critical: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+
+ $testMessage = 'error message';
+ CakeLog::error($testMessage);
+ $contents = file_get_contents(LOGS . 'error.log');
+ $this->assertContains('Error: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+
+ $testMessage = 'warning message';
+ CakeLog::warning($testMessage);
+ $contents = file_get_contents(LOGS . 'error.log');
+ $this->assertContains('Warning: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'debug.log'));
+ $this->_deleteLogs();
+
+ $testMessage = 'notice message';
+ CakeLog::notice($testMessage);
+ $contents = file_get_contents(LOGS . 'debug.log');
+ $this->assertContains('Notice: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->_deleteLogs();
+
+ $testMessage = 'info message';
+ CakeLog::info($testMessage);
+ $contents = file_get_contents(LOGS . 'debug.log');
+ $this->assertContains('Info: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->_deleteLogs();
+
+ $testMessage = 'debug message';
+ CakeLog::debug($testMessage);
+ $contents = file_get_contents(LOGS . 'debug.log');
+ $this->assertContains('Debug: ' . $testMessage, $contents);
+ $this->assertFalse(file_exists(LOGS . 'error.log'));
+ $this->_deleteLogs();
+ }
+
+/**
+ * test levels customization
+ */
+ public function testLevelCustomization() {
+ $this->skipIf(DIRECTORY_SEPARATOR === '\\', 'Log level tests not supported on Windows.');
+
+ $levels = CakeLog::defaultLevels();
+ $this->assertNotEmpty($levels);
+ $result = array_keys($levels);
+ $this->assertEquals(array(0, 1, 2, 3, 4, 5, 6, 7), $result);
+
+ $levels = CakeLog::levels(array('foo', 'bar'));
+ CakeLog::defaultLevels();
+ $this->assertEquals('foo', $levels[8]);
+ $this->assertEquals('bar', $levels[9]);
+
+ $levels = CakeLog::levels(array(11 => 'spam', 'bar' => 'eggs'));
+ CakeLog::defaultLevels();
+ $this->assertEquals('spam', $levels[8]);
+ $this->assertEquals('eggs', $levels[9]);
+
+ $levels = CakeLog::levels(array(11 => 'spam', 'bar' => 'eggs'), false);
+ CakeLog::defaultLevels();
+ $this->assertEquals(array('spam', 'eggs'), $levels);
+
+ $levels = CakeLog::levels(array('ham', 9 => 'spam', '12' => 'fam'), false);
+ CakeLog::defaultLevels();
+ $this->assertEquals(array('ham', 'spam', 'fam'), $levels);
+ }
+
+/**
+ * Test writing log files with custom levels
+ */
+ public function testCustomLevelWrites() {
+ $this->_deleteLogs();
+ $this->_resetLogConfig();
+
+ $levels = CakeLog::levels(array('spam', 'eggs'));
+
+ $testMessage = 'error message';
+ CakeLog::write('error', $testMessage);
+ CakeLog::defaultLevels();
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+ $contents = file_get_contents(LOGS . 'error.log');
+ $this->assertContains('Error: ' . $testMessage, $contents);
+
+ CakeLog::config('spam', array(
+ 'engine' => 'FileLog',
+ 'file' => 'spam.log',
+ 'types' => 'spam',
+ ));
+ CakeLog::config('eggs', array(
+ 'engine' => 'FileLog',
+ 'file' => 'eggs.log',
+ 'types' => array('spam', 'eggs'),
+ ));
+
+ $testMessage = 'spam message';
+ CakeLog::write('spam', $testMessage);
+ CakeLog::defaultLevels();
+ $this->assertTrue(file_exists(LOGS . 'spam.log'));
+ $this->assertTrue(file_exists(LOGS . 'eggs.log'));
+ $contents = file_get_contents(LOGS . 'spam.log');
+ $this->assertContains('Spam: ' . $testMessage, $contents);
+
+ $testMessage = 'egg message';
+ CakeLog::write('eggs', $testMessage);
+ CakeLog::defaultLevels();
+ $contents = file_get_contents(LOGS . 'spam.log');
+ $this->assertNotContains('Eggs: ' . $testMessage, $contents);
+ $contents = file_get_contents(LOGS . 'eggs.log');
+ $this->assertContains('Eggs: ' . $testMessage, $contents);
+
+ CakeLog::drop('spam');
+ CakeLog::drop('eggs');
+
+ $this->_deleteLogs();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php
new file mode 100644
index 0000000..e786827
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/ConsoleLogTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * ConsoleLogTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Log.Engine
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ConsoleLog', 'Log/Engine');
+
+class TestConsoleLog extends ConsoleLog {
+
+}
+
+class TestCakeLog extends CakeLog {
+
+ public static function replace($key, &$engine) {
+ self::$_Collection->{$key} = $engine;
+ }
+
+}
+
+/**
+ * ConsoleLogTest class
+ *
+ * @package Cake.Test.Case.Log.Engine
+ */
+class ConsoleLogTest extends CakeTestCase {
+
+ public function setUp() {
+ parent::setUp();
+ CakeLog::config('debug', array(
+ 'engine' => 'FileLog',
+ 'types' => array('notice', 'info', 'debug'),
+ 'file' => 'debug',
+ ));
+ CakeLog::config('error', array(
+ 'engine' => 'FileLog',
+ 'types' => array('error', 'warning'),
+ 'file' => 'error',
+ ));
+ }
+
+ public function tearDown() {
+ parent::tearDown();
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ if (file_exists(LOGS . 'debug.log')) {
+ unlink(LOGS . 'debug.log');
+ }
+ }
+
+/**
+ * Test writing to ConsoleOutput
+ */
+ public function testConsoleOutputWrites() {
+ TestCakeLog::config('test_console_log', array(
+ 'engine' => 'TestConsoleLog',
+ ));
+
+ $mock = $this->getMock('TestConsoleLog', array('write'), array(
+ array('types' => 'error'),
+ ));
+ TestCakeLog::replace('test_console_log', $mock);
+
+ $message = 'Test error message';
+ $mock->expects($this->once())
+ ->method('write');
+ TestCakeLog::write(LOG_ERR, $message);
+ }
+
+/**
+ * Test logging to both ConsoleLog and FileLog
+ */
+ public function testCombinedLogWriting() {
+ TestCakeLog::config('test_console_log', array(
+ 'engine' => 'TestConsoleLog',
+ ));
+ $mock = $this->getMock('TestConsoleLog', array('write'), array(
+ array('types' => 'error'),
+ ));
+ TestCakeLog::replace('test_console_log', $mock);
+
+ // log to both file and console
+ $message = 'Test error message';
+ $mock->expects($this->once())
+ ->method('write');
+ TestCakeLog::write(LOG_ERR, $message);
+ $this->assertTrue(file_exists(LOGS . 'error.log'), 'error.log missing');
+ $logOutput = file_get_contents(LOGS . 'error.log');
+ $this->assertContains($message, $logOutput);
+
+ // TestConsoleLog is only interested in `error` type
+ $message = 'Test info message';
+ $mock->expects($this->never())
+ ->method('write');
+ TestCakeLog::write(LOG_INFO, $message);
+
+ // checks that output is correctly written in the correct logfile
+ $this->assertTrue(file_exists(LOGS . 'error.log'), 'error.log missing');
+ $this->assertTrue(file_exists(LOGS . 'debug.log'), 'debug.log missing');
+ $logOutput = file_get_contents(LOGS . 'error.log');
+ $this->assertNotContains($message, $logOutput);
+ $logOutput = file_get_contents(LOGS . 'debug.log');
+ $this->assertContains($message, $logOutput);
+ }
+
+/**
+ * test default value of stream 'outputAs'
+ */
+ public function testDefaultOutputAs() {
+ TestCakeLog::config('test_console_log', array(
+ 'engine' => 'TestConsoleLog',
+ ));
+ if (DS == '\\' && !(bool)env('ANSICON')) {
+ $expected = ConsoleOutput::PLAIN;
+ } else {
+ $expected = ConsoleOutput::COLOR;
+ }
+ $stream = TestCakeLog::stream('test_console_log');
+ $config = $stream->config();
+ $this->assertEquals($expected, $config['outputAs']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/FileLogTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/FileLogTest.php
new file mode 100644
index 0000000..b4c13c8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Log/Engine/FileLogTest.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * FileLogTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Log.Engine
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('FileLog', 'Log/Engine');
+
+/**
+ * CakeLogTest class
+ *
+ * @package Cake.Test.Case.Log.Engine
+ */
+class FileLogTest extends CakeTestCase {
+
+/**
+ * testLogFileWriting method
+ *
+ * @return void
+ */
+ public function testLogFileWriting() {
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+ $log = new FileLog();
+ $log->write('warning', 'Test warning');
+ $this->assertTrue(file_exists(LOGS . 'error.log'));
+
+ $result = file_get_contents(LOGS . 'error.log');
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Warning: Test warning/', $result);
+ unlink(LOGS . 'error.log');
+
+ if (file_exists(LOGS . 'debug.log')) {
+ unlink(LOGS . 'debug.log');
+ }
+ $log->write('debug', 'Test warning');
+ $this->assertTrue(file_exists(LOGS . 'debug.log'));
+
+ $result = file_get_contents(LOGS . 'debug.log');
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Debug: Test warning/', $result);
+ unlink(LOGS . 'debug.log');
+
+ if (file_exists(LOGS . 'random.log')) {
+ unlink(LOGS . 'random.log');
+ }
+ $log->write('random', 'Test warning');
+ $this->assertTrue(file_exists(LOGS . 'random.log'));
+
+ $result = file_get_contents(LOGS . 'random.log');
+ $this->assertRegExp('/^2[0-9]{3}-[0-9]+-[0-9]+ [0-9]+:[0-9]+:[0-9]+ Random: Test warning/', $result);
+ unlink(LOGS . 'random.log');
+ }
+
+/**
+ * test using the path setting to write logs in other places.
+ *
+ * @return void
+ */
+ public function testPathSetting() {
+ $path = TMP . 'tests' . DS;
+ if (file_exists(LOGS . 'error.log')) {
+ unlink(LOGS . 'error.log');
+ }
+
+ $log = new FileLog(compact('path'));
+ $log->write('warning', 'Test warning');
+ $this->assertTrue(file_exists($path . 'error.log'));
+ unlink($path . 'error.log');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/AclNodeTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/AclNodeTest.php
new file mode 100644
index 0000000..cc297ba
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/AclNodeTest.php
@@ -0,0 +1,385 @@
+<?php
+/**
+ * AclNodeTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('DbAcl', 'Controller/Component/Acl');
+App::uses('AclNode', 'Model');
+
+/**
+ * DB ACL wrapper test class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DbAclNodeTestBase extends AclNode {
+
+/**
+ * useDbConfig property
+ *
+ * @var string 'test'
+ */
+ public $useDbConfig = 'test';
+
+/**
+ * cacheSources property
+ *
+ * @var bool false
+ */
+ public $cacheSources = false;
+}
+
+/**
+ * Aro Test Wrapper
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DbAroTest extends DbAclNodeTestBase {
+
+/**
+ * name property
+ *
+ * @var string 'DbAroTest'
+ */
+ public $name = 'DbAroTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'aros'
+ */
+ public $useTable = 'aros';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('DbAcoTest' => array('with' => 'DbPermissionTest'));
+}
+
+/**
+ * Aco Test Wrapper
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DbAcoTest extends DbAclNodeTestBase {
+
+/**
+ * name property
+ *
+ * @var string 'DbAcoTest'
+ */
+ public $name = 'DbAcoTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'acos'
+ */
+ public $useTable = 'acos';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('DbAroTest' => array('with' => 'DbPermissionTest'));
+}
+
+/**
+ * Permission Test Wrapper
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DbPermissionTest extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'DbPermissionTest'
+ */
+ public $name = 'DbPermissionTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'aros_acos'
+ */
+ public $useTable = 'aros_acos';
+
+/**
+ * cacheQueries property
+ *
+ * @var bool false
+ */
+ public $cacheQueries = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('DbAroTest' => array('foreignKey' => 'aro_id'), 'DbAcoTest' => array('foreignKey' => 'aco_id'));
+}
+
+/**
+ * DboActionTest class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DbAcoActionTest extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'DbAcoActionTest'
+ */
+ public $name = 'DbAcoActionTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'aco_actions'
+ */
+ public $useTable = 'aco_actions';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('DbAcoTest' => array('foreignKey' => 'aco_id'));
+}
+
+/**
+ * DbAroUserTest class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DbAroUserTest extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'AuthUser'
+ */
+ public $name = 'AuthUser';
+
+/**
+ * useTable property
+ *
+ * @var string 'auth_users'
+ */
+ public $useTable = 'auth_users';
+
+/**
+ * bindNode method
+ *
+ * @param string|array|Model $ref
+ * @return void
+ */
+ public function bindNode($ref = null) {
+ if (Configure::read('DbAclbindMode') == 'string') {
+ return 'ROOT/admins/Gandalf';
+ } elseif (Configure::read('DbAclbindMode') == 'array') {
+ return array('DbAroTest' => array('DbAroTest.model' => 'AuthUser', 'DbAroTest.foreign_key' => 2));
+ }
+ }
+
+}
+
+/**
+ * TestDbAcl class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestDbAcl extends DbAcl {
+
+/**
+ * construct method
+ *
+ * @return void
+ */
+ public function __construct() {
+ $this->Aro = new DbAroTest();
+ $this->Aro->Permission = new DbPermissionTest();
+ $this->Aco = new DbAcoTest();
+ $this->Aro->Permission = new DbPermissionTest();
+ }
+
+}
+
+/**
+ * AclNodeTest class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class AclNodeTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.aro', 'core.aco', 'core.aros_aco', 'core.aco_action', 'core.auth_user');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Acl.classname', 'TestDbAcl');
+ Configure::write('Acl.database', 'test');
+ }
+
+/**
+ * testNode method
+ *
+ * @return void
+ */
+ public function testNode() {
+ $Aco = new DbAcoTest();
+ $result = Hash::extract($Aco->node('Controller1'), '{n}.DbAcoTest.id');
+ $expected = array(2, 1);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($Aco->node('Controller1/action1'), '{n}.DbAcoTest.id');
+ $expected = array(3, 2, 1);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($Aco->node('Controller2/action1'), '{n}.DbAcoTest.id');
+ $expected = array(7, 6, 1);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($Aco->node('Controller1/action2'), '{n}.DbAcoTest.id');
+ $expected = array(5, 2, 1);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($Aco->node('Controller1/action1/record1'), '{n}.DbAcoTest.id');
+ $expected = array(4, 3, 2, 1);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($Aco->node('Controller2/action1/record1'), '{n}.DbAcoTest.id');
+ $expected = array(8, 7, 6, 1);
+ $this->assertEquals($expected, $result);
+
+ $this->assertFalse($Aco->node('Controller2/action3'));
+
+ $this->assertFalse($Aco->node('Controller2/action3/record5'));
+
+ $result = $Aco->node('');
+ $this->assertEquals(null, $result);
+ }
+
+/**
+ * test that node() doesn't dig deeper than it should.
+ *
+ * @return void
+ */
+ public function testNodeWithDuplicatePathSegments() {
+ $Aco = new DbAcoTest();
+ $nodes = $Aco->node('ROOT/Users');
+ $this->assertEquals(1, $nodes[0]['DbAcoTest']['parent_id'], 'Parent id does not point at ROOT. %s');
+ }
+
+/**
+ * testNodeArrayFind method
+ *
+ * @return void
+ */
+ public function testNodeArrayFind() {
+ $Aro = new DbAroTest();
+ Configure::write('DbAclbindMode', 'string');
+ $result = Hash::extract($Aro->node(array('DbAroUserTest' => array('id' => '1', 'foreign_key' => '1'))), '{n}.DbAroTest.id');
+ $expected = array(3, 2, 1);
+ $this->assertEquals($expected, $result);
+
+ Configure::write('DbAclbindMode', 'array');
+ $result = Hash::extract($Aro->node(array('DbAroUserTest' => array('id' => 4, 'foreign_key' => 2))), '{n}.DbAroTest.id');
+ $expected = array(4);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testNodeObjectFind method
+ *
+ * @return void
+ */
+ public function testNodeObjectFind() {
+ $Aro = new DbAroTest();
+ $Model = new DbAroUserTest();
+ $Model->id = 1;
+ $result = Hash::extract($Aro->node($Model), '{n}.DbAroTest.id');
+ $expected = array(3, 2, 1);
+ $this->assertEquals($expected, $result);
+
+ $Model->id = 2;
+ $result = Hash::extract($Aro->node($Model), '{n}.DbAroTest.id');
+ $expected = array(4, 2, 1);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testNodeAliasParenting method
+ *
+ * @return void
+ */
+ public function testNodeAliasParenting() {
+ $Aco = ClassRegistry::init('DbAcoTest');
+ $db = $Aco->getDataSource();
+ $db->truncate($Aco);
+
+ $Aco->create(array('model' => null, 'foreign_key' => null, 'parent_id' => null, 'alias' => 'Application'));
+ $Aco->save();
+
+ $Aco->create(array('model' => null, 'foreign_key' => null, 'parent_id' => $Aco->id, 'alias' => 'Pages'));
+ $Aco->save();
+
+ $result = $Aco->find('all');
+ $expected = array(
+ array('DbAcoTest' => array('id' => '1', 'parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'Application', 'lft' => '1', 'rght' => '4'), 'DbAroTest' => array()),
+ array('DbAcoTest' => array('id' => '2', 'parent_id' => '1', 'model' => null, 'foreign_key' => null, 'alias' => 'Pages', 'lft' => '2', 'rght' => '3'), 'DbAroTest' => array())
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testNodeActionAuthorize method
+ *
+ * @return void
+ */
+ public function testNodeActionAuthorize() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+
+ $Aro = new DbAroTest();
+ $Aro->create();
+ $Aro->save(array('model' => 'TestPluginAuthUser', 'foreign_key' => 1));
+ $result = $Aro->id;
+ $expected = 5;
+ $this->assertEquals($expected, $result);
+
+ $node = $Aro->node(array('TestPlugin.TestPluginAuthUser' => array('id' => 1, 'user' => 'mariano')));
+ $result = Hash::get($node, '0.DbAroTest.id');
+ $expected = $Aro->id;
+ $this->assertEquals($expected, $result);
+ CakePlugin::unload('TestPlugin');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/AclBehaviorTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/AclBehaviorTest.php
new file mode 100644
index 0000000..f37bcaa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/AclBehaviorTest.php
@@ -0,0 +1,491 @@
+<?php
+/**
+ * AclBehaviorTest file
+ *
+ * Test the Acl Behavior
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP v 1.2.0.4487
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AclBehavior', 'Model/Behavior');
+App::uses('Aco', 'Model');
+App::uses('Aro', 'Model');
+App::uses('AclNode', 'Model');
+App::uses('DbAcl', 'Model');
+
+
+/**
+ * Test Person class - self joined model
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class AclPerson extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string
+ */
+ public $name = 'AclPerson';
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = 'people';
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Acl' => 'both');
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Mother' => array(
+ 'className' => 'AclPerson',
+ 'foreignKey' => 'mother_id',
+ )
+ );
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Child' => array(
+ 'className' => 'AclPerson',
+ 'foreignKey' => 'mother_id'
+ )
+ );
+
+/**
+ * parentNode method
+ *
+ * @return void
+ */
+ public function parentNode() {
+ if (!$this->id && empty($this->data)) {
+ return null;
+ }
+ if (isset($this->data['AclPerson']['mother_id'])) {
+ $motherId = $this->data['AclPerson']['mother_id'];
+ } else {
+ $motherId = $this->field('mother_id');
+ }
+ if (!$motherId) {
+ return null;
+ } else {
+ return array('AclPerson' => array('id' => $motherId));
+ }
+ }
+
+}
+
+/**
+ * AclUser class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class AclUser extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string
+ */
+ public $name = 'User';
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = 'users';
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Acl' => array('type' => 'requester'));
+
+/**
+ * parentNode
+ *
+ */
+ public function parentNode() {
+ return null;
+ }
+
+}
+
+/**
+ * AclPost class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class AclPost extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string
+ */
+ public $name = 'Post';
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = 'posts';
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Acl' => array('type' => 'Controlled'));
+
+/**
+ * parentNode
+ *
+ */
+ public function parentNode() {
+ return null;
+ }
+
+}
+
+/**
+ * AclBehaviorTest class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class AclBehaviorTest extends CakeTestCase {
+
+/**
+ * Aco property
+ *
+ * @var Aco
+ */
+ public $Aco;
+
+/**
+ * Aro property
+ *
+ * @var Aro
+ */
+ public $Aro;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.person', 'core.user', 'core.post', 'core.aco', 'core.aro', 'core.aros_aco');
+
+/**
+ * Set up the test
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Acl.database', 'test');
+
+ $this->Aco = new Aco();
+ $this->Aro = new Aro();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Aro, $this->Aco);
+ }
+
+/**
+ * Test Setup of AclBehavior
+ *
+ * @return void
+ */
+ public function testSetup() {
+ $User = new AclUser();
+ $this->assertTrue(isset($User->Behaviors->Acl->settings['User']));
+ $this->assertEquals('requester', $User->Behaviors->Acl->settings['User']['type']);
+ $this->assertTrue(is_object($User->Aro));
+
+ $Post = new AclPost();
+ $this->assertTrue(isset($Post->Behaviors->Acl->settings['Post']));
+ $this->assertEquals('controlled', $Post->Behaviors->Acl->settings['Post']['type']);
+ $this->assertTrue(is_object($Post->Aco));
+ }
+
+/**
+ * Test Setup of AclBehavior as both requester and controlled
+ *
+ * @return void
+ */
+ public function testSetupMulti() {
+ $User = new AclPerson();
+ $this->assertTrue(isset($User->Behaviors->Acl->settings['AclPerson']));
+ $this->assertEquals('both', $User->Behaviors->Acl->settings['AclPerson']['type']);
+ $this->assertTrue(is_object($User->Aro));
+ $this->assertTrue(is_object($User->Aco));
+ }
+
+/**
+ * test After Save
+ *
+ * @return void
+ */
+ public function testAfterSave() {
+ $Post = new AclPost();
+ $data = array(
+ 'Post' => array(
+ 'author_id' => 1,
+ 'title' => 'Acl Post',
+ 'body' => 'post body',
+ 'published' => 1
+ ),
+ );
+ $Post->save($data);
+ $result = $this->Aco->find('first', array(
+ 'conditions' => array('Aco.model' => 'Post', 'Aco.foreign_key' => $Post->id)
+ ));
+ $this->assertTrue(is_array($result));
+ $this->assertEquals('Post', $result['Aco']['model']);
+ $this->assertEquals($Post->id, $result['Aco']['foreign_key']);
+
+ $aroData = array(
+ 'Aro' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 2,
+ 'parent_id' => null
+ )
+ );
+ $this->Aro->save($aroData);
+
+ $acoData = array(
+ 'Aco' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 2,
+ 'parent_id' => null
+ )
+ );
+ $this->Aco->save($acoData);
+
+ $Person = new AclPerson();
+ $data = array(
+ 'AclPerson' => array(
+ 'name' => 'Trent',
+ 'mother_id' => 2,
+ 'father_id' => 3,
+ ),
+ );
+ $Person->save($data);
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => $Person->id)
+ ));
+ $this->assertTrue(is_array($result));
+ $this->assertEquals(5, $result['Aro']['parent_id']);
+
+ $node = $Person->node(array('model' => 'AclPerson', 'foreign_key' => 8), 'Aro');
+ $this->assertEquals(2, count($node));
+ $this->assertEquals(5, $node[0]['Aro']['parent_id']);
+ $this->assertEquals(null, $node[1]['Aro']['parent_id']);
+
+ $aroData = array(
+ 'Aro' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 1,
+ 'parent_id' => null
+ )
+ );
+ $this->Aro->create();
+ $this->Aro->save($aroData);
+ $acoData = array(
+ 'Aco' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 1,
+ 'parent_id' => null
+ ));
+ $this->Aco->create();
+ $this->Aco->save($acoData);
+ $Person->read(null, 8);
+ $Person->set('mother_id', 1);
+ $Person->save();
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => $Person->id)
+ ));
+ $this->assertTrue(is_array($result));
+ $this->assertEquals(7, $result['Aro']['parent_id']);
+
+ $node = $Person->node(array('model' => 'AclPerson', 'foreign_key' => 8), 'Aro');
+ $this->assertEquals(2, count($node));
+ $this->assertEquals(7, $node[0]['Aro']['parent_id']);
+ $this->assertEquals(null, $node[1]['Aro']['parent_id']);
+ }
+
+/**
+ * test that an afterSave on an update does not cause parent_id to become null.
+ *
+ * @return void
+ */
+ public function testAfterSaveUpdateParentIdNotNull() {
+ $aroData = array(
+ 'Aro' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 2,
+ 'parent_id' => null
+ )
+ );
+ $this->Aro->save($aroData);
+
+ $acoData = array(
+ 'Aco' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 2,
+ 'parent_id' => null
+ )
+ );
+ $this->Aco->save($acoData);
+
+ $Person = new AclPerson();
+ $data = array(
+ 'AclPerson' => array(
+ 'name' => 'Trent',
+ 'mother_id' => 2,
+ 'father_id' => 3,
+ ),
+ );
+ $Person->save($data);
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => $Person->id)
+ ));
+ $this->assertTrue(is_array($result));
+ $this->assertEquals(5, $result['Aro']['parent_id']);
+
+ $Person->save(array('id' => $Person->id, 'name' => 'Bruce'));
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => $Person->id)
+ ));
+ $this->assertEquals(5, $result['Aro']['parent_id']);
+ }
+
+/**
+ * Test After Delete
+ *
+ * @return void
+ */
+ public function testAfterDelete() {
+ $aroData = array(
+ 'Aro' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 2,
+ 'parent_id' => null
+ )
+ );
+ $this->Aro->save($aroData);
+
+ $acoData = array(
+ 'Aco' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 2,
+ 'parent_id' => null
+ )
+ );
+ $this->Aco->save($acoData);
+ $Person = new AclPerson();
+
+ $data = array(
+ 'AclPerson' => array(
+ 'name' => 'Trent',
+ 'mother_id' => 2,
+ 'father_id' => 3,
+ ),
+ );
+ $Person->save($data);
+ $id = $Person->id;
+ $node = $Person->node(null, 'Aro');
+ $this->assertEquals(2, count($node));
+ $this->assertEquals(5, $node[0]['Aro']['parent_id']);
+ $this->assertEquals(null, $node[1]['Aro']['parent_id']);
+
+ $Person->delete($id);
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => $id)
+ ));
+ $this->assertTrue(empty($result));
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => 2)
+ ));
+ $this->assertFalse(empty($result));
+
+ $data = array(
+ 'AclPerson' => array(
+ 'name' => 'Trent',
+ 'mother_id' => 2,
+ 'father_id' => 3,
+ ),
+ );
+ $Person->save($data);
+ $id = $Person->id;
+ $Person->delete(2);
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => $id)
+ ));
+ $this->assertTrue(empty($result));
+
+ $result = $this->Aro->find('first', array(
+ 'conditions' => array('Aro.model' => 'AclPerson', 'Aro.foreign_key' => 2)
+ ));
+ $this->assertTrue(empty($result));
+ }
+
+/**
+ * Test Node()
+ *
+ * @return void
+ */
+ public function testNode() {
+ $Person = new AclPerson();
+ $aroData = array(
+ 'Aro' => array(
+ 'model' => 'AclPerson',
+ 'foreign_key' => 2,
+ 'parent_id' => null
+ )
+ );
+ $this->Aro->save($aroData);
+
+ $Person->id = 2;
+ $result = $Person->node(null, 'Aro');
+ $this->assertTrue(is_array($result));
+ $this->assertEquals(1, count($result));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php
new file mode 100644
index 0000000..8345c87
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php
@@ -0,0 +1,3660 @@
+<?php
+/**
+ * ContainableBehaviorTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once dirname(dirname(__FILE__)) . DS . 'models.php';
+
+/**
+ * ContainableTest class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class ContainableBehaviorTest extends CakeTestCase {
+
+/**
+ * Fixtures associated with this test case
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.article', 'core.article_featured', 'core.article_featureds_tags',
+ 'core.articles_tag', 'core.attachment', 'core.category',
+ 'core.comment', 'core.featured', 'core.tag', 'core.user',
+ 'core.join_a', 'core.join_b', 'core.join_c', 'core.join_a_c', 'core.join_a_b'
+ );
+
+/**
+ * Method executed before each test
+ *
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->User = ClassRegistry::init('User');
+ $this->Article = ClassRegistry::init('Article');
+ $this->Tag = ClassRegistry::init('Tag');
+
+ $this->User->bindModel(array(
+ 'hasMany' => array('Article', 'ArticleFeatured', 'Comment')
+ ), false);
+ $this->User->ArticleFeatured->unbindModel(array('belongsTo' => array('Category')), false);
+ $this->User->ArticleFeatured->hasMany['Comment']['foreignKey'] = 'article_id';
+
+ $this->Tag->bindModel(array(
+ 'hasAndBelongsToMany' => array('Article')
+ ), false);
+
+ $this->User->Behaviors->attach('Containable');
+ $this->Article->Behaviors->attach('Containable');
+ $this->Tag->Behaviors->attach('Containable');
+ }
+
+/**
+ * Method executed after each test
+ *
+ */
+ public function tearDown() {
+ unset($this->Article);
+ unset($this->User);
+ unset($this->Tag);
+ parent::tearDown();
+ }
+
+/**
+ * testContainments method
+ *
+ * @return void
+ */
+ public function testContainments() {
+ $r = $this->_containments($this->Article, array('Comment' => array('conditions' => array('Comment.user_id' => 2))));
+ $this->assertTrue(Set::matches('/Article/keep/Comment/conditions[Comment.user_id=2]', $r));
+
+ $r = $this->_containments($this->User, array(
+ 'ArticleFeatured' => array(
+ 'Featured' => array(
+ 'id',
+ 'Category' => 'name'
+ )
+ )));
+ $this->assertEquals(array('id'), Hash::extract($r, 'ArticleFeatured.keep.Featured.fields'));
+
+ $r = $this->_containments($this->Article, array(
+ 'Comment' => array(
+ 'User',
+ 'conditions' => array('Comment' => array('user_id' => 2)),
+ ),
+ ));
+ $this->assertTrue(Set::matches('/User', $r));
+ $this->assertTrue(Set::matches('/Comment', $r));
+ $this->assertTrue(Set::matches('/Article/keep/Comment/conditions/Comment[user_id=2]', $r));
+
+ $r = $this->_containments($this->Article, array('Comment(comment, published)' => 'Attachment(attachment)', 'User(user)'));
+ $this->assertTrue(Set::matches('/Comment', $r));
+ $this->assertTrue(Set::matches('/User', $r));
+ $this->assertTrue(Set::matches('/Article/keep/Comment', $r));
+ $this->assertTrue(Set::matches('/Article/keep/User', $r));
+ $this->assertEquals(array('comment', 'published'), Hash::extract($r, 'Article.keep.Comment.fields'));
+ $this->assertEquals(array('user'), Hash::extract($r, 'Article.keep.User.fields'));
+ $this->assertTrue(Set::matches('/Comment/keep/Attachment', $r));
+ $this->assertEquals(array('attachment'), Hash::extract($r, 'Comment.keep.Attachment.fields'));
+
+ $r = $this->_containments($this->Article, array('Comment' => array('limit' => 1)));
+ $this->assertEquals(array('Comment', 'Article'), array_keys($r));
+ $result = Hash::extract($r, 'Comment[keep]');
+ $this->assertEquals(array('keep' => array()), array_shift($result));
+ $this->assertTrue(Set::matches('/Article/keep/Comment', $r));
+ $result = Hash::extract($r, 'Article.keep');
+ $this->assertEquals(array('limit' => 1), array_shift($result));
+
+ $r = $this->_containments($this->Article, array('Comment.User'));
+ $this->assertEquals(array('User', 'Comment', 'Article'), array_keys($r));
+
+ $result = Hash::extract($r, 'User[keep]');
+ $this->assertEquals(array('keep' => array()), array_shift($result));
+
+ $result = Hash::extract($r, 'Comment[keep]');
+ $this->assertEquals(array('keep' => array('User' => array())), array_shift($result));
+
+ $result = Hash::extract($r, 'Article[keep]');
+ $this->assertEquals(array('keep' => array('Comment' => array())), array_shift($result));
+
+ $r = $this->_containments($this->Tag, array('Article' => array('User' => array('Comment' => array(
+ 'Attachment' => array('conditions' => array('Attachment.id >' => 1))
+ )))));
+ $this->assertTrue(Set::matches('/Attachment', $r));
+ $this->assertTrue(Set::matches('/Comment/keep/Attachment/conditions', $r));
+ $this->assertEquals(array('Attachment.id >' => 1), $r['Comment']['keep']['Attachment']['conditions']);
+ $this->assertTrue(Set::matches('/User/keep/Comment', $r));
+ $this->assertTrue(Set::matches('/Article/keep/User', $r));
+ $this->assertTrue(Set::matches('/Tag/keep/Article', $r));
+ }
+
+/**
+ * testInvalidContainments method
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testInvalidContainments() {
+ $r = $this->_containments($this->Article, array('Comment', 'InvalidBinding'));
+ }
+
+/**
+ * testInvalidContainments method with suppressing error notices
+ *
+ * @return void
+ */
+ public function testInvalidContainmentsNoNotices() {
+ $this->Article->Behaviors->attach('Containable', array('notices' => false));
+ $r = $this->_containments($this->Article, array('Comment', 'InvalidBinding'));
+ }
+
+/**
+ * testBeforeFind method
+ *
+ * @return void
+ */
+ public function testBeforeFind() {
+ $r = $this->Article->find('all', array('contain' => array('Comment')));
+ $this->assertFalse(Set::matches('/User', $r));
+ $this->assertTrue(Set::matches('/Comment', $r));
+ $this->assertFalse(Set::matches('/Comment/User', $r));
+
+ $r = $this->Article->find('all', array('contain' => 'Comment.User'));
+ $this->assertTrue(Set::matches('/Comment/User', $r));
+ $this->assertFalse(Set::matches('/Comment/Article', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('Comment' => array('User', 'Article'))));
+ $this->assertTrue(Set::matches('/Comment/User', $r));
+ $this->assertTrue(Set::matches('/Comment/Article', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('Comment' => array('conditions' => array('Comment.user_id' => 2)))));
+ $this->assertFalse(Set::matches('/Comment[user_id!=2]', $r));
+ $this->assertTrue(Set::matches('/Comment[user_id=2]', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('Comment.user_id = 2')));
+ $this->assertFalse(Set::matches('/Comment[user_id!=2]', $r));
+
+ $r = $this->Article->find('all', array('contain' => 'Comment.id DESC'));
+ $ids = $descIds = Hash::extract($r, 'Comment[1].id');
+ rsort($descIds);
+ $this->assertEquals($ids, $descIds);
+
+ $r = $this->Article->find('all', array('contain' => 'Comment'));
+ $this->assertTrue(Set::matches('/Comment[user_id!=2]', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('Comment' => array('fields' => 'comment'))));
+ $this->assertFalse(Set::matches('/Comment/created', $r));
+ $this->assertTrue(Set::matches('/Comment/comment', $r));
+ $this->assertFalse(Set::matches('/Comment/updated', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('Comment' => array('fields' => array('comment', 'updated')))));
+ $this->assertFalse(Set::matches('/Comment/created', $r));
+ $this->assertTrue(Set::matches('/Comment/comment', $r));
+ $this->assertTrue(Set::matches('/Comment/updated', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('Comment' => array('comment', 'updated'))));
+ $this->assertFalse(Set::matches('/Comment/created', $r));
+ $this->assertTrue(Set::matches('/Comment/comment', $r));
+ $this->assertTrue(Set::matches('/Comment/updated', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('Comment(comment,updated)')));
+ $this->assertFalse(Set::matches('/Comment/created', $r));
+ $this->assertTrue(Set::matches('/Comment/comment', $r));
+ $this->assertTrue(Set::matches('/Comment/updated', $r));
+
+ $r = $this->Article->find('all', array('contain' => 'Comment.created'));
+ $this->assertTrue(Set::matches('/Comment/created', $r));
+ $this->assertFalse(Set::matches('/Comment/comment', $r));
+
+ $r = $this->Article->find('all', array('contain' => array('User.Article(title)', 'Comment(comment)')));
+ $this->assertFalse(Set::matches('/Comment/Article', $r));
+ $this->assertFalse(Set::matches('/Comment/User', $r));
+ $this->assertTrue(Set::matches('/Comment/comment', $r));
+ $this->assertFalse(Set::matches('/Comment/created', $r));
+ $this->assertTrue(Set::matches('/User/Article/title', $r));
+ $this->assertFalse(Set::matches('/User/Article/created', $r));
+
+ $r = $this->Article->find('all', array('contain' => array()));
+ $this->assertFalse(Set::matches('/User', $r));
+ $this->assertFalse(Set::matches('/Comment', $r));
+ }
+
+/**
+ * testBeforeFindWithNonExistingBinding method
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testBeforeFindWithNonExistingBinding() {
+ $r = $this->Article->find('all', array('contain' => array('Comment' => 'NonExistingBinding')));
+ }
+
+/**
+ * testContain method
+ *
+ * @return void
+ */
+ public function testContain() {
+ $this->Article->contain('Comment.User');
+ $r = $this->Article->find('all');
+ $this->assertTrue(Set::matches('/Comment/User', $r));
+ $this->assertFalse(Set::matches('/Comment/Article', $r));
+
+ $r = $this->Article->find('all');
+ $this->assertFalse(Set::matches('/Comment/User', $r));
+ }
+
+/**
+ * testFindEmbeddedNoBindings method
+ *
+ * @return void
+ */
+ public function testFindEmbeddedNoBindings() {
+ $result = $this->Article->find('all', array('contain' => false));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ )),
+ array('Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )),
+ array('Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ))
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindFirstLevel method
+ *
+ * @return void
+ */
+ public function testFindFirstLevel() {
+ $this->Article->contain('User');
+ $result = $this->Article->find('all', array('recursive' => 1));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain('User', 'Comment');
+ $result = $this->Article->find('all', array('recursive' => 1));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31'
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindEmbeddedFirstLevel method
+ *
+ * @return void
+ */
+ public function testFindEmbeddedFirstLevel() {
+ $result = $this->Article->find('all', array('contain' => array('User')));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array('contain' => array('User', 'Comment')));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31'
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindSecondLevel method
+ *
+ * @return void
+ */
+ public function testFindSecondLevel() {
+ $this->Article->contain(array('Comment' => 'User'));
+ $result = $this->Article->find('all', array('recursive' => 2));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ )
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ )
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'Comment' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(array('User' => 'ArticleFeatured'));
+ $result = $this->Article->find('all', array('recursive' => 2));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(array('User' => array('ArticleFeatured', 'Comment')));
+ $result = $this->Article->find('all', array('recursive' => 2));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ 'Comment' => array()
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'
+ )
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(array('User' => array('ArticleFeatured')), 'Tag', array('Comment' => 'Attachment'));
+ $result = $this->Article->find('all', array('recursive' => 2));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Attachment' => array()
+ )
+ ),
+ 'Tag' => array(
+ array('id' => 1, 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
+ array('id' => 2, 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31')
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Attachment' => array()
+ )
+ ),
+ 'Tag' => array(
+ array('id' => 1, 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
+ array('id' => 3, 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31')
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindEmbeddedSecondLevel method
+ *
+ * @return void
+ */
+ public function testFindEmbeddedSecondLevel() {
+ $result = $this->Article->find('all', array('contain' => array('Comment' => 'User')));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ )
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ )
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'Comment' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array('contain' => array('User' => 'ArticleFeatured')));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array('contain' => array('User' => array('ArticleFeatured', 'Comment'))));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ 'Comment' => array()
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'
+ )
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array('contain' => array('User' => 'ArticleFeatured', 'Tag', 'Comment' => 'Attachment')));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Attachment' => array()
+ )
+ ),
+ 'Tag' => array(
+ array('id' => 1, 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
+ array('id' => 2, 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31')
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Attachment' => array()
+ )
+ ),
+ 'Tag' => array(
+ array('id' => 1, 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
+ array('id' => 3, 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31')
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindThirdLevel method
+ *
+ * @return void
+ */
+ public function testFindThirdLevel() {
+ $this->User->contain(array('ArticleFeatured' => array('Featured' => 'Category')));
+ $result = $this->User->find('all', array('recursive' => 3));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->User->contain(array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => array('Article', 'Attachment'))));
+ $result = $this->User->find('all', array('recursive' => 3));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->User->contain(array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => 'Attachment'), 'Article'));
+ $result = $this->User->find('all', array('recursive' => 3));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindEmbeddedThirdLevel method
+ *
+ * @return void
+ */
+ public function testFindEmbeddedThirdLevel() {
+ $result = $this->User->find('all', array('contain' => array('ArticleFeatured' => array('Featured' => 'Category'))));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->User->find('all', array('contain' => array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => array('Article', 'Attachment')))));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->User->find('all', array('contain' => array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => 'Attachment'), 'Article')));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSettingsThirdLevel method
+ *
+ * @return void
+ */
+ public function testSettingsThirdLevel() {
+ $result = $this->User->find('all', array('contain' => array('ArticleFeatured' => array('Featured' => array('Category' => array('id', 'name'))))));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'name' => 'Category 1'
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'name' => 'Category 1'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $r = $this->User->find('all', array('contain' => array(
+ 'ArticleFeatured' => array(
+ 'id', 'title',
+ 'Featured' => array(
+ 'id', 'category_id',
+ 'Category' => array('id', 'name')
+ )
+ )
+ )));
+
+ $this->assertTrue(Set::matches('/User[id=1]', $r));
+ $this->assertFalse(Set::matches('/Article', $r) || Set::matches('/Comment', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured', $r));
+ $this->assertFalse(Set::matches('/ArticleFeatured/User', $r) || Set::matches('/ArticleFeatured/Comment', $r) || Set::matches('/ArticleFeatured/Tag', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured', $r));
+ $this->assertFalse(Set::matches('/ArticleFeatured/Featured/ArticleFeatured', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured/Category', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured[id=1]', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured[id=1]/Category[id=1]', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured[id=1]/Category[name=Category 1]', $r));
+
+ $r = $this->User->find('all', array('contain' => array(
+ 'ArticleFeatured' => array(
+ 'title',
+ 'Featured' => array(
+ 'id',
+ 'Category' => 'name'
+ )
+ )
+ )));
+
+ $this->assertTrue(Set::matches('/User[id=1]', $r));
+ $this->assertFalse(Set::matches('/Article', $r) || Set::matches('/Comment', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured', $r));
+ $this->assertFalse(Set::matches('/ArticleFeatured/User', $r) || Set::matches('/ArticleFeatured/Comment', $r) || Set::matches('/ArticleFeatured/Tag', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured', $r));
+ $this->assertFalse(Set::matches('/ArticleFeatured/Featured/ArticleFeatured', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured/Category', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured[id=1]', $r));
+ $this->assertTrue(Set::matches('/ArticleFeatured/Featured[id=1]/Category[name=Category 1]', $r));
+
+ $result = $this->User->find('all', array('contain' => array(
+ 'ArticleFeatured' => array(
+ 'title',
+ 'Featured' => array(
+ 'category_id',
+ 'Category' => 'name'
+ )
+ )
+ )));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'title' => 'First Article', 'id' => 1, 'user_id' => 1,
+ 'Featured' => array(
+ 'category_id' => 1, 'id' => 1,
+ 'Category' => array(
+ 'name' => 'Category 1'
+ )
+ )
+ ),
+ array(
+ 'title' => 'Third Article', 'id' => 3, 'user_id' => 1,
+ 'Featured' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'title' => 'Second Article', 'id' => 2, 'user_id' => 3,
+ 'Featured' => array(
+ 'category_id' => 1, 'id' => 2,
+ 'Category' => array(
+ 'name' => 'Category 1'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $orders = array(
+ 'title DESC', 'title DESC, published DESC',
+ array('title' => 'DESC'), array('title' => 'DESC', 'published' => 'DESC'),
+ );
+ foreach ($orders as $order) {
+ $result = $this->User->find('all', array('contain' => array(
+ 'ArticleFeatured' => array(
+ 'title', 'order' => $order,
+ 'Featured' => array(
+ 'category_id',
+ 'Category' => 'name'
+ )
+ )
+ )));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'title' => 'Third Article', 'id' => 3, 'user_id' => 1,
+ 'Featured' => array()
+ ),
+ array(
+ 'title' => 'First Article', 'id' => 1, 'user_id' => 1,
+ 'Featured' => array(
+ 'category_id' => 1, 'id' => 1,
+ 'Category' => array(
+ 'name' => 'Category 1'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'title' => 'Second Article', 'id' => 2, 'user_id' => 3,
+ 'Featured' => array(
+ 'category_id' => 1, 'id' => 2,
+ 'Category' => array(
+ 'name' => 'Category 1'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+ }
+
+/**
+ * testFindThirdLevelNonReset method
+ *
+ * @return void
+ */
+ public function testFindThirdLevelNonReset() {
+ $this->User->contain(false, array('ArticleFeatured' => array('Featured' => 'Category')));
+ $result = $this->User->find('all', array('recursive' => 3));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->User->resetBindings();
+
+ $this->User->contain(false, array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => array('Article', 'Attachment'))));
+ $result = $this->User->find('all', array('recursive' => 3));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->User->resetBindings();
+
+ $this->User->contain(false, array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => 'Attachment'), 'Article'));
+ $result = $this->User->find('all', array('recursive' => 3));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindEmbeddedThirdLevelNonReset method
+ *
+ * @return void
+ */
+ public function testFindEmbeddedThirdLevelNonReset() {
+ $result = $this->User->find('all', array('reset' => false, 'contain' => array('ArticleFeatured' => array('Featured' => 'Category'))));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->_assertBindings($this->User, array('hasMany' => array('ArticleFeatured')));
+ $this->_assertBindings($this->User->ArticleFeatured, array('hasOne' => array('Featured')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('Category')));
+
+ $this->User->resetBindings();
+
+ $this->_assertBindings($this->User, array('hasMany' => array('Article', 'ArticleFeatured', 'Comment')));
+ $this->_assertBindings($this->User->ArticleFeatured, array('belongsTo' => array('User'), 'hasOne' => array('Featured'), 'hasMany' => array('Comment'), 'hasAndBelongsToMany' => array('Tag')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('ArticleFeatured', 'Category')));
+ $this->_assertBindings($this->User->ArticleFeatured->Comment, array('belongsTo' => array('Article', 'User'), 'hasOne' => array('Attachment')));
+
+ $result = $this->User->find('all', array('reset' => false, 'contain' => array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => array('Article', 'Attachment')))));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->_assertBindings($this->User, array('hasMany' => array('ArticleFeatured')));
+ $this->_assertBindings($this->User->ArticleFeatured, array('hasOne' => array('Featured'), 'hasMany' => array('Comment')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('Category')));
+ $this->_assertBindings($this->User->ArticleFeatured->Comment, array('belongsTo' => array('Article'), 'hasOne' => array('Attachment')));
+
+ $this->User->resetBindings();
+ $this->_assertBindings($this->User, array('hasMany' => array('Article', 'ArticleFeatured', 'Comment')));
+ $this->_assertBindings($this->User->ArticleFeatured, array('belongsTo' => array('User'), 'hasOne' => array('Featured'), 'hasMany' => array('Comment'), 'hasAndBelongsToMany' => array('Tag')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('ArticleFeatured', 'Category')));
+ $this->_assertBindings($this->User->ArticleFeatured->Comment, array('belongsTo' => array('Article', 'User'), 'hasOne' => array('Attachment')));
+
+ $result = $this->User->find('all', array('contain' => array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => array('Article', 'Attachment')), false)));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Article' => array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Article' => array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->_assertBindings($this->User, array('hasMany' => array('ArticleFeatured')));
+ $this->_assertBindings($this->User->ArticleFeatured, array('hasOne' => array('Featured'), 'hasMany' => array('Comment')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('Category')));
+ $this->_assertBindings($this->User->ArticleFeatured->Comment, array('belongsTo' => array('Article'), 'hasOne' => array('Attachment')));
+
+ $this->User->resetBindings();
+ $this->_assertBindings($this->User, array('hasMany' => array('Article', 'ArticleFeatured', 'Comment')));
+ $this->_assertBindings($this->User->ArticleFeatured, array('belongsTo' => array('User'), 'hasOne' => array('Featured'), 'hasMany' => array('Comment'), 'hasAndBelongsToMany' => array('Tag')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('ArticleFeatured', 'Category')));
+ $this->_assertBindings($this->User->ArticleFeatured->Comment, array('belongsTo' => array('Article', 'User'), 'hasOne' => array('Attachment')));
+
+ $result = $this->User->find('all', array('reset' => false, 'contain' => array('ArticleFeatured' => array('Featured' => 'Category', 'Comment' => 'Attachment'), 'Article')));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => 1, 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Featured' => array(
+ 'id' => 1, 'article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31',
+ 'Attachment' => array()
+ ),
+ array(
+ 'id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31',
+ 'Attachment' => array()
+ )
+ )
+ ),
+ array(
+ 'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31',
+ 'Featured' => array(),
+ 'Comment' => array()
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 2, 'user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => 3, 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ 'ArticleFeatured' => array(
+ array(
+ 'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
+ 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31',
+ 'Featured' => array(
+ 'id' => 2, 'article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31',
+ 'Category' => array(
+ 'id' => 1, 'parent_id' => 0, 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'
+ )
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31',
+ 'Attachment' => array(
+ 'id' => 1, 'comment_id' => 5, 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31',
+ 'Attachment' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 4, 'user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'Article' => array(),
+ 'ArticleFeatured' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->_assertBindings($this->User, array('hasMany' => array('Article', 'ArticleFeatured')));
+ $this->_assertBindings($this->User->Article);
+ $this->_assertBindings($this->User->ArticleFeatured, array('hasOne' => array('Featured'), 'hasMany' => array('Comment')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('Category')));
+ $this->_assertBindings($this->User->ArticleFeatured->Comment, array('hasOne' => array('Attachment')));
+
+ $this->User->resetBindings();
+ $this->_assertBindings($this->User, array('hasMany' => array('Article', 'ArticleFeatured', 'Comment')));
+ $this->_assertBindings($this->User->Article, array('belongsTo' => array('User'), 'hasMany' => array('Comment'), 'hasAndBelongsToMany' => array('Tag')));
+ $this->_assertBindings($this->User->ArticleFeatured, array('belongsTo' => array('User'), 'hasOne' => array('Featured'), 'hasMany' => array('Comment'), 'hasAndBelongsToMany' => array('Tag')));
+ $this->_assertBindings($this->User->ArticleFeatured->Featured, array('belongsTo' => array('ArticleFeatured', 'Category')));
+ $this->_assertBindings($this->User->ArticleFeatured->Comment, array('belongsTo' => array('Article', 'User'), 'hasOne' => array('Attachment')));
+ }
+
+/**
+ * testEmbeddedFindFields method
+ *
+ * @return void
+ */
+ public function testEmbeddedFindFields() {
+ $result = $this->Article->find('all', array(
+ 'contain' => array('User(user)'),
+ 'fields' => array('title'),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array('title' => 'First Article'), 'User' => array('user' => 'mariano', 'id' => 1)),
+ array('Article' => array('title' => 'Second Article'), 'User' => array('user' => 'larry', 'id' => 3)),
+ array('Article' => array('title' => 'Third Article'), 'User' => array('user' => 'mariano', 'id' => 1)),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array(
+ 'contain' => array('User(id, user)'),
+ 'fields' => array('title'),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array('title' => 'First Article'), 'User' => array('user' => 'mariano', 'id' => 1)),
+ array('Article' => array('title' => 'Second Article'), 'User' => array('user' => 'larry', 'id' => 3)),
+ array('Article' => array('title' => 'Third Article'), 'User' => array('user' => 'mariano', 'id' => 1)),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array(
+ 'contain' => array(
+ 'Comment(comment, published)' => 'Attachment(attachment)', 'User(user)'
+ ),
+ 'fields' => array('title'),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ if (!empty($result)) {
+ foreach ($result as $i => $article) {
+ foreach ($article['Comment'] as $j => $comment) {
+ $result[$i]['Comment'][$j] = array_diff_key($comment, array('id' => true));
+ }
+ }
+ }
+ $expected = array(
+ array(
+ 'Article' => array('title' => 'First Article', 'id' => 1),
+ 'User' => array('user' => 'mariano', 'id' => 1),
+ 'Comment' => array(
+ array('comment' => 'First Comment for First Article', 'published' => 'Y', 'article_id' => 1, 'Attachment' => array()),
+ array('comment' => 'Second Comment for First Article', 'published' => 'Y', 'article_id' => 1, 'Attachment' => array()),
+ array('comment' => 'Third Comment for First Article', 'published' => 'Y', 'article_id' => 1, 'Attachment' => array()),
+ array('comment' => 'Fourth Comment for First Article', 'published' => 'N', 'article_id' => 1, 'Attachment' => array()),
+ )
+ ),
+ array(
+ 'Article' => array('title' => 'Second Article', 'id' => 2),
+ 'User' => array('user' => 'larry', 'id' => 3),
+ 'Comment' => array(
+ array('comment' => 'First Comment for Second Article', 'published' => 'Y', 'article_id' => 2, 'Attachment' => array(
+ 'attachment' => 'attachment.zip', 'id' => 1
+ )),
+ array('comment' => 'Second Comment for Second Article', 'published' => 'Y', 'article_id' => 2, 'Attachment' => array())
+ )
+ ),
+ array(
+ 'Article' => array('title' => 'Third Article', 'id' => 3),
+ 'User' => array('user' => 'mariano', 'id' => 1),
+ 'Comment' => array()
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that hasOne and belongsTo fields act the same in a contain array.
+ *
+ * @return void
+ */
+ public function testHasOneFieldsInContain() {
+ $this->Article->unbindModel(array(
+ 'hasMany' => array('Comment')
+ ), true);
+ unset($this->Article->Comment);
+ $this->Article->bindModel(array(
+ 'hasOne' => array('Comment')
+ ));
+
+ $result = $this->Article->find('all', array(
+ 'fields' => array('title', 'body'),
+ 'contain' => array(
+ 'Comment' => array(
+ 'fields' => array('comment')
+ ),
+ 'User' => array(
+ 'fields' => array('user')
+ )
+ )
+ ));
+ $this->assertTrue(isset($result[0]['Article']['title']), 'title missing %s');
+ $this->assertTrue(isset($result[0]['Article']['body']), 'body missing %s');
+ $this->assertTrue(isset($result[0]['Comment']['comment']), 'comment missing %s');
+ $this->assertTrue(isset($result[0]['User']['user']), 'body missing %s');
+ $this->assertFalse(isset($result[0]['Comment']['published']), 'published found %s');
+ $this->assertFalse(isset($result[0]['User']['password']), 'password found %s');
+ }
+
+/**
+ * testFindConditionalBinding method
+ *
+ * @return void
+ */
+ public function testFindConditionalBinding() {
+ $this->Article->contain(array(
+ 'User(user)',
+ 'Tag' => array(
+ 'fields' => array('tag', 'created'),
+ 'conditions' => array('created >=' => '2007-03-18 12:24')
+ )
+ ));
+ $result = $this->Article->find('all', array('fields' => array('title'), 'order' => array('Article.id' => 'ASC')));
+ $expected = array(
+ array(
+ 'Article' => array('id' => 1, 'title' => 'First Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array(array('tag' => 'tag2', 'created' => '2007-03-18 12:24:23'))
+ ),
+ array(
+ 'Article' => array('id' => 2, 'title' => 'Second Article'),
+ 'User' => array('id' => 3, 'user' => 'larry'),
+ 'Tag' => array(array('tag' => 'tag3', 'created' => '2007-03-18 12:26:23'))
+ ),
+ array(
+ 'Article' => array('id' => 3, 'title' => 'Third Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(array('User(id,user)', 'Tag' => array('fields' => array('tag', 'created'))));
+ $result = $this->Article->find('all', array('fields' => array('title'), 'order' => array('Article.id' => 'ASC')));
+ $expected = array(
+ array(
+ 'Article' => array('id' => 1, 'title' => 'First Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array(
+ array('tag' => 'tag1', 'created' => '2007-03-18 12:22:23'),
+ array('tag' => 'tag2', 'created' => '2007-03-18 12:24:23')
+ )
+ ),
+ array(
+ 'Article' => array('id' => 2, 'title' => 'Second Article'),
+ 'User' => array('id' => 3, 'user' => 'larry'),
+ 'Tag' => array(
+ array('tag' => 'tag1', 'created' => '2007-03-18 12:22:23'),
+ array('tag' => 'tag3', 'created' => '2007-03-18 12:26:23')
+ )
+ ),
+ array(
+ 'Article' => array('id' => 3, 'title' => 'Third Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array(
+ 'fields' => array('title'),
+ 'contain' => array('User(id,user)', 'Tag' => array('fields' => array('tag', 'created'))),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array(
+ 'Article' => array('id' => 1, 'title' => 'First Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array(
+ array('tag' => 'tag1', 'created' => '2007-03-18 12:22:23'),
+ array('tag' => 'tag2', 'created' => '2007-03-18 12:24:23')
+ )
+ ),
+ array(
+ 'Article' => array('id' => 2, 'title' => 'Second Article'),
+ 'User' => array('id' => 3, 'user' => 'larry'),
+ 'Tag' => array(
+ array('tag' => 'tag1', 'created' => '2007-03-18 12:22:23'),
+ array('tag' => 'tag3', 'created' => '2007-03-18 12:26:23')
+ )
+ ),
+ array(
+ 'Article' => array('id' => 3, 'title' => 'Third Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(array(
+ 'User(id,user)',
+ 'Tag' => array(
+ 'fields' => array('tag', 'created'),
+ 'conditions' => array('created >=' => '2007-03-18 12:24')
+ )
+ ));
+ $result = $this->Article->find('all', array('fields' => array('title'), 'order' => array('Article.id' => 'ASC')));
+ $expected = array(
+ array(
+ 'Article' => array('id' => 1, 'title' => 'First Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array(array('tag' => 'tag2', 'created' => '2007-03-18 12:24:23'))
+ ),
+ array(
+ 'Article' => array('id' => 2, 'title' => 'Second Article'),
+ 'User' => array('id' => 3, 'user' => 'larry'),
+ 'Tag' => array(array('tag' => 'tag3', 'created' => '2007-03-18 12:26:23'))
+ ),
+ array(
+ 'Article' => array('id' => 3, 'title' => 'Third Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->assertTrue(empty($this->User->Article->hasAndBelongsToMany['Tag']['conditions']));
+
+ $result = $this->User->find('all', array('contain' => array(
+ 'Article.Tag' => array('conditions' => array('created >=' => '2007-03-18 12:24'))
+ )));
+
+ $this->assertTrue(Set::matches('/User[id=1]', $result));
+ $this->assertFalse(Set::matches('/Article[id=1]/Tag[id=1]', $result));
+ $this->assertTrue(Set::matches('/Article[id=1]/Tag[id=2]', $result));
+ $this->assertTrue(empty($this->User->Article->hasAndBelongsToMany['Tag']['conditions']));
+
+ $this->assertTrue(empty($this->User->Article->hasAndBelongsToMany['Tag']['order']));
+
+ $result = $this->User->find('all', array('contain' => array(
+ 'Article.Tag' => array('order' => 'created DESC')
+ )));
+
+ $this->assertTrue(Set::matches('/User[id=1]', $result));
+ $this->assertTrue(Set::matches('/Article[id=1]/Tag[id=1]', $result));
+ $this->assertTrue(Set::matches('/Article[id=1]/Tag[id=2]', $result));
+ $this->assertTrue(empty($this->User->Article->hasAndBelongsToMany['Tag']['order']));
+ }
+
+/**
+ * testOtherFinds method
+ *
+ * @return void
+ */
+ public function testOtherFinds() {
+ $result = $this->Article->find('count');
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('count', array('conditions' => array('Article.id >' => '1')));
+ $expected = 2;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('count', array('contain' => array()));
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(array('User(id,user)', 'Tag' => array('fields' => array('tag', 'created'), 'conditions' => array('created >=' => '2007-03-18 12:24'))));
+ $result = $this->Article->find('first', array('fields' => array('title')));
+ $expected = array(
+ 'Article' => array('id' => 1, 'title' => 'First Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array(array('tag' => 'tag2', 'created' => '2007-03-18 12:24:23'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(array('User(id,user)', 'Tag' => array('fields' => array('tag', 'created'))));
+ $result = $this->Article->find('first', array('fields' => array('title')));
+ $expected = array(
+ 'Article' => array('id' => 1, 'title' => 'First Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array(
+ array('tag' => 'tag1', 'created' => '2007-03-18 12:22:23'),
+ array('tag' => 'tag2', 'created' => '2007-03-18 12:24:23')
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('first', array(
+ 'fields' => array('title'),
+ 'order' => 'Article.id DESC',
+ 'contain' => array('User(id,user)', 'Tag' => array('fields' => array('tag', 'created')))
+ ));
+ $expected = array(
+ 'Article' => array('id' => 3, 'title' => 'Third Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Tag' => array()
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('list', array(
+ 'contain' => array('User(id,user)'),
+ 'fields' => array('Article.id', 'Article.title')
+ ));
+ $expected = array(
+ 1 => 'First Article',
+ 2 => 'Second Article',
+ 3 => 'Third Article'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testOriginalAssociations method
+ *
+ * @return void
+ */
+ public function testOriginalAssociations() {
+ $this->Article->Comment->Behaviors->attach('Containable');
+
+ $options = array(
+ 'conditions' => array(
+ 'Comment.published' => 'Y',
+ ),
+ 'contain' => 'User',
+ 'recursive' => 1
+ );
+
+ $firstResult = $this->Article->Comment->find('all', $options);
+
+ $dummyResult = $this->Article->Comment->find('all', array(
+ 'conditions' => array(
+ 'User.user' => 'mariano'
+ ),
+ 'fields' => array('User.password'),
+ 'contain' => array('User.password'),
+ ));
+
+ $result = $this->Article->Comment->find('all', $options);
+ $this->assertEquals($firstResult, $result);
+
+ $this->Article->unbindModel(array('hasMany' => array('Comment'), 'belongsTo' => array('User'), 'hasAndBelongsToMany' => array('Tag')), false);
+ $this->Article->bindModel(array('hasMany' => array('Comment'), 'belongsTo' => array('User')), false);
+
+ $r = $this->Article->find('all', array('contain' => array('Comment(comment)', 'User(user)'), 'fields' => array('title')));
+ $this->assertTrue(Set::matches('/Article[id=1]', $r));
+ $this->assertTrue(Set::matches('/User[id=1]', $r));
+ $this->assertTrue(Set::matches('/Comment[article_id=1]', $r));
+ $this->assertFalse(Set::matches('/Comment[id=1]', $r));
+
+ $r = $this->Article->find('all');
+ $this->assertTrue(Set::matches('/Article[id=1]', $r));
+ $this->assertTrue(Set::matches('/User[id=1]', $r));
+ $this->assertTrue(Set::matches('/Comment[article_id=1]', $r));
+ $this->assertTrue(Set::matches('/Comment[id=1]', $r));
+
+ $this->Article->bindModel(array('hasAndBelongsToMany' => array('Tag')), false);
+
+ $this->Article->contain(false, array('User(id,user)', 'Comment' => array('fields' => array('comment'), 'conditions' => array('created >=' => '2007-03-18 10:49'))));
+ $result = $this->Article->find('all', array('fields' => array('title'), 'limit' => 1, 'page' => 1, 'order' => 'Article.id ASC'));
+ $expected = array(array(
+ 'Article' => array('id' => 1, 'title' => 'First Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Comment' => array(
+ array('comment' => 'Third Comment for First Article', 'article_id' => 1),
+ array('comment' => 'Fourth Comment for First Article', 'article_id' => 1)
+ )
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array('fields' => array('title', 'User.id', 'User.user'), 'limit' => 1, 'page' => 2, 'order' => 'Article.id ASC'));
+ $expected = array(array(
+ 'Article' => array('id' => 2, 'title' => 'Second Article'),
+ 'User' => array('id' => 3, 'user' => 'larry'),
+ 'Comment' => array(
+ array('comment' => 'First Comment for Second Article', 'article_id' => 2),
+ array('comment' => 'Second Comment for Second Article', 'article_id' => 2)
+ )
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Article->find('all', array('fields' => array('title', 'User.id', 'User.user'), 'limit' => 1, 'page' => 3, 'order' => 'Article.id ASC'));
+ $expected = array(array(
+ 'Article' => array('id' => 3, 'title' => 'Third Article'),
+ 'User' => array('id' => 1, 'user' => 'mariano'),
+ 'Comment' => array()
+ ));
+ $this->assertEquals($expected, $result);
+
+ $this->Article->contain(false, array('User' => array('fields' => 'user'), 'Comment'));
+ $result = $this->Article->find('all');
+ $this->assertTrue(Set::matches('/Article[id=1]', $result));
+ $this->assertTrue(Set::matches('/User[user=mariano]', $result));
+ $this->assertTrue(Set::matches('/Comment[article_id=1]', $result));
+ $this->Article->resetBindings();
+
+ $this->Article->contain(false, array('User' => array('fields' => array('user')), 'Comment'));
+ $result = $this->Article->find('all');
+ $this->assertTrue(Set::matches('/Article[id=1]', $result));
+ $this->assertTrue(Set::matches('/User[user=mariano]', $result));
+ $this->assertTrue(Set::matches('/Comment[article_id=1]', $result));
+ $this->Article->resetBindings();
+ }
+
+/**
+ * testResetAddedAssociation method
+ *
+ */
+ public function testResetAddedAssociation() {
+ $this->assertTrue(empty($this->Article->hasMany['ArticlesTag']));
+
+ $this->Article->bindModel(array(
+ 'hasMany' => array('ArticlesTag')
+ ));
+ $this->assertTrue(!empty($this->Article->hasMany['ArticlesTag']));
+
+ $result = $this->Article->find('first', array(
+ 'conditions' => array('Article.id' => 1),
+ 'contain' => array('ArticlesTag')
+ ));
+
+ $expected = array('Article', 'ArticlesTag');
+ $this->assertTrue(!empty($result));
+ $this->assertEquals('First Article', $result['Article']['title']);
+ $this->assertTrue(!empty($result['ArticlesTag']));
+ $this->assertEquals($expected, array_keys($result));
+
+ $this->assertTrue(empty($this->Article->hasMany['ArticlesTag']));
+
+ $this->JoinA = ClassRegistry::init('JoinA');
+ $this->JoinB = ClassRegistry::init('JoinB');
+ $this->JoinC = ClassRegistry::init('JoinC');
+
+ $this->JoinA->Behaviors->attach('Containable');
+ $this->JoinB->Behaviors->attach('Containable');
+ $this->JoinC->Behaviors->attach('Containable');
+
+ $this->JoinA->JoinB->find('all', array('contain' => array('JoinA')));
+ $this->JoinA->bindModel(array('hasOne' => array('JoinAsJoinC' => array('joinTable' => 'as_cs'))), false);
+ $result = $this->JoinA->hasOne;
+ $this->JoinA->find('all');
+ $resultAfter = $this->JoinA->hasOne;
+ $this->assertEquals($result, $resultAfter);
+ }
+
+/**
+ * testResetAssociation method
+ *
+ */
+ public function testResetAssociation() {
+ $this->Article->Behaviors->attach('Containable');
+ $this->Article->Comment->Behaviors->attach('Containable');
+ $this->Article->User->Behaviors->attach('Containable');
+
+ $initialOptions = array(
+ 'conditions' => array(
+ 'Comment.published' => 'Y',
+ ),
+ 'contain' => 'User',
+ 'recursive' => 1,
+ );
+
+ $initialModels = $this->Article->Comment->find('all', $initialOptions);
+
+ $findOptions = array(
+ 'conditions' => array(
+ 'User.user' => 'mariano',
+ ),
+ 'fields' => array('User.password'),
+ 'contain' => array('User.password')
+ );
+ $result = $this->Article->Comment->find('all', $findOptions);
+ $result = $this->Article->Comment->find('all', $initialOptions);
+ $this->assertEquals($initialModels, $result);
+ }
+
+/**
+ * testResetDeeperHasOneAssociations method
+ *
+ */
+ public function testResetDeeperHasOneAssociations() {
+ $this->Article->User->unbindModel(array(
+ 'hasMany' => array('ArticleFeatured', 'Comment')
+ ), false);
+ $userHasOne = array('hasOne' => array('ArticleFeatured', 'Comment'));
+
+ $this->Article->User->bindModel($userHasOne, false);
+ $expected = $this->Article->User->hasOne;
+ $this->Article->find('all');
+ $this->assertEquals($expected, $this->Article->User->hasOne);
+
+ $this->Article->User->bindModel($userHasOne, false);
+ $expected = $this->Article->User->hasOne;
+ $this->Article->find('all', array(
+ 'contain' => array(
+ 'User' => array('ArticleFeatured', 'Comment')
+ )
+ ));
+ $this->assertEquals($expected, $this->Article->User->hasOne);
+
+ $this->Article->User->bindModel($userHasOne, false);
+ $expected = $this->Article->User->hasOne;
+ $this->Article->find('all', array(
+ 'contain' => array(
+ 'User' => array(
+ 'ArticleFeatured',
+ 'Comment' => array('fields' => array('created'))
+ )
+ )
+ ));
+ $this->assertEquals($expected, $this->Article->User->hasOne);
+
+ $this->Article->User->bindModel($userHasOne, false);
+ $expected = $this->Article->User->hasOne;
+ $this->Article->find('all', array(
+ 'contain' => array(
+ 'User' => array(
+ 'Comment' => array('fields' => array('created'))
+ )
+ )
+ ));
+ $this->assertEquals($expected, $this->Article->User->hasOne);
+
+ $this->Article->User->bindModel($userHasOne, false);
+ $expected = $this->Article->User->hasOne;
+ $this->Article->find('all', array(
+ 'contain' => array(
+ 'User.ArticleFeatured' => array(
+ 'conditions' => array('ArticleFeatured.published' => 'Y')
+ ),
+ 'User.Comment'
+ )
+ ));
+ $this->assertEquals($expected, $this->Article->User->hasOne);
+ }
+
+/**
+ * testResetMultipleHabtmAssociations method
+ *
+ */
+ public function testResetMultipleHabtmAssociations() {
+ $articleHabtm = array(
+ 'hasAndBelongsToMany' => array(
+ 'Tag' => array(
+ 'className' => 'Tag',
+ 'joinTable' => 'articles_tags',
+ 'foreignKey' => 'article_id',
+ 'associationForeignKey' => 'tag_id'
+ ),
+ 'ShortTag' => array(
+ 'className' => 'Tag',
+ 'joinTable' => 'articles_tags',
+ 'foreignKey' => 'article_id',
+ 'associationForeignKey' => 'tag_id',
+ // LENGHT function mysql-only, using LIKE does almost the same
+ 'conditions' => "ShortTag.tag LIKE '???'"
+ )
+ )
+ );
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all');
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => 'Tag.tag'));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => 'Tag'));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => array('Tag' => array('fields' => array(null)))));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => array('Tag' => array('fields' => array('Tag.tag')))));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => array('Tag' => array('fields' => array('Tag.tag', 'Tag.created')))));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => 'ShortTag.tag'));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => 'ShortTag'));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => array('ShortTag' => array('fields' => array(null)))));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => array('ShortTag' => array('fields' => array('ShortTag.tag')))));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+
+ $this->Article->resetBindings();
+ $this->Article->bindModel($articleHabtm, false);
+ $expected = $this->Article->hasAndBelongsToMany;
+ $this->Article->find('all', array('contain' => array('ShortTag' => array('fields' => array('ShortTag.tag', 'ShortTag.created')))));
+ $this->assertEquals($expected, $this->Article->hasAndBelongsToMany);
+ }
+
+/**
+ * test that bindModel and unbindModel work with find() calls in between.
+ */
+ public function testBindMultipleTimesWithFind() {
+ $binding = array(
+ 'hasOne' => array(
+ 'ArticlesTag' => array(
+ 'foreignKey' => false,
+ 'type' => 'INNER',
+ 'conditions' => array(
+ 'ArticlesTag.article_id = Article.id'
+ )
+ ),
+ 'Tag' => array(
+ 'type' => 'INNER',
+ 'foreignKey' => false,
+ 'conditions' => array(
+ 'ArticlesTag.tag_id = Tag.id'
+ )
+ )
+ )
+ );
+ $this->Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')));
+ $this->Article->bindModel($binding);
+ $result = $this->Article->find('all', array('limit' => 1, 'contain' => array('ArticlesTag', 'Tag')));
+
+ $this->Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')));
+ $this->Article->bindModel($binding);
+ $result = $this->Article->find('all', array('limit' => 1, 'contain' => array('ArticlesTag', 'Tag')));
+
+ $associated = $this->Article->getAssociated();
+ $this->assertEquals('hasAndBelongsToMany', $associated['Tag']);
+ $this->assertFalse(isset($associated['ArticleTag']));
+ }
+
+/**
+ * test that autoFields doesn't splice in fields from other databases.
+ *
+ * @return void
+ */
+ public function testAutoFieldsWithMultipleDatabases() {
+ $config = new DATABASE_CONFIG();
+
+ $this->skipIf(
+ !isset($config->test) || !isset($config->test2),
+ 'Primary and secondary test databases not configured, ' .
+ 'skipping cross-database join tests. ' .
+ ' To run these tests, you must define $test and $test2 ' .
+ 'in your database configuration.'
+ );
+
+ $db = ConnectionManager::getDataSource('test2');
+ $this->fixtureManager->loadSingle('User', $db);
+
+ $this->Article->User->setDataSource('test2');
+
+ $result = $this->Article->find('all', array(
+ 'fields' => array('Article.title'),
+ 'contain' => array('User')
+ ));
+ $this->assertTrue(isset($result[0]['Article']));
+ $this->assertTrue(isset($result[0]['User']));
+ }
+
+/**
+ * test that autoFields doesn't splice in columns that aren't part of the join.
+ *
+ * @return void
+ */
+ public function testAutoFieldsWithRecursiveNegativeOne() {
+ $this->Article->recursive = -1;
+ $result = $this->Article->field('title', array('Article.title' => 'First Article'));
+ $this->assertNoErrors();
+ $this->assertEquals('First Article', $result, 'Field is wrong');
+ }
+
+/**
+ * test that find(all) doesn't return incorrect values when mixed with containable.
+ *
+ * @return void
+ */
+ public function testFindAllReturn() {
+ $result = $this->Article->find('all', array(
+ 'conditions' => array('Article.id' => 999999999)
+ ));
+ $this->assertEmpty($result, 'Should be empty.');
+ }
+
+/**
+ * testLazyLoad method
+ *
+ * @return void
+ */
+ public function testLazyLoad() {
+ // Local set up
+ $this->User = ClassRegistry::init('User');
+ $this->User->bindModel(array(
+ 'hasMany' => array('Article', 'ArticleFeatured', 'Comment')
+ ), false);
+
+ try {
+ $this->User->find('first', array(
+ 'contain' => 'Comment',
+ 'lazyLoad' => true
+ ));
+ } catch (Exception $e) {
+ $exceptions = true;
+ }
+ $this->assertTrue(empty($exceptions));
+ }
+
+/**
+ * _containments method
+ *
+ * @param Model $Model
+ * @param array $contain
+ * @return void
+ */
+ protected function _containments($Model, $contain = array()) {
+ if (!is_array($Model)) {
+ $result = $Model->containments($contain);
+ return $this->_containments($result['models']);
+ } else {
+ $result = $Model;
+ foreach ($result as $i => $containment) {
+ $result[$i] = array_diff_key($containment, array('instance' => true));
+ }
+ }
+ return $result;
+ }
+
+/**
+ * _assertBindings method
+ *
+ * @param Model $Model
+ * @param array $expected
+ * @return void
+ */
+ protected function _assertBindings(Model $Model, $expected = array()) {
+ $expected = array_merge(array(
+ 'belongsTo' => array(),
+ 'hasOne' => array(),
+ 'hasMany' => array(),
+ 'hasAndBelongsToMany' => array()
+ ), $expected);
+ foreach ($expected as $binding => $expect) {
+ $this->assertEquals(array_keys($Model->$binding), $expect);
+ }
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php
new file mode 100644
index 0000000..2593d44
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php
@@ -0,0 +1,1061 @@
+<?php
+/**
+ * TranslateBehaviorTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once dirname(dirname(__FILE__)) . DS . 'models.php';
+
+/**
+ * TranslateBehaviorTest class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class TranslateBehaviorTest extends CakeTestCase {
+
+/**
+ * autoFixtures property
+ *
+ * @var bool false
+ */
+ public $autoFixtures = false;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.translated_item', 'core.translate', 'core.translate_table',
+ 'core.translated_article', 'core.translate_article', 'core.user', 'core.comment', 'core.tag', 'core.articles_tag',
+ 'core.translate_with_prefix'
+ );
+
+/**
+ * Test that count queries with conditions get the correct joins
+ *
+ * @return void
+ */
+ public function testCountWithConditions() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $Model = new TranslatedItem();
+ $Model->locale = 'eng';
+ $result = $Model->find('count', array(
+ 'conditions' => array(
+ 'I18n__content.locale' => 'eng'
+ )
+ ));
+ $this->assertEquals(3, $result);
+ }
+
+/**
+ * testTranslateModel method
+ *
+ * @return void
+ */
+ public function testTranslateModel() {
+ $this->loadFixtures('TranslateTable', 'Tag', 'TranslatedItem', 'Translate', 'User', 'TranslatedArticle', 'TranslateArticle');
+ $TestModel = new Tag();
+ $TestModel->translateTable = 'another_i18n';
+ $TestModel->Behaviors->attach('Translate', array('title'));
+ $translateModel = $TestModel->Behaviors->Translate->translateModel($TestModel);
+ $this->assertEquals('I18nModel', $translateModel->name);
+ $this->assertEquals('another_i18n', $translateModel->useTable);
+
+ $TestModel = new User();
+ $TestModel->Behaviors->attach('Translate', array('title'));
+ $translateModel = $TestModel->Behaviors->Translate->translateModel($TestModel);
+ $this->assertEquals('I18nModel', $translateModel->name);
+ $this->assertEquals('i18n', $translateModel->useTable);
+
+ $TestModel = new TranslatedArticle();
+ $translateModel = $TestModel->Behaviors->Translate->translateModel($TestModel);
+ $this->assertEquals('TranslateArticleModel', $translateModel->name);
+ $this->assertEquals('article_i18n', $translateModel->useTable);
+
+ $TestModel = new TranslatedItem();
+ $translateModel = $TestModel->Behaviors->Translate->translateModel($TestModel);
+ $this->assertEquals('TranslateTestModel', $translateModel->name);
+ $this->assertEquals('i18n', $translateModel->useTable);
+ }
+
+/**
+ * testLocaleFalsePlain method
+ *
+ * @return void
+ */
+ public function testLocaleFalsePlain() {
+ $this->loadFixtures('Translate', 'TranslatedItem', 'User');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = false;
+
+ $result = $TestModel->read(null, 1);
+ $expected = array('TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'translated_article_id' => 1,
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('fields' => array('slug')));
+ $expected = array(
+ array('TranslatedItem' => array('slug' => 'first_translated')),
+ array('TranslatedItem' => array('slug' => 'second_translated')),
+ array('TranslatedItem' => array('slug' => 'third_translated'))
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testLocaleFalseAssociations method
+ *
+ * @return void
+ */
+ public function testLocaleFalseAssociations() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = false;
+ $TestModel->unbindTranslation();
+ $translations = array('title' => 'Title', 'content' => 'Content');
+ $TestModel->bindTranslation($translations, false);
+
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedItem' => array('id' => 1, 'slug' => 'first_translated', 'translated_article_id' => 1),
+ 'Title' => array(
+ array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
+ array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
+ array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1')
+ ),
+ 'Content' => array(
+ array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
+ array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
+ array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Obsah #1')
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->hasMany['Title']['fields'] = $TestModel->hasMany['Content']['fields'] = array('content');
+ $TestModel->hasMany['Title']['conditions']['locale'] = $TestModel->hasMany['Content']['conditions']['locale'] = 'eng';
+
+ $result = $TestModel->find('all', array('fields' => array('TranslatedItem.slug')));
+ $expected = array(
+ array(
+ 'TranslatedItem' => array('id' => 1, 'slug' => 'first_translated'),
+ 'Title' => array(array('foreign_key' => 1, 'content' => 'Title #1')),
+ 'Content' => array(array('foreign_key' => 1, 'content' => 'Content #1'))
+ ),
+ array(
+ 'TranslatedItem' => array('id' => 2, 'slug' => 'second_translated'),
+ 'Title' => array(array('foreign_key' => 2, 'content' => 'Title #2')),
+ 'Content' => array(array('foreign_key' => 2, 'content' => 'Content #2'))
+ ),
+ array(
+ 'TranslatedItem' => array('id' => 3, 'slug' => 'third_translated'),
+ 'Title' => array(array('foreign_key' => 3, 'content' => 'Title #3')),
+ 'Content' => array(array('foreign_key' => 3, 'content' => 'Content #3'))
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testLocaleSingle method
+ *
+ * @return void
+ */
+ public function testLocaleSingle() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'eng';
+
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'title' => 'Title #1',
+ 'content' => 'Content #1',
+ 'translated_article_id' => 1,
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'title' => 'Title #1',
+ 'content' => 'Content #1',
+ 'translated_article_id' => 1,
+ )
+ ),
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 2,
+ 'slug' => 'second_translated',
+ 'locale' => 'eng',
+ 'title' => 'Title #2',
+ 'content' => 'Content #2',
+ 'translated_article_id' => 1,
+ )
+ ),
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 3,
+ 'slug' => 'third_translated',
+ 'locale' => 'eng',
+ 'title' => 'Title #3',
+ 'content' => 'Content #3',
+ 'translated_article_id' => 1,
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testLocaleSingleWithConditions method
+ *
+ * @return void
+ */
+ public function testLocaleSingleWithConditions() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'eng';
+ $result = $TestModel->find('all', array('conditions' => array('slug' => 'first_translated')));
+ $expected = array(
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'title' => 'Title #1',
+ 'content' => 'Content #1',
+ 'translated_article_id' => 1,
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('conditions' => "TranslatedItem.slug = 'first_translated'"));
+ $expected = array(
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'title' => 'Title #1',
+ 'content' => 'Content #1',
+ 'translated_article_id' => 1,
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testLocaleSingleAssociations method
+ *
+ * @return void
+ */
+ public function testLocaleSingleAssociations() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'eng';
+ $TestModel->unbindTranslation();
+ $translations = array('title' => 'Title', 'content' => 'Content');
+ $TestModel->bindTranslation($translations, false);
+
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'title' => 'Title #1',
+ 'content' => 'Content #1',
+ 'translated_article_id' => 1,
+ ),
+ 'Title' => array(
+ array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
+ array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
+ array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1')
+ ),
+ 'Content' => array(
+ array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
+ array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
+ array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Obsah #1')
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->hasMany['Title']['fields'] = $TestModel->hasMany['Content']['fields'] = array('content');
+ $TestModel->hasMany['Title']['conditions']['locale'] = $TestModel->hasMany['Content']['conditions']['locale'] = 'eng';
+
+ $result = $TestModel->find('all', array('fields' => array('TranslatedItem.title')));
+ $expected = array(
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'locale' => 'eng',
+ 'title' => 'Title #1',
+ 'slug' => 'first_translated',
+ 'translated_article_id' => 1,
+ ),
+ 'Title' => array(array('foreign_key' => 1, 'content' => 'Title #1')),
+ 'Content' => array(array('foreign_key' => 1, 'content' => 'Content #1'))
+ ),
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 2,
+ 'locale' => 'eng',
+ 'title' => 'Title #2',
+ 'slug' => 'second_translated',
+ 'translated_article_id' => 1,
+ ),
+ 'Title' => array(array('foreign_key' => 2, 'content' => 'Title #2')),
+ 'Content' => array(array('foreign_key' => 2, 'content' => 'Content #2'))
+ ),
+ array(
+ 'TranslatedItem' => array(
+ 'id' => 3,
+ 'locale' => 'eng',
+ 'title' => 'Title #3',
+ 'slug' => 'third_translated',
+ 'translated_article_id' => 1,
+ ),
+ 'Title' => array(array('foreign_key' => 3, 'content' => 'Title #3')),
+ 'Content' => array(array('foreign_key' => 3, 'content' => 'Content #3'))
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testLocaleMultiple method
+ *
+ * @return void
+ */
+ public function testLocaleMultiple() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = array('deu', 'eng', 'cze');
+
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'deu',
+ 'title' => 'Titel #1',
+ 'content' => 'Inhalt #1',
+ 'translated_article_id' => 1,
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('fields' => array('slug', 'title', 'content')));
+ $expected = array(
+ array(
+ 'TranslatedItem' => array(
+ 'slug' => 'first_translated',
+ 'locale' => 'deu',
+ 'content' => 'Inhalt #1',
+ 'title' => 'Titel #1',
+ )
+ ),
+ array(
+ 'TranslatedItem' => array(
+ 'slug' => 'second_translated',
+ 'locale' => 'deu',
+ 'title' => 'Titel #2',
+ 'content' => 'Inhalt #2',
+ )
+ ),
+ array(
+ 'TranslatedItem' => array(
+ 'slug' => 'third_translated',
+ 'locale' => 'deu',
+ 'title' => 'Titel #3',
+ 'content' => 'Inhalt #3',
+ )
+ )
+ );
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMissingTranslation method
+ *
+ * @return void
+ */
+ public function testMissingTranslation() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'rus';
+ $result = $TestModel->read(null, 1);
+ $this->assertFalse($result);
+
+ $TestModel->locale = array('rus');
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'rus',
+ 'title' => '',
+ 'content' => '',
+ 'translated_article_id' => 1,
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testTranslatedFindList method
+ *
+ * @return void
+ */
+ public function testTranslatedFindList() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'deu';
+ $TestModel->displayField = 'title';
+ $result = $TestModel->find('list', array('recursive' => 1));
+ $expected = array(1 => 'Titel #1', 2 => 'Titel #2', 3 => 'Titel #3');
+ $this->assertEquals($expected, $result);
+
+ // SQL Server trigger an error and stops the page even if the debug = 0
+ if ($this->db instanceof Sqlserver) {
+ $debug = Configure::read('debug');
+ Configure::write('debug', 0);
+
+ $result = $TestModel->find('list', array('recursive' => 1, 'callbacks' => false));
+ $this->assertEquals(array(), $result);
+
+ $result = $TestModel->find('list', array('recursive' => 1, 'callbacks' => 'after'));
+ $this->assertEquals(array(), $result);
+ Configure::write('debug', $debug);
+ }
+
+ $result = $TestModel->find('list', array('recursive' => 1, 'callbacks' => 'before'));
+ $expected = array(1 => null, 2 => null, 3 => null);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testReadSelectedFields method
+ *
+ * @return void
+ */
+ public function testReadSelectedFields() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'eng';
+ $result = $TestModel->find('all', array('fields' => array('slug', 'TranslatedItem.content')));
+ $expected = array(
+ array('TranslatedItem' => array('slug' => 'first_translated', 'locale' => 'eng', 'content' => 'Content #1')),
+ array('TranslatedItem' => array('slug' => 'second_translated', 'locale' => 'eng', 'content' => 'Content #2')),
+ array('TranslatedItem' => array('slug' => 'third_translated', 'locale' => 'eng', 'content' => 'Content #3'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('fields' => array('TranslatedItem.slug', 'content')));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->locale = array('eng', 'deu', 'cze');
+ $delete = array(array('locale' => 'deu'), array('field' => 'content', 'locale' => 'eng'));
+ $I18nModel = ClassRegistry::getObject('TranslateTestModel');
+ $I18nModel->deleteAll(array('or' => $delete));
+
+ $result = $TestModel->find('all', array('fields' => array('title', 'content')));
+ $expected = array(
+ array('TranslatedItem' => array('locale' => 'eng', 'title' => 'Title #1', 'content' => 'Obsah #1')),
+ array('TranslatedItem' => array('locale' => 'eng', 'title' => 'Title #2', 'content' => 'Obsah #2')),
+ array('TranslatedItem' => array('locale' => 'eng', 'title' => 'Title #3', 'content' => 'Obsah #3'))
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveCreate method
+ *
+ * @return void
+ */
+ public function testSaveCreate() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'spa';
+ $data = array(
+ 'slug' => 'fourth_translated',
+ 'title' => 'Leyenda #4',
+ 'content' => 'Contenido #4',
+ 'translated_article_id' => 1,
+ );
+ $TestModel->create($data);
+ $TestModel->save();
+ $result = $TestModel->read();
+ $expected = array('TranslatedItem' => array_merge($data, array('id' => $TestModel->id, 'locale' => 'spa')));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that saving only some of the translated fields allows the record to be found again.
+ *
+ * @return void
+ */
+ public function testSavePartialFields() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'spa';
+ $data = array(
+ 'slug' => 'fourth_translated',
+ 'title' => 'Leyenda #4',
+ );
+ $TestModel->create($data);
+ $TestModel->save();
+ $result = $TestModel->read();
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => $TestModel->id,
+ 'translated_article_id' => null,
+ 'locale' => 'spa',
+ 'content' => '',
+ ) + $data
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveUpdate method
+ *
+ * @return void
+ */
+ public function testSaveUpdate() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'spa';
+ $oldData = array('slug' => 'fourth_translated', 'title' => 'Leyenda #4', 'translated_article_id' => 1);
+ $TestModel->create($oldData);
+ $TestModel->save();
+ $id = $TestModel->id;
+ $newData = array('id' => $id, 'content' => 'Contenido #4');
+ $TestModel->create($newData);
+ $TestModel->save();
+ $result = $TestModel->read(null, $id);
+ $expected = array('TranslatedItem' => array_merge($oldData, $newData, array('locale' => 'spa')));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultipleCreate method
+ *
+ * @return void
+ */
+ public function testMultipleCreate() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'deu';
+ $data = array(
+ 'slug' => 'new_translated',
+ 'title' => array('eng' => 'New title', 'spa' => 'Nuevo leyenda'),
+ 'content' => array('eng' => 'New content', 'spa' => 'Nuevo contenido')
+ );
+ $TestModel->create($data);
+ $TestModel->save();
+
+ $TestModel->unbindTranslation();
+ $translations = array('title' => 'Title', 'content' => 'Content');
+ $TestModel->bindTranslation($translations, false);
+ $TestModel->locale = array('eng', 'spa');
+
+ $result = $TestModel->read();
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => 4,
+ 'slug' => 'new_translated',
+ 'locale' => 'eng',
+ 'title' => 'New title',
+ 'content' => 'New content',
+ 'translated_article_id' => null,
+ ),
+ 'Title' => array(
+ array('id' => 21, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'title', 'content' => 'New title'),
+ array('id' => 22, 'locale' => 'spa', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'title', 'content' => 'Nuevo leyenda')
+ ),
+ 'Content' => array(
+ array('id' => 19, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'content', 'content' => 'New content'),
+ array('id' => 20, 'locale' => 'spa', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'content', 'content' => 'Nuevo contenido')
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultipleUpdate method
+ *
+ * @return void
+ */
+ public function testMultipleUpdate() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'eng';
+ $TestModel->validate['title'] = 'notEmpty';
+ $data = array('TranslatedItem' => array(
+ 'id' => 1,
+ 'title' => array('eng' => 'New Title #1', 'deu' => 'Neue Titel #1', 'cze' => 'Novy Titulek #1'),
+ 'content' => array('eng' => 'New Content #1', 'deu' => 'Neue Inhalt #1', 'cze' => 'Novy Obsah #1')
+ ));
+ $TestModel->create();
+ $TestModel->save($data);
+
+ $TestModel->unbindTranslation();
+ $translations = array('title' => 'Title', 'content' => 'Content');
+ $TestModel->bindTranslation($translations, false);
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => '1',
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'title' => 'New Title #1',
+ 'content' => 'New Content #1',
+ 'translated_article_id' => 1,
+ ),
+ 'Title' => array(
+ array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'New Title #1'),
+ array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Neue Titel #1'),
+ array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Novy Titulek #1')
+ ),
+ 'Content' => array(
+ array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'New Content #1'),
+ array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Neue Inhalt #1'),
+ array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Novy Obsah #1')
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->unbindTranslation($translations);
+ $TestModel->bindTranslation(array('title', 'content'), false);
+ }
+
+/**
+ * testMixedCreateUpdateWithArrayLocale method
+ *
+ * @return void
+ */
+ public function testMixedCreateUpdateWithArrayLocale() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = array('cze', 'deu');
+ $data = array('TranslatedItem' => array(
+ 'id' => 1,
+ 'title' => array('eng' => 'Updated Title #1', 'spa' => 'Nuevo leyenda #1'),
+ 'content' => 'Upraveny obsah #1'
+ ));
+ $TestModel->create();
+ $TestModel->save($data);
+
+ $TestModel->unbindTranslation();
+ $translations = array('title' => 'Title', 'content' => 'Content');
+ $TestModel->bindTranslation($translations, false);
+ $result = $TestModel->read(null, 1);
+ $result['Title'] = Hash::sort($result['Title'], '{n}.id', 'asc');
+ $result['Content'] = Hash::sort($result['Content'], '{n}.id', 'asc');
+ $expected = array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'cze',
+ 'title' => 'Titulek #1',
+ 'content' => 'Upraveny obsah #1',
+ 'translated_article_id' => 1,
+ ),
+ 'Title' => array(
+ array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Updated Title #1'),
+ array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
+ array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
+ array('id' => 19, 'locale' => 'spa', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Nuevo leyenda #1')
+ ),
+ 'Content' => array(
+ array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
+ array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
+ array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Upraveny obsah #1')
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that saveAll() works with hasMany associations that contain
+ * translations.
+ *
+ * @return void
+ */
+ public function testSaveAllTranslatedAssociations() {
+ $this->loadFixtures('Translate', 'TranslateArticle', 'TranslatedItem', 'TranslatedArticle', 'User');
+ $Model = new TranslatedArticle();
+ $Model->locale = 'eng';
+
+ $data = array(
+ 'TranslatedArticle' => array(
+ 'id' => 4,
+ 'user_id' => 1,
+ 'published' => 'Y',
+ 'title' => 'Title (eng) #1',
+ 'body' => 'Body (eng) #1'
+ ),
+ 'TranslatedItem' => array(
+ array(
+ 'slug' => '',
+ 'title' => 'Nuevo leyenda #1',
+ 'content' => 'Upraveny obsah #1'
+ ),
+ array(
+ 'slug' => '',
+ 'title' => 'New Title #2',
+ 'content' => 'New Content #2'
+ ),
+ )
+ );
+ $result = $Model->saveAll($data);
+ $this->assertTrue($result);
+
+ $result = $Model->TranslatedItem->find('all', array(
+ 'conditions' => array('translated_article_id' => $Model->id)
+ ));
+ $this->assertCount(2, $result);
+ $this->assertEquals($data['TranslatedItem'][0]['title'], $result[0]['TranslatedItem']['title']);
+ $this->assertEquals($data['TranslatedItem'][1]['title'], $result[1]['TranslatedItem']['title']);
+ }
+
+/**
+ * testValidation method
+ *
+ * @return void
+ */
+ public function testValidation() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->locale = 'eng';
+ $TestModel->validate['title'] = '/Only this title/';
+ $data = array(
+ 'TranslatedItem' => array(
+ 'id' => 1,
+ 'title' => array('eng' => 'New Title #1', 'deu' => 'Neue Titel #1', 'cze' => 'Novy Titulek #1'),
+ 'content' => array('eng' => 'New Content #1', 'deu' => 'Neue Inhalt #1', 'cze' => 'Novy Obsah #1')
+ )
+ );
+ $TestModel->create();
+ $this->assertFalse($TestModel->save($data));
+ $this->assertEquals(array('This field cannot be left blank'), $TestModel->validationErrors['title']);
+
+ $TestModel->locale = 'eng';
+ $TestModel->validate['title'] = '/Only this title/';
+ $data = array('TranslatedItem' => array(
+ 'id' => 1,
+ 'title' => array('eng' => 'Only this title', 'deu' => 'Neue Titel #1', 'cze' => 'Novy Titulek #1'),
+ 'content' => array('eng' => 'New Content #1', 'deu' => 'Neue Inhalt #1', 'cze' => 'Novy Obsah #1')
+ ));
+ $TestModel->create();
+ $result = $TestModel->save($data);
+ $this->assertFalse(empty($result));
+ }
+
+/**
+ * testAttachDetach method
+ *
+ * @return void
+ */
+ public function testAttachDetach() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+
+ $TestModel->unbindTranslation();
+ $translations = array('title' => 'Title', 'content' => 'Content');
+ $TestModel->bindTranslation($translations, false);
+
+ $result = array_keys($TestModel->hasMany);
+ $expected = array('Title', 'Content');
+ $this->assertEquals($expected, $result);
+
+ $TestModel->Behaviors->detach('Translate');
+ $result = array_keys($TestModel->hasMany);
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = isset($TestModel->Behaviors->Translate);
+ $this->assertFalse($result);
+
+ $result = isset($Behavior->settings[$TestModel->alias]);
+ $this->assertFalse($result);
+
+ $result = isset($Behavior->runtime[$TestModel->alias]);
+ $this->assertFalse($result);
+
+ $TestModel->Behaviors->attach('Translate', array('title' => 'Title', 'content' => 'Content'));
+ $result = array_keys($TestModel->hasMany);
+ $expected = array('Title', 'Content');
+ $this->assertEquals($expected, $result);
+
+ $result = isset($TestModel->Behaviors->Translate);
+ $this->assertTrue($result);
+
+ $Behavior = $TestModel->Behaviors->Translate;
+
+ $result = isset($Behavior->settings[$TestModel->alias]);
+ $this->assertTrue($result);
+
+ $result = isset($Behavior->runtime[$TestModel->alias]);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testAnotherTranslateTable method
+ *
+ * @return void
+ */
+ public function testAnotherTranslateTable() {
+ $this->loadFixtures('Translate', 'TranslatedItem', 'TranslateTable');
+
+ $TestModel = new TranslatedItemWithTable();
+ $TestModel->locale = 'eng';
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedItemWithTable' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'title' => 'Another Title #1',
+ 'content' => 'Another Content #1',
+ 'translated_article_id' => 1,
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testTranslateWithAssociations method
+ *
+ * @return void
+ */
+ public function testTranslateWithAssociations() {
+ $this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'TranslatedItem', 'User', 'Comment', 'ArticlesTag', 'Tag');
+
+ $TestModel = new TranslatedArticle();
+ $TestModel->locale = 'eng';
+ $recursive = $TestModel->recursive;
+
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedArticle' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'locale' => 'eng',
+ 'title' => 'Title (eng) #1',
+ 'body' => 'Body (eng) #1'
+ ),
+ 'User' => array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'TranslatedItem' => array(
+ array(
+ 'id' => 1,
+ 'translated_article_id' => 1,
+ 'slug' => 'first_translated'
+ ),
+ array(
+ 'id' => 2,
+ 'translated_article_id' => 1,
+ 'slug' => 'second_translated'
+ ),
+ array(
+ 'id' => 3,
+ 'translated_article_id' => 1,
+ 'slug' => 'third_translated'
+ ),
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('recursive' => -1));
+ $expected = array(
+ array(
+ 'TranslatedArticle' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'locale' => 'eng',
+ 'title' => 'Title (eng) #1',
+ 'body' => 'Body (eng) #1'
+ )
+ ),
+ array(
+ 'TranslatedArticle' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31',
+ 'locale' => 'eng',
+ 'title' => 'Title (eng) #2',
+ 'body' => 'Body (eng) #2'
+ )
+ ),
+ array(
+ 'TranslatedArticle' => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31',
+ 'locale' => 'eng',
+ 'title' => 'Title (eng) #3',
+ 'body' => 'Body (eng) #3'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($TestModel->recursive, $recursive);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'TranslatedArticle' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'locale' => 'eng',
+ 'title' => 'Title (eng) #1',
+ 'body' => 'Body (eng) #1'
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testTranslateTableWithPrefix method
+ * Tests that is possible to have a translation model with a custom tablePrefix
+ *
+ * @return void
+ */
+ public function testTranslateTableWithPrefix() {
+ $this->loadFixtures('TranslateWithPrefix', 'TranslatedItem');
+ $TestModel = new TranslatedItem2;
+ $TestModel->locale = 'eng';
+ $result = $TestModel->read(null, 1);
+ $expected = array('TranslatedItem' => array(
+ 'id' => 1,
+ 'slug' => 'first_translated',
+ 'locale' => 'eng',
+ 'content' => 'Content #1',
+ 'title' => 'Title #1',
+ 'translated_article_id' => 1,
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test infinite loops not occurring with unbindTranslation()
+ *
+ * @return void
+ */
+ public function testUnbindTranslationInfinteLoop() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+
+ $TestModel = new TranslatedItem();
+ $TestModel->Behaviors->detach('Translate');
+ $TestModel->actsAs = array();
+ $TestModel->Behaviors->attach('Translate');
+ $TestModel->bindTranslation(array('title', 'content'), true);
+ $result = $TestModel->unbindTranslation();
+
+ $this->assertFalse($result);
+ }
+
+/**
+ * Test that an exception is raised when you try to over-write the name attribute.
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testExceptionOnNameTranslation() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+ $TestModel = new TranslatedItem();
+ $TestModel->bindTranslation(array('name' => 'name'));
+ }
+
+/**
+ * Test that translations can be bound and unbound dynamically.
+ *
+ * @return void
+ */
+ public function testUnbindTranslation() {
+ $this->loadFixtures('Translate', 'TranslatedItem');
+ $Model = new TranslatedItem();
+ $Model->unbindTranslation();
+ $Model->bindTranslation(array('body', 'slug'), false);
+
+ $result = $Model->Behaviors->Translate->settings['TranslatedItem'];
+ $this->assertEquals(array('body', 'slug'), $result);
+
+ $Model->unbindTranslation(array('body'));
+ $result = $Model->Behaviors->Translate->settings['TranslatedItem'];
+ $this->assertNotContains('body', $result);
+
+ $Model->unbindTranslation('slug');
+ $result = $Model->Behaviors->Translate->settings['TranslatedItem'];
+ $this->assertNotContains('slug', $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php
new file mode 100644
index 0000000..4e8ae4c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorAfterTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * TreeBehaviorAfterTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5330
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once dirname(dirname(__FILE__)) . DS . 'models.php';
+
+
+/**
+ * TreeBehaviorAfterTest class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class TreeBehaviorAfterTest extends CakeTestCase {
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ */
+ public $backupGlobals = false;
+
+/**
+ * settings property
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'modelClass' => 'AfterTree',
+ 'leftField' => 'lft',
+ 'rightField' => 'rght',
+ 'parentField' => 'parent_id'
+ );
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.after_tree');
+
+/**
+ * Tests the afterSave callback in the model
+ *
+ * @return void
+ */
+ public function testAftersaveCallback() {
+ $this->Tree = new AfterTree();
+
+ $expected = array('AfterTree' => array('name' => 'Six and One Half Changed in AfterTree::afterSave() but not in database', 'parent_id' => 6, 'lft' => 11, 'rght' => 12));
+ $result = $this->Tree->save(array('AfterTree' => array('name' => 'Six and One Half', 'parent_id' => 6)));
+ $expected['AfterTree']['id'] = $this->Tree->id;
+ $this->assertEquals($expected, $result);
+
+ $expected = array('AfterTree' => array('name' => 'Six and One Half', 'parent_id' => 6, 'lft' => 11, 'rght' => 12, 'id' => 8));
+ $result = $this->Tree->find('all');
+ $this->assertEquals($expected, $result[7]);
+ }
+}
+
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php
new file mode 100644
index 0000000..1078286
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php
@@ -0,0 +1,1379 @@
+<?php
+/**
+ * TreeBehaviorNumberTest file
+ *
+ * This is the basic Tree behavior test
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5330
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once dirname(dirname(__FILE__)) . DS . 'models.php';
+
+/**
+ * TreeBehaviorNumberTest class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class TreeBehaviorNumberTest extends CakeTestCase {
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ */
+ public $backupGlobals = false;
+
+/**
+ * settings property
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'modelClass' => 'NumberTree',
+ 'leftField' => 'lft',
+ 'rightField' => 'rght',
+ 'parentField' => 'parent_id'
+ );
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.number_tree', 'core.person');
+
+/**
+ * testInitialize method
+ *
+ * @return void
+ */
+ public function testInitialize() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->find('count');
+ $this->assertEquals(7, $result);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testDetectInvalidLeft method
+ *
+ * @return void
+ */
+ public function testDetectInvalidLeft() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->findByName('1.1');
+
+ $save[$modelClass]['id'] = $result[$modelClass]['id'];
+ $save[$modelClass][$leftField] = 0;
+
+ $this->Tree->save($save);
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover();
+ $this->assertSame($result, true);
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+ }
+
+/**
+ * testDetectInvalidRight method
+ *
+ * @return void
+ */
+ public function testDetectInvalidRight() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->findByName('1.1');
+
+ $save[$modelClass]['id'] = $result[$modelClass]['id'];
+ $save[$modelClass][$rightField] = 0;
+
+ $this->Tree->save($save);
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover();
+ $this->assertSame($result, true);
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+ }
+
+/**
+ * testDetectInvalidParent method
+ *
+ * @return void
+ */
+ public function testDetectInvalidParent() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->findByName('1.1');
+
+ // Bypass behavior and any other logic
+ $this->Tree->updateAll(array($parentField => null), array('id' => $result[$modelClass]['id']));
+
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover();
+ $this->assertSame($result, true);
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+ }
+
+/**
+ * testDetectNoneExistentParent method
+ *
+ * @return void
+ */
+ public function testDetectNoneExistentParent() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->findByName('1.1');
+ $this->Tree->updateAll(array($parentField => 999999), array('id' => $result[$modelClass]['id']));
+
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover('MPTT');
+ $this->assertSame($result, true);
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+ }
+
+/**
+ * testRecoverUsingParentMode method
+ *
+ * @return void
+ */
+ public function testRecoverUsingParentMode() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->Behaviors->disable('Tree');
+
+ $this->Tree->save(array('parent_id' => null, 'name' => 'Main', $parentField => null, $leftField => 0, $rightField => 0));
+ $node1 = $this->Tree->id;
+
+ $this->Tree->create();
+ $this->Tree->save(array('parent_id' => null, 'name' => 'About Us', $parentField => $node1, $leftField => 0, $rightField => 0));
+ $node11 = $this->Tree->id;
+ $this->Tree->create();
+ $this->Tree->save(array('parent_id' => null, 'name' => 'Programs', $parentField => $node1, $leftField => 0, $rightField => 0));
+ $node12 = $this->Tree->id;
+ $this->Tree->create();
+ $this->Tree->save(array('parent_id' => null, 'name' => 'Mission and History', $parentField => $node11, $leftField => 0, $rightField => 0));
+ $this->Tree->create();
+ $this->Tree->save(array('parent_id' => null, 'name' => 'Overview', $parentField => $node12, $leftField => 0, $rightField => 0));
+
+ $this->Tree->Behaviors->enable('Tree');
+
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover();
+ $this->assertTrue($result);
+
+ $result = $this->Tree->verify();
+ $this->assertTrue($result);
+
+ $result = $this->Tree->find('first', array(
+ 'fields' => array('name', $parentField, $leftField, $rightField),
+ 'conditions' => array('name' => 'Main'),
+ 'recursive' => -1
+ ));
+ $expected = array(
+ $modelClass => array(
+ 'name' => 'Main',
+ $parentField => null,
+ $leftField => 1,
+ $rightField => 10
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRecoverFromMissingParent method
+ *
+ * @return void
+ */
+ public function testRecoverFromMissingParent() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->findByName('1.1');
+ $this->Tree->updateAll(array($parentField => 999999), array('id' => $result[$modelClass]['id']));
+
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover();
+ $this->assertSame($result, true);
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+ }
+
+/**
+ * testDetectInvalidParents method
+ *
+ * @return void
+ */
+ public function testDetectInvalidParents() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $this->Tree->updateAll(array($parentField => null));
+
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover();
+ $this->assertSame($result, true);
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+ }
+
+/**
+ * testDetectInvalidLftsRghts method
+ *
+ * @return void
+ */
+ public function testDetectInvalidLftsRghts() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $this->Tree->updateAll(array($leftField => 0, $rightField => 0));
+
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $this->Tree->recover();
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+ }
+
+/**
+ * Reproduces a situation where a single node has lft= rght, and all other lft and rght fields follow sequentially
+ *
+ * @return void
+ */
+ public function testDetectEqualLftsRghts() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(1, 3);
+
+ $result = $this->Tree->findByName('1.1');
+ $this->Tree->updateAll(array($rightField => $result[$modelClass][$leftField]), array('id' => $result[$modelClass]['id']));
+ $this->Tree->updateAll(array($leftField => $this->Tree->escapeField($leftField) . ' -1'),
+ array($leftField . ' >' => $result[$modelClass][$leftField]));
+ $this->Tree->updateAll(array($rightField => $this->Tree->escapeField($rightField) . ' -1'),
+ array($rightField . ' >' => $result[$modelClass][$leftField]));
+
+ $result = $this->Tree->verify();
+ $this->assertNotSame($result, true);
+
+ $result = $this->Tree->recover();
+ $this->assertTrue($result);
+
+ $result = $this->Tree->verify();
+ $this->assertTrue($result);
+ }
+
+/**
+ * testAddOrphan method
+ *
+ * @return void
+ */
+ public function testAddOrphan() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $this->Tree->save(array($modelClass => array('name' => 'testAddOrphan', $parentField => null)));
+ $result = $this->Tree->find('first', array('fields' => array('name', $parentField), 'order' => $modelClass . '.' . $leftField . ' desc'));
+ $expected = array($modelClass => array('name' => 'testAddOrphan', $parentField => null));
+ $this->assertEquals($expected, $result);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testAddMiddle method
+ *
+ * @return void
+ */
+ public function testAddMiddle() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
+ $initialCount = $this->Tree->find('count');
+
+ $this->Tree->create();
+ $result = $this->Tree->save(array($modelClass => array('name' => 'testAddMiddle', $parentField => $data[$modelClass]['id'])));
+ $expected = array_merge(array($modelClass => array('name' => 'testAddMiddle', $parentField => '2')), $result);
+ $this->assertSame($expected, $result);
+
+ $laterCount = $this->Tree->find('count');
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount + 1, $laterCount);
+
+ $children = $this->Tree->children($data[$modelClass]['id'], true, array('name'));
+ $expects = array(array($modelClass => array('name' => '1.1.1')),
+ array($modelClass => array('name' => '1.1.2')),
+ array($modelClass => array('name' => 'testAddMiddle')));
+ $this->assertSame($children, $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testAddInvalid method
+ *
+ * @return void
+ */
+ public function testAddInvalid() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $initialCount = $this->Tree->find('count');
+ //$this->expectError('Trying to save a node under a none-existant node in TreeBehavior::beforeSave');
+
+ $saveSuccess = $this->Tree->save(array($modelClass => array('name' => 'testAddInvalid', $parentField => 99999)));
+ $this->assertSame($saveSuccess, false);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertSame($initialCount, $laterCount);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testAddNotIndexedByModel method
+ *
+ * @return void
+ */
+ public function testAddNotIndexedByModel() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $this->Tree->save(array('name' => 'testAddNotIndexed', $parentField => null));
+ $result = $this->Tree->find('first', array('fields' => array('name', $parentField), 'order' => $modelClass . '.' . $leftField . ' desc'));
+ $expected = array($modelClass => array('name' => 'testAddNotIndexed', $parentField => null));
+ $this->assertEquals($expected, $result);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMovePromote method
+ *
+ * @return void
+ */
+ public function testMovePromote() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $parentId = $parent[$modelClass]['id'];
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->saveField($parentField, $parentId);
+ $direct = $this->Tree->children($parentId, true, array('id', 'name', $parentField, $leftField, $rightField));
+ $expects = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 5)),
+ array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 6, $rightField => 11)),
+ array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 1, $leftField => 12, $rightField => 13)));
+ $this->assertEquals($direct, $expects);
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMoveWithWhitelist method
+ *
+ * @return void
+ */
+ public function testMoveWithWhitelist() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $parentId = $parent[$modelClass]['id'];
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->whitelist = array($parentField, 'name', 'description');
+ $this->Tree->saveField($parentField, $parentId);
+
+ $result = $this->Tree->children($parentId, true, array('id', 'name', $parentField, $leftField, $rightField));
+ $expected = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 5)),
+ array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 6, $rightField => 11)),
+ array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 1, $leftField => 12, $rightField => 13)));
+ $this->assertEquals($expected, $result);
+ $this->assertTrue($this->Tree->verify());
+ }
+
+/**
+ * testInsertWithWhitelist method
+ *
+ * @return void
+ */
+ public function testInsertWithWhitelist() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $this->Tree->whitelist = array('name', $parentField);
+ $this->Tree->save(array($modelClass => array('name' => 'testAddOrphan', $parentField => null)));
+ $result = $this->Tree->findByName('testAddOrphan', array('name', $parentField, $leftField, $rightField));
+ $expected = array('name' => 'testAddOrphan', $parentField => null, $leftField => '15', $rightField => 16);
+ $this->assertEquals($expected, $result[$modelClass]);
+ $this->assertSame($this->Tree->verify(), true);
+ }
+
+/**
+ * testMoveBefore method
+ *
+ * @return void
+ */
+ public function testMoveBefore() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.1')));
+ $parentId = $parent[$modelClass]['id'];
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.2')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->saveField($parentField, $parentId);
+
+ $result = $this->Tree->children($parentId, true, array('name'));
+ $expects = array(array($modelClass => array('name' => '1.1.1')),
+ array($modelClass => array('name' => '1.1.2')),
+ array($modelClass => array('name' => '1.2')));
+ $this->assertEquals($expects, $result);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMoveAfter method
+ *
+ * @return void
+ */
+ public function testMoveAfter() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2')));
+ $parentId = $parent[$modelClass]['id'];
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->saveField($parentField, $parentId);
+
+ $result = $this->Tree->children($parentId, true, array('name'));
+ $expects = array(array($modelClass => array('name' => '1.2.1')),
+ array($modelClass => array('name' => '1.2.2')),
+ array($modelClass => array('name' => '1.1')));
+ $this->assertEquals($expects, $result);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMoveDemoteInvalid method
+ *
+ * @return void
+ */
+ public function testMoveDemoteInvalid() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $parentId = $parent[$modelClass]['id'];
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
+
+ $expects = $this->Tree->find('all');
+ $before = $this->Tree->read(null, $data[$modelClass]['id']);
+
+ $this->Tree->id = $parentId;
+ $this->Tree->saveField($parentField, $data[$modelClass]['id']);
+
+ $results = $this->Tree->find('all');
+ $after = $this->Tree->read(null, $data[$modelClass]['id']);
+
+ $this->assertEquals($expects, $results);
+ $this->assertEquals($before, $after);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMoveInvalid method
+ *
+ * @return void
+ */
+ public function testMoveInvalid() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $initialCount = $this->Tree->find('count');
+ $data = $this->Tree->findByName('1.1');
+
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->saveField($parentField, 999999);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertSame($initialCount, $laterCount);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMoveSelfInvalid method
+ *
+ * @return void
+ */
+ public function testMoveSelfInvalid() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $initialCount = $this->Tree->find('count');
+ $data = $this->Tree->findByName('1.1');
+
+ $this->Tree->id = $data[$modelClass]['id'];
+ $saveSuccess = $this->Tree->saveField($parentField, $this->Tree->id);
+
+ $this->assertSame($saveSuccess, false);
+ $laterCount = $this->Tree->find('count');
+ $this->assertSame($initialCount, $laterCount);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMoveUpSuccess method
+ *
+ * @return void
+ */
+ public function testMoveUpSuccess() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.2')));
+ $this->Tree->moveUp($data[$modelClass]['id']);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(array($modelClass => array('name' => '1.2', )),
+ array($modelClass => array('name' => '1.1', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveUpFail method
+ *
+ * @return void
+ */
+ public function testMoveUpFail() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.1')));
+
+ $this->Tree->moveUp($data[$modelClass]['id']);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(array($modelClass => array('name' => '1.1', )),
+ array($modelClass => array('name' => '1.2', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveUp2 method
+ *
+ * @return void
+ */
+ public function testMoveUp2() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(1, 10);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
+ $this->Tree->moveUp($data[$modelClass]['id'], 2);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(
+ array($modelClass => array('name' => '1.1', )),
+ array($modelClass => array('name' => '1.2', )),
+ array($modelClass => array('name' => '1.5', )),
+ array($modelClass => array('name' => '1.3', )),
+ array($modelClass => array('name' => '1.4', )),
+ array($modelClass => array('name' => '1.6', )),
+ array($modelClass => array('name' => '1.7', )),
+ array($modelClass => array('name' => '1.8', )),
+ array($modelClass => array('name' => '1.9', )),
+ array($modelClass => array('name' => '1.10', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveUpFirst method
+ *
+ * @return void
+ */
+ public function testMoveUpFirst() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(1, 10);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
+ $this->Tree->moveUp($data[$modelClass]['id'], true);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(
+ array($modelClass => array('name' => '1.5', )),
+ array($modelClass => array('name' => '1.1', )),
+ array($modelClass => array('name' => '1.2', )),
+ array($modelClass => array('name' => '1.3', )),
+ array($modelClass => array('name' => '1.4', )),
+ array($modelClass => array('name' => '1.6', )),
+ array($modelClass => array('name' => '1.7', )),
+ array($modelClass => array('name' => '1.8', )),
+ array($modelClass => array('name' => '1.9', )),
+ array($modelClass => array('name' => '1.10', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveDownSuccess method
+ *
+ * @return void
+ */
+ public function testMoveDownSuccess() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
+ $this->Tree->moveDown($data[$modelClass]['id']);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(array($modelClass => array('name' => '1.2', )),
+ array($modelClass => array('name' => '1.1', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveDownFail method
+ *
+ * @return void
+ */
+ public function testMoveDownFail() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2')));
+ $this->Tree->moveDown($data[$modelClass]['id']);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(array($modelClass => array('name' => '1.1', )),
+ array($modelClass => array('name' => '1.2', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveDownLast method
+ *
+ * @return void
+ */
+ public function testMoveDownLast() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(1, 10);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
+ $this->Tree->moveDown($data[$modelClass]['id'], true);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(
+ array($modelClass => array('name' => '1.1', )),
+ array($modelClass => array('name' => '1.2', )),
+ array($modelClass => array('name' => '1.3', )),
+ array($modelClass => array('name' => '1.4', )),
+ array($modelClass => array('name' => '1.6', )),
+ array($modelClass => array('name' => '1.7', )),
+ array($modelClass => array('name' => '1.8', )),
+ array($modelClass => array('name' => '1.9', )),
+ array($modelClass => array('name' => '1.10', )),
+ array($modelClass => array('name' => '1.5', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveDown2 method
+ *
+ * @return void
+ */
+ public function testMoveDown2() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(1, 10);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
+ $this->Tree->moveDown($data[$modelClass]['id'], 2);
+
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(
+ array($modelClass => array('name' => '1.1', )),
+ array($modelClass => array('name' => '1.2', )),
+ array($modelClass => array('name' => '1.3', )),
+ array($modelClass => array('name' => '1.4', )),
+ array($modelClass => array('name' => '1.6', )),
+ array($modelClass => array('name' => '1.7', )),
+ array($modelClass => array('name' => '1.5', )),
+ array($modelClass => array('name' => '1.8', )),
+ array($modelClass => array('name' => '1.9', )),
+ array($modelClass => array('name' => '1.10', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testSaveNoMove method
+ *
+ * @return void
+ */
+ public function testSaveNoMove() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(1, 10);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.5')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->saveField('name', 'renamed');
+ $parent = $this->Tree->findByName('1. Root', array('id'));
+ $this->Tree->id = $parent[$modelClass]['id'];
+ $result = $this->Tree->children(null, true, array('name'));
+ $expected = array(
+ array($modelClass => array('name' => '1.1', )),
+ array($modelClass => array('name' => '1.2', )),
+ array($modelClass => array('name' => '1.3', )),
+ array($modelClass => array('name' => '1.4', )),
+ array($modelClass => array('name' => 'renamed', )),
+ array($modelClass => array('name' => '1.6', )),
+ array($modelClass => array('name' => '1.7', )),
+ array($modelClass => array('name' => '1.8', )),
+ array($modelClass => array('name' => '1.9', )),
+ array($modelClass => array('name' => '1.10', )));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMoveToRootAndMoveUp method
+ *
+ * @return void
+ */
+ public function testMoveToRootAndMoveUp() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(1, 1);
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->save(array($parentField => null));
+
+ $result = $this->Tree->verify();
+ $this->assertSame($result, true);
+
+ $this->Tree->moveUp();
+
+ $result = $this->Tree->find('all', array('fields' => 'name', 'order' => $modelClass . '.' . $leftField . ' ASC'));
+ $expected = array(array($modelClass => array('name' => '1.1')),
+ array($modelClass => array('name' => '1. Root')));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testDelete method
+ *
+ * @return void
+ */
+ public function testDelete() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $initialCount = $this->Tree->find('count');
+ $result = $this->Tree->findByName('1.1.1');
+
+ $return = $this->Tree->delete($result[$modelClass]['id']);
+ $this->assertEquals(true, $return);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount - 1, $laterCount);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+
+ $initialCount = $this->Tree->find('count');
+ $result = $this->Tree->findByName('1.1');
+
+ $return = $this->Tree->delete($result[$modelClass]['id']);
+ $this->assertEquals(true, $return);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount - 2, $laterCount);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * Test deleting a record that doesn't exist.
+ *
+ * @return void
+ */
+ public function testDeleteDoesNotExist() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->delete(99999);
+ }
+
+/**
+ * testRemove method
+ *
+ * @return void
+ */
+ public function testRemove() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $initialCount = $this->Tree->find('count');
+ $result = $this->Tree->findByName('1.1');
+
+ $this->Tree->removeFromTree($result[$modelClass]['id']);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount, $laterCount);
+
+ $children = $this->Tree->children($result[$modelClass][$parentField], true, array('name'));
+ $expects = array(array($modelClass => array('name' => '1.1.1')),
+ array($modelClass => array('name' => '1.1.2')),
+ array($modelClass => array('name' => '1.2')));
+ $this->assertEquals($children, $expects);
+
+ $topNodes = $this->Tree->children(false, true,array('name'));
+ $expects = array(array($modelClass => array('name' => '1. Root')),
+ array($modelClass => array('name' => '1.1')));
+ $this->assertEquals($topNodes, $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testRemoveLastTopParent method
+ *
+ * @return void
+ */
+ public function testRemoveLastTopParent() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $initialCount = $this->Tree->find('count');
+ $initialTopNodes = $this->Tree->childCount(false);
+
+ $result = $this->Tree->findByName('1. Root');
+ $this->Tree->removeFromTree($result[$modelClass]['id']);
+
+ $laterCount = $this->Tree->find('count');
+ $laterTopNodes = $this->Tree->childCount(false);
+
+ $this->assertEquals($initialCount, $laterCount);
+ $this->assertEquals($initialTopNodes, $laterTopNodes);
+
+ $topNodes = $this->Tree->children(false, true,array('name'));
+ $expects = array(array($modelClass => array('name' => '1.1')),
+ array($modelClass => array('name' => '1.2')),
+ array($modelClass => array('name' => '1. Root')));
+
+ $this->assertEquals($topNodes, $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testRemoveNoChildren method
+ *
+ * @return void
+ */
+ public function testRemoveNoChildren() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $initialCount = $this->Tree->find('count');
+
+ $result = $this->Tree->findByName('1.1.1');
+ $this->Tree->removeFromTree($result[$modelClass]['id']);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount, $laterCount);
+
+ $nodes = $this->Tree->find('list', array('order' => $leftField));
+ $expects = array(
+ 1 => '1. Root',
+ 2 => '1.1',
+ 4 => '1.1.2',
+ 5 => '1.2',
+ 6 => '1.2.1',
+ 7 => '1.2.2',
+ 3 => '1.1.1',
+ );
+
+ $this->assertEquals($nodes, $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testRemoveAndDelete method
+ *
+ * @return void
+ */
+ public function testRemoveAndDelete() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $initialCount = $this->Tree->find('count');
+ $result = $this->Tree->findByName('1.1');
+
+ $this->Tree->removeFromTree($result[$modelClass]['id'], true);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount - 1, $laterCount);
+
+ $children = $this->Tree->children($result[$modelClass][$parentField], true, array('name'), $leftField . ' asc');
+ $expects = array(
+ array($modelClass => array('name' => '1.1.1')),
+ array($modelClass => array('name' => '1.1.2')),
+ array($modelClass => array('name' => '1.2'))
+ );
+ $this->assertEquals($children, $expects);
+
+ $topNodes = $this->Tree->children(false, true,array('name'));
+ $expects = array(array($modelClass => array('name' => '1. Root')));
+ $this->assertEquals($topNodes, $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testRemoveAndDeleteNoChildren method
+ *
+ * @return void
+ */
+ public function testRemoveAndDeleteNoChildren() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $initialCount = $this->Tree->find('count');
+
+ $result = $this->Tree->findByName('1.1.1');
+ $this->Tree->removeFromTree($result[$modelClass]['id'], true);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount - 1, $laterCount);
+
+ $nodes = $this->Tree->find('list', array('order' => $leftField));
+ $expects = array(
+ 1 => '1. Root',
+ 2 => '1.1',
+ 4 => '1.1.2',
+ 5 => '1.2',
+ 6 => '1.2.1',
+ 7 => '1.2.2',
+ );
+ $this->assertEquals($nodes, $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testChildren method
+ *
+ * @return void
+ */
+ public function testChildren() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $this->Tree->id = $data[$modelClass]['id'];
+
+ $direct = $this->Tree->children(null, true, array('id', 'name', $parentField, $leftField, $rightField));
+ $expects = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
+ array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)));
+ $this->assertEquals($direct, $expects);
+
+ $total = $this->Tree->children(null, null, array('id', 'name', $parentField, $leftField, $rightField));
+ $expects = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
+ array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 2, $leftField => 3, $rightField => 4)),
+ array($modelClass => array('id' => 4, 'name' => '1.1.2', $parentField => 2, $leftField => 5, $rightField => 6)),
+ array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)),
+ array($modelClass => array('id' => 6, 'name' => '1.2.1', $parentField => 5, $leftField => 9, $rightField => 10)),
+ array($modelClass => array('id' => 7, 'name' => '1.2.2', $parentField => 5, $leftField => 11, $rightField => 12)));
+ $this->assertEquals($total, $expects);
+
+ $this->assertEquals(array(), $this->Tree->children(10000));
+ }
+
+/**
+ * testCountChildren method
+ *
+ * @return void
+ */
+ public function testCountChildren() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $this->Tree->id = $data[$modelClass]['id'];
+
+ $direct = $this->Tree->childCount(null, true);
+ $this->assertEquals(2, $direct);
+
+ $total = $this->Tree->childCount();
+ $this->assertEquals(6, $total);
+
+ $this->Tree->read(null, $data[$modelClass]['id']);
+ $id = $this->Tree->field('id', array($modelClass . '.name' => '1.2'));
+ $total = $this->Tree->childCount($id);
+ $this->assertEquals(2, $total);
+ }
+
+/**
+ * testGetParentNode method
+ *
+ * @return void
+ */
+ public function testGetParentNode() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2.2')));
+ $this->Tree->id = $data[$modelClass]['id'];
+
+ $result = $this->Tree->getParentNode(null, array('name'));
+ $expects = array($modelClass => array('name' => '1.2'));
+ $this->assertSame($expects, $result);
+ }
+
+/**
+ * testGetPath method
+ *
+ * @return void
+ */
+ public function testGetPath() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1.2.2')));
+ $this->Tree->id = $data[$modelClass]['id'];
+
+ $result = $this->Tree->getPath(null, array('name'));
+ $expects = array(array($modelClass => array('name' => '1. Root')),
+ array($modelClass => array('name' => '1.2')),
+ array($modelClass => array('name' => '1.2.2')));
+ $this->assertSame($expects, $result);
+ }
+
+/**
+ * testNoAmbiguousColumn method
+ *
+ * @return void
+ */
+ public function testNoAmbiguousColumn() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
+ array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $this->Tree->id = $data[$modelClass]['id'];
+
+ $direct = $this->Tree->children(null, true, array('id', 'name', $parentField, $leftField, $rightField));
+ $expects = array(array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
+ array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)));
+ $this->assertEquals($direct, $expects);
+
+ $total = $this->Tree->children(null, null, array('id', 'name', $parentField, $leftField, $rightField));
+ $expects = array(
+ array($modelClass => array('id' => 2, 'name' => '1.1', $parentField => 1, $leftField => 2, $rightField => 7)),
+ array($modelClass => array('id' => 3, 'name' => '1.1.1', $parentField => 2, $leftField => 3, $rightField => 4)),
+ array($modelClass => array('id' => 4, 'name' => '1.1.2', $parentField => 2, $leftField => 5, $rightField => 6)),
+ array($modelClass => array('id' => 5, 'name' => '1.2', $parentField => 1, $leftField => 8, $rightField => 13)),
+ array($modelClass => array('id' => 6, 'name' => '1.2.1', $parentField => 5, $leftField => 9, $rightField => 10)),
+ array($modelClass => array('id' => 7, 'name' => '1.2.2', $parentField => 5, $leftField => 11, $rightField => 12))
+ );
+ $this->assertEquals($total, $expects);
+ }
+
+/**
+ * testReorderTree method
+ *
+ * @return void
+ */
+ public function testReorderTree() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(3, 3);
+ $nodes = $this->Tree->find('list', array('order' => $leftField));
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1')));
+ $this->Tree->moveDown($data[$modelClass]['id']);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.2.1')));
+ $this->Tree->moveDown($data[$modelClass]['id']);
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.3.2.2')));
+ $this->Tree->moveDown($data[$modelClass]['id']);
+
+ $unsortedNodes = $this->Tree->find('list', array('order' => $leftField));
+ $this->assertEquals($nodes, $unsortedNodes);
+ $this->assertNotEquals(array_keys($nodes), array_keys($unsortedNodes));
+
+ $this->Tree->reorder();
+ $sortedNodes = $this->Tree->find('list', array('order' => $leftField));
+ $this->assertSame($nodes, $sortedNodes);
+ }
+
+/**
+ * test reordering large-ish trees with cacheQueries = true.
+ * This caused infinite loops when moving down elements as stale data is returned
+ * from the memory cache
+ *
+ * @return void
+ */
+ public function testReorderBigTreeWithQueryCaching() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 10);
+
+ $original = $this->Tree->cacheQueries;
+ $this->Tree->cacheQueries = true;
+ $this->Tree->reorder(array('field' => 'name', 'direction' => 'DESC'));
+ $this->assertTrue($this->Tree->cacheQueries, 'cacheQueries was not restored after reorder(). %s');
+ $this->Tree->cacheQueries = $original;
+ }
+
+/**
+ * testGenerateTreeListWithSelfJoin method
+ *
+ * @return void
+ */
+ public function testGenerateTreeListWithSelfJoin() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
+ array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->generateTreeList();
+ $expected = array(1 => '1. Root', 2 => '_1.1', 3 => '__1.1.1', 4 => '__1.1.2', 5 => '_1.2', 6 => '__1.2.1', 7 => '__1.2.2');
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testArraySyntax method
+ *
+ * @return void
+ */
+ public function testArraySyntax() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(3, 3);
+ $this->assertSame($this->Tree->childCount(2), $this->Tree->childCount(array('id' => 2)));
+ $this->assertSame($this->Tree->getParentNode(2), $this->Tree->getParentNode(array('id' => 2)));
+ $this->assertSame($this->Tree->getPath(4), $this->Tree->getPath(array('id' => 4)));
+ }
+
+/**
+ * testFindThreaded method
+ *
+ * @return void
+ */
+ public function testFindThreaded() {
+ $Model = new Person();
+ $Model->recursive = -1;
+ $Model->Behaviors->attach('Tree', array('parent' => 'mother_id'));
+
+ $result = $Model->find('threaded');
+ $expected = array(
+ array(
+ 'Person' => array(
+ 'id' => '4',
+ 'name' => 'mother - grand mother',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array(
+ array(
+ 'Person' => array(
+ 'id' => '2',
+ 'name' => 'mother',
+ 'mother_id' => '4',
+ 'father_id' => '5'
+ ),
+ 'children' => array(
+ array(
+ 'Person' => array(
+ 'id' => '1',
+ 'name' => 'person',
+ 'mother_id' => '2',
+ 'father_id' => '3'
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'Person' => array(
+ 'id' => '5',
+ 'name' => 'mother - grand father',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'Person' => array(
+ 'id' => '6',
+ 'name' => 'father - grand mother',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array(
+ array(
+ 'Person' => array(
+ 'id' => '3',
+ 'name' => 'father',
+ 'mother_id' => '6',
+ 'father_id' => '7'
+ ),
+ 'children' => array()
+ )
+ )
+ ),
+ array(
+ 'Person' => array(
+ 'id' => '7',
+ 'name' => 'father - grand father',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php
new file mode 100644
index 0000000..b9e8297
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorScopedTest.php
@@ -0,0 +1,316 @@
+<?php
+/**
+ * TreeBehaviorScopedTest file
+ *
+ * A tree test using scope
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5330
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once dirname(dirname(__FILE__)) . DS . 'models.php';
+
+/**
+ * TreeBehaviorScopedTest class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class TreeBehaviorScopedTest extends CakeTestCase {
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ */
+ public $backupGlobals = false;
+
+/**
+ * settings property
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'modelClass' => 'FlagTree',
+ 'leftField' => 'lft',
+ 'rightField' => 'rght',
+ 'parentField' => 'parent_id'
+ );
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.flag_tree', 'core.ad', 'core.campaign', 'core.translate', 'core.number_tree_two');
+
+/**
+ * testStringScope method
+ *
+ * @return void
+ */
+ public function testStringScope() {
+ $this->Tree = new FlagTree();
+ $this->Tree->initialize(2, 3);
+
+ $this->Tree->id = 1;
+ $this->Tree->saveField('flag', 1);
+ $this->Tree->id = 2;
+ $this->Tree->saveField('flag', 1);
+
+ $result = $this->Tree->children();
+ $expected = array(
+ array('FlagTree' => array('id' => '3', 'name' => '1.1.1', 'parent_id' => '2', 'lft' => '3', 'rght' => '4', 'flag' => '0')),
+ array('FlagTree' => array('id' => '4', 'name' => '1.1.2', 'parent_id' => '2', 'lft' => '5', 'rght' => '6', 'flag' => '0')),
+ array('FlagTree' => array('id' => '5', 'name' => '1.1.3', 'parent_id' => '2', 'lft' => '7', 'rght' => '8', 'flag' => '0'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Tree->Behaviors->attach('Tree', array('scope' => 'FlagTree.flag = 1'));
+ $this->assertEquals(array(), $this->Tree->children());
+
+ $this->Tree->id = 1;
+ $this->Tree->Behaviors->attach('Tree', array('scope' => 'FlagTree.flag = 1'));
+
+ $result = $this->Tree->children();
+ $expected = array(array('FlagTree' => array('id' => '2', 'name' => '1.1', 'parent_id' => '1', 'lft' => '2', 'rght' => '9', 'flag' => '1')));
+ $this->assertEquals($expected, $result);
+
+ $this->assertTrue($this->Tree->delete());
+ $this->assertEquals(11, $this->Tree->find('count'));
+ }
+
+/**
+ * testArrayScope method
+ *
+ * @return void
+ */
+ public function testArrayScope() {
+ $this->Tree = new FlagTree();
+ $this->Tree->initialize(2, 3);
+
+ $this->Tree->id = 1;
+ $this->Tree->saveField('flag', 1);
+ $this->Tree->id = 2;
+ $this->Tree->saveField('flag', 1);
+
+ $result = $this->Tree->children();
+ $expected = array(
+ array('FlagTree' => array('id' => '3', 'name' => '1.1.1', 'parent_id' => '2', 'lft' => '3', 'rght' => '4', 'flag' => '0')),
+ array('FlagTree' => array('id' => '4', 'name' => '1.1.2', 'parent_id' => '2', 'lft' => '5', 'rght' => '6', 'flag' => '0')),
+ array('FlagTree' => array('id' => '5', 'name' => '1.1.3', 'parent_id' => '2', 'lft' => '7', 'rght' => '8', 'flag' => '0'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Tree->Behaviors->attach('Tree', array('scope' => array('FlagTree.flag' => 1)));
+ $this->assertEquals(array(), $this->Tree->children());
+
+ $this->Tree->id = 1;
+ $this->Tree->Behaviors->attach('Tree', array('scope' => array('FlagTree.flag' => 1)));
+
+ $result = $this->Tree->children();
+ $expected = array(array('FlagTree' => array('id' => '2', 'name' => '1.1', 'parent_id' => '1', 'lft' => '2', 'rght' => '9', 'flag' => '1')));
+ $this->assertEquals($expected, $result);
+
+ $this->assertTrue($this->Tree->delete());
+ $this->assertEquals(11, $this->Tree->find('count'));
+ }
+
+/**
+ * testMoveUpWithScope method
+ *
+ * @return void
+ */
+ public function testMoveUpWithScope() {
+ $this->Ad = new Ad();
+ $this->Ad->Behaviors->attach('Tree', array('scope' => 'Campaign'));
+ $this->Ad->moveUp(6);
+
+ $this->Ad->id = 4;
+ $result = $this->Ad->children();
+ $this->assertEquals(array(6, 5), Hash::extract($result, '{n}.Ad.id'));
+ $this->assertEquals(array(2, 2), Hash::extract($result, '{n}.Campaign.id'));
+ }
+
+/**
+ * testMoveDownWithScope method
+ *
+ * @return void
+ */
+ public function testMoveDownWithScope() {
+ $this->Ad = new Ad();
+ $this->Ad->Behaviors->attach('Tree', array('scope' => 'Campaign'));
+ $this->Ad->moveDown(6);
+
+ $this->Ad->id = 4;
+ $result = $this->Ad->children();
+ $this->assertEquals(array(5, 6), Hash::extract($result, '{n}.Ad.id'));
+ $this->assertEquals(array(2, 2), Hash::extract($result, '{n}.Campaign.id'));
+ }
+
+/**
+ * Tests the interaction (non-interference) between TreeBehavior and other behaviors with respect
+ * to callback hooks
+ *
+ * @return void
+ */
+ public function testTranslatingTree() {
+ $this->Tree = new FlagTree();
+ $this->Tree->cacheQueries = false;
+ $this->Tree->Behaviors->attach('Translate', array('name'));
+
+ //Save
+ $this->Tree->locale = 'eng';
+ $data = array('FlagTree' => array(
+ 'name' => 'name #1',
+ 'locale' => 'eng',
+ 'parent_id' => null,
+ ));
+ $this->Tree->save($data);
+ $result = $this->Tree->find('all');
+ $expected = array(array('FlagTree' => array(
+ 'id' => 1,
+ 'name' => 'name #1',
+ 'parent_id' => null,
+ 'lft' => 1,
+ 'rght' => 2,
+ 'flag' => 0,
+ 'locale' => 'eng',
+ )));
+ $this->assertEquals($expected, $result);
+
+ //update existing record, same locale
+ $this->Tree->create();
+ $data['FlagTree']['name'] = 'Named 2';
+ $this->Tree->id = 1;
+ $this->Tree->save($data);
+ $result = $this->Tree->find('all');
+ $expected = array(array('FlagTree' => array(
+ 'id' => 1,
+ 'name' => 'Named 2',
+ 'parent_id' => null,
+ 'lft' => 1,
+ 'rght' => 2,
+ 'flag' => 0,
+ 'locale' => 'eng',
+ )));
+ $this->assertEquals($expected, $result);
+
+ //update different locale, same record
+ $this->Tree->create();
+ $this->Tree->locale = 'deu';
+ $this->Tree->id = 1;
+ $data = array('FlagTree' => array(
+ 'id' => 1,
+ 'parent_id' => null,
+ 'name' => 'namen #1',
+ 'locale' => 'deu',
+ ));
+ $this->Tree->save($data);
+
+ $this->Tree->locale = 'deu';
+ $result = $this->Tree->find('all');
+ $expected = array(array('FlagTree' => array(
+ 'id' => 1,
+ 'name' => 'namen #1',
+ 'parent_id' => null,
+ 'lft' => 1,
+ 'rght' => 2,
+ 'flag' => 0,
+ 'locale' => 'deu',
+ )));
+ $this->assertEquals($expected, $result);
+
+ //Save with bindTranslation
+ $this->Tree->locale = 'eng';
+ $data = array(
+ 'name' => array('eng' => 'New title', 'spa' => 'Nuevo leyenda'),
+ 'parent_id' => null
+ );
+ $this->Tree->create($data);
+ $this->Tree->save();
+
+ $this->Tree->unbindTranslation();
+ $translations = array('name' => 'Name');
+ $this->Tree->bindTranslation($translations, false);
+ $this->Tree->locale = array('eng', 'spa');
+
+ $result = $this->Tree->read();
+ $expected = array(
+ 'FlagTree' => array('id' => 2, 'parent_id' => null, 'locale' => 'eng', 'name' => 'New title', 'flag' => 0, 'lft' => 3, 'rght' => 4),
+ 'Name' => array(
+ array('id' => 21, 'locale' => 'eng', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'name', 'content' => 'New title'),
+ array('id' => 22, 'locale' => 'spa', 'model' => 'FlagTree', 'foreign_key' => 2, 'field' => 'name', 'content' => 'Nuevo leyenda')
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testGenerateTreeListWithSelfJoin method
+ *
+ * @return void
+ */
+ public function testAliasesWithScopeInTwoTreeAssociations() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $this->TreeTwo = new NumberTreeTwo();
+
+ $record = $this->Tree->find('first');
+
+ $this->Tree->bindModel(array(
+ 'hasMany' => array(
+ 'SecondTree' => array(
+ 'className' => 'NumberTreeTwo',
+ 'foreignKey' => 'number_tree_id'
+ )
+ )
+ ));
+ $this->TreeTwo->bindModel(array(
+ 'belongsTo' => array(
+ 'FirstTree' => array(
+ 'className' => $modelClass,
+ 'foreignKey' => 'number_tree_id'
+ )
+ )
+ ));
+ $this->TreeTwo->Behaviors->attach('Tree', array(
+ 'scope' => 'FirstTree'
+ ));
+
+ $data = array(
+ 'NumberTreeTwo' => array(
+ 'name' => 'First',
+ 'number_tree_id' => $record['FlagTree']['id']
+ )
+ );
+ $this->TreeTwo->create();
+ $result = $this->TreeTwo->save($data);
+ $this->assertFalse(empty($result));
+
+ $result = $this->TreeTwo->find('first');
+ $expected = array('NumberTreeTwo' => array(
+ 'id' => 1,
+ 'name' => 'First',
+ 'number_tree_id' => $record['FlagTree']['id'],
+ 'parent_id' => null,
+ 'lft' => 1,
+ 'rght' => 2
+ ));
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorTest.php
new file mode 100644
index 0000000..4b55e7e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Tree Behavior test file - runs all the tree behavior tests
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Tree Behavior test
+ *
+ * A test group to run all the component parts
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class TreeBehaviorTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new CakeTestSuite('TreeBehavior tests');
+
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'Behavior' . DS . 'TreeBehaviorNumberTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'Behavior' . DS . 'TreeBehaviorScopedTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'Behavior' . DS . 'TreeBehaviorAfterTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'Behavior' . DS . 'TreeBehaviorUuidTest.php');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php
new file mode 100644
index 0000000..a69445e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php
@@ -0,0 +1,255 @@
+<?php
+/**
+ * TreeBehaviorUuidTest file
+ *
+ * Tree test using UUIDs
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5330
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once dirname(dirname(__FILE__)) . DS . 'models.php';
+
+/**
+ * TreeBehaviorUuidTest class
+ *
+ * @package Cake.Test.Case.Model.Behavior
+ */
+class TreeBehaviorUuidTest extends CakeTestCase {
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ */
+ public $backupGlobals = false;
+
+/**
+ * settings property
+ *
+ * @var array
+ */
+ public $settings = array(
+ 'modelClass' => 'UuidTree',
+ 'leftField' => 'lft',
+ 'rightField' => 'rght',
+ 'parentField' => 'parent_id'
+ );
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.uuid_tree');
+
+/**
+ * testMovePromote method
+ *
+ * @return void
+ */
+ public function testMovePromote() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $parentId = $parent[$modelClass]['id'];
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->saveField($parentField, $parentId);
+ $direct = $this->Tree->children($parentId, true, array('name', $leftField, $rightField));
+ $expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 5)),
+ array($modelClass => array('name' => '1.2', $leftField => 6, $rightField => 11)),
+ array($modelClass => array('name' => '1.1.1', $leftField => 12, $rightField => 13)));
+ $this->assertEquals($direct, $expects);
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testMoveWithWhitelist method
+ *
+ * @return void
+ */
+ public function testMoveWithWhitelist() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $this->Tree->id = null;
+
+ $parent = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $parentId = $parent[$modelClass]['id'];
+
+ $data = $this->Tree->find('first', array('fields' => array('id'), 'conditions' => array($modelClass . '.name' => '1.1.1')));
+ $this->Tree->id = $data[$modelClass]['id'];
+ $this->Tree->whitelist = array($parentField, 'name', 'description');
+ $this->Tree->saveField($parentField, $parentId);
+
+ $result = $this->Tree->children($parentId, true, array('name', $leftField, $rightField));
+ $expected = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 5)),
+ array($modelClass => array('name' => '1.2', $leftField => 6, $rightField => 11)),
+ array($modelClass => array('name' => '1.1.1', $leftField => 12, $rightField => 13)));
+ $this->assertEquals($expected, $result);
+ $this->assertTrue($this->Tree->verify());
+ }
+
+/**
+ * testRemoveNoChildren method
+ *
+ * @return void
+ */
+ public function testRemoveNoChildren() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $initialCount = $this->Tree->find('count');
+
+ $result = $this->Tree->findByName('1.1.1');
+ $this->Tree->removeFromTree($result[$modelClass]['id']);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount, $laterCount);
+
+ $nodes = $this->Tree->find('list', array('order' => $leftField));
+ $expects = array(
+ '1. Root',
+ '1.1',
+ '1.1.2',
+ '1.2',
+ '1.2.1',
+ '1.2.2',
+ '1.1.1',
+ );
+
+ $this->assertEquals(array_values($nodes), $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testRemoveAndDeleteNoChildren method
+ *
+ * @return void
+ */
+ public function testRemoveAndDeleteNoChildren() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+ $initialCount = $this->Tree->find('count');
+
+ $result = $this->Tree->findByName('1.1.1');
+ $this->Tree->removeFromTree($result[$modelClass]['id'], true);
+
+ $laterCount = $this->Tree->find('count');
+ $this->assertEquals($initialCount - 1, $laterCount);
+
+ $nodes = $this->Tree->find('list', array('order' => $leftField));
+ $expects = array(
+ '1. Root',
+ '1.1',
+ '1.1.2',
+ '1.2',
+ '1.2.1',
+ '1.2.2',
+ );
+ $this->assertEquals(array_values($nodes), $expects);
+
+ $validTree = $this->Tree->verify();
+ $this->assertSame($validTree, true);
+ }
+
+/**
+ * testChildren method
+ *
+ * @return void
+ */
+ public function testChildren() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $this->Tree->id = $data[$modelClass]['id'];
+
+ $direct = $this->Tree->children(null, true, array('name', $leftField, $rightField));
+ $expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+ array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)));
+ $this->assertEquals($direct, $expects);
+
+ $total = $this->Tree->children(null, null, array('name', $leftField, $rightField));
+ $expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+ array($modelClass => array('name' => '1.1.1', $leftField => 3, $rightField => 4)),
+ array($modelClass => array('name' => '1.1.2', $leftField => 5, $rightField => 6)),
+ array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)),
+ array($modelClass => array('name' => '1.2.1', $leftField => 9, $rightField => 10)),
+ array($modelClass => array('name' => '1.2.2', $leftField => 11, $rightField => 12)));
+ $this->assertEquals($total, $expects);
+ }
+
+/**
+ * testNoAmbiguousColumn method
+ *
+ * @return void
+ */
+ public function testNoAmbiguousColumn() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->initialize(2, 2);
+
+ $this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
+ array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
+
+ $data = $this->Tree->find('first', array('conditions' => array($modelClass . '.name' => '1. Root')));
+ $this->Tree->id = $data[$modelClass]['id'];
+
+ $direct = $this->Tree->children(null, true, array('name', $leftField, $rightField));
+ $expects = array(array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+ array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)));
+ $this->assertEquals($direct, $expects);
+
+ $total = $this->Tree->children(null, null, array('name', $leftField, $rightField));
+ $expects = array(
+ array($modelClass => array('name' => '1.1', $leftField => 2, $rightField => 7)),
+ array($modelClass => array('name' => '1.1.1', $leftField => 3, $rightField => 4)),
+ array($modelClass => array('name' => '1.1.2', $leftField => 5, $rightField => 6)),
+ array($modelClass => array('name' => '1.2', $leftField => 8, $rightField => 13)),
+ array($modelClass => array('name' => '1.2.1', $leftField => 9, $rightField => 10)),
+ array($modelClass => array('name' => '1.2.2', $leftField => 11, $rightField => 12))
+ );
+ $this->assertEquals($total, $expects);
+ }
+
+/**
+ * testGenerateTreeListWithSelfJoin method
+ *
+ * @return void
+ */
+ public function testGenerateTreeListWithSelfJoin() {
+ extract($this->settings);
+ $this->Tree = new $modelClass();
+ $this->Tree->bindModel(array('belongsTo' => array('Dummy' =>
+ array('className' => $modelClass, 'foreignKey' => $parentField, 'conditions' => array('Dummy.id' => null)))), false);
+ $this->Tree->initialize(2, 2);
+
+ $result = $this->Tree->generateTreeList();
+ $expected = array('1. Root', '_1.1', '__1.1.1', '__1.1.2', '_1.2', '__1.2.1', '__1.2.2');
+ $this->assertSame(array_values($result), $expected);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php
new file mode 100644
index 0000000..b2b26b7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/BehaviorCollectionTest.php
@@ -0,0 +1,1185 @@
+<?php
+/**
+ * BehaviorTest file
+ *
+ * Long description for behavior.test.php
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model
+ * @since 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppModel', 'Model');
+require_once dirname(__FILE__) . DS . 'models.php';
+
+/**
+ * TestBehavior class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestBehavior extends ModelBehavior {
+
+/**
+ * mapMethods property
+ *
+ * @var array
+ */
+ public $mapMethods = array('/test(\w+)/' => 'testMethod', '/look for\s+(.+)/' => 'speakEnglish');
+
+/**
+ * setup method
+ *
+ * @param Model $model
+ * @param array $config
+ * @return void
+ */
+ public function setup(Model $model, $config = array()) {
+ parent::setup($model, $config);
+ if (isset($config['mangle'])) {
+ $config['mangle'] .= ' mangled';
+ }
+ $this->settings[$model->alias] = array_merge(array('beforeFind' => 'on', 'afterFind' => 'off'), $config);
+ }
+
+/**
+ * beforeFind method
+ *
+ * @param Model $model
+ * @param array $query
+ * @return void
+ */
+ public function beforeFind(Model $model, $query) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['beforeFind']) || $settings['beforeFind'] == 'off') {
+ return parent::beforeFind($model, $query);
+ }
+ switch ($settings['beforeFind']) {
+ case 'on':
+ return false;
+ break;
+ case 'test':
+ return null;
+ break;
+ case 'modify':
+ $query['fields'] = array($model->alias . '.id', $model->alias . '.name', $model->alias . '.mytime');
+ $query['recursive'] = -1;
+ return $query;
+ break;
+ }
+ }
+
+/**
+ * afterFind method
+ *
+ * @param Model $model
+ * @param array $results
+ * @param boolean $primary
+ * @return void
+ */
+ public function afterFind(Model $model, $results, $primary) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['afterFind']) || $settings['afterFind'] == 'off') {
+ return parent::afterFind($model, $results, $primary);
+ }
+ switch ($settings['afterFind']) {
+ case 'on':
+ return array();
+ break;
+ case 'test':
+ return true;
+ break;
+ case 'test2':
+ return null;
+ break;
+ case 'modify':
+ return Hash::extract($results, "{n}.{$model->alias}");
+ break;
+ }
+ }
+
+/**
+ * beforeSave method
+ *
+ * @param Model $model
+ * @return void
+ */
+ public function beforeSave(Model $model) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['beforeSave']) || $settings['beforeSave'] == 'off') {
+ return parent::beforeSave($model);
+ }
+ switch ($settings['beforeSave']) {
+ case 'on':
+ return false;
+ break;
+ case 'test':
+ return true;
+ break;
+ case 'modify':
+ $model->data[$model->alias]['name'] .= ' modified before';
+ return true;
+ break;
+ }
+ }
+
+/**
+ * afterSave method
+ *
+ * @param Model $model
+ * @param boolean $created
+ * @return void
+ */
+ public function afterSave(Model $model, $created) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['afterSave']) || $settings['afterSave'] == 'off') {
+ return parent::afterSave($model, $created);
+ }
+ $string = 'modified after';
+ if ($created) {
+ $string .= ' on create';
+ }
+ switch ($settings['afterSave']) {
+ case 'on':
+ $model->data[$model->alias]['aftersave'] = $string;
+ break;
+ case 'test':
+ unset($model->data[$model->alias]['name']);
+ break;
+ case 'test2':
+ return false;
+ break;
+ case 'modify':
+ $model->data[$model->alias]['name'] .= ' ' . $string;
+ break;
+ }
+ }
+
+/**
+ * beforeValidate method
+ *
+ * @param Model $model
+ * @return void
+ */
+ public function beforeValidate(Model $model) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['validate']) || $settings['validate'] == 'off') {
+ return parent::beforeValidate($model);
+ }
+ switch ($settings['validate']) {
+ case 'on':
+ $model->invalidate('name');
+ return true;
+ break;
+ case 'test':
+ return null;
+ break;
+ case 'whitelist':
+ $this->_addToWhitelist($model, array('name'));
+ return true;
+ break;
+ case 'stop':
+ $model->invalidate('name');
+ return false;
+ break;
+ }
+ }
+
+/**
+ * afterValidate method
+ *
+ * @param Model $model
+ * @param bool $cascade
+ * @return void
+ */
+ public function afterValidate(Model $model) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['afterValidate']) || $settings['afterValidate'] == 'off') {
+ return parent::afterValidate($model);
+ }
+ switch ($settings['afterValidate']) {
+ case 'on':
+ return false;
+ break;
+ case 'test':
+ $model->data = array('foo');
+ return true;
+ break;
+ }
+ }
+
+/**
+ * beforeDelete method
+ *
+ * @param Model $model
+ * @param bool $cascade
+ * @return void
+ */
+ public function beforeDelete(Model $model, $cascade = true) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['beforeDelete']) || $settings['beforeDelete'] == 'off') {
+ return parent::beforeDelete($model, $cascade);
+ }
+ switch ($settings['beforeDelete']) {
+ case 'on':
+ return false;
+ break;
+ case 'test':
+ return null;
+ break;
+ case 'test2':
+ echo 'beforeDelete success';
+ if ($cascade) {
+ echo ' (cascading) ';
+ }
+ return true;
+ break;
+ }
+ }
+
+/**
+ * afterDelete method
+ *
+ * @param Model $model
+ * @return void
+ */
+ public function afterDelete(Model $model) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['afterDelete']) || $settings['afterDelete'] == 'off') {
+ return parent::afterDelete($model);
+ }
+ switch ($settings['afterDelete']) {
+ case 'on':
+ echo 'afterDelete success';
+ break;
+ }
+ }
+
+/**
+ * onError method
+ *
+ * @param Model $model
+ * @return void
+ */
+ public function onError(Model $model, $error) {
+ $settings = $this->settings[$model->alias];
+ if (!isset($settings['onError']) || $settings['onError'] == 'off') {
+ return parent::onError($model, $error);
+ }
+ echo "onError trigger success";
+ }
+
+/**
+ * beforeTest method
+ *
+ * @param Model $model
+ * @return void
+ */
+ public function beforeTest(Model $model) {
+ if (!isset($model->beforeTestResult)) {
+ $model->beforeTestResult = array();
+ }
+ $model->beforeTestResult[] = strtolower(get_class($this));
+ return strtolower(get_class($this));
+ }
+
+/**
+ * testMethod method
+ *
+ * @param Model $model
+ * @param bool $param
+ * @return void
+ */
+ public function testMethod(Model $model, $param = true) {
+ if ($param === true) {
+ return 'working';
+ }
+ }
+
+/**
+ * testData method
+ *
+ * @param Model $model
+ * @return void
+ */
+ public function testData(Model $model) {
+ if (!isset($model->data['Apple']['field'])) {
+ return false;
+ }
+ $model->data['Apple']['field_2'] = true;
+ return true;
+ }
+
+/**
+ * validateField method
+ *
+ * @param Model $model
+ * @param string|array $field
+ * @return void
+ */
+ public function validateField(Model $model, $field) {
+ return current($field) === 'Orange';
+ }
+
+/**
+ * speakEnglish method
+ *
+ * @param Model $model
+ * @param string $method
+ * @param string $query
+ * @return void
+ */
+ public function speakEnglish(Model $model, $method, $query) {
+ $method = preg_replace('/look for\s+/', 'Item.name = \'', $method);
+ $query = preg_replace('/^in\s+/', 'Location.name = \'', $query);
+ return $method . '\' AND ' . $query . '\'';
+ }
+
+}
+
+/**
+ * Test2Behavior class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Test2Behavior extends TestBehavior {
+
+ public $mapMethods = array('/mappingRobot(\w+)/' => 'mapped');
+
+ public function resolveMethod(Model $model, $stuff) {
+ }
+
+ public function mapped(Model $model, $method, $query) {
+ }
+
+}
+
+/**
+ * Test3Behavior class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Test3Behavior extends TestBehavior{
+}
+
+/**
+ * Test4Behavior class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Test4Behavior extends ModelBehavior{
+
+ public function setup(Model $model, $config = null) {
+ $model->bindModel(
+ array('hasMany' => array('Comment'))
+ );
+ }
+
+}
+
+/**
+ * Test5Behavior class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Test5Behavior extends ModelBehavior{
+
+ public function setup(Model $model, $config = null) {
+ $model->bindModel(
+ array('belongsTo' => array('User'))
+ );
+ }
+
+}
+
+/**
+ * Test6Behavior class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Test6Behavior extends ModelBehavior{
+
+ public function setup(Model $model, $config = null) {
+ $model->bindModel(
+ array('hasAndBelongsToMany' => array('Tag'))
+ );
+ }
+
+}
+
+/**
+ * Test7Behavior class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Test7Behavior extends ModelBehavior{
+
+ public function setup(Model $model, $config = null) {
+ $model->bindModel(
+ array('hasOne' => array('Attachment'))
+ );
+ }
+
+}
+
+/**
+ * Extended TestBehavior
+ */
+class TestAliasBehavior extends TestBehavior {
+}
+
+/**
+ * BehaviorCollection class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class BehaviorCollectionTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.apple', 'core.sample', 'core.article', 'core.user', 'core.comment',
+ 'core.attachment', 'core.tag', 'core.articles_tag', 'core.translate'
+ );
+
+/**
+ * Test load() with enabled => false
+ *
+ */
+ public function testLoadDisabled() {
+ $Apple = new Apple();
+ $this->assertSame(array(), $Apple->Behaviors->attached());
+
+ $Apple->Behaviors->load('Translate', array('enabled' => false));
+ $this->assertTrue($Apple->Behaviors->attached('Translate'));
+ $this->assertFalse($Apple->Behaviors->enabled('Translate'));
+ }
+
+/**
+ * Tests loading aliased behaviors
+ */
+ public function testLoadAlias() {
+ $Apple = new Apple();
+ $this->assertSame(array(), $Apple->Behaviors->attached());
+
+ $Apple->Behaviors->load('Test', array('className' => 'TestAlias', 'somesetting' => true));
+ $this->assertSame(array('Test'), $Apple->Behaviors->attached());
+ $this->assertInstanceOf('TestAliasBehavior', $Apple->Behaviors->Test);
+ $this->assertTrue($Apple->Behaviors->Test->settings['Apple']['somesetting']);
+
+ $this->assertEquals('working', $Apple->Behaviors->Test->testMethod($Apple, true));
+ $this->assertEquals('working', $Apple->testMethod(true));
+ $this->assertEquals('working', $Apple->Behaviors->dispatchMethod($Apple, 'testMethod'));
+
+ App::build(array('Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
+ CakePlugin::load('TestPlugin');
+ $this->assertTrue($Apple->Behaviors->load('SomeOther', array('className' => 'TestPlugin.TestPluginPersisterOne')));
+ $this->assertInstanceOf('TestPluginPersisterOneBehavior', $Apple->Behaviors->SomeOther);
+
+ $result = $Apple->Behaviors->attached();
+ $this->assertEquals(array('Test', 'SomeOther'), $result, 'attached() results are wrong.');
+ App::build();
+ CakePlugin::unload();
+ }
+
+/**
+ * testBehaviorBinding method
+ *
+ * @return void
+ */
+ public function testBehaviorBinding() {
+ $Apple = new Apple();
+ $this->assertSame(array(), $Apple->Behaviors->attached());
+
+ $Apple->Behaviors->attach('Test', array('key' => 'value'));
+ $this->assertSame(array('Test'), $Apple->Behaviors->attached());
+ $this->assertEquals('testbehavior', strtolower(get_class($Apple->Behaviors->Test)));
+ $expected = array('beforeFind' => 'on', 'afterFind' => 'off', 'key' => 'value');
+ $this->assertEquals($expected, $Apple->Behaviors->Test->settings['Apple']);
+ $this->assertEquals(array('Apple'), array_keys($Apple->Behaviors->Test->settings));
+
+ $this->assertSame($Apple->Sample->Behaviors->attached(), array());
+ $Apple->Sample->Behaviors->attach('Test', array('key2' => 'value2'));
+ $this->assertSame($Apple->Sample->Behaviors->attached(), array('Test'));
+ $this->assertEquals(array('beforeFind' => 'on', 'afterFind' => 'off', 'key2' => 'value2'), $Apple->Sample->Behaviors->Test->settings['Sample']);
+
+ $this->assertEquals(array('Apple', 'Sample'), array_keys($Apple->Behaviors->Test->settings));
+ $this->assertSame(
+ $Apple->Sample->Behaviors->Test->settings,
+ $Apple->Behaviors->Test->settings
+ );
+ $this->assertNotSame($Apple->Behaviors->Test->settings['Apple'], $Apple->Sample->Behaviors->Test->settings['Sample']);
+
+ $Apple->Behaviors->attach('Test', array('key2' => 'value2', 'key3' => 'value3', 'beforeFind' => 'off'));
+ $Apple->Sample->Behaviors->attach('Test', array('key' => 'value', 'key3' => 'value3', 'beforeFind' => 'off'));
+ $this->assertEquals(array('beforeFind' => 'off', 'afterFind' => 'off', 'key' => 'value', 'key2' => 'value2', 'key3' => 'value3'), $Apple->Behaviors->Test->settings['Apple']);
+ $this->assertEquals($Apple->Behaviors->Test->settings['Apple'], $Apple->Sample->Behaviors->Test->settings['Sample']);
+
+ $this->assertFalse(isset($Apple->Child->Behaviors->Test));
+ $Apple->Child->Behaviors->attach('Test', array('key' => 'value', 'key2' => 'value2', 'key3' => 'value3', 'beforeFind' => 'off'));
+ $this->assertEquals($Apple->Child->Behaviors->Test->settings['Child'], $Apple->Sample->Behaviors->Test->settings['Sample']);
+
+ $this->assertFalse(isset($Apple->Parent->Behaviors->Test));
+ $Apple->Parent->Behaviors->attach('Test', array('key' => 'value', 'key2' => 'value2', 'key3' => 'value3', 'beforeFind' => 'off'));
+ $this->assertEquals($Apple->Parent->Behaviors->Test->settings['Parent'], $Apple->Sample->Behaviors->Test->settings['Sample']);
+
+ $Apple->Parent->Behaviors->attach('Test', array('key' => 'value', 'key2' => 'value', 'key3' => 'value', 'beforeFind' => 'off'));
+ $this->assertNotEquals($Apple->Parent->Behaviors->Test->settings['Parent'], $Apple->Sample->Behaviors->Test->settings['Sample']);
+
+ $Apple->Behaviors->attach('Plugin.Test', array('key' => 'new value'));
+ $expected = array(
+ 'beforeFind' => 'off', 'afterFind' => 'off', 'key' => 'new value',
+ 'key2' => 'value2', 'key3' => 'value3'
+ );
+ $this->assertEquals($expected, $Apple->Behaviors->Test->settings['Apple']);
+
+ $current = $Apple->Behaviors->Test->settings['Apple'];
+ $expected = array_merge($current, array('mangle' => 'trigger mangled'));
+ $Apple->Behaviors->attach('Test', array('mangle' => 'trigger'));
+ $this->assertEquals($expected, $Apple->Behaviors->Test->settings['Apple']);
+
+ $Apple->Behaviors->attach('Test');
+ $expected = array_merge($current, array('mangle' => 'trigger mangled mangled'));
+
+ $this->assertEquals($expected, $Apple->Behaviors->Test->settings['Apple']);
+ $Apple->Behaviors->attach('Test', array('mangle' => 'trigger'));
+ $expected = array_merge($current, array('mangle' => 'trigger mangled'));
+ $this->assertEquals($expected, $Apple->Behaviors->Test->settings['Apple']);
+ }
+
+/**
+ * test that attach()/detach() works with plugin.banana
+ *
+ * @return void
+ */
+ public function testDetachWithPluginNames() {
+ $Apple = new Apple();
+ $Apple->Behaviors->attach('Plugin.Test');
+ $this->assertTrue(isset($Apple->Behaviors->Test), 'Missing behavior');
+ $this->assertEquals(array('Test'), $Apple->Behaviors->attached());
+
+ $Apple->Behaviors->detach('Plugin.Test');
+ $this->assertEquals(array(), $Apple->Behaviors->attached());
+
+ $Apple->Behaviors->attach('Plugin.Test');
+ $this->assertTrue(isset($Apple->Behaviors->Test), 'Missing behavior');
+ $this->assertEquals(array('Test'), $Apple->Behaviors->attached());
+
+ $Apple->Behaviors->detach('Test');
+ $this->assertEquals(array(), $Apple->Behaviors->attached());
+ }
+
+/**
+ * test that attaching a non existent Behavior triggers a cake error.
+ *
+ * @expectedException MissingBehaviorException
+ * @return void
+ */
+ public function testInvalidBehaviorCausingCakeError() {
+ $Apple = new Apple();
+ $Apple->Behaviors->attach('NoSuchBehavior');
+ }
+
+/**
+ * testBehaviorToggling method
+ *
+ * @return void
+ */
+ public function testBehaviorToggling() {
+ $Apple = new Apple();
+ $expected = $Apple->find('all');
+ $this->assertSame($Apple->Behaviors->enabled(), array());
+
+ $Apple->Behaviors->init('Apple', array('Test' => array('key' => 'value')));
+ $this->assertSame($Apple->Behaviors->enabled(), array('Test'));
+
+ $Apple->Behaviors->disable('Test');
+ $this->assertSame(array('Test'), $Apple->Behaviors->attached());
+ $this->assertSame($Apple->Behaviors->enabled(), array());
+
+ $Apple->Sample->Behaviors->attach('Test');
+ $this->assertSame($Apple->Sample->Behaviors->enabled('Test'), true);
+ $this->assertSame($Apple->Behaviors->enabled(), array());
+
+ $Apple->Behaviors->enable('Test');
+ $this->assertSame($Apple->Behaviors->attached('Test'), true);
+ $this->assertSame($Apple->Behaviors->enabled(), array('Test'));
+
+ $Apple->Behaviors->disable('Test');
+ $this->assertSame($Apple->Behaviors->enabled(), array());
+ $Apple->Behaviors->attach('Test', array('enabled' => true));
+ $this->assertSame($Apple->Behaviors->enabled(), array('Test'));
+ $Apple->Behaviors->attach('Test', array('enabled' => false));
+ $this->assertSame($Apple->Behaviors->enabled(), array());
+ $Apple->Behaviors->detach('Test');
+ $this->assertSame($Apple->Behaviors->enabled(), array());
+ }
+
+/**
+ * testBehaviorFindCallbacks method
+ *
+ * @return void
+ */
+ public function testBehaviorFindCallbacks() {
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $Apple = new Apple();
+ $expected = $Apple->find('all');
+
+ $Apple->Behaviors->attach('Test');
+ $this->assertSame($Apple->find('all'), null);
+
+ $Apple->Behaviors->attach('Test', array('beforeFind' => 'off'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $Apple->Behaviors->attach('Test', array('beforeFind' => 'test'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $Apple->Behaviors->attach('Test', array('beforeFind' => 'modify'));
+ $expected2 = array(
+ array('Apple' => array('id' => '1', 'name' => 'Red Apple 1', 'mytime' => '22:57:17')),
+ array('Apple' => array('id' => '2', 'name' => 'Bright Red Apple', 'mytime' => '22:57:17')),
+ array('Apple' => array('id' => '3', 'name' => 'green blue', 'mytime' => '22:57:17'))
+ );
+ $result = $Apple->find('all', array('conditions' => array('Apple.id <' => '4')));
+ $this->assertEquals($expected2, $result);
+
+ $Apple->Behaviors->disable('Test');
+ $result = $Apple->find('all');
+ $this->assertEquals($expected, $result);
+
+ $Apple->Behaviors->attach('Test', array('beforeFind' => 'off', 'afterFind' => 'on'));
+ $this->assertSame($Apple->find('all'), array());
+
+ $Apple->Behaviors->attach('Test', array('afterFind' => 'off'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Behaviors->attach('Test', array('afterFind' => 'test'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Behaviors->attach('Test', array('afterFind' => 'test2'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Behaviors->attach('Test', array('afterFind' => 'modify'));
+ $expected = array(
+ array('id' => '1', 'apple_id' => '2', 'color' => 'Red 1', 'name' => 'Red Apple 1', 'created' => '2006-11-22 10:38:58', 'date' => '1951-01-04', 'modified' => '2006-12-01 13:31:26', 'mytime' => '22:57:17'),
+ array('id' => '2', 'apple_id' => '1', 'color' => 'Bright Red 1', 'name' => 'Bright Red Apple', 'created' => '2006-11-22 10:43:13', 'date' => '2014-01-01', 'modified' => '2006-11-30 18:38:10', 'mytime' => '22:57:17'),
+ array('id' => '3', 'apple_id' => '2', 'color' => 'blue green', 'name' => 'green blue', 'created' => '2006-12-25 05:13:36', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:24', 'mytime' => '22:57:17'),
+ array('id' => '4', 'apple_id' => '2', 'color' => 'Blue Green', 'name' => 'Test Name', 'created' => '2006-12-25 05:23:36', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:36', 'mytime' => '22:57:17'),
+ array('id' => '5', 'apple_id' => '5', 'color' => 'Green', 'name' => 'Blue Green', 'created' => '2006-12-25 05:24:06', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:16', 'mytime' => '22:57:17'),
+ array('id' => '6', 'apple_id' => '4', 'color' => 'My new appleOrange', 'name' => 'My new apple', 'created' => '2006-12-25 05:29:39', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:39', 'mytime' => '22:57:17'),
+ array('id' => '7', 'apple_id' => '6', 'color' => 'Some wierd color', 'name' => 'Some odd color', 'created' => '2006-12-25 05:34:21', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:34:21', 'mytime' => '22:57:17')
+ );
+ $this->assertEquals($expected, $Apple->find('all'));
+ }
+
+/**
+ * testBehaviorHasManyFindCallbacks method
+ *
+ * @return void
+ */
+ public function testBehaviorHasManyFindCallbacks() {
+ $Apple = new Apple();
+ $Apple->unbindModel(array('hasOne' => array('Sample'), 'belongsTo' => array('Parent')), false);
+ $expected = $Apple->find('all');
+
+ $Apple->unbindModel(array('hasMany' => array('Child')));
+ $wellBehaved = $Apple->find('all');
+ $Apple->Child->Behaviors->attach('Test', array('afterFind' => 'modify'));
+ $Apple->unbindModel(array('hasMany' => array('Child')));
+ $this->assertSame($Apple->find('all'), $wellBehaved);
+
+ $Apple->Child->Behaviors->attach('Test', array('before' => 'off'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $Apple->Child->Behaviors->attach('Test', array('before' => 'test'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $expected2 = array(
+ array(
+ 'Apple' => array('id' => 1),
+ 'Child' => array(
+ array('id' => 2, 'name' => 'Bright Red Apple', 'mytime' => '22:57:17'))),
+ array(
+ 'Apple' => array('id' => 2),
+ 'Child' => array(
+ array('id' => 1, 'name' => 'Red Apple 1', 'mytime' => '22:57:17'),
+ array('id' => 3, 'name' => 'green blue', 'mytime' => '22:57:17'),
+ array('id' => 4, 'name' => 'Test Name', 'mytime' => '22:57:17'))),
+ array(
+ 'Apple' => array('id' => 3),
+ 'Child' => array())
+ );
+
+ $Apple->Child->Behaviors->attach('Test', array('before' => 'modify'));
+ $result = $Apple->find('all', array('fields' => array('Apple.id'), 'conditions' => array('Apple.id <' => '4')));
+
+ $Apple->Child->Behaviors->disable('Test');
+ $result = $Apple->find('all');
+ $this->assertEquals($expected, $result);
+
+ $Apple->Child->Behaviors->attach('Test', array('before' => 'off', 'after' => 'on'));
+
+ $Apple->Child->Behaviors->attach('Test', array('after' => 'off'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Child->Behaviors->attach('Test', array('after' => 'test'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Child->Behaviors->attach('Test', array('after' => 'test2'));
+ $this->assertEquals($expected, $Apple->find('all'));
+ }
+
+/**
+ * testBehaviorHasOneFindCallbacks method
+ *
+ * @return void
+ */
+ public function testBehaviorHasOneFindCallbacks() {
+ $Apple = new Apple();
+ $Apple->unbindModel(array('hasMany' => array('Child'), 'belongsTo' => array('Parent')), false);
+ $expected = $Apple->find('all');
+
+ $Apple->unbindModel(array('hasOne' => array('Sample')));
+ $wellBehaved = $Apple->find('all');
+ $Apple->Sample->Behaviors->attach('Test');
+ $Apple->unbindModel(array('hasOne' => array('Sample')));
+ $this->assertSame($Apple->find('all'), $wellBehaved);
+
+ $Apple->Sample->Behaviors->attach('Test', array('before' => 'off'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $Apple->Sample->Behaviors->attach('Test', array('before' => 'test'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $Apple->Sample->Behaviors->disable('Test');
+ $result = $Apple->find('all');
+ $this->assertEquals($expected, $result);
+
+ $Apple->Sample->Behaviors->attach('Test', array('after' => 'off'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Sample->Behaviors->attach('Test', array('after' => 'test'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Sample->Behaviors->attach('Test', array('after' => 'test2'));
+ $this->assertEquals($expected, $Apple->find('all'));
+ }
+
+/**
+ * testBehaviorBelongsToFindCallbacks method
+ *
+ * @return void
+ */
+ public function testBehaviorBelongsToFindCallbacks() {
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $Apple = new Apple();
+ $Apple->unbindModel(array('hasMany' => array('Child'), 'hasOne' => array('Sample')), false);
+ $expected = $Apple->find('all');
+
+ $Apple->unbindModel(array('belongsTo' => array('Parent')));
+ $wellBehaved = $Apple->find('all');
+ $Apple->Parent->Behaviors->attach('Test');
+ $Apple->unbindModel(array('belongsTo' => array('Parent')));
+ $this->assertSame($Apple->find('all'), $wellBehaved);
+
+ $Apple->Parent->Behaviors->attach('Test', array('before' => 'off'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $Apple->Parent->Behaviors->attach('Test', array('before' => 'test'));
+ $this->assertSame($expected, $Apple->find('all'));
+
+ $Apple->Parent->Behaviors->attach('Test', array('before' => 'modify'));
+ $expected2 = array(
+ array(
+ 'Apple' => array('id' => 1),
+ 'Parent' => array('id' => 2, 'name' => 'Bright Red Apple', 'mytime' => '22:57:17')),
+ array(
+ 'Apple' => array('id' => 2),
+ 'Parent' => array('id' => 1, 'name' => 'Red Apple 1', 'mytime' => '22:57:17')),
+ array(
+ 'Apple' => array('id' => 3),
+ 'Parent' => array('id' => 2, 'name' => 'Bright Red Apple', 'mytime' => '22:57:17'))
+ );
+ $result2 = $Apple->find('all', array(
+ 'fields' => array('Apple.id', 'Parent.id', 'Parent.name', 'Parent.mytime'),
+ 'conditions' => array('Apple.id <' => '4')
+ ));
+ $this->assertEquals($expected2, $result2);
+
+ $Apple->Parent->Behaviors->disable('Test');
+ $result = $Apple->find('all');
+ $this->assertEquals($expected, $result);
+
+ $Apple->Parent->Behaviors->attach('Test', array('after' => 'off'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Parent->Behaviors->attach('Test', array('after' => 'test'));
+ $this->assertEquals($expected, $Apple->find('all'));
+
+ $Apple->Parent->Behaviors->attach('Test', array('after' => 'test2'));
+ $this->assertEquals($expected, $Apple->find('all'));
+ }
+
+/**
+ * testBehaviorSaveCallbacks method
+ *
+ * @return void
+ */
+ public function testBehaviorSaveCallbacks() {
+ $Sample = new Sample();
+ $record = array('Sample' => array('apple_id' => 6, 'name' => 'sample99'));
+
+ $Sample->Behaviors->attach('Test', array('beforeSave' => 'on'));
+ $Sample->create();
+ $this->assertSame(false, $Sample->save($record));
+
+ $Sample->Behaviors->attach('Test', array('beforeSave' => 'off'));
+ $Sample->create();
+ $result = $Sample->save($record);
+ $expected = $record;
+ $expected['Sample']['id'] = $Sample->id;
+ $this->assertSame($expected, $result);
+
+ $Sample->Behaviors->attach('Test', array('beforeSave' => 'test'));
+ $Sample->create();
+ $result = $Sample->save($record);
+ $expected = $record;
+ $expected['Sample']['id'] = $Sample->id;
+ $this->assertSame($expected, $result);
+
+ $Sample->Behaviors->attach('Test', array('beforeSave' => 'modify'));
+ $expected = Hash::insert($record, 'Sample.name', 'sample99 modified before');
+ $Sample->create();
+ $result = $Sample->save($record);
+ $expected['Sample']['id'] = $Sample->id;
+ $this->assertSame($expected, $result);
+
+ $Sample->Behaviors->disable('Test');
+ $this->assertSame($record, $Sample->save($record));
+
+ $Sample->Behaviors->attach('Test', array('beforeSave' => 'off', 'afterSave' => 'on'));
+ $expected = Hash::merge($record, array('Sample' => array('aftersave' => 'modified after on create')));
+ $Sample->create();
+ $result = $Sample->save($record);
+ $expected['Sample']['id'] = $Sample->id;
+ $this->assertEquals($expected, $result);
+
+ $Sample->Behaviors->attach('Test', array('beforeSave' => 'modify', 'afterSave' => 'modify'));
+ $expected = Hash::merge($record, array('Sample' => array('name' => 'sample99 modified before modified after on create')));
+ $Sample->create();
+ $result = $Sample->save($record);
+ $expected['Sample']['id'] = $Sample->id;
+ $this->assertSame($expected, $result);
+
+ $Sample->Behaviors->attach('Test', array('beforeSave' => 'off', 'afterSave' => 'test'));
+ $Sample->create();
+ $expected = $record;
+ $result = $Sample->save($record);
+ $expected['Sample']['id'] = $Sample->id;
+ $this->assertSame($expected, $result);
+
+ $Sample->Behaviors->attach('Test', array('afterSave' => 'test2'));
+ $Sample->create();
+ $expected = $record;
+ $result = $Sample->save($record);
+ $expected['Sample']['id'] = $Sample->id;
+ $this->assertSame($expected, $result);
+
+ $Sample->Behaviors->attach('Test', array('beforeFind' => 'off', 'afterFind' => 'off'));
+ $Sample->recursive = -1;
+ $record2 = $Sample->read(null, 1);
+
+ $Sample->Behaviors->attach('Test', array('afterSave' => 'on'));
+ $expected = Hash::merge($record2, array('Sample' => array('aftersave' => 'modified after')));
+ $Sample->create();
+ $this->assertSame($expected, $Sample->save($record2));
+
+ $Sample->Behaviors->attach('Test', array('afterSave' => 'modify'));
+ $expected = Hash::merge($record2, array('Sample' => array('name' => 'sample1 modified after')));
+ $Sample->create();
+ $this->assertSame($expected, $Sample->save($record2));
+ }
+
+/**
+ * testBehaviorDeleteCallbacks method
+ *
+ * @return void
+ */
+ public function testBehaviorDeleteCallbacks() {
+ $Apple = new Apple();
+
+ $Apple->Behaviors->attach('Test', array('beforeFind' => 'off', 'beforeDelete' => 'off'));
+ $this->assertSame($Apple->delete(6), true);
+
+ $Apple->Behaviors->attach('Test', array('beforeDelete' => 'on'));
+ $this->assertSame($Apple->delete(4), false);
+
+ $Apple->Behaviors->attach('Test', array('beforeDelete' => 'test2'));
+
+ ob_start();
+ $results = $Apple->delete(4);
+ $this->assertSame(trim(ob_get_clean()), 'beforeDelete success (cascading)');
+ $this->assertSame($results, true);
+
+ ob_start();
+ $results = $Apple->delete(3, false);
+ $this->assertSame(trim(ob_get_clean()), 'beforeDelete success');
+ $this->assertSame($results, true);
+
+ $Apple->Behaviors->attach('Test', array('beforeDelete' => 'off', 'afterDelete' => 'on'));
+ ob_start();
+ $results = $Apple->delete(2, false);
+ $this->assertSame(trim(ob_get_clean()), 'afterDelete success');
+ $this->assertSame($results, true);
+ }
+
+/**
+ * testBehaviorOnErrorCallback method
+ *
+ * @return void
+ */
+ public function testBehaviorOnErrorCallback() {
+ $Apple = new Apple();
+
+ $Apple->Behaviors->attach('Test', array('beforeFind' => 'off', 'onError' => 'on'));
+ ob_start();
+ $Apple->Behaviors->Test->onError($Apple, '');
+ $this->assertSame(trim(ob_get_clean()), 'onError trigger success');
+ }
+
+/**
+ * testBehaviorValidateCallback method
+ *
+ * @return void
+ */
+ public function testBehaviorValidateCallback() {
+ $Apple = new Apple();
+
+ $Apple->Behaviors->attach('Test');
+ $this->assertSame($Apple->validates(), true);
+
+ $Apple->Behaviors->attach('Test', array('validate' => 'on'));
+ $this->assertSame($Apple->validates(), false);
+ $this->assertSame($Apple->validationErrors, array('name' => array(true)));
+
+ $Apple->Behaviors->attach('Test', array('validate' => 'stop'));
+ $this->assertSame($Apple->validates(), false);
+ $this->assertSame($Apple->validationErrors, array('name' => array(true, true)));
+
+ $Apple->Behaviors->attach('Test', array('validate' => 'whitelist'));
+ $Apple->validates();
+ $this->assertSame($Apple->whitelist, array());
+
+ $Apple->whitelist = array('unknown');
+ $Apple->validates();
+ $this->assertSame($Apple->whitelist, array('unknown', 'name'));
+ }
+
+/**
+ * testBehaviorValidateAfterCallback method
+ *
+ * @return void
+ */
+ public function testBehaviorValidateAfterCallback() {
+ $Apple = new Apple();
+
+ $Apple->Behaviors->attach('Test');
+ $this->assertSame($Apple->validates(), true);
+
+ $Apple->Behaviors->attach('Test', array('afterValidate' => 'on'));
+ $this->assertSame($Apple->validates(), true);
+ $this->assertSame($Apple->validationErrors, array());
+
+ $Apple->Behaviors->attach('Test', array('afterValidate' => 'test'));
+ $Apple->data = array('bar');
+ $Apple->validates();
+ $this->assertEquals(array('foo'), $Apple->data);
+ }
+
+/**
+ * testBehaviorValidateMethods method
+ *
+ * @return void
+ */
+ public function testBehaviorValidateMethods() {
+ $Apple = new Apple();
+ $Apple->Behaviors->attach('Test');
+ $Apple->validate['color'] = 'validateField';
+
+ $result = $Apple->save(array('name' => 'Genetically Modified Apple', 'color' => 'Orange'));
+ $this->assertEquals(array('name', 'color', 'modified', 'created', 'id'), array_keys($result['Apple']));
+
+ $Apple->create();
+ $result = $Apple->save(array('name' => 'Regular Apple', 'color' => 'Red'));
+ $this->assertFalse($result);
+ }
+
+/**
+ * testBehaviorMethodDispatching method
+ *
+ * @return void
+ */
+ public function testBehaviorMethodDispatching() {
+ $Apple = new Apple();
+ $Apple->Behaviors->attach('Test');
+
+ $expected = 'working';
+ $this->assertEquals($expected, $Apple->testMethod());
+ $this->assertEquals($expected, $Apple->Behaviors->dispatchMethod($Apple, 'testMethod'));
+
+ $result = $Apple->Behaviors->dispatchMethod($Apple, 'wtf');
+ $this->assertEquals(array('unhandled'), $result);
+
+ $result = $Apple->{'look for the remote'}('in the couch');
+ $expected = "Item.name = 'the remote' AND Location.name = 'the couch'";
+ $this->assertEquals($expected, $result);
+
+ $result = $Apple->{'look for THE REMOTE'}('in the couch');
+ $expected = "Item.name = 'THE REMOTE' AND Location.name = 'the couch'";
+ $this->assertEquals($expected, $result, 'Mapped method was lowercased.');
+ }
+
+/**
+ * testBehaviorMethodDispatchingWithData method
+ *
+ * @return void
+ */
+ public function testBehaviorMethodDispatchingWithData() {
+ $Apple = new Apple();
+ $Apple->Behaviors->attach('Test');
+
+ $Apple->set('field', 'value');
+ $this->assertTrue($Apple->testData());
+ $this->assertTrue($Apple->data['Apple']['field_2']);
+
+ $this->assertTrue($Apple->testData('one', 'two', 'three', 'four', 'five', 'six'));
+ }
+
+/**
+ * undocumented function
+ *
+ * @return void
+ */
+ public function testBindModelCallsInBehaviors() {
+ // hasMany
+ $Article = new Article();
+ $Article->unbindModel(array('hasMany' => array('Comment')));
+ $result = $Article->find('first');
+ $this->assertFalse(array_key_exists('Comment', $result));
+
+ $Article->Behaviors->attach('Test4');
+ $result = $Article->find('first');
+ $this->assertTrue(array_key_exists('Comment', $result));
+
+ // belongsTo
+ $Article->unbindModel(array('belongsTo' => array('User')));
+ $result = $Article->find('first');
+ $this->assertFalse(array_key_exists('User', $result));
+
+ $Article->Behaviors->attach('Test5');
+ $result = $Article->find('first');
+ $this->assertTrue(array_key_exists('User', $result));
+
+ // hasAndBelongsToMany
+ $Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')));
+ $result = $Article->find('first');
+ $this->assertFalse(array_key_exists('Tag', $result));
+
+ $Article->Behaviors->attach('Test6');
+ $result = $Article->find('first');
+ $this->assertTrue(array_key_exists('Comment', $result));
+
+ // hasOne
+ $Comment = new Comment();
+ $Comment->unbindModel(array('hasOne' => array('Attachment')));
+ $result = $Comment->find('first');
+ $this->assertFalse(array_key_exists('Attachment', $result));
+
+ $Comment->Behaviors->attach('Test7');
+ $result = $Comment->find('first');
+ $this->assertTrue(array_key_exists('Attachment', $result));
+ }
+
+/**
+ * Test attach and detaching
+ *
+ * @return void
+ */
+ public function testBehaviorAttachAndDetach() {
+ $Sample = new Sample();
+ $Sample->actsAs = array('Test3' => array('bar'), 'Test2' => array('foo', 'bar'));
+ $Sample->Behaviors->init($Sample->alias, $Sample->actsAs);
+ $Sample->Behaviors->attach('Test2');
+ $Sample->Behaviors->detach('Test3');
+
+ $Sample->Behaviors->trigger('beforeTest', array(&$Sample));
+ }
+
+/**
+ * test that hasMethod works with basic functions.
+ *
+ * @return void
+ */
+ public function testHasMethodBasic() {
+ $Sample = new Sample();
+ $Collection = new BehaviorCollection();
+ $Collection->init('Sample', array('Test', 'Test2'));
+
+ $this->assertTrue($Collection->hasMethod('testMethod'));
+ $this->assertTrue($Collection->hasMethod('resolveMethod'));
+
+ $this->assertFalse($Collection->hasMethod('No method'));
+ }
+
+/**
+ * test that hasMethod works with mapped methods.
+ *
+ * @return void
+ */
+ public function testHasMethodMappedMethods() {
+ $Sample = new Sample();
+ $Collection = new BehaviorCollection();
+ $Collection->init('Sample', array('Test', 'Test2'));
+
+ $this->assertTrue($Collection->hasMethod('look for the remote in the couch'));
+ $this->assertTrue($Collection->hasMethod('mappingRobotOnTheRoof'));
+ }
+
+/**
+ * test hasMethod returning a 'callback'
+ *
+ * @return void
+ */
+ public function testHasMethodAsCallback() {
+ $Sample = new Sample();
+ $Collection = new BehaviorCollection();
+ $Collection->init('Sample', array('Test', 'Test2'));
+
+ $result = $Collection->hasMethod('testMethod', true);
+ $expected = array('Test', 'testMethod');
+ $this->assertEquals($expected, $result);
+
+ $result = $Collection->hasMethod('resolveMethod', true);
+ $expected = array('Test2', 'resolveMethod');
+ $this->assertEquals($expected, $result);
+
+ $result = $Collection->hasMethod('mappingRobotOnTheRoof', true);
+ $expected = array('Test2', 'mapped', 'mappingRobotOnTheRoof');
+ $this->assertEquals($expected, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/CakeSchemaTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/CakeSchemaTest.php
new file mode 100644
index 0000000..47effcc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/CakeSchemaTest.php
@@ -0,0 +1,1091 @@
+<?php
+/**
+ * Test for Schema database management
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.5550
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeSchema', 'Model');
+App::uses('CakeTestFixture', 'TestSuite/Fixture');
+
+/**
+ * Test for Schema database management
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MyAppSchema extends CakeSchema {
+
+/**
+ * name property
+ *
+ * @var string 'MyApp'
+ */
+ public $name = 'MyApp';
+
+/**
+ * connection property
+ *
+ * @var string 'test'
+ */
+ public $connection = 'test';
+
+/**
+ * comments property
+ *
+ * @var array
+ */
+ public $comments = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false, 'length' => 100),
+ 'comment' => array('type' => 'text', 'null' => false, 'default' => null),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ );
+
+/**
+ * posts property
+ *
+ * @var array
+ */
+ public $posts = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
+ 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
+ 'body' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'summary' => array('type' => 'text', 'null' => true),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ );
+
+/**
+ * _foo property
+ *
+ * @var array
+ */
+ protected $_foo = array('bar');
+
+/**
+ * setup method
+ *
+ * @param mixed $version
+ * @return void
+ */
+ public function setup($version) {
+ }
+
+/**
+ * teardown method
+ *
+ * @param mixed $version
+ * @return void
+ */
+ public function teardown($version) {
+ }
+
+/**
+ * getVar method
+ *
+ * @param string $var Name of var
+ * @return mixed
+ */
+ public function getVar($var) {
+ if (!isset($this->$var)) {
+ return null;
+ }
+ return $this->$var;
+ }
+
+}
+
+/**
+ * TestAppSchema class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestAppSchema extends CakeSchema {
+
+/**
+ * name property
+ *
+ * @var string 'MyApp'
+ */
+ public $name = 'MyApp';
+
+/**
+ * comments property
+ *
+ * @var array
+ */
+ public $comments = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0,'key' => 'primary'),
+ 'article_id' => array('type' => 'integer', 'null' => false),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'comment' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ 'tableParameters' => array(),
+ );
+
+/**
+ * posts property
+ *
+ * @var array
+ */
+ public $posts = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'body' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ 'tableParameters' => array(),
+ );
+
+/**
+ * posts_tags property
+ *
+ * @var array
+ */
+ public $posts_tags = array(
+ 'post_id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
+ 'tag_id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
+ 'indexes' => array('posts_tag' => array('column' => array('tag_id', 'post_id'), 'unique' => 1)),
+ 'tableParameters' => array()
+ );
+
+/**
+ * tags property
+ *
+ * @var array
+ */
+ public $tags = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'tag' => array('type' => 'string', 'null' => false),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ 'tableParameters' => array()
+ );
+
+/**
+ * datatypes property
+ *
+ * @var array
+ */
+ public $datatypes = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
+ 'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ 'tableParameters' => array()
+ );
+
+/**
+ * setup method
+ *
+ * @param mixed $version
+ * @return void
+ */
+ public function setup($version) {
+ }
+
+/**
+ * teardown method
+ *
+ * @param mixed $version
+ * @return void
+ */
+ public function teardown($version) {
+ }
+
+}
+
+/**
+ * SchemaPost class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SchemaPost extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SchemaPost'
+ */
+ public $name = 'SchemaPost';
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'posts';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('SchemaComment');
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('SchemaTag');
+}
+
+/**
+ * SchemaComment class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SchemaComment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SchemaComment'
+ */
+ public $name = 'SchemaComment';
+
+/**
+ * useTable property
+ *
+ * @var string 'comments'
+ */
+ public $useTable = 'comments';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('SchemaPost');
+}
+
+/**
+ * SchemaTag class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SchemaTag extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SchemaTag'
+ */
+ public $name = 'SchemaTag';
+
+/**
+ * useTable property
+ *
+ * @var string 'tags'
+ */
+ public $useTable = 'tags';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('SchemaPost');
+}
+
+/**
+ * SchemaDatatype class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SchemaDatatype extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SchemaDatatype'
+ */
+ public $name = 'SchemaDatatype';
+
+/**
+ * useTable property
+ *
+ * @var string 'datatypes'
+ */
+ public $useTable = 'datatypes';
+}
+
+/**
+ * Testdescribe class
+ *
+ * This class is defined purely to inherit the cacheSources variable otherwise
+ * testSchemaCreateTable will fail if listSources has already been called and
+ * its source cache populated - I.e. if the test is run within a group
+ *
+ * @uses CakeTestModel
+ * @package
+ * @package Cake.Test.Case.Model
+ */
+class Testdescribe extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Testdescribe'
+ */
+ public $name = 'Testdescribe';
+}
+
+/**
+ * SchemaCrossDatabase class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SchemaCrossDatabase extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SchemaCrossDatabase'
+ */
+ public $name = 'SchemaCrossDatabase';
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'cross_database';
+
+/**
+ * useDbConfig property
+ *
+ * @var string 'test2'
+ */
+ public $useDbConfig = 'test2';
+}
+
+/**
+ * SchemaCrossDatabaseFixture class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SchemaCrossDatabaseFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'CrossDatabase'
+ */
+ public $name = 'CrossDatabase';
+
+/**
+ * table property
+ *
+ */
+ public $table = 'cross_database';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => 'string'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'name' => 'First'),
+ array('id' => 2, 'name' => 'Second'),
+ );
+}
+
+/**
+ * SchemaPrefixAuthUser class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SchemaPrefixAuthUser extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string
+ */
+ public $name = 'SchemaPrefixAuthUser';
+
+/**
+ * table prefix
+ *
+ * @var string
+ */
+ public $tablePrefix = 'auth_';
+
+/**
+ * useTable
+ *
+ * @var string
+ */
+ public $useTable = 'users';
+}
+
+/**
+ * CakeSchemaTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+class CakeSchemaTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.post', 'core.tag', 'core.posts_tag', 'core.test_plugin_comment',
+ 'core.datatype', 'core.auth_user', 'core.author',
+ 'core.test_plugin_article', 'core.user', 'core.comment',
+ 'core.prefix_test'
+ );
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ ConnectionManager::getDataSource('test')->cacheSources = false;
+ $this->Schema = new TestAppSchema();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ if (file_exists(TMP . 'tests' . DS . 'schema.php')) {
+ unlink(TMP . 'tests' . DS . 'schema.php');
+ }
+ unset($this->Schema);
+ CakePlugin::unload();
+ }
+
+/**
+ * testSchemaName method
+ *
+ * @return void
+ */
+ public function testSchemaName() {
+ $Schema = new CakeSchema();
+ $this->assertEquals(Inflector::camelize(Inflector::slug(APP_DIR)), $Schema->name);
+
+ Configure::write('App.dir', 'Some.name.with.dots');
+ $Schema = new CakeSchema();
+ $this->assertEquals('SomeNameWithDots', $Schema->name);
+
+ Configure::write('App.dir', 'Some-name-with-dashes');
+ $Schema = new CakeSchema();
+ $this->assertEquals('SomeNameWithDashes', $Schema->name);
+
+ Configure::write('App.dir', 'Some name with spaces');
+ $Schema = new CakeSchema();
+ $this->assertEquals('SomeNameWithSpaces', $Schema->name);
+
+ Configure::write('App.dir', 'Some,name;with&weird=characters');
+ $Schema = new CakeSchema();
+ $this->assertEquals('SomeNameWithWeirdCharacters', $Schema->name);
+
+ Configure::write('App.dir', 'app');
+ }
+
+/**
+ * testSchemaRead method
+ *
+ * @return void
+ */
+ public function testSchemaRead() {
+ $read = $this->Schema->read(array(
+ 'connection' => 'test',
+ 'name' => 'TestApp',
+ 'models' => array('SchemaPost', 'SchemaComment', 'SchemaTag', 'SchemaDatatype')
+ ));
+ unset($read['tables']['missing']);
+
+ $expected = array('comments', 'datatypes', 'posts', 'posts_tags', 'tags');
+ foreach ($expected as $table) {
+ $this->assertTrue(isset($read['tables'][$table]), 'Missing table ' . $table);
+ }
+ foreach ($this->Schema->tables as $table => $fields) {
+ $this->assertEquals(array_keys($fields), array_keys($read['tables'][$table]));
+ }
+
+ if (isset($read['tables']['datatypes']['float_field']['length'])) {
+ $this->assertEquals(
+ $read['tables']['datatypes']['float_field']['length'],
+ $this->Schema->tables['datatypes']['float_field']['length']
+ );
+ }
+
+ $this->assertEquals(
+ $read['tables']['datatypes']['float_field']['type'],
+ $this->Schema->tables['datatypes']['float_field']['type']
+ );
+
+ $this->assertEquals(
+ $read['tables']['datatypes']['float_field']['null'],
+ $this->Schema->tables['datatypes']['float_field']['null']
+ );
+
+ $db = ConnectionManager::getDataSource('test');
+ $config = $db->config;
+ $config['prefix'] = 'schema_test_prefix_';
+ ConnectionManager::create('schema_prefix', $config);
+ $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
+ $this->assertTrue(empty($read['tables']));
+
+ $read = $this->Schema->read(array(
+ 'connection' => 'test',
+ 'name' => 'TestApp',
+ 'models' => array('SchemaComment', 'SchemaTag', 'SchemaPost')
+ ));
+ $this->assertFalse(isset($read['tables']['missing']['posts_tags']), 'Join table marked as missing');
+ }
+
+/**
+ * testSchemaReadWithAppModel method
+ *
+ * @access public
+ * @return void
+ */
+ public function testSchemaReadWithAppModel() {
+ $connections = ConnectionManager::enumConnectionObjects();
+ ConnectionManager::drop('default');
+ ConnectionManager::create('default', $connections['test']);
+ try {
+ $read = $this->Schema->read(array(
+ 'connection' => 'default',
+ 'name' => 'TestApp',
+ 'models' => array('AppModel')
+ ));
+ } catch(MissingTableException $mte) {
+ ConnectionManager::drop('default');
+ $this->fail($mte->getMessage());
+ }
+ ConnectionManager::drop('default');
+ }
+
+/**
+ * testSchemaReadWithOddTablePrefix method
+ *
+ * @return void
+ */
+ public function testSchemaReadWithOddTablePrefix() {
+ $config = ConnectionManager::getDataSource('test')->config;
+ $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
+
+ $SchemaPost = ClassRegistry::init('SchemaPost');
+ $SchemaPost->tablePrefix = 'po';
+ $SchemaPost->useTable = 'sts';
+ $read = $this->Schema->read(array(
+ 'connection' => 'test',
+ 'name' => 'TestApp',
+ 'models' => array('SchemaPost')
+ ));
+
+ $this->assertFalse(isset($read['tables']['missing']['posts']), 'Posts table was not read from tablePrefix');
+ }
+
+/**
+ * test read() with tablePrefix properties.
+ *
+ * @return void
+ */
+ public function testSchemaReadWithTablePrefix() {
+ $config = ConnectionManager::getDataSource('test')->config;
+ $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
+
+ $model = new SchemaPrefixAuthUser();
+
+ $Schema = new CakeSchema();
+ $read = $Schema->read(array(
+ 'connection' => 'test',
+ 'name' => 'TestApp',
+ 'models' => array('SchemaPrefixAuthUser')
+ ));
+ unset($read['tables']['missing']);
+ $this->assertTrue(isset($read['tables']['auth_users']), 'auth_users key missing %s');
+ }
+
+/**
+ * test reading schema with config prefix.
+ *
+ * @return void
+ */
+ public function testSchemaReadWithConfigPrefix() {
+ $this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
+
+ $db = ConnectionManager::getDataSource('test');
+ $config = $db->config;
+ $this->skipIf(!empty($config['prefix']), 'This test can not be executed with datasource prefix set.');
+
+ $config['prefix'] = 'schema_test_prefix_';
+ ConnectionManager::create('schema_prefix', $config);
+ $read = $this->Schema->read(array('connection' => 'schema_prefix', 'models' => false));
+ $this->assertTrue(empty($read['tables']));
+
+ $config['prefix'] = 'prefix_';
+ ConnectionManager::create('schema_prefix2', $config);
+ $read = $this->Schema->read(array(
+ 'connection' => 'schema_prefix2',
+ 'name' => 'TestApp',
+ 'models' => false));
+ $this->assertTrue(isset($read['tables']['prefix_tests']));
+ }
+
+/**
+ * test reading schema from plugins.
+ *
+ * @return void
+ */
+ public function testSchemaReadWithPlugins() {
+ App::objects('model', null, false);
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+
+ $Schema = new CakeSchema();
+ $Schema->plugin = 'TestPlugin';
+ $read = $Schema->read(array(
+ 'connection' => 'test',
+ 'name' => 'TestApp',
+ 'models' => true
+ ));
+ unset($read['tables']['missing']);
+ $this->assertTrue(isset($read['tables']['auth_users']));
+ $this->assertTrue(isset($read['tables']['authors']));
+ $this->assertTrue(isset($read['tables']['test_plugin_comments']));
+ $this->assertTrue(isset($read['tables']['posts']));
+ $this->assertTrue(count($read['tables']) >= 4);
+
+ App::build();
+ }
+
+/**
+ * test reading schema with tables from another database.
+ *
+ * @return void
+ */
+ public function testSchemaReadWithCrossDatabase() {
+ $config = ConnectionManager::enumConnectionObjects();
+ $this->skipIf(
+ !isset($config['test']) || !isset($config['test2']),
+ 'Primary and secondary test databases not configured, ' .
+ 'skipping cross-database join tests. ' .
+ 'To run these tests, you must define $test and $test2 in your database configuration.'
+ );
+
+ $db = ConnectionManager::getDataSource('test2');
+ $fixture = new SchemaCrossDatabaseFixture();
+ $fixture->create($db);
+ $fixture->insert($db);
+
+ $read = $this->Schema->read(array(
+ 'connection' => 'test',
+ 'name' => 'TestApp',
+ 'models' => array('SchemaCrossDatabase', 'SchemaPost')
+ ));
+ $this->assertTrue(isset($read['tables']['posts']));
+ $this->assertFalse(isset($read['tables']['cross_database']), 'Cross database should not appear');
+ $this->assertFalse(isset($read['tables']['missing']['cross_database']), 'Cross database should not appear');
+
+ $read = $this->Schema->read(array(
+ 'connection' => 'test2',
+ 'name' => 'TestApp',
+ 'models' => array('SchemaCrossDatabase', 'SchemaPost')
+ ));
+ $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
+ $this->assertFalse(isset($read['tables']['posts']), 'Posts should not appear');
+ $this->assertTrue(isset($read['tables']['cross_database']));
+
+ $fixture->drop($db);
+ }
+
+/**
+ * test that tables are generated correctly
+ *
+ * @return void
+ */
+ public function testGenerateTable() {
+ $posts = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'body' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'N', 'length' => 1),
+ 'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'updated' => array('type' => 'datetime', 'null' => true, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
+ );
+ $result = $this->Schema->generateTable('posts', $posts);
+ $this->assertRegExp('/public \$posts/', $result);
+ }
+
+/**
+ * testSchemaWrite method
+ *
+ * @return void
+ */
+ public function testSchemaWrite() {
+ $write = $this->Schema->write(array(
+ 'name' => 'MyOtherApp',
+ 'tables' => $this->Schema->tables,
+ 'path' => TMP . 'tests'
+ ));
+ $file = file_get_contents(TMP . 'tests' . DS . 'schema.php');
+ $this->assertEquals($write, $file);
+
+ require_once TMP . 'tests' . DS . 'schema.php';
+ $OtherSchema = new MyOtherAppSchema();
+ $this->assertEquals($this->Schema->tables, $OtherSchema->tables);
+ }
+
+/**
+ * testSchemaComparison method
+ *
+ * @return void
+ */
+ public function testSchemaComparison() {
+ $New = new MyAppSchema();
+ $compare = $New->compare($this->Schema);
+ $expected = array(
+ 'comments' => array(
+ 'add' => array(
+ 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'after' => 'id'),
+ 'title' => array('type' => 'string', 'null' => false, 'length' => 100, 'after' => 'user_id'),
+ ),
+ 'drop' => array(
+ 'article_id' => array('type' => 'integer', 'null' => false),
+ 'tableParameters' => array(),
+ ),
+ 'change' => array(
+ 'comment' => array('type' => 'text', 'null' => false, 'default' => null),
+ )
+ ),
+ 'posts' => array(
+ 'add' => array(
+ 'summary' => array('type' => 'text', 'null' => true, 'after' => 'body'),
+ ),
+ 'drop' => array(
+ 'tableParameters' => array(),
+ ),
+ 'change' => array(
+ 'author_id' => array('type' => 'integer', 'null' => true, 'default' => ''),
+ 'title' => array('type' => 'string', 'null' => false, 'default' => 'Title'),
+ 'published' => array('type' => 'string', 'null' => true, 'default' => 'Y', 'length' => 1)
+ )
+ ),
+ );
+ $this->assertEquals($expected, $compare);
+ $this->assertNull($New->getVar('comments'));
+ $this->assertEquals(array('bar'), $New->getVar('_foo'));
+
+ $tables = array(
+ 'missing' => array(
+ 'categories' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
+ 'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
+ 'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
+ 'name' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 100),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
+ )
+ ),
+ 'ratings' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
+ 'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => null),
+ 'model' => array('type' => 'varchar', 'null' => false, 'default' => null),
+ 'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => null),
+ 'created' => array('type' => 'datetime', 'null' => false, 'default' => null),
+ 'modified' => array('type' => 'datetime', 'null' => false, 'default' => null),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
+ )
+ );
+ $compare = $New->compare($this->Schema, $tables);
+ $expected = array(
+ 'ratings' => array(
+ 'add' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
+ 'foreign_key' => array('type' => 'integer', 'null' => false, 'default' => null, 'after' => 'id'),
+ 'model' => array('type' => 'varchar', 'null' => false, 'default' => null, 'after' => 'foreign_key'),
+ 'value' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => null, 'after' => 'model'),
+ 'created' => array('type' => 'datetime', 'null' => false, 'default' => null, 'after' => 'value'),
+ 'modified' => array('type' => 'datetime', 'null' => false, 'default' => null, 'after' => 'created'),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
+ 'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'MyISAM')
+ )
+ )
+ );
+ $this->assertEquals($expected, $compare);
+ }
+
+/**
+ * test comparing '' and null and making sure they are different.
+ *
+ * @return void
+ */
+ public function testCompareEmptyStringAndNull() {
+ $One = new CakeSchema(array(
+ 'posts' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false, 'default' => '')
+ )
+ ));
+ $Two = new CakeSchema(array(
+ 'posts' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false, 'default' => null)
+ )
+ ));
+ $compare = $One->compare($Two);
+ $expected = array(
+ 'posts' => array(
+ 'change' => array(
+ 'name' => array('type' => 'string', 'null' => false, 'default' => null)
+ )
+ )
+ );
+ $this->assertEquals($expected, $compare);
+ }
+
+/**
+ * Test comparing tableParameters and indexes.
+ *
+ * @return void
+ */
+ public function testTableParametersAndIndexComparison() {
+ $old = array(
+ 'posts' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => true)
+ ),
+ 'tableParameters' => array(
+ 'charset' => 'latin1',
+ 'collate' => 'latin1_general_ci'
+ )
+ ),
+ 'comments' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'comment' => array('type' => 'text'),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => true),
+ 'post_id' => array('column' => 'post_id'),
+ ),
+ 'tableParameters' => array(
+ 'engine' => 'InnoDB',
+ 'charset' => 'latin1',
+ 'collate' => 'latin1_general_ci'
+ )
+ )
+ );
+ $new = array(
+ 'posts' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => true),
+ 'author_id' => array('column' => 'author_id'),
+ ),
+ 'tableParameters' => array(
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_general_ci',
+ 'engine' => 'MyISAM'
+ )
+ ),
+ 'comments' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'comment' => array('type' => 'text'),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => true),
+ ),
+ 'tableParameters' => array(
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_general_ci'
+ )
+ )
+ );
+ $compare = $this->Schema->compare($old, $new);
+ $expected = array(
+ 'posts' => array(
+ 'add' => array(
+ 'indexes' => array('author_id' => array('column' => 'author_id')),
+ ),
+ 'change' => array(
+ 'tableParameters' => array(
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_general_ci',
+ 'engine' => 'MyISAM'
+ )
+ )
+ ),
+ 'comments' => array(
+ 'drop' => array(
+ 'indexes' => array('post_id' => array('column' => 'post_id')),
+ ),
+ 'change' => array(
+ 'tableParameters' => array(
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_general_ci',
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $compare);
+ }
+
+/**
+ * Test comparing with field changed from VARCHAR to DATETIME
+ *
+ * @return void
+ */
+ public function testCompareVarcharToDatetime() {
+ $old = array(
+ 'posts' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => true, 'length' => 45),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => true)
+ ),
+ 'tableParameters' => array(
+ 'charset' => 'latin1',
+ 'collate' => 'latin1_general_ci'
+ )
+ ),
+ );
+ $new = array(
+ 'posts' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'datetime', 'null' => false),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => true)
+ ),
+ 'tableParameters' => array(
+ 'charset' => 'latin1',
+ 'collate' => 'latin1_general_ci'
+ )
+ ),
+ );
+ $compare = $this->Schema->compare($old, $new);
+ $expected = array(
+ 'posts' => array(
+ 'change' => array(
+ 'title' => array(
+ 'type' => 'datetime',
+ 'null' => false,
+ )
+ )
+ ),
+ );
+ $this->assertEquals($expected, $compare, 'Invalid SQL, datetime does not have length');
+ }
+
+/**
+ * testSchemaLoading method
+ *
+ * @return void
+ */
+ public function testSchemaLoading() {
+ $Other = $this->Schema->load(array('name' => 'MyOtherApp', 'path' => TMP . 'tests'));
+ $this->assertEquals('MyOtherApp', $Other->name);
+ $this->assertEquals($Other->tables, $this->Schema->tables);
+ }
+
+/**
+ * test loading schema files inside of plugins.
+ *
+ * @return void
+ */
+ public function testSchemaLoadingFromPlugin() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $Other = $this->Schema->load(array('name' => 'TestPluginApp', 'plugin' => 'TestPlugin'));
+ $this->assertEquals('TestPluginApp', $Other->name);
+ $this->assertEquals(array('test_plugin_acos'), array_keys($Other->tables));
+
+ App::build();
+ }
+
+/**
+ * testSchemaCreateTable method
+ *
+ * @return void
+ */
+ public function testSchemaCreateTable() {
+ $db = ConnectionManager::getDataSource('test');
+ $db->cacheSources = false;
+
+ $Schema = new CakeSchema(array(
+ 'connection' => 'test',
+ 'testdescribes' => array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'int_null' => array('type' => 'integer', 'null' => true),
+ 'int_not_null' => array('type' => 'integer', 'null' => false),
+ ),
+ ));
+ $sql = $db->createSchema($Schema);
+
+ $col = $Schema->tables['testdescribes']['int_null'];
+ $col['name'] = 'int_null';
+ $column = $this->db->buildColumn($col);
+ $this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
+
+ $col = $Schema->tables['testdescribes']['int_not_null'];
+ $col['name'] = 'int_not_null';
+ $column = $this->db->buildColumn($col);
+ $this->assertRegExp('/' . preg_quote($column, '/') . '/', $sql);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ConnectionManagerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ConnectionManagerTest.php
new file mode 100644
index 0000000..a35d06b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ConnectionManagerTest.php
@@ -0,0 +1,346 @@
+<?php
+/**
+ * Connection Manager tests
+ *
+ * PHP 5
+ *
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.5550
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ConnectionManager', 'Model');
+
+/**
+ * ConnectionManagerTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ConnectionManagerTest extends CakeTestCase {
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ }
+
+/**
+ * testEnumConnectionObjects method
+ *
+ * @return void
+ */
+ public function testEnumConnectionObjects() {
+ $sources = ConnectionManager::enumConnectionObjects();
+ $this->assertTrue(count($sources) >= 1);
+
+ $connections = array('default', 'test', 'test');
+ $this->assertTrue(count(array_intersect(array_keys($sources), $connections)) >= 1);
+ }
+
+/**
+ * testGetDataSource method
+ *
+ * @return void
+ */
+ public function testGetDataSource() {
+ App::build(array(
+ 'Model/Datasource' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS . 'Datasource' . DS
+ )
+ ));
+
+ $name = 'test_get_datasource';
+ $config = array('datasource' => 'Test2Source');
+
+ $connection = ConnectionManager::create($name, $config);
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertTrue((bool)(count(array_keys($connections) >= 1)));
+
+ $source = ConnectionManager::getDataSource('test_get_datasource');
+ $this->assertTrue(is_object($source));
+ ConnectionManager::drop('test_get_datasource');
+ }
+
+/**
+ * testGetDataSourceException() method
+ *
+ * @return void
+ * @expectedException MissingDatasourceConfigException
+ */
+ public function testGetDataSourceException() {
+ ConnectionManager::getDataSource('non_existent_source');
+ }
+
+/**
+ * testGetPluginDataSource method
+ *
+ * @return void
+ */
+ public function testGetPluginDataSource() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+ $name = 'test_source';
+ $config = array('datasource' => 'TestPlugin.TestSource');
+ $connection = ConnectionManager::create($name, $config);
+
+ $this->assertTrue(class_exists('TestSource'));
+ $this->assertEquals($connection->configKeyName, $name);
+ $this->assertEquals($connection->config, $config);
+
+ ConnectionManager::drop($name);
+ }
+
+/**
+ * testGetPluginDataSourceAndPluginDriver method
+ *
+ * @return void
+ */
+ public function testGetPluginDataSourceAndPluginDriver() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+ $name = 'test_plugin_source_and_driver';
+ $config = array('datasource' => 'TestPlugin.Database/TestDriver');
+
+ $connection = ConnectionManager::create($name, $config);
+
+ $this->assertTrue(class_exists('TestSource'));
+ $this->assertTrue(class_exists('TestDriver'));
+ $this->assertEquals($connection->configKeyName, $name);
+ $this->assertEquals($connection->config, $config);
+
+ ConnectionManager::drop($name);
+ }
+
+/**
+ * testGetLocalDataSourceAndPluginDriver method
+ *
+ * @return void
+ */
+ public function testGetLocalDataSourceAndPluginDriver() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $name = 'test_local_source_and_plugin_driver';
+ $config = array('datasource' => 'TestPlugin.Database/DboDummy');
+
+ $connection = ConnectionManager::create($name, $config);
+
+ $this->assertTrue(class_exists('DboSource'));
+ $this->assertTrue(class_exists('DboDummy'));
+ $this->assertEquals($connection->configKeyName, $name);
+
+ ConnectionManager::drop($name);
+ }
+
+/**
+ * testGetPluginDataSourceAndLocalDriver method
+ *
+ * @return void
+ */
+ public function testGetPluginDataSourceAndLocalDriver() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Model/Datasource/Database' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS . 'Datasource' . DS . 'Database' . DS
+ )
+ ));
+
+ $name = 'test_plugin_source_and_local_driver';
+ $config = array('datasource' => 'Database/TestLocalDriver');
+
+ $connection = ConnectionManager::create($name, $config);
+
+ $this->assertTrue(class_exists('TestSource'));
+ $this->assertTrue(class_exists('TestLocalDriver'));
+ $this->assertEquals($connection->configKeyName, $name);
+ $this->assertEquals($connection->config, $config);
+ ConnectionManager::drop($name);
+ }
+
+/**
+ * testSourceList method
+ *
+ * @return void
+ */
+ public function testSourceList() {
+ ConnectionManager::getDataSource('test');
+ $sources = ConnectionManager::sourceList();
+ $this->assertTrue(count($sources) >= 1);
+ $this->assertTrue(in_array('test', array_keys($sources)));
+ }
+
+/**
+ * testGetSourceName method
+ *
+ * @return void
+ */
+ public function testGetSourceName() {
+ $connections = ConnectionManager::enumConnectionObjects();
+ $source = ConnectionManager::getDataSource('test');
+ $result = ConnectionManager::getSourceName($source);
+
+ $this->assertEquals('test', $result);
+
+ $source = new StdClass();
+ $result = ConnectionManager::getSourceName($source);
+ $this->assertNull($result);
+ }
+
+/**
+ * testLoadDataSource method
+ *
+ * @return void
+ */
+ public function testLoadDataSource() {
+ $connections = array(
+ array('classname' => 'Mysql', 'filename' => 'Mysql', 'package' => 'Database'),
+ array('classname' => 'Postgres', 'filename' => 'Postgres', 'package' => 'Database'),
+ array('classname' => 'Sqlite', 'filename' => 'Sqlite', 'package' => 'Database'),
+ );
+
+ foreach ($connections as $connection) {
+ $exists = class_exists($connection['classname']);
+ $loaded = ConnectionManager::loadDataSource($connection);
+ $this->assertEquals($loaded, !$exists, "Failed loading the {$connection['classname']} datasource");
+ }
+ }
+
+/**
+ * testLoadDataSourceException() method
+ *
+ * @return void
+ * @expectedException MissingDatasourceException
+ */
+ public function testLoadDataSourceException() {
+ $connection = array('classname' => 'NonExistentDataSource', 'filename' => 'non_existent');
+ $loaded = ConnectionManager::loadDataSource($connection);
+ }
+
+/**
+ * testCreateDataSource method
+ *
+ * @return void
+ */
+ public function testCreateDataSourceWithIntegrationTests() {
+ $name = 'test_created_connection';
+
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertTrue((bool)(count(array_keys($connections) >= 1)));
+
+ $source = ConnectionManager::getDataSource('test');
+ $this->assertTrue(is_object($source));
+
+ $config = $source->config;
+ $connection = ConnectionManager::create($name, $config);
+
+ $this->assertTrue(is_object($connection));
+ $this->assertEquals($name, $connection->configKeyName);
+ $this->assertEquals($name, ConnectionManager::getSourceName($connection));
+
+ $source = ConnectionManager::create(null, array());
+ $this->assertEquals(null, $source);
+
+ $source = ConnectionManager::create('another_test', array());
+ $this->assertEquals(null, $source);
+
+ $config = array('classname' => 'DboMysql', 'filename' => 'dbo' . DS . 'dbo_mysql');
+ $source = ConnectionManager::create(null, $config);
+ $this->assertEquals(null, $source);
+ }
+
+/**
+ * testConnectionData method
+ *
+ * @return void
+ */
+ public function testConnectionData() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Model/Datasource' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS . 'Datasource' . DS
+ )
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+ $expected = array(
+ 'datasource' => 'Test2Source'
+ );
+
+ ConnectionManager::create('connection1', array('datasource' => 'Test2Source'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertEquals($expected, $connections['connection1']);
+ ConnectionManager::drop('connection1');
+
+ ConnectionManager::create('connection2', array('datasource' => 'Test2Source'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertEquals($expected, $connections['connection2']);
+ ConnectionManager::drop('connection2');
+
+ ConnectionManager::create('connection3', array('datasource' => 'TestPlugin.TestSource'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $expected['datasource'] = 'TestPlugin.TestSource';
+ $this->assertEquals($expected, $connections['connection3']);
+ ConnectionManager::drop('connection3');
+
+ ConnectionManager::create('connection4', array('datasource' => 'TestPlugin.TestSource'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertEquals($expected, $connections['connection4']);
+ ConnectionManager::drop('connection4');
+
+ ConnectionManager::create('connection5', array('datasource' => 'Test2OtherSource'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $expected['datasource'] = 'Test2OtherSource';
+ $this->assertEquals($expected, $connections['connection5']);
+ ConnectionManager::drop('connection5');
+
+ ConnectionManager::create('connection6', array('datasource' => 'Test2OtherSource'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertEquals($expected, $connections['connection6']);
+ ConnectionManager::drop('connection6');
+
+ ConnectionManager::create('connection7', array('datasource' => 'TestPlugin.TestOtherSource'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $expected['datasource'] = 'TestPlugin.TestOtherSource';
+ $this->assertEquals($expected, $connections['connection7']);
+ ConnectionManager::drop('connection7');
+
+ ConnectionManager::create('connection8', array('datasource' => 'TestPlugin.TestOtherSource'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertEquals($expected, $connections['connection8']);
+ ConnectionManager::drop('connection8');
+ }
+
+/**
+ * Tests that a connection configuration can be deleted in runtime
+ *
+ * @return void
+ */
+ public function testDrop() {
+ App::build(array(
+ 'Model/Datasource' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS . 'Datasource' . DS
+ )
+ ));
+ ConnectionManager::create('droppable', array('datasource' => 'Test2Source'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertEquals(array('datasource' => 'Test2Source'), $connections['droppable']);
+
+ $this->assertTrue(ConnectionManager::drop('droppable'));
+ $connections = ConnectionManager::enumConnectionObjects();
+ $this->assertFalse(isset($connections['droppable']));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php
new file mode 100644
index 0000000..a227697
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php
@@ -0,0 +1,754 @@
+<?php
+/**
+ * SessionTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Datasource
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeSession', 'Model/Datasource');
+App::uses('DatabaseSession', 'Model/Datasource/Session');
+App::uses('CacheSession', 'Model/Datasource/Session');
+
+class TestCakeSession extends CakeSession {
+
+ public static function setUserAgent($value) {
+ self::$_userAgent = $value;
+ }
+
+ public static function setHost($host) {
+ self::_setHost($host);
+ }
+
+}
+
+class TestCacheSession extends CacheSession {
+
+ protected function _writeSession() {
+ return true;
+ }
+
+}
+
+class TestDatabaseSession extends DatabaseSession {
+
+ protected function _writeSession() {
+ return true;
+ }
+
+}
+
+/**
+ * CakeSessionTest class
+ *
+ * @package Cake.Test.Case.Model.Datasource
+ */
+class CakeSessionTest extends CakeTestCase {
+
+ protected static $_gcDivisor;
+
+/**
+ * Fixtures used in the SessionTest
+ *
+ * @var array
+ */
+ public $fixtures = array('core.session');
+
+/**
+ * setup before class.
+ *
+ * @return void
+ */
+ public static function setupBeforeClass() {
+ // Make sure garbage colector will be called
+ self::$_gcDivisor = ini_get('session.gc_divisor');
+ ini_set('session.gc_divisor', '1');
+ }
+
+/**
+ * teardown after class
+ *
+ * @return void
+ */
+ public static function teardownAfterClass() {
+ // Revert to the default setting
+ ini_set('session.gc_divisor', self::$_gcDivisor);
+ }
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Session', array(
+ 'defaults' => 'php',
+ 'cookie' => 'cakephp',
+ 'timeout' => 120,
+ 'cookieTimeout' => 120,
+ 'ini' => array(),
+ ));
+ TestCakeSession::init();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function teardown() {
+ if (TestCakeSession::started()) {
+ session_write_close();
+ }
+ unset($_SESSION);
+ parent::teardown();
+ }
+
+/**
+ * test setting ini properties with Session configuration.
+ *
+ * @return void
+ */
+ public function testSessionConfigIniSetting() {
+ $_SESSION = null;
+
+ Configure::write('Session', array(
+ 'cookie' => 'test',
+ 'checkAgent' => false,
+ 'timeout' => 86400,
+ 'ini' => array(
+ 'session.referer_check' => 'example.com',
+ 'session.use_trans_sid' => false
+ )
+ ));
+ TestCakeSession::start();
+ $this->assertEquals('', ini_get('session.use_trans_sid'), 'Ini value is incorrect');
+ $this->assertEquals('example.com', ini_get('session.referer_check'), 'Ini value is incorrect');
+ $this->assertEquals('test', ini_get('session.name'), 'Ini value is incorrect');
+ }
+
+/**
+ * testSessionPath
+ *
+ * @return void
+ */
+ public function testSessionPath() {
+ TestCakeSession::init('/index.php');
+ $this->assertEquals('/', TestCakeSession::$path);
+
+ TestCakeSession::init('/sub_dir/index.php');
+ $this->assertEquals('/sub_dir/', TestCakeSession::$path);
+ }
+
+/**
+ * testCakeSessionPathEmpty
+ *
+ * @return void
+ */
+ public function testCakeSessionPathEmpty() {
+ TestCakeSession::init('');
+ $this->assertEquals('/', TestCakeSession::$path, 'Session path is empty, with "" as $base needs to be /');
+ }
+
+/**
+ * testCakeSessionPathContainsParams
+ *
+ * @return void
+ */
+ public function testCakeSessionPathContainsQuestion() {
+ TestCakeSession::init('/index.php?');
+ $this->assertEquals('/', TestCakeSession::$path);
+ }
+
+/**
+ * testSetHost
+ *
+ * @return void
+ */
+ public function testSetHost() {
+ TestCakeSession::init();
+ TestCakeSession::setHost('cakephp.org');
+ $this->assertEquals('cakephp.org', TestCakeSession::$host);
+ }
+
+/**
+ * testSetHostWithPort
+ *
+ * @return void
+ */
+ public function testSetHostWithPort() {
+ TestCakeSession::init();
+ TestCakeSession::setHost('cakephp.org:443');
+ $this->assertEquals('cakephp.org', TestCakeSession::$host);
+ }
+
+/**
+ * test valid with bogus user agent.
+ *
+ * @return void
+ */
+ public function testValidBogusUserAgent() {
+ Configure::write('Session.checkAgent', true);
+ TestCakeSession::start();
+ $this->assertTrue(TestCakeSession::valid(), 'Newly started session should be valid');
+
+ TestCakeSession::userAgent('bogus!');
+ $this->assertFalse(TestCakeSession::valid(), 'user agent mismatch should fail.');
+ }
+
+/**
+ * test valid with bogus user agent.
+ *
+ * @return void
+ */
+ public function testValidTimeExpiry() {
+ Configure::write('Session.checkAgent', true);
+ TestCakeSession::start();
+ $this->assertTrue(TestCakeSession::valid(), 'Newly started session should be valid');
+
+ TestCakeSession::$time = strtotime('next year');
+ $this->assertFalse(TestCakeSession::valid(), 'time should cause failure.');
+ }
+
+/**
+ * testCheck method
+ *
+ * @return void
+ */
+ public function testCheck() {
+ TestCakeSession::write('SessionTestCase', 'value');
+ $this->assertTrue(TestCakeSession::check('SessionTestCase'));
+
+ $this->assertFalse(TestCakeSession::check('NotExistingSessionTestCase'), false);
+ }
+
+/**
+ * testSimpleRead method
+ *
+ * @return void
+ */
+ public function testSimpleRead() {
+ TestCakeSession::write('testing', '1,2,3');
+ $result = TestCakeSession::read('testing');
+ $this->assertEquals('1,2,3', $result);
+
+ TestCakeSession::write('testing', array('1' => 'one', '2' => 'two','3' => 'three'));
+ $result = TestCakeSession::read('testing.1');
+ $this->assertEquals('one', $result);
+
+ $result = TestCakeSession::read('testing');
+ $this->assertEquals(array('1' => 'one', '2' => 'two', '3' => 'three'), $result);
+
+ $result = TestCakeSession::read();
+ $this->assertTrue(isset($result['testing']));
+ $this->assertTrue(isset($result['Config']));
+ $this->assertTrue(isset($result['Config']['userAgent']));
+
+ TestCakeSession::write('This.is.a.deep.array.my.friend', 'value');
+ $result = TestCakeSession::read('This.is.a.deep.array.my.friend');
+ $this->assertEquals('value', $result);
+ }
+
+/**
+ * testReadyEmpty
+ *
+ * @return void
+ */
+ public function testReadyEmpty() {
+ $this->assertFalse(TestCakeSession::read(''));
+ }
+
+/**
+ * test writing a hash of values/
+ *
+ * @return void
+ */
+ public function testWriteArray() {
+ $result = TestCakeSession::write(array(
+ 'one' => 1,
+ 'two' => 2,
+ 'three' => array('something'),
+ 'null' => null
+ ));
+ $this->assertTrue($result);
+ $this->assertEquals(1, TestCakeSession::read('one'));
+ $this->assertEquals(array('something'), TestCakeSession::read('three'));
+ $this->assertEquals(null, TestCakeSession::read('null'));
+ }
+
+/**
+ * testWriteEmptyKey
+ *
+ * @return void
+ */
+ public function testWriteEmptyKey() {
+ $this->assertFalse(TestCakeSession::write('', 'graham'));
+ $this->assertFalse(TestCakeSession::write('', ''));
+ $this->assertFalse(TestCakeSession::write(''));
+ }
+
+/**
+ * Test overwriting a string value as if it were an array.
+ *
+ * @return void
+ */
+ public function testWriteOverwriteStringValue() {
+ TestCakeSession::write('Some.string', 'value');
+ $this->assertEquals('value', TestCakeSession::read('Some.string'));
+
+ TestCakeSession::write('Some.string.array', array('values'));
+ $this->assertEquals(
+ array('values'),
+ TestCakeSession::read('Some.string.array')
+ );
+ }
+
+/**
+ * testId method
+ *
+ * @return void
+ */
+ public function testId() {
+ TestCakeSession::destroy();
+
+ $result = TestCakeSession::id();
+ $expected = session_id();
+ $this->assertEquals($expected, $result);
+
+ TestCakeSession::id('MySessionId');
+ $result = TestCakeSession::id();
+ $this->assertEquals('MySessionId', $result);
+ }
+
+/**
+ * testStarted method
+ *
+ * @return void
+ */
+ public function testStarted() {
+ unset($_SESSION);
+ $_SESSION = null;
+
+ $this->assertFalse(TestCakeSession::started());
+ $this->assertTrue(TestCakeSession::start());
+ $this->assertTrue(TestCakeSession::started());
+ }
+
+/**
+ * testError method
+ *
+ * @return void
+ */
+ public function testError() {
+ TestCakeSession::read('Does.not.exist');
+ $result = TestCakeSession::error();
+ $this->assertEquals("Does.not.exist doesn't exist", $result);
+
+ TestCakeSession::delete('Failing.delete');
+ $result = TestCakeSession::error();
+ $this->assertEquals("Failing.delete doesn't exist", $result);
+ }
+
+/**
+ * testDel method
+ *
+ * @return void
+ */
+ public function testDelete() {
+ $this->assertTrue(TestCakeSession::write('Delete.me', 'Clearing out'));
+ $this->assertTrue(TestCakeSession::delete('Delete.me'));
+ $this->assertFalse(TestCakeSession::check('Delete.me'));
+ $this->assertTrue(TestCakeSession::check('Delete'));
+
+ $this->assertTrue(TestCakeSession::write('Clearing.sale', 'everything must go'));
+ $this->assertTrue(TestCakeSession::delete('Clearing'));
+ $this->assertFalse(TestCakeSession::check('Clearing.sale'));
+ $this->assertFalse(TestCakeSession::check('Clearing'));
+ }
+
+/**
+ * testDestroy method
+ *
+ * @return void
+ */
+ public function testDestroy() {
+ TestCakeSession::write('bulletProof', 'invincible');
+ $id = TestCakeSession::id();
+ TestCakeSession::destroy();
+
+ $this->assertFalse(TestCakeSession::check('bulletProof'));
+ $this->assertNotEquals(TestCakeSession::id(), $id);
+ }
+
+/**
+ * testCheckingSavedEmpty method
+ *
+ * @return void
+ */
+ public function testCheckingSavedEmpty() {
+ $this->assertTrue(TestCakeSession::write('SessionTestCase', 0));
+ $this->assertTrue(TestCakeSession::check('SessionTestCase'));
+
+ $this->assertTrue(TestCakeSession::write('SessionTestCase', '0'));
+ $this->assertTrue(TestCakeSession::check('SessionTestCase'));
+
+ $this->assertTrue(TestCakeSession::write('SessionTestCase', false));
+ $this->assertTrue(TestCakeSession::check('SessionTestCase'));
+
+ $this->assertTrue(TestCakeSession::write('SessionTestCase', null));
+ $this->assertFalse(TestCakeSession::check('SessionTestCase'));
+ }
+
+/**
+ * testCheckKeyWithSpaces method
+ *
+ * @return void
+ */
+ public function testCheckKeyWithSpaces() {
+ $this->assertTrue(TestCakeSession::write('Session Test', "test"));
+ $this->assertTrue(TestCakeSession::check('Session Test'));
+ TestCakeSession::delete('Session Test');
+
+ $this->assertTrue(TestCakeSession::write('Session Test.Test Case', "test"));
+ $this->assertTrue(TestCakeSession::check('Session Test.Test Case'));
+ }
+
+/**
+ * testCheckEmpty
+ *
+ * @return void
+ */
+ public function testCheckEmpty() {
+ $this->assertFalse(TestCakeSession::check());
+ }
+
+/**
+ * test key exploitation
+ *
+ * @return void
+ */
+ public function testKeyExploit() {
+ $key = "a'] = 1; phpinfo(); \$_SESSION['a";
+ $result = TestCakeSession::write($key, 'haxored');
+ $this->assertTrue($result);
+
+ $result = TestCakeSession::read($key);
+ $this->assertEquals('haxored', $result);
+ }
+
+/**
+ * testReadingSavedEmpty method
+ *
+ * @return void
+ */
+ public function testReadingSavedEmpty() {
+ TestCakeSession::write('SessionTestCase', 0);
+ $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', '0');
+ $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
+ $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
+
+ TestCakeSession::write('SessionTestCase', false);
+ $this->assertFalse(TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', null);
+ $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
+ }
+
+/**
+ * testCheckUserAgentFalse method
+ *
+ * @return void
+ */
+ public function testCheckUserAgentFalse() {
+ Configure::write('Session.checkAgent', false);
+ TestCakeSession::setUserAgent(md5('http://randomdomainname.com' . Configure::read('Security.salt')));
+ $this->assertTrue(TestCakeSession::valid());
+ }
+
+/**
+ * testCheckUserAgentTrue method
+ *
+ * @return void
+ */
+ public function testCheckUserAgentTrue() {
+ Configure::write('Session.checkAgent', true);
+ TestCakeSession::$error = false;
+ $agent = md5('http://randomdomainname.com' . Configure::read('Security.salt'));
+
+ TestCakeSession::write('Config.userAgent', md5('Hacking you!'));
+ TestCakeSession::setUserAgent($agent);
+ $this->assertFalse(TestCakeSession::valid());
+ }
+
+/**
+ * testReadAndWriteWithCakeStorage method
+ *
+ * @return void
+ */
+ public function testReadAndWriteWithCakeStorage() {
+ Configure::write('Session.defaults', 'cake');
+
+ TestCakeSession::init();
+ TestCakeSession::start();
+
+ TestCakeSession::write('SessionTestCase', 0);
+ $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', '0');
+ $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
+ $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
+
+ TestCakeSession::write('SessionTestCase', false);
+ $this->assertFalse(TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', null);
+ $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', 'This is a Test');
+ $this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', 'This is a Test');
+ TestCakeSession::write('SessionTestCase', 'This was updated');
+ $this->assertEquals('This was updated', TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::destroy();
+ $this->assertNull(TestCakeSession::read('SessionTestCase'));
+ }
+
+/**
+ * test using a handler from app/Model/Datasource/Session.
+ *
+ * @return void
+ */
+ public function testUsingAppLibsHandler() {
+ App::build(array(
+ 'Model/Datasource/Session' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS . 'Datasource' . DS . 'Session' . DS
+ ),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ Configure::write('Session', array(
+ 'defaults' => 'cake',
+ 'handler' => array(
+ 'engine' => 'TestAppLibSession'
+ )
+ ));
+ TestCakeSession::destroy();
+ $this->assertTrue(TestCakeSession::started());
+
+ App::build();
+ }
+
+/**
+ * test using a handler from a plugin.
+ *
+ * @return void
+ */
+ public function testUsingPluginHandler() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load('TestPlugin');
+
+ Configure::write('Session', array(
+ 'defaults' => 'cake',
+ 'handler' => array(
+ 'engine' => 'TestPlugin.TestPluginSession'
+ )
+ ));
+
+ TestCakeSession::destroy();
+ $this->assertTrue(TestCakeSession::started());
+
+ App::build();
+ }
+
+/**
+ * testReadAndWriteWithCacheStorage method
+ *
+ * @return void
+ */
+ public function testReadAndWriteWithCacheStorage() {
+ Configure::write('Session.defaults', 'cache');
+ Configure::write('Session.handler.engine', 'TestCacheSession');
+
+ TestCakeSession::init();
+ TestCakeSession::destroy();
+
+ TestCakeSession::write('SessionTestCase', 0);
+ $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', '0');
+ $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
+ $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
+
+ TestCakeSession::write('SessionTestCase', false);
+ $this->assertFalse(TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', null);
+ $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', 'This is a Test');
+ $this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', 'This is a Test');
+ TestCakeSession::write('SessionTestCase', 'This was updated');
+ $this->assertEquals('This was updated', TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::destroy();
+ $this->assertNull(TestCakeSession::read('SessionTestCase'));
+ }
+
+/**
+ * test that changing the config name of the cache config works.
+ *
+ * @return void
+ */
+ public function testReadAndWriteWithCustomCacheConfig() {
+ Configure::write('Session.defaults', 'cache');
+ Configure::write('Session.handler.engine', 'TestCacheSession');
+ Configure::write('Session.handler.config', 'session_test');
+
+ Cache::config('session_test', array(
+ 'engine' => 'File',
+ 'prefix' => 'session_test_',
+ ));
+
+ TestCakeSession::init();
+ TestCakeSession::start();
+
+ TestCakeSession::write('SessionTestCase', 'Some value');
+ $this->assertEquals('Some value', TestCakeSession::read('SessionTestCase'));
+ $id = TestCakeSession::id();
+
+ Cache::delete($id, 'session_test');
+ }
+
+/**
+ * testReadAndWriteWithDatabaseStorage method
+ *
+ * @return void
+ */
+ public function testReadAndWriteWithDatabaseStorage() {
+ Configure::write('Session.defaults', 'database');
+ Configure::write('Session.handler.engine', 'TestDatabaseSession');
+ Configure::write('Session.handler.table', 'sessions');
+ Configure::write('Session.handler.model', 'Session');
+ Configure::write('Session.handler.database', 'test');
+
+ TestCakeSession::init();
+ $this->assertNull(TestCakeSession::id());
+
+ TestCakeSession::start();
+ $expected = session_id();
+ $this->assertEquals($expected, TestCakeSession::id());
+
+ TestCakeSession::renew();
+ $this->assertFalse($expected == TestCakeSession::id());
+
+ $expected = session_id();
+ $this->assertEquals($expected, TestCakeSession::id());
+
+ TestCakeSession::write('SessionTestCase', 0);
+ $this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', '0');
+ $this->assertEquals('0', TestCakeSession::read('SessionTestCase'));
+ $this->assertFalse(TestCakeSession::read('SessionTestCase') === 0);
+
+ TestCakeSession::write('SessionTestCase', false);
+ $this->assertFalse(TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', null);
+ $this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', 'This is a Test');
+ $this->assertEquals('This is a Test', TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::write('SessionTestCase', 'Some additional data');
+ $this->assertEquals('Some additional data', TestCakeSession::read('SessionTestCase'));
+
+ TestCakeSession::destroy();
+ $this->assertNull(TestCakeSession::read('SessionTestCase'));
+
+ Configure::write('Session', array(
+ 'defaults' => 'php'
+ ));
+ TestCakeSession::init();
+ }
+
+/**
+ * testSessionTimeout method
+ *
+ * @return void
+ */
+ public function testSessionTimeout() {
+ Configure::write('debug', 2);
+ Configure::write('Session.defaults', 'cake');
+ Configure::write('Session.autoRegenerate', false);
+
+ $timeoutSeconds = Configure::read('Session.timeout') * 60;
+
+ TestCakeSession::destroy();
+ TestCakeSession::write('Test', 'some value');
+
+ $this->assertWithinMargin(time() + $timeoutSeconds, CakeSession::$sessionTime, 1);
+ $this->assertEquals(10, $_SESSION['Config']['countdown']);
+ $this->assertWithinMargin(CakeSession::$sessionTime, $_SESSION['Config']['time'], 1);
+ $this->assertWithinMargin(time(), CakeSession::$time, 1);
+ $this->assertWithinMargin(time() + $timeoutSeconds, $_SESSION['Config']['time'], 1);
+
+ Configure::write('Session.harden', true);
+ TestCakeSession::destroy();
+
+ TestCakeSession::write('Test', 'some value');
+ $this->assertWithinMargin(time() + $timeoutSeconds, CakeSession::$sessionTime, 1);
+ $this->assertEquals(10, $_SESSION['Config']['countdown']);
+ $this->assertWithinMargin(CakeSession::$sessionTime, $_SESSION['Config']['time'], 1);
+ $this->assertWithinMargin(time(), CakeSession::$time, 1);
+ $this->assertWithinMargin(CakeSession::$time + $timeoutSeconds, $_SESSION['Config']['time'], 1);
+ }
+
+/**
+ * Test that cookieTimeout matches timeout when unspecified.
+ *
+ * @return void
+ */
+ public function testCookieTimeoutFallback() {
+ $_SESSION = null;
+ Configure::write('Session', array(
+ 'defaults' => 'cake',
+ 'timeout' => 400,
+ ));
+ TestCakeSession::start();
+ $this->assertEquals(400, Configure::read('Session.cookieTimeout'));
+ $this->assertEquals(400, Configure::read('Session.timeout'));
+ $this->assertEquals(400 * 60, ini_get('session.cookie_lifetime'));
+ $this->assertEquals(400 * 60, ini_get('session.gc_maxlifetime'));
+
+ $_SESSION = null;
+ Configure::write('Session', array(
+ 'defaults' => 'cake',
+ 'timeout' => 400,
+ 'cookieTimeout' => 600
+ ));
+ TestCakeSession::start();
+ $this->assertEquals(600, Configure::read('Session.cookieTimeout'));
+ $this->assertEquals(400, Configure::read('Session.timeout'));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php
new file mode 100644
index 0000000..3bb9bd0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DataSourceTest.php
@@ -0,0 +1,250 @@
+<?php
+/**
+ * DataSourceTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Datasource
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('DataSource', 'Model/Datasource');
+
+/**
+ * TestSource
+ *
+ * @package Cake.Test.Case.Model.Datasource
+ */
+class TestSource extends DataSource {
+
+/**
+ * _schema
+ * @var type
+ */
+ protected $_schema = array(
+ 'id' => array(
+ 'type' => 'integer',
+ 'null' => false,
+ 'key' => 'primary',
+ 'length' => 11,
+ ),
+ 'text' => array(
+ 'type' => 'string',
+ 'null' => true,
+ 'length' => 140,
+ ),
+ 'status' => array(
+ 'type' => 'string',
+ 'null' => true,
+ 'length' => 140,
+ ),
+ 'customField' => array(
+ 'type' => 'string',
+ 'null' => true,
+ 'length' => 255,
+ ),
+ );
+
+/**
+ * listSources
+ *
+ * @return boolean
+ */
+ public function listSources() {
+ return null;
+ }
+
+/**
+ * Returns the schema for the datasource to enable create/update
+ *
+ * @param object $Model
+ * @return array
+ */
+ public function describe(Model $Model) {
+ return $this->_schema;
+ }
+
+/**
+ * Just return $func to pass to read() to figure out the COUNT
+ * Required for delete/update to work
+ *
+ * @param Model $Model
+ * @param type $func
+ * @param type $params
+ * @return array
+ */
+ public function calculate(Model $Model, $func, $params = array()) {
+ return $func;
+ }
+
+}
+
+/**
+ * DataSourceTest class
+ *
+ * @package Cake.Test.Case.Model.Datasource
+ */
+class DataSourceTest extends CakeTestCase {
+
+/**
+ * Name of test source
+ *
+ * @var string
+ */
+ public $sourceName = 'myapitest';
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Source = $this->getMock(
+ 'TestSource',
+ array('create', 'read', 'update', 'delete')
+ );
+ ConnectionManager::create($this->sourceName, array(
+ 'datasource' => get_class($this->Source),
+ 'apiKey' => '1234abcd',
+ ));
+ $this->Model = $this->getMock(
+ 'Model',
+ array('getDataSource'),
+ array(array('ds' => $this->sourceName))
+ );
+ $this->Model->expects($this->any())
+ ->method('getDataSource')
+ ->will($this->returnValue($this->Source));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Model, $this->Source);
+ ConnectionManager::drop($this->sourceName);
+ }
+
+/**
+ * testCreate
+ *
+ * @return void
+ */
+ public function testCreate() {
+ $data = array(
+ $this->Model->alias => array(
+ 'text' => 'This is a test',
+ 'status' => 'Test status',
+ 'customField' => array(
+ 'array', 'field', 'type',
+ 'for', 'custom', 'datasources',
+ ),
+ ),
+ );
+ $this->Source->expects($this->once())
+ ->method('create')
+ ->with(
+ $this->equalTo($this->Model),
+ $this->equalTo(array_keys($data[$this->Model->alias])),
+ $this->equalTo(array_values($data[$this->Model->alias]))
+ );
+ $this->Model->save($data);
+ }
+
+/**
+ * testRead
+ *
+ * @return void
+ */
+ public function testRead() {
+ $expected = array(
+ 'conditions' => array('status' => 'test'),
+ 'fields' => null,
+ 'joins' => array(),
+ 'limit' => 10,
+ 'offset' => null,
+ 'order' => array(array('status')),
+ 'page' => 1,
+ 'group' => null,
+ 'callbacks' => true,
+ );
+ $this->Source->expects($this->once())
+ ->method('read')
+ ->with(
+ $this->anything(),
+ $this->equalTo($expected)
+ );
+ $this->Model->find('all', array(
+ 'conditions' => array('status' => 'test'),
+ 'limit' => 10,
+ 'order' => array('status'),
+ ));
+ }
+
+/**
+ * testUpdate
+ *
+ * @return void
+ */
+ public function testUpdate() {
+ $data = array(
+ $this->Model->alias => array(
+ 'id' => 1,
+ 'text' => 'This is a test',
+ 'status' => 'Test status',
+ 'customField' => array(
+ 'array', 'field', 'type',
+ 'for', 'custom', 'datasources',
+ ),
+ ),
+ );
+ $this->Source->expects($this->any())
+ ->method('read')
+ ->will($this->returnValue(array(
+ array($this->Model->alias => array('count' => 1))
+ )));
+ $this->Source->expects($this->once())
+ ->method('update')
+ ->with(
+ $this->equalTo($this->Model),
+ $this->equalTo(array_keys($data[$this->Model->alias])),
+ $this->equalTo(array_values($data[$this->Model->alias]))
+ );
+ $this->Model->save($data);
+ }
+
+/**
+ * testDelete
+ *
+ * @return void
+ */
+ public function testDelete() {
+ $this->Source->expects($this->any())
+ ->method('read')
+ ->will($this->returnValue(array(
+ array($this->Model->alias => array('count' => 1))
+ )));
+ $this->Source->expects($this->once())
+ ->method('delete')
+ ->with(
+ $this->equalTo($this->Model),
+ $this->equalTo(array($this->Model->alias . '.id' => 1))
+ );
+ $this->Model->delete(1);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php
new file mode 100644
index 0000000..dcd9aef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php
@@ -0,0 +1,3623 @@
+<?php
+/**
+ * DboMysqlTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model.Datasource.Database
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('Mysql', 'Model/Datasource/Database');
+App::uses('CakeSchema', 'Model');
+
+require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
+
+/**
+ * DboMysqlTest class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class MysqlTest extends CakeTestCase {
+
+/**
+ * autoFixtures property
+ *
+ * @var bool false
+ */
+ public $autoFixtures = false;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.apple', 'core.article', 'core.articles_tag', 'core.attachment', 'core.comment',
+ 'core.sample', 'core.tag', 'core.user', 'core.post', 'core.author', 'core.data_test',
+ 'core.binary_test', 'core.inno'
+ );
+
+/**
+ * The Dbo instance to be tested
+ *
+ * @var DboSource
+ */
+ public $Dbo = null;
+
+/**
+ * Sets up a Dbo class instance for testing
+ *
+ */
+ public function setUp() {
+ $this->Dbo = ConnectionManager::getDataSource('test');
+ if (!($this->Dbo instanceof Mysql)) {
+ $this->markTestSkipped('The MySQL extension is not available.');
+ }
+ $this->_debug = Configure::read('debug');
+ Configure::write('debug', 1);
+ $this->model = ClassRegistry::init('MysqlTestModel');
+ }
+
+/**
+ * Sets up a Dbo class instance for testing
+ *
+ */
+ public function tearDown() {
+ unset($this->model);
+ ClassRegistry::flush();
+ Configure::write('debug', $this->_debug);
+ }
+
+/**
+ * Test Dbo value method
+ *
+ * @group quoting
+ */
+ public function testQuoting() {
+ $result = $this->Dbo->fields($this->model);
+ $expected = array(
+ '`MysqlTestModel`.`id`',
+ '`MysqlTestModel`.`client_id`',
+ '`MysqlTestModel`.`name`',
+ '`MysqlTestModel`.`login`',
+ '`MysqlTestModel`.`passwd`',
+ '`MysqlTestModel`.`addr_1`',
+ '`MysqlTestModel`.`addr_2`',
+ '`MysqlTestModel`.`zip_code`',
+ '`MysqlTestModel`.`city`',
+ '`MysqlTestModel`.`country`',
+ '`MysqlTestModel`.`phone`',
+ '`MysqlTestModel`.`fax`',
+ '`MysqlTestModel`.`url`',
+ '`MysqlTestModel`.`email`',
+ '`MysqlTestModel`.`comments`',
+ '`MysqlTestModel`.`last_login`',
+ '`MysqlTestModel`.`created`',
+ '`MysqlTestModel`.`updated`'
+ );
+ $this->assertEquals($expected, $result);
+
+ $expected = 1.2;
+ $result = $this->Dbo->value(1.2, 'float');
+ $this->assertEquals($expected, $result);
+
+ $expected = "'1,2'";
+ $result = $this->Dbo->value('1,2', 'float');
+ $this->assertEquals($expected, $result);
+
+ $expected = "'4713e29446'";
+ $result = $this->Dbo->value('4713e29446');
+
+ $this->assertEquals($expected, $result);
+
+ $expected = 'NULL';
+ $result = $this->Dbo->value('', 'integer');
+ $this->assertEquals($expected, $result);
+
+ $expected = "'0'";
+ $result = $this->Dbo->value('', 'boolean');
+ $this->assertEquals($expected, $result);
+
+ $expected = 10010001;
+ $result = $this->Dbo->value(10010001);
+ $this->assertEquals($expected, $result);
+
+ $expected = "'00010010001'";
+ $result = $this->Dbo->value('00010010001');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that localized floats don't cause trouble.
+ *
+ * @group quoting
+ * @return void
+ */
+ public function testLocalizedFloats() {
+ $this->skipIf(DS === '\\', 'The locale is not supported in Windows and affect the others tests.');
+
+ $restore = setlocale(LC_NUMERIC, 0);
+ setlocale(LC_NUMERIC, 'de_DE');
+
+ $result = $this->Dbo->value(3.141593);
+ $this->assertEquals('3.141593', $result);
+
+ $result = $this->db->value(3.141593, 'float');
+ $this->assertEquals('3.141593', $result);
+
+ $result = $this->db->value(1234567.11, 'float');
+ $this->assertEquals('1234567.11', $result);
+
+ $result = $this->db->value(123456.45464748, 'float');
+ $this->assertContains('123456.454647', $result);
+
+ $result = $this->db->value(0.987654321, 'float');
+ $this->assertEquals('0.987654321', (string)$result);
+
+ $result = $this->db->value(2.2E-54, 'float');
+ $this->assertEquals('2.2E-54', (string)$result);
+
+ $result = $this->db->value(2.2E-54);
+ $this->assertEquals('2.2E-54', (string)$result);
+
+ setlocale(LC_NUMERIC, $restore);
+ }
+
+/**
+ * test that scientific notations are working correctly
+ *
+ * @return void
+ */
+ public function testScientificNotation() {
+ $result = $this->db->value(2.2E-54, 'float');
+ $this->assertEquals('2.2E-54', (string)$result);
+
+ $result = $this->db->value(2.2E-54);
+ $this->assertEquals('2.2E-54', (string)$result);
+ }
+
+/**
+ * testTinyintCasting method
+ *
+ *
+ * @return void
+ */
+ public function testTinyintCasting() {
+ $this->Dbo->cacheSources = false;
+ $tableName = 'tinyint_' . uniqid();
+ $this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
+
+ $this->model = new CakeTestModel(array(
+ 'name' => 'Tinyint', 'table' => $tableName, 'ds' => 'test'
+ ));
+
+ $result = $this->model->schema();
+ $this->assertEquals('boolean', $result['bool']['type']);
+ $this->assertEquals('integer', $result['small_int']['type']);
+
+ $this->assertTrue((bool)$this->model->save(array('bool' => 5, 'small_int' => 5)));
+ $result = $this->model->find('first');
+ $this->assertSame($result['Tinyint']['bool'], true);
+ $this->assertSame($result['Tinyint']['small_int'], '5');
+ $this->model->deleteAll(true);
+
+ $this->assertTrue((bool)$this->model->save(array('bool' => 0, 'small_int' => 100)));
+ $result = $this->model->find('first');
+ $this->assertSame($result['Tinyint']['bool'], false);
+ $this->assertSame($result['Tinyint']['small_int'], '100');
+ $this->model->deleteAll(true);
+
+ $this->assertTrue((bool)$this->model->save(array('bool' => true, 'small_int' => 0)));
+ $result = $this->model->find('first');
+ $this->assertSame($result['Tinyint']['bool'], true);
+ $this->assertSame($result['Tinyint']['small_int'], '0');
+ $this->model->deleteAll(true);
+
+ $this->Dbo->rawQuery('DROP TABLE ' . $this->Dbo->fullTableName($tableName));
+ }
+
+/**
+ * testLastAffected method
+ *
+ *
+ * @return void
+ */
+ public function testLastAffected() {
+ $this->Dbo->cacheSources = false;
+ $tableName = 'tinyint_' . uniqid();
+ $this->Dbo->rawQuery('CREATE TABLE ' . $this->Dbo->fullTableName($tableName) . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
+
+ $this->model = new CakeTestModel(array(
+ 'name' => 'Tinyint', 'table' => $tableName, 'ds' => 'test'
+ ));
+
+ $this->assertTrue((bool)$this->model->save(array('bool' => 5, 'small_int' => 5)));
+ $this->assertEquals(1, $this->model->find('count'));
+ $this->model->deleteAll(true);
+ $result = $this->Dbo->lastAffected();
+ $this->assertEquals(1, $result);
+ $this->assertEquals(0, $this->model->find('count'));
+
+ $this->Dbo->rawQuery('DROP TABLE ' . $this->Dbo->fullTableName($tableName));
+ }
+
+/**
+ * testIndexDetection method
+ *
+ * @group indices
+ * @return void
+ */
+ public function testIndexDetection() {
+ $this->Dbo->cacheSources = false;
+
+ $name = $this->Dbo->fullTableName('simple');
+ $this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id));');
+ $expected = array('PRIMARY' => array('column' => 'id', 'unique' => 1));
+ $result = $this->Dbo->index('simple', false);
+ $this->Dbo->rawQuery('DROP TABLE ' . $name);
+ $this->assertEquals($expected, $result);
+
+ $name = $this->Dbo->fullTableName('with_a_key');
+ $this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ));');
+ $expected = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'pointless_bool' => array('column' => 'bool', 'unique' => 0),
+ );
+ $result = $this->Dbo->index('with_a_key', false);
+ $this->Dbo->rawQuery('DROP TABLE ' . $name);
+ $this->assertEquals($expected, $result);
+
+ $name = $this->Dbo->fullTableName('with_two_keys');
+ $this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ));');
+ $expected = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'pointless_bool' => array('column' => 'bool', 'unique' => 0),
+ 'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
+ );
+ $result = $this->Dbo->index('with_two_keys', false);
+ $this->Dbo->rawQuery('DROP TABLE ' . $name);
+ $this->assertEquals($expected, $result);
+
+ $name = $this->Dbo->fullTableName('with_compound_keys');
+ $this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ), KEY `one_way` ( `bool`, `small_int` ));');
+ $expected = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'pointless_bool' => array('column' => 'bool', 'unique' => 0),
+ 'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
+ 'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
+ );
+ $result = $this->Dbo->index('with_compound_keys', false);
+ $this->Dbo->rawQuery('DROP TABLE ' . $name);
+ $this->assertEquals($expected, $result);
+
+ $name = $this->Dbo->fullTableName('with_multiple_compound_keys');
+ $this->Dbo->rawQuery('CREATE TABLE ' . $name . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id), KEY `pointless_bool` ( `bool` ), KEY `pointless_small_int` ( `small_int` ), KEY `one_way` ( `bool`, `small_int` ), KEY `other_way` ( `small_int`, `bool` ));');
+ $expected = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'pointless_bool' => array('column' => 'bool', 'unique' => 0),
+ 'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
+ 'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
+ 'other_way' => array('column' => array('small_int', 'bool'), 'unique' => 0),
+ );
+ $result = $this->Dbo->index('with_multiple_compound_keys', false);
+ $this->Dbo->rawQuery('DROP TABLE ' . $name);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBuildColumn method
+ *
+ * @return void
+ */
+ public function testBuildColumn() {
+ $restore = $this->Dbo->columns;
+ $this->Dbo->columns = array('varchar(255)' => 1);
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'varchar(255)',
+ 'default',
+ 'null' => true,
+ 'key',
+ 'comment' => 'test'
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`testName` DEFAULT NULL COMMENT \'test\'';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'varchar(255)',
+ 'default',
+ 'null' => true,
+ 'key',
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_unicode_ci'
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`testName` CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL';
+ $this->assertEquals($expected, $result);
+ $this->Dbo->columns = $restore;
+ }
+
+/**
+ * MySQL 4.x returns index data in a different format,
+ * Using a mock ensure that MySQL 4.x output is properly parsed.
+ *
+ * @group indices
+ * @return void
+ */
+ public function testIndexOnMySQL4Output() {
+ $name = $this->Dbo->fullTableName('simple');
+
+ $mockDbo = $this->getMock('Mysql', array('connect', '_execute', 'getVersion'));
+ $columnData = array(
+ array('0' => array(
+ 'Table' => 'with_compound_keys',
+ 'Non_unique' => '0',
+ 'Key_name' => 'PRIMARY',
+ 'Seq_in_index' => '1',
+ 'Column_name' => 'id',
+ 'Collation' => 'A',
+ 'Cardinality' => '0',
+ 'Sub_part' => null,
+ 'Packed' => null,
+ 'Null' => '',
+ 'Index_type' => 'BTREE',
+ 'Comment' => ''
+ )),
+ array('0' => array(
+ 'Table' => 'with_compound_keys',
+ 'Non_unique' => '1',
+ 'Key_name' => 'pointless_bool',
+ 'Seq_in_index' => '1',
+ 'Column_name' => 'bool',
+ 'Collation' => 'A',
+ 'Cardinality' => null,
+ 'Sub_part' => null,
+ 'Packed' => null,
+ 'Null' => 'YES',
+ 'Index_type' => 'BTREE',
+ 'Comment' => ''
+ )),
+ array('0' => array(
+ 'Table' => 'with_compound_keys',
+ 'Non_unique' => '1',
+ 'Key_name' => 'pointless_small_int',
+ 'Seq_in_index' => '1',
+ 'Column_name' => 'small_int',
+ 'Collation' => 'A',
+ 'Cardinality' => null,
+ 'Sub_part' => null,
+ 'Packed' => null,
+ 'Null' => 'YES',
+ 'Index_type' => 'BTREE',
+ 'Comment' => ''
+ )),
+ array('0' => array(
+ 'Table' => 'with_compound_keys',
+ 'Non_unique' => '1',
+ 'Key_name' => 'one_way',
+ 'Seq_in_index' => '1',
+ 'Column_name' => 'bool',
+ 'Collation' => 'A',
+ 'Cardinality' => null,
+ 'Sub_part' => null,
+ 'Packed' => null,
+ 'Null' => 'YES',
+ 'Index_type' => 'BTREE',
+ 'Comment' => ''
+ )),
+ array('0' => array(
+ 'Table' => 'with_compound_keys',
+ 'Non_unique' => '1',
+ 'Key_name' => 'one_way',
+ 'Seq_in_index' => '2',
+ 'Column_name' => 'small_int',
+ 'Collation' => 'A',
+ 'Cardinality' => null,
+ 'Sub_part' => null,
+ 'Packed' => null,
+ 'Null' => 'YES',
+ 'Index_type' => 'BTREE',
+ 'Comment' => ''
+ ))
+ );
+
+ $mockDbo->expects($this->once())->method('getVersion')->will($this->returnValue('4.1'));
+ $resultMock = $this->getMock('PDOStatement', array('fetch'));
+ $mockDbo->expects($this->once())
+ ->method('_execute')
+ ->with('SHOW INDEX FROM ' . $name)
+ ->will($this->returnValue($resultMock));
+
+ foreach ($columnData as $i => $data) {
+ $resultMock->expects($this->at($i))->method('fetch')->will($this->returnValue((object)$data));
+ }
+
+ $result = $mockDbo->index($name, false);
+ $expected = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'pointless_bool' => array('column' => 'bool', 'unique' => 0),
+ 'pointless_small_int' => array('column' => 'small_int', 'unique' => 0),
+ 'one_way' => array('column' => array('bool', 'small_int'), 'unique' => 0),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testColumn method
+ *
+ * @return void
+ */
+ public function testColumn() {
+ $result = $this->Dbo->column('varchar(50)');
+ $expected = 'string';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('text');
+ $expected = 'text';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('int(11)');
+ $expected = 'integer';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('int(11) unsigned');
+ $expected = 'integer';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('tinyint(1)');
+ $expected = 'boolean';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('boolean');
+ $expected = 'boolean';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('float');
+ $expected = 'float';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('float unsigned');
+ $expected = 'float';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('double unsigned');
+ $expected = 'float';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->column('decimal(14,7) unsigned');
+ $expected = 'float';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testAlterSchemaIndexes method
+ *
+ * @group indices
+ * @return void
+ */
+ public function testAlterSchemaIndexes() {
+ $this->Dbo->cacheSources = $this->Dbo->testing = false;
+ $table = $this->Dbo->fullTableName('altertest');
+
+ $schemaA = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'group1' => array('type' => 'integer', 'null' => true),
+ 'group2' => array('type' => 'integer', 'null' => true)
+ )));
+ $result = $this->Dbo->createSchema($schemaA);
+ $this->assertContains('`id` int(11) DEFAULT 0 NOT NULL,', $result);
+ $this->assertContains('`name` varchar(50) NOT NULL,', $result);
+ $this->assertContains('`group1` int(11) DEFAULT NULL', $result);
+ $this->assertContains('`group2` int(11) DEFAULT NULL', $result);
+
+ //Test that the string is syntactically correct
+ $query = $this->Dbo->getConnection()->prepare($result);
+ $this->assertEquals($query->queryString, $result);
+
+ $schemaB = new CakeSchema(array(
+ 'name' => 'AlterTest2',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'group1' => array('type' => 'integer', 'null' => true),
+ 'group2' => array('type' => 'integer', 'null' => true),
+ 'indexes' => array(
+ 'name_idx' => array('column' => 'name', 'unique' => 0),
+ 'group_idx' => array('column' => 'group1', 'unique' => 0),
+ 'compound_idx' => array('column' => array('group1', 'group2'), 'unique' => 0),
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1))
+ )));
+
+ $result = $this->Dbo->alterSchema($schemaB->compare($schemaA));
+ $this->assertContains("ALTER TABLE $table", $result);
+ $this->assertContains('ADD KEY name_idx (`name`),', $result);
+ $this->assertContains('ADD KEY group_idx (`group1`),', $result);
+ $this->assertContains('ADD KEY compound_idx (`group1`, `group2`),', $result);
+ $this->assertContains('ADD PRIMARY KEY (`id`);', $result);
+
+ //Test that the string is syntactically correct
+ $query = $this->Dbo->getConnection()->prepare($result);
+ $this->assertEquals($query->queryString, $result);
+
+ // Change three indexes, delete one and add another one
+ $schemaC = new CakeSchema(array(
+ 'name' => 'AlterTest3',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'group1' => array('type' => 'integer', 'null' => true),
+ 'group2' => array('type' => 'integer', 'null' => true),
+ 'indexes' => array(
+ 'name_idx' => array('column' => 'name', 'unique' => 1),
+ 'group_idx' => array('column' => 'group2', 'unique' => 0),
+ 'compound_idx' => array('column' => array('group2', 'group1'), 'unique' => 0),
+ 'id_name_idx' => array('column' => array('id', 'name'), 'unique' => 0))
+ )));
+
+ $result = $this->Dbo->alterSchema($schemaC->compare($schemaB));
+ $this->assertContains("ALTER TABLE $table", $result);
+ $this->assertContains('DROP PRIMARY KEY,', $result);
+ $this->assertContains('DROP KEY name_idx,', $result);
+ $this->assertContains('DROP KEY group_idx,', $result);
+ $this->assertContains('DROP KEY compound_idx,', $result);
+ $this->assertContains('ADD KEY id_name_idx (`id`, `name`),', $result);
+ $this->assertContains('ADD UNIQUE KEY name_idx (`name`),', $result);
+ $this->assertContains('ADD KEY group_idx (`group2`),', $result);
+ $this->assertContains('ADD KEY compound_idx (`group2`, `group1`);', $result);
+
+ $query = $this->Dbo->getConnection()->prepare($result);
+ $this->assertEquals($query->queryString, $result);
+
+ // Compare us to ourself.
+ $this->assertEquals(array(), $schemaC->compare($schemaC));
+
+ // Drop the indexes
+ $result = $this->Dbo->alterSchema($schemaA->compare($schemaC));
+
+ $this->assertContains("ALTER TABLE $table", $result);
+ $this->assertContains('DROP KEY name_idx,', $result);
+ $this->assertContains('DROP KEY group_idx,', $result);
+ $this->assertContains('DROP KEY compound_idx,', $result);
+ $this->assertContains('DROP KEY id_name_idx;', $result);
+
+ $query = $this->Dbo->getConnection()->prepare($result);
+ $this->assertEquals($query->queryString, $result);
+ }
+
+/**
+ * test saving and retrieval of blobs
+ *
+ * @return void
+ */
+ public function testBlobSaving() {
+ $this->loadFixtures('BinaryTest');
+ $this->Dbo->cacheSources = false;
+ $data = file_get_contents(CAKE . 'Test' . DS . 'test_app' . DS . 'webroot' . DS . 'img' . DS . 'cake.power.gif');
+
+ $model = new CakeTestModel(array('name' => 'BinaryTest', 'ds' => 'test'));
+ $model->save(compact('data'));
+
+ $result = $model->find('first');
+ $this->assertEquals($data, $result['BinaryTest']['data']);
+ }
+
+/**
+ * test altering the table settings with schema.
+ *
+ * @return void
+ */
+ public function testAlteringTableParameters() {
+ $this->Dbo->cacheSources = $this->Dbo->testing = false;
+
+ $schemaA = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'tableParameters' => array(
+ 'charset' => 'latin1',
+ 'collate' => 'latin1_general_ci',
+ 'engine' => 'MyISAM'
+ )
+ )
+ ));
+ $this->Dbo->rawQuery($this->Dbo->createSchema($schemaA));
+ $schemaB = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'tableParameters' => array(
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_general_ci',
+ 'engine' => 'InnoDB'
+ )
+ )
+ ));
+ $result = $this->Dbo->alterSchema($schemaB->compare($schemaA));
+ $this->assertContains('DEFAULT CHARSET=utf8', $result);
+ $this->assertContains('ENGINE=InnoDB', $result);
+ $this->assertContains('COLLATE=utf8_general_ci', $result);
+
+ $this->Dbo->rawQuery($result);
+ $result = $this->Dbo->listDetailedSources($this->Dbo->fullTableName('altertest', false, false));
+ $this->assertEquals('utf8_general_ci', $result['Collation']);
+ $this->assertEquals('InnoDB', $result['Engine']);
+ $this->assertEquals('utf8', $result['charset']);
+
+ $this->Dbo->rawQuery($this->Dbo->dropSchema($schemaA));
+ }
+
+/**
+ * test alterSchema on two tables.
+ *
+ * @return void
+ */
+ public function testAlteringTwoTables() {
+ $schema1 = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ ),
+ 'other_table' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ )
+ ));
+ $schema2 = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
+ ),
+ 'other_table' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
+ )
+ ));
+ $result = $this->Dbo->alterSchema($schema2->compare($schema1));
+ $this->assertEquals(2, substr_count($result, 'field_two'), 'Too many fields');
+ }
+
+/**
+ * testReadTableParameters method
+ *
+ * @return void
+ */
+ public function testReadTableParameters() {
+ $this->Dbo->cacheSources = $this->Dbo->testing = false;
+ $tableName = 'tinyint_' . uniqid();
+ $table = $this->Dbo->fullTableName($tableName);
+ $this->Dbo->rawQuery('CREATE TABLE ' . $table . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;');
+ $result = $this->Dbo->readTableParameters($this->Dbo->fullTableName($tableName, false, false));
+ $this->Dbo->rawQuery('DROP TABLE ' . $table);
+ $expected = array(
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_unicode_ci',
+ 'engine' => 'InnoDB');
+ $this->assertEquals($expected, $result);
+
+ $table = $this->Dbo->fullTableName($tableName);
+ $this->Dbo->rawQuery('CREATE TABLE ' . $table . ' (id int(11) AUTO_INCREMENT, bool tinyint(1), small_int tinyint(2), primary key(id)) ENGINE=MyISAM DEFAULT CHARSET=cp1250 COLLATE=cp1250_general_ci;');
+ $result = $this->Dbo->readTableParameters($this->Dbo->fullTableName($tableName, false, false));
+ $this->Dbo->rawQuery('DROP TABLE ' . $table);
+ $expected = array(
+ 'charset' => 'cp1250',
+ 'collate' => 'cp1250_general_ci',
+ 'engine' => 'MyISAM');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBuildTableParameters method
+ *
+ * @return void
+ */
+ public function testBuildTableParameters() {
+ $this->Dbo->cacheSources = $this->Dbo->testing = false;
+ $data = array(
+ 'charset' => 'utf8',
+ 'collate' => 'utf8_unicode_ci',
+ 'engine' => 'InnoDB');
+ $result = $this->Dbo->buildTableParameters($data);
+ $expected = array(
+ 'DEFAULT CHARSET=utf8',
+ 'COLLATE=utf8_unicode_ci',
+ 'ENGINE=InnoDB');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBuildTableParameters method
+ *
+ * @return void
+ */
+ public function testGetCharsetName() {
+ $this->Dbo->cacheSources = $this->Dbo->testing = false;
+ $result = $this->Dbo->getCharsetName('utf8_unicode_ci');
+ $this->assertEquals('utf8', $result);
+ $result = $this->Dbo->getCharsetName('cp1250_general_ci');
+ $this->assertEquals('cp1250', $result);
+ }
+
+/**
+ * test that changing the virtualFieldSeparator allows for __ fields.
+ *
+ * @return void
+ */
+ public function testVirtualFieldSeparators() {
+ $this->loadFixtures('BinaryTest');
+ $model = new CakeTestModel(array('table' => 'binary_tests', 'ds' => 'test', 'name' => 'BinaryTest'));
+ $model->virtualFields = array(
+ 'other__field' => 'SUM(id)'
+ );
+
+ $this->Dbo->virtualFieldSeparator = '_$_';
+ $result = $this->Dbo->fields($model, null, array('data', 'other__field'));
+
+ $expected = array('`BinaryTest`.`data`', '(SUM(id)) AS `BinaryTest_$_other__field`');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test describe() on a fixture.
+ *
+ * @return void
+ */
+ public function testDescribe() {
+ $this->loadFixtures('Apple');
+
+ $model = new Apple();
+ $result = $this->Dbo->describe($model);
+
+ $this->assertTrue(isset($result['id']));
+ $this->assertTrue(isset($result['color']));
+
+ $result = $this->Dbo->describe($model->useTable);
+
+ $this->assertTrue(isset($result['id']));
+ $this->assertTrue(isset($result['color']));
+ }
+
+/**
+ * test that a describe() gets additional fieldParameters
+ *
+ * @return void
+ */
+ public function testDescribeGettingFieldParameters() {
+ $schema = new CakeSchema(array(
+ 'connection' => 'test',
+ 'testdescribes' => array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'stringy' => array(
+ 'type' => 'string',
+ 'null' => true,
+ 'charset' => 'cp1250',
+ 'collate' => 'cp1250_general_ci',
+ ),
+ 'other_col' => array(
+ 'type' => 'string',
+ 'null' => false,
+ 'charset' => 'latin1',
+ 'comment' => 'Test Comment'
+ )
+ )
+ ));
+
+ $this->Dbo->execute($this->Dbo->createSchema($schema));
+ $model = new CakeTestModel(array('table' => 'testdescribes', 'name' => 'Testdescribes'));
+ $result = $model->getDataSource()->describe($model);
+ $this->Dbo->execute($this->Dbo->dropSchema($schema));
+
+ $this->assertEquals('cp1250_general_ci', $result['stringy']['collate']);
+ $this->assertEquals('cp1250', $result['stringy']['charset']);
+ $this->assertEquals('Test Comment', $result['other_col']['comment']);
+ }
+
+/**
+ * Tests that listSources method sends the correct query and parses the result accordingly
+ * @return void
+ */
+ public function testListSources() {
+ $db = $this->getMock('Mysql', array('connect', '_execute'));
+ $queryResult = $this->getMock('PDOStatement');
+ $db->expects($this->once())
+ ->method('_execute')
+ ->with('SHOW TABLES FROM `cake`')
+ ->will($this->returnValue($queryResult));
+ $queryResult->expects($this->at(0))
+ ->method('fetch')
+ ->will($this->returnValue(array('cake_table')));
+ $queryResult->expects($this->at(1))
+ ->method('fetch')
+ ->will($this->returnValue(array('another_table')));
+ $queryResult->expects($this->at(2))
+ ->method('fetch')
+ ->will($this->returnValue(null));
+
+ $tables = $db->listSources();
+ $this->assertEquals(array('cake_table', 'another_table'), $tables);
+ }
+
+/**
+ * test that listDetailedSources with a named table that doesn't exist.
+ *
+ * @return void
+ */
+ public function testListDetailedSourcesNamed() {
+ $this->loadFixtures('Apple');
+
+ $result = $this->Dbo->listDetailedSources('imaginary');
+ $this->assertEquals(array(), $result, 'Should be empty when table does not exist.');
+
+ $result = $this->Dbo->listDetailedSources();
+ $tableName = $this->Dbo->fullTableName('apples', false, false);
+ $this->assertTrue(isset($result[$tableName]), 'Key should exist');
+ }
+
+/**
+ * Tests that getVersion method sends the correct query for getting the mysql version
+ * @return void
+ */
+ public function testGetVersion() {
+ $version = $this->Dbo->getVersion();
+ $this->assertTrue(is_string($version));
+ }
+
+/**
+ * Tests that getVersion method sends the correct query for getting the client encoding
+ * @return void
+ */
+ public function testGetEncoding() {
+ $db = $this->getMock('Mysql', array('connect', '_execute'));
+ $queryResult = $this->getMock('PDOStatement');
+
+ $db->expects($this->once())
+ ->method('_execute')
+ ->with('SHOW VARIABLES LIKE ?', array('character_set_client'))
+ ->will($this->returnValue($queryResult));
+ $result = new StdClass;
+ $result->Value = 'utf-8';
+ $queryResult->expects($this->once())
+ ->method('fetchObject')
+ ->will($this->returnValue($result));
+
+ $encoding = $db->getEncoding();
+ $this->assertEquals('utf-8', $encoding);
+ }
+
+/**
+ * testFieldDoubleEscaping method
+ *
+ * @return void
+ */
+ public function testFieldDoubleEscaping() {
+ $db = $this->Dbo->config['database'];
+ $test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
+ $test->config['database'] = $db;
+
+ $this->Model = $this->getMock('Article2', array('getDataSource'));
+ $this->Model->alias = 'Article';
+ $this->Model->expects($this->any())
+ ->method('getDataSource')
+ ->will($this->returnValue($test));
+
+ $this->assertEquals('`Article`.`id`', $this->Model->escapeField());
+ $result = $test->fields($this->Model, null, $this->Model->escapeField());
+ $this->assertEquals(array('`Article`.`id`'), $result);
+
+ $test->expects($this->at(0))->method('execute')
+ ->with('SELECT `Article`.`id` FROM ' . $test->fullTableName('articles') . ' AS `Article` WHERE 1 = 1');
+
+ $result = $test->read($this->Model, array(
+ 'fields' => $this->Model->escapeField(),
+ 'conditions' => null,
+ 'recursive' => -1
+ ));
+
+ $test->startQuote = '[';
+ $test->endQuote = ']';
+ $this->assertEquals('[Article].[id]', $this->Model->escapeField());
+
+ $result = $test->fields($this->Model, null, $this->Model->escapeField());
+ $this->assertEquals(array('[Article].[id]'), $result);
+
+ $test->expects($this->at(0))->method('execute')
+ ->with('SELECT [Article].[id] FROM ' . $test->fullTableName('articles') . ' AS [Article] WHERE 1 = 1');
+ $result = $test->read($this->Model, array(
+ 'fields' => $this->Model->escapeField(),
+ 'conditions' => null,
+ 'recursive' => -1
+ ));
+ }
+
+/**
+ * testGenerateAssociationQuerySelfJoin method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQuerySelfJoin() {
+ $this->Dbo = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
+ $this->startTime = microtime(true);
+ $this->Model = new Article2();
+ $this->_buildRelatedModels($this->Model);
+ $this->_buildRelatedModels($this->Model->Category2);
+ $this->Model->Category2->ChildCat = new Category2();
+ $this->Model->Category2->ParentCat = new Category2();
+
+ $queryData = array();
+
+ foreach ($this->Model->Category2->associations() as $type) {
+ foreach ($this->Model->Category2->{$type} as $assoc => $assocData) {
+ $linkModel = $this->Model->Category2->{$assoc};
+ $external = isset($assocData['external']);
+
+ if ($this->Model->Category2->alias == $linkModel->alias && $type != 'hasAndBelongsToMany' && $type != 'hasMany') {
+ $result = $this->Dbo->generateAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null);
+ $this->assertFalse(empty($result));
+ } else {
+ if ($this->Model->Category2->useDbConfig == $linkModel->useDbConfig) {
+ $result = $this->Dbo->generateAssociationQuery($this->Model->Category2, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null);
+ $this->assertFalse(empty($result));
+ }
+ }
+ }
+ }
+
+ $query = $this->Dbo->generateAssociationQuery($this->Model->Category2, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+(.+)FROM(.+)`Category2`\.`group_id`\s+=\s+`Group`\.`id`\)\s+LEFT JOIN(.+)WHERE\s+1 = 1\s*$/', $query);
+
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'belongsTo', 'model' => 'TestModel4Parent');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $_queryData = $queryData;
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $expected = array(
+ 'conditions' => array(),
+ 'fields' => array(
+ '`TestModel4`.`id`',
+ '`TestModel4`.`name`',
+ '`TestModel4`.`created`',
+ '`TestModel4`.`updated`',
+ '`TestModel4Parent`.`id`',
+ '`TestModel4Parent`.`name`',
+ '`TestModel4Parent`.`created`',
+ '`TestModel4Parent`.`updated`'
+ ),
+ 'joins' => array(
+ array(
+ 'table' => $this->Dbo->fullTableName($this->Model),
+ 'alias' => 'TestModel4Parent',
+ 'type' => 'LEFT',
+ 'conditions' => '`TestModel4`.`parent_id` = `TestModel4Parent`.`id`'
+ )
+ ),
+ 'order' => array(),
+ 'limit' => array(),
+ 'offset' => array(),
+ 'group' => array(),
+ 'callbacks' => null
+ );
+ $queryData['joins'][0]['table'] = $this->Dbo->fullTableName($queryData['joins'][0]['table']);
+ $this->assertEquals($expected, $queryData);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
+ $this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+1 = 1\s+$/', $result);
+
+ $params['assocData']['type'] = 'INNER';
+ $this->Model->belongsTo['TestModel4Parent']['type'] = 'INNER';
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $_queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+ $this->assertEquals('INNER', $_queryData['joins'][0]['type']);
+ }
+
+/**
+ * buildRelatedModels method
+ *
+ * @param Model $model
+ * @return void
+ */
+ protected function _buildRelatedModels(Model $model) {
+ foreach ($model->associations() as $type) {
+ foreach ($model->{$type} as $assoc => $assocData) {
+ if (is_string($assocData)) {
+ $className = $assocData;
+ } elseif (isset($assocData['className'])) {
+ $className = $assocData['className'];
+ }
+ $model->$className = new $className();
+ $model->$className->schema();
+ }
+ }
+ }
+
+/**
+ * &_prepareAssociationQuery method
+ *
+ * @param Model $model
+ * @param array $queryData
+ * @param array $binding
+ * @return void
+ */
+ protected function &_prepareAssociationQuery(Model $model, &$queryData, $binding) {
+ $type = $binding['type'];
+ $assoc = $binding['model'];
+ $assocData = $model->{$type}[$assoc];
+ $className = $assocData['className'];
+
+ $linkModel = $model->{$className};
+ $external = isset($assocData['external']);
+ $queryData = $this->_scrubQueryData($queryData);
+
+ $result = array_merge(array('linkModel' => &$linkModel), compact('type', 'assoc', 'assocData', 'external'));
+ return $result;
+ }
+
+/**
+ * Helper method copied from DboSource::_scrubQueryData()
+ *
+ * @param array $data
+ * @return array
+ */
+ protected function _scrubQueryData($data) {
+ static $base = null;
+ if ($base === null) {
+ $base = array_fill_keys(array('conditions', 'fields', 'joins', 'order', 'limit', 'offset', 'group'), array());
+ $base['callbacks'] = null;
+ }
+ return (array)$data + $base;
+ }
+
+/**
+ * testGenerateInnerJoinAssociationQuery method
+ *
+ * @return void
+ */
+ public function testGenerateInnerJoinAssociationQuery() {
+ $db = $this->Dbo->config['database'];
+ $test = $this->getMock('Mysql', array('connect', '_execute', 'execute'));
+ $test->config['database'] = $db;
+
+ $this->Model = $this->getMock('TestModel9', array('getDataSource'));
+ $this->Model->expects($this->any())
+ ->method('getDataSource')
+ ->will($this->returnValue($test));
+
+ $this->Model->TestModel8 = $this->getMock('TestModel8', array('getDataSource'));
+ $this->Model->TestModel8->expects($this->any())
+ ->method('getDataSource')
+ ->will($this->returnValue($test));
+
+ $testModel8Table = $this->Model->TestModel8->getDataSource()->fullTableName($this->Model->TestModel8);
+
+ $test->expects($this->at(0))->method('execute')
+ ->with($this->stringContains('`TestModel9` LEFT JOIN ' . $testModel8Table));
+
+ $test->expects($this->at(1))->method('execute')
+ ->with($this->stringContains('TestModel9` INNER JOIN ' . $testModel8Table));
+
+ $test->read($this->Model, array('recursive' => 1));
+ $this->Model->belongsTo['TestModel8']['type'] = 'INNER';
+ $test->read($this->Model, array('recursive' => 1));
+ }
+
+/**
+ * testGenerateAssociationQuerySelfJoinWithConditionsInHasOneBinding method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQuerySelfJoinWithConditionsInHasOneBinding() {
+ $this->Model = new TestModel8();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasOne', 'model' => 'TestModel9');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel8`\.`id`, `TestModel8`\.`test_model9_id`, `TestModel8`\.`name`, `TestModel8`\.`created`, `TestModel8`\.`updated`, `TestModel9`\.`id`, `TestModel9`\.`test_model8_id`, `TestModel9`\.`name`, `TestModel9`\.`created`, `TestModel9`\.`updated`\s+/', $result);
+ $this->assertRegExp('/FROM\s+\S+`test_model8` AS `TestModel8`\s+LEFT JOIN\s+\S+`test_model9` AS `TestModel9`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel9`\.`name` != \'mariano\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQuerySelfJoinWithConditionsInBelongsToBinding method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQuerySelfJoinWithConditionsInBelongsToBinding() {
+ $this->Model = new TestModel9();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'belongsTo', 'model' => 'TestModel8');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel9`\.`id`, `TestModel9`\.`test_model8_id`, `TestModel9`\.`name`, `TestModel9`\.`created`, `TestModel9`\.`updated`, `TestModel8`\.`id`, `TestModel8`\.`test_model9_id`, `TestModel8`\.`name`, `TestModel8`\.`created`, `TestModel8`\.`updated`\s+/', $result);
+ $this->assertRegExp('/FROM\s+\S+`test_model9` AS `TestModel9`\s+LEFT JOIN\s+\S+`test_model8` AS `TestModel8`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel8`\.`name` != \'larry\'\s+AND\s+`TestModel9`.`test_model8_id` = `TestModel8`.`id`\)\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQuerySelfJoinWithConditions method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQuerySelfJoinWithConditions() {
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'belongsTo', 'model' => 'TestModel4Parent');
+ $queryData = array('conditions' => array('TestModel4Parent.name !=' => 'mariano'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
+ $this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?`TestModel4Parent`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
+
+ $this->Featured2 = new Featured2();
+ $this->Featured2->schema();
+
+ $this->Featured2->bindModel(array(
+ 'belongsTo' => array(
+ 'ArticleFeatured2' => array(
+ 'conditions' => 'ArticleFeatured2.published = \'Y\'',
+ 'fields' => 'id, title, user_id, published'
+ )
+ )
+ ));
+
+ $this->_buildRelatedModels($this->Featured2);
+
+ $binding = array('type' => 'belongsTo', 'model' => 'ArticleFeatured2');
+ $queryData = array('conditions' => array());
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Featured2, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Featured2, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+ $result = $this->Dbo->generateAssociationQuery($this->Featured2, $null, null, null, null, $queryData, false, $null);
+
+ $this->assertRegExp(
+ '/^SELECT\s+`Featured2`\.`id`, `Featured2`\.`article_id`, `Featured2`\.`category_id`, `Featured2`\.`name`,\s+' .
+ '`ArticleFeatured2`\.`id`, `ArticleFeatured2`\.`title`, `ArticleFeatured2`\.`user_id`, `ArticleFeatured2`\.`published`\s+' .
+ 'FROM\s+\S+`featured2` AS `Featured2`\s+LEFT JOIN\s+\S+`article_featured` AS `ArticleFeatured2`' .
+ '\s+ON\s+\(`ArticleFeatured2`.`published` = \'Y\'\s+AND\s+`Featured2`\.`article_featured2_id` = `ArticleFeatured2`\.`id`\)' .
+ '\s+WHERE\s+1\s+=\s+1\s*$/',
+ $result
+ );
+ }
+
+/**
+ * testGenerateAssociationQueryHasOne method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasOne() {
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasOne', 'model' => 'TestModel5');
+
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $testModel5Table = $this->Dbo->fullTableName($this->Model->TestModel5);
+ $result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
+ $expected = ' LEFT JOIN ' . $testModel5Table . ' AS `TestModel5` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
+ $this->assertEquals(trim($expected), trim($result));
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+/', $result);
+ $this->assertRegExp('/`test_model5` AS `TestModel5`\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryHasOneWithConditions method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasOneWithConditions() {
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasOne', 'model' => 'TestModel5');
+
+ $queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model5` AS `TestModel5`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id`\s+=\s+`TestModel4`.`id`\)\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?\s*`TestModel5`.`name`\s+!=\s+\'mariano\'\s*(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryBelongsTo method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryBelongsTo() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'belongsTo', 'model' => 'TestModel4');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $testModel4Table = $this->Dbo->fullTableName($this->Model->TestModel4, true, true);
+ $result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
+ $expected = ' LEFT JOIN ' . $testModel4Table . ' AS `TestModel4` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
+ $this->assertEquals(trim($expected), trim($result));
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`, `TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryBelongsToWithConditions method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryBelongsToWithConditions() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'belongsTo', 'model' => 'TestModel4');
+ $queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertTrue($result);
+
+ $testModel4Table = $this->Dbo->fullTableName($this->Model->TestModel4, true, true);
+ $result = $this->Dbo->buildJoinStatement($queryData['joins'][0]);
+ $expected = ' LEFT JOIN ' . $testModel4Table . ' AS `TestModel4` ON (`TestModel5`.`test_model4_id` = `TestModel4`.`id`)';
+ $this->assertEquals(trim($expected), trim($result));
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`, `TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel5`.`test_model4_id` = `TestModel4`.`id`\)\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+`TestModel5`.`name` != \'mariano\'\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryHasMany method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasMany() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+`TestModel6`.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?\s*1 = 1\s*(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryHasManyWithLimit method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasManyWithLimit() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $this->Model->hasMany['TestModel6']['limit'] = 2;
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp(
+ '/^SELECT\s+' .
+ '`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+' .
+ 'FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+' .
+ '`TestModel6`.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)\s*' .
+ 'LIMIT \d*' .
+ '\s*$/', $result
+ );
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp(
+ '/^SELECT\s+' .
+ '`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+' .
+ 'FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+' .
+ '(?:\()?\s*1 = 1\s*(?:\))?' .
+ '\s*$/', $result
+ );
+ }
+
+/**
+ * testGenerateAssociationQueryHasManyWithConditions method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasManyWithConditions() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('conditions' => array('TestModel5.name !=' => 'mariano'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?`TestModel5`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryHasManyWithOffsetAndLimit method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasManyWithOffsetAndLimit() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $backup = $this->Model->hasMany['TestModel6'];
+
+ $this->Model->hasMany['TestModel6']['offset'] = 2;
+ $this->Model->hasMany['TestModel6']['limit'] = 5;
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+ $this->assertRegExp('/\s+LIMIT 2,\s*5\s*$/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ $this->Model->hasMany['TestModel6'] = $backup;
+ }
+
+/**
+ * testGenerateAssociationQueryHasManyWithPageAndLimit method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasManyWithPageAndLimit() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $backup = $this->Model->hasMany['TestModel6'];
+
+ $this->Model->hasMany['TestModel6']['page'] = 2;
+ $this->Model->hasMany['TestModel6']['limit'] = 5;
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+ $this->assertRegExp('/\s+LIMIT 5,\s*5\s*$/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`test_model4_id`, `TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ $this->Model->hasMany['TestModel6'] = $backup;
+ }
+
+/**
+ * testGenerateAssociationQueryHasManyWithFields method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasManyWithFields() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('fields' => array('`TestModel5`.`name`'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('fields' => array('`TestModel5`.`id`, `TestModel5`.`name`'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('fields' => array('`TestModel5`.`name`', '`TestModel5`.`created`'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`, `TestModel6`\.`created`, `TestModel6`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ $this->Model->hasMany['TestModel6']['fields'] = array('name');
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ unset($this->Model->hasMany['TestModel6']['fields']);
+
+ $this->Model->hasMany['TestModel6']['fields'] = array('id', 'name');
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ unset($this->Model->hasMany['TestModel6']['fields']);
+
+ $this->Model->hasMany['TestModel6']['fields'] = array('test_model5_id', 'name');
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel6`\.`test_model5_id`, `TestModel6`\.`name`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+=\s+\({\$__cakeID__\$}\)(?:\))?/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ unset($this->Model->hasMany['TestModel6']['fields']);
+ }
+
+/**
+ * test generateAssociationQuery with a hasMany and an aggregate function.
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasManyAndAggregateFunction() {
+ $this->Model = new TestModel5();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasMany', 'model' => 'TestModel6');
+ $queryData = array('fields' => array('MIN(`TestModel5`.`test_model4_id`)'));
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+ $this->Model->recursive = 0;
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, $params['type'], $params['assoc'], $params['assocData'], $queryData, false, $resultSet);
+ $this->assertRegExp('/^SELECT\s+MIN\(`TestModel5`\.`test_model4_id`\)\s+FROM/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryHasAndBelongsToMany method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasAndBelongsToMany() {
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = $this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $assocTable = $this->Dbo->fullTableName($this->Model->TestModel4TestModel7, true, true);
+ $this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model7` AS `TestModel7`\s+JOIN\s+' . $assocTable . '/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}\s+AND/', $result);
+ $this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)/', $result);
+ $this->assertRegExp('/WHERE\s+(?:\()?1 = 1(?:\))?\s*$/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE/', $result);
+ $this->assertRegExp('/\s+WHERE\s+(?:\()?1 = 1(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryHasAndBelongsToManyWithConditions method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasAndBelongsToManyWithConditions() {
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
+ $queryData = array('conditions' => array('TestModel4.name !=' => 'mariano'));
+ $resultSet = null;
+ $null = null;
+
+ $params = $this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model7`\s+AS\s+`TestModel7`\s+JOIN\s+\S+`test_model4_test_model7`\s+AS\s+`TestModel4TestModel7`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}/', $result);
+ $this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?`TestModel4`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result);
+ }
+
+/**
+ * testGenerateAssociationQueryHasAndBelongsToManyWithOffsetAndLimit method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasAndBelongsToManyWithOffsetAndLimit() {
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $backup = $this->Model->hasAndBelongsToMany['TestModel7'];
+
+ $this->Model->hasAndBelongsToMany['TestModel7']['offset'] = 2;
+ $this->Model->hasAndBelongsToMany['TestModel7']['limit'] = 5;
+
+ $binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model7`\s+AS\s+`TestModel7`\s+JOIN\s+\S+`test_model4_test_model7`\s+AS\s+`TestModel4TestModel7`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}\s+/', $result);
+ $this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+(?:\()?1\s+=\s+1(?:\))?\s*\s+LIMIT 2,\s*5\s*$/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ $this->Model->hasAndBelongsToMany['TestModel7'] = $backup;
+ }
+
+/**
+ * testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit method
+ *
+ * @return void
+ */
+ public function testGenerateAssociationQueryHasAndBelongsToManyWithPageAndLimit() {
+ $this->Model = new TestModel4();
+ $this->Model->schema();
+ $this->_buildRelatedModels($this->Model);
+
+ $backup = $this->Model->hasAndBelongsToMany['TestModel7'];
+
+ $this->Model->hasAndBelongsToMany['TestModel7']['page'] = 2;
+ $this->Model->hasAndBelongsToMany['TestModel7']['limit'] = 5;
+
+ $binding = array('type' => 'hasAndBelongsToMany', 'model' => 'TestModel7');
+ $queryData = array();
+ $resultSet = null;
+ $null = null;
+
+ $params = &$this->_prepareAssociationQuery($this->Model, $queryData, $binding);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet);
+ $this->assertRegExp('/^SELECT\s+`TestModel7`\.`id`, `TestModel7`\.`name`, `TestModel7`\.`created`, `TestModel7`\.`updated`, `TestModel4TestModel7`\.`test_model4_id`, `TestModel4TestModel7`\.`test_model7_id`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model7`\s+AS\s+`TestModel7`\s+JOIN\s+\S+`test_model4_test_model7`\s+AS\s+`TestModel4TestModel7`/', $result);
+ $this->assertRegExp('/\s+ON\s+\(`TestModel4TestModel7`\.`test_model4_id`\s+=\s+{\$__cakeID__\$}/', $result);
+ $this->assertRegExp('/\s+AND\s+`TestModel4TestModel7`\.`test_model7_id`\s+=\s+`TestModel7`\.`id`\)\s+WHERE\s+/', $result);
+ $this->assertRegExp('/\s+(?:\()?1\s+=\s+1(?:\))?\s*\s+LIMIT 5,\s*5\s*$/', $result);
+
+ $result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);
+ $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`\s+/', $result);
+ $this->assertRegExp('/\s+FROM\s+\S+`test_model4` AS `TestModel4`\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result);
+
+ $this->Model->hasAndBelongsToMany['TestModel7'] = $backup;
+ }
+
+/**
+ * testSelectDistict method
+ *
+ * @return void
+ */
+ public function testSelectDistict() {
+ $this->Model = new TestModel4();
+ $result = $this->Dbo->fields($this->Model, 'Vendor', "DISTINCT Vendor.id, Vendor.name");
+ $expected = array('DISTINCT `Vendor`.`id`', '`Vendor`.`name`');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStringConditionsParsing method
+ *
+ * @return void
+ */
+ public function testStringConditionsParsing() {
+ $result = $this->Dbo->conditions("ProjectBid.project_id = Project.id");
+ $expected = " WHERE `ProjectBid`.`project_id` = `Project`.`id`";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("Candy.name LIKE 'a' AND HardCandy.name LIKE 'c'");
+ $expected = " WHERE `Candy`.`name` LIKE 'a' AND `HardCandy`.`name` LIKE 'c'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("HardCandy.name LIKE 'a' AND Candy.name LIKE 'c'");
+ $expected = " WHERE `HardCandy`.`name` LIKE 'a' AND `Candy`.`name` LIKE 'c'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("Post.title = '1.1'");
+ $expected = " WHERE `Post`.`title` = '1.1'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("User.id != 0 AND User.user LIKE '%arr%'");
+ $expected = " WHERE `User`.`id` != 0 AND `User`.`user` LIKE '%arr%'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("SUM(Post.comments_count) > 500");
+ $expected = " WHERE SUM(`Post`.`comments_count`) > 500";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("(Post.created < '" . date('Y-m-d H:i:s') . "') GROUP BY YEAR(Post.created), MONTH(Post.created)");
+ $expected = " WHERE (`Post`.`created` < '" . date('Y-m-d H:i:s') . "') GROUP BY YEAR(`Post`.`created`), MONTH(`Post`.`created`)";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("score BETWEEN 90.1 AND 95.7");
+ $expected = " WHERE score BETWEEN 90.1 AND 95.7";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('score' => array(2 => 1, 2, 10)));
+ $expected = " WHERE score IN (1, 2, 10)";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("Aro.rght = Aro.lft + 1.1");
+ $expected = " WHERE `Aro`.`rght` = `Aro`.`lft` + 1.1";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("(Post.created < '" . date('Y-m-d H:i:s') . "') GROUP BY YEAR(Post.created), MONTH(Post.created)");
+ $expected = " WHERE (`Post`.`created` < '" . date('Y-m-d H:i:s') . "') GROUP BY YEAR(`Post`.`created`), MONTH(`Post`.`created`)";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('Sportstaette.sportstaette LIKE "%ru%" AND Sportstaette.sportstaettenart_id = 2');
+ $expected = ' WHERE `Sportstaette`.`sportstaette` LIKE "%ru%" AND `Sportstaette`.`sportstaettenart_id` = 2';
+ $this->assertRegExp('/\s*WHERE\s+`Sportstaette`\.`sportstaette`\s+LIKE\s+"%ru%"\s+AND\s+`Sports/', $result);
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('Sportstaette.sportstaettenart_id = 2 AND Sportstaette.sportstaette LIKE "%ru%"');
+ $expected = ' WHERE `Sportstaette`.`sportstaettenart_id` = 2 AND `Sportstaette`.`sportstaette` LIKE "%ru%"';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('SUM(Post.comments_count) > 500 AND NOT Post.title IS NULL AND NOT Post.extended_title IS NULL');
+ $expected = ' WHERE SUM(`Post`.`comments_count`) > 500 AND NOT `Post`.`title` IS NULL AND NOT `Post`.`extended_title` IS NULL';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('NOT Post.title IS NULL AND NOT Post.extended_title IS NULL AND SUM(Post.comments_count) > 500');
+ $expected = ' WHERE NOT `Post`.`title` IS NULL AND NOT `Post`.`extended_title` IS NULL AND SUM(`Post`.`comments_count`) > 500';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('NOT Post.extended_title IS NULL AND NOT Post.title IS NULL AND Post.title != "" AND SPOON(SUM(Post.comments_count) + 1.1) > 500');
+ $expected = ' WHERE NOT `Post`.`extended_title` IS NULL AND NOT `Post`.`title` IS NULL AND `Post`.`title` != "" AND SPOON(SUM(`Post`.`comments_count`) + 1.1) > 500';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('NOT Post.title_extended IS NULL AND NOT Post.title IS NULL AND Post.title_extended != Post.title');
+ $expected = ' WHERE NOT `Post`.`title_extended` IS NULL AND NOT `Post`.`title` IS NULL AND `Post`.`title_extended` != `Post`.`title`';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("Comment.id = 'a'");
+ $expected = " WHERE `Comment`.`id` = 'a'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("lower(Article.title) LIKE 'a%'");
+ $expected = " WHERE lower(`Article`.`title`) LIKE 'a%'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('((MATCH(Video.title) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 2) + (MATCH(Video.description) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 0.4) + (MATCH(Video.tags) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 1.5))');
+ $expected = ' WHERE ((MATCH(`Video`.`title`) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 2) + (MATCH(`Video`.`description`) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 0.4) + (MATCH(`Video`.`tags`) AGAINST(\'My Search*\' IN BOOLEAN MODE) * 1.5))';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('DATEDIFF(NOW(),Article.published) < 1 && Article.live=1');
+ $expected = " WHERE DATEDIFF(NOW(),`Article`.`published`) < 1 && `Article`.`live`=1";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('file = "index.html"');
+ $expected = ' WHERE file = "index.html"';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions("file = 'index.html'");
+ $expected = " WHERE file = 'index.html'";
+ $this->assertEquals($expected, $result);
+
+ $letter = $letter = 'd.a';
+ $conditions = array('Company.name like ' => $letter . '%');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `Company`.`name` like 'd.a%'";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('Artist.name' => 'JUDY and MARY');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `Artist`.`name` = 'JUDY and MARY'";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('Artist.name' => 'JUDY AND MARY');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `Artist`.`name` = 'JUDY AND MARY'";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('Company.name similar to ' => 'a word');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `Company`.`name` similar to 'a word'";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testQuotesInStringConditions method
+ *
+ * @return void
+ */
+ public function testQuotesInStringConditions() {
+ $result = $this->Dbo->conditions('Member.email = \'mariano@cricava.com\'');
+ $expected = ' WHERE `Member`.`email` = \'mariano@cricava.com\'';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('Member.email = "mariano@cricava.com"');
+ $expected = ' WHERE `Member`.`email` = "mariano@cricava.com"';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('Member.email = \'mariano@cricava.com\' AND Member.user LIKE \'mariano.iglesias%\'');
+ $expected = ' WHERE `Member`.`email` = \'mariano@cricava.com\' AND `Member`.`user` LIKE \'mariano.iglesias%\'';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions('Member.email = "mariano@cricava.com" AND Member.user LIKE "mariano.iglesias%"');
+ $expected = ' WHERE `Member`.`email` = "mariano@cricava.com" AND `Member`.`user` LIKE "mariano.iglesias%"';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testParenthesisInStringConditions method
+ *
+ * @return void
+ */
+ public function testParenthesisInStringConditions() {
+ $result = $this->Dbo->conditions('Member.name = \'(lu\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(lu\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \')lu\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\)lu\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'va(lu\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'va)lu\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\)lu\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'va(lu)\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'va(lu)e\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)e\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'(mariano)\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'(mariano)iglesias\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)iglesias\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'(mariano) iglesias\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\) iglesias\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'(mariano word) iglesias\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano word\) iglesias\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'(mariano.iglesias)\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\)\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'Mariano Iglesias (mariano.iglesias)\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\)\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'Mariano Iglesias (mariano.iglesias) CakePHP\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\) CakePHP\'$/', $result);
+
+ $result = $this->Dbo->conditions('Member.name = \'(mariano.iglesias) CakePHP\'');
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\) CakePHP\'$/', $result);
+ }
+
+/**
+ * testParenthesisInArrayConditions method
+ *
+ * @return void
+ */
+ public function testParenthesisInArrayConditions() {
+ $result = $this->Dbo->conditions(array('Member.name' => '(lu'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(lu\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => ')lu'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\)lu\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => 'va(lu'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => 'va)lu'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\)lu\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => 'va(lu)'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => 'va(lu)e'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'va\(lu\)e\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => '(mariano)'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => '(mariano)iglesias'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\)iglesias\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => '(mariano) iglesias'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano\) iglesias\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => '(mariano word) iglesias'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano word\) iglesias\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => '(mariano.iglesias)'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\)\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => 'Mariano Iglesias (mariano.iglesias)'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\)\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => 'Mariano Iglesias (mariano.iglesias) CakePHP'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'Mariano Iglesias \(mariano.iglesias\) CakePHP\'$/', $result);
+
+ $result = $this->Dbo->conditions(array('Member.name' => '(mariano.iglesias) CakePHP'));
+ $this->assertRegExp('/^\s+WHERE\s+`Member`.`name`\s+=\s+\'\(mariano.iglesias\) CakePHP\'$/', $result);
+ }
+
+/**
+ * testArrayConditionsParsing method
+ *
+ * @return void
+ */
+ public function testArrayConditionsParsing() {
+ $this->loadFixtures('Post', 'Author');
+ $result = $this->Dbo->conditions(array('Stereo.type' => 'in dash speakers'));
+ $this->assertRegExp("/^\s+WHERE\s+`Stereo`.`type`\s+=\s+'in dash speakers'/", $result);
+
+ $result = $this->Dbo->conditions(array('Candy.name LIKE' => 'a', 'HardCandy.name LIKE' => 'c'));
+ $this->assertRegExp("/^\s+WHERE\s+`Candy`.`name` LIKE\s+'a'\s+AND\s+`HardCandy`.`name`\s+LIKE\s+'c'/", $result);
+
+ $result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'a', 'Candy.name LIKE' => 'c'));
+ $expected = " WHERE `HardCandy`.`name` LIKE 'a' AND `Candy`.`name` LIKE 'c'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'a%', 'Candy.name LIKE' => '%c%'));
+ $expected = " WHERE `HardCandy`.`name` LIKE 'a%' AND `Candy`.`name` LIKE '%c%'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('HardCandy.name LIKE' => 'to be or%', 'Candy.name LIKE' => '%not to be%'));
+ $expected = " WHERE `HardCandy`.`name` LIKE 'to be or%' AND `Candy`.`name` LIKE '%not to be%'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('score BETWEEN ? AND ?' => array(90.1, 95.7)));
+ $expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Post.title' => 1.1));
+ $expected = " WHERE `Post`.`title` = 1.1";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Post.title' => 1.1), true, true, new Post());
+ $expected = " WHERE `Post`.`title` = '1.1'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('SUM(Post.comments_count) >' => '500'));
+ $expected = " WHERE SUM(`Post`.`comments_count`) > '500'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('MAX(Post.rating) >' => '50'));
+ $expected = " WHERE MAX(`Post`.`rating`) > '50'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('lower(Article.title)' => 'secrets'));
+ $expected = " WHERE lower(`Article`.`title`) = 'secrets'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('title LIKE' => '%hello'));
+ $expected = " WHERE `title` LIKE '%hello'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Post.name' => 'mad(g)ik'));
+ $expected = " WHERE `Post`.`name` = 'mad(g)ik'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('score' => array(1, 2, 10)));
+ $expected = " WHERE score IN (1, 2, 10)";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('score' => array()));
+ $expected = " WHERE `score` IS NULL";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('score !=' => array()));
+ $expected = " WHERE `score` IS NOT NULL";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('score !=' => '20'));
+ $expected = " WHERE `score` != '20'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('score >' => '20'));
+ $expected = " WHERE `score` > '20'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('client_id >' => '20'), true, true, new TestModel());
+ $expected = " WHERE `client_id` > 20";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('OR' => array(
+ array('User.user' => 'mariano'),
+ array('User.user' => 'nate')
+ )));
+
+ $expected = " WHERE ((`User`.`user` = 'mariano') OR (`User`.`user` = 'nate'))";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('or' => array(
+ 'score BETWEEN ? AND ?' => array('4', '5'), 'rating >' => '20'
+ )));
+ $expected = " WHERE ((`score` BETWEEN '4' AND '5') OR (`rating` > '20'))";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('or' => array(
+ 'score BETWEEN ? AND ?' => array('4', '5'), array('score >' => '20')
+ )));
+ $expected = " WHERE ((`score` BETWEEN '4' AND '5') OR (`score` > '20'))";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('and' => array(
+ 'score BETWEEN ? AND ?' => array('4', '5'), array('score >' => '20')
+ )));
+ $expected = " WHERE ((`score` BETWEEN '4' AND '5') AND (`score` > '20'))";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(
+ 'published' => 1, 'or' => array('score >' => '2', array('score >' => '20'))
+ ));
+ $expected = " WHERE `published` = 1 AND ((`score` > '2') OR (`score` > '20'))";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(array('Project.removed' => false)));
+ $expected = " WHERE `Project`.`removed` = '0'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(array('Project.removed' => true)));
+ $expected = " WHERE `Project`.`removed` = '1'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(array('Project.removed' => null)));
+ $expected = " WHERE `Project`.`removed` IS NULL";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(array('Project.removed !=' => null)));
+ $expected = " WHERE `Project`.`removed` IS NOT NULL";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('(Usergroup.permissions) & 4' => 4));
+ $expected = " WHERE (`Usergroup`.`permissions`) & 4 = 4";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('((Usergroup.permissions) & 4)' => 4));
+ $expected = " WHERE ((`Usergroup`.`permissions`) & 4) = 4";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Post.modified >=' => 'DATE_SUB(NOW(), INTERVAL 7 DAY)'));
+ $expected = " WHERE `Post`.`modified` >= 'DATE_SUB(NOW(), INTERVAL 7 DAY)'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Post.modified >= DATE_SUB(NOW(), INTERVAL 7 DAY)'));
+ $expected = " WHERE `Post`.`modified` >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(
+ 'NOT' => array('Course.id' => null, 'Course.vet' => 'N', 'level_of_education_id' => array(912,999)),
+ 'Enrollment.yearcompleted >' => '0')
+ );
+ $this->assertRegExp('/^\s*WHERE\s+\(NOT\s+\(`Course`\.`id` IS NULL\)\s+AND NOT\s+\(`Course`\.`vet`\s+=\s+\'N\'\)\s+AND NOT\s+\(level_of_education_id IN \(912, 999\)\)\)\s+AND\s+`Enrollment`\.`yearcompleted`\s+>\s+\'0\'\s*$/', $result);
+
+ $result = $this->Dbo->conditions(array('id <>' => '8'));
+ $this->assertRegExp('/^\s*WHERE\s+`id`\s+<>\s+\'8\'\s*$/', $result);
+
+ $result = $this->Dbo->conditions(array('TestModel.field =' => 'gribe$@()lu'));
+ $expected = " WHERE `TestModel`.`field` = 'gribe$@()lu'";
+ $this->assertEquals($expected, $result);
+
+ $conditions['NOT'] = array('Listing.expiration BETWEEN ? AND ?' => array("1", "100"));
+ $conditions[0]['OR'] = array(
+ "Listing.title LIKE" => "%term%",
+ "Listing.description LIKE" => "%term%"
+ );
+ $conditions[1]['OR'] = array(
+ "Listing.title LIKE" => "%term_2%",
+ "Listing.description LIKE" => "%term_2%"
+ );
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE NOT (`Listing`.`expiration` BETWEEN '1' AND '100') AND" .
+ " ((`Listing`.`title` LIKE '%term%') OR (`Listing`.`description` LIKE '%term%')) AND" .
+ " ((`Listing`.`title` LIKE '%term_2%') OR (`Listing`.`description` LIKE '%term_2%'))";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('MD5(CONCAT(Reg.email,Reg.id))' => 'blah'));
+ $expected = " WHERE MD5(CONCAT(`Reg`.`email`,`Reg`.`id`)) = 'blah'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(
+ 'MD5(CONCAT(Reg.email,Reg.id))' => array('blah', 'blahblah')
+ ));
+ $expected = " WHERE MD5(CONCAT(`Reg`.`email`,`Reg`.`id`)) IN ('blah', 'blahblah')";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('id' => array(2, 5, 6, 9, 12, 45, 78, 43, 76));
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE id IN (2, 5, 6, 9, 12, 45, 78, 43, 76)";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('title' => 'user(s)');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `title` = 'user(s)'";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('title' => 'user(s) data');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `title` = 'user(s) data'";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('title' => 'user(s,arg) data');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `title` = 'user(s,arg) data'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array("Book.book_name" => 'Java(TM)'));
+ $expected = " WHERE `Book`.`book_name` = 'Java(TM)'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array("Book.book_name" => 'Java(TM) '));
+ $expected = " WHERE `Book`.`book_name` = 'Java(TM) '";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array("Book.id" => 0));
+ $expected = " WHERE `Book`.`id` = 0";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array("Book.id" => null));
+ $expected = " WHERE `Book`.`id` IS NULL";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('MysqlModel.id' => '');
+ $result = $this->Dbo->conditions($conditions, true, true, $this->model);
+ $expected = " WHERE `MysqlModel`.`id` IS NULL";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Listing.beds >=' => 0));
+ $expected = " WHERE `Listing`.`beds` >= 0";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(
+ 'ASCII(SUBSTRING(keyword, 1, 1)) BETWEEN ? AND ?' => array(65, 90)
+ ));
+ $expected = ' WHERE ASCII(SUBSTRING(keyword, 1, 1)) BETWEEN 65 AND 90';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('or' => array(
+ '? BETWEEN Model.field1 AND Model.field2' => '2009-03-04'
+ )));
+ $expected = " WHERE '2009-03-04' BETWEEN Model.field1 AND Model.field2";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testArrayConditionsParsingComplexKeys method
+ *
+ * @return void
+ */
+ public function testArrayConditionsParsingComplexKeys() {
+ $result = $this->Dbo->conditions(array(
+ 'CAST(Book.created AS DATE)' => '2008-08-02'
+ ));
+ $expected = " WHERE CAST(`Book`.`created` AS DATE) = '2008-08-02'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(
+ 'CAST(Book.created AS DATE) <=' => '2008-08-02'
+ ));
+ $expected = " WHERE CAST(`Book`.`created` AS DATE) <= '2008-08-02'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array(
+ '(Stats.clicks * 100) / Stats.views >' => 50
+ ));
+ $expected = " WHERE (`Stats`.`clicks` * 100) / `Stats`.`views` > 50";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMixedConditionsParsing method
+ *
+ * @return void
+ */
+ public function testMixedConditionsParsing() {
+ $conditions[] = 'User.first_name = \'Firstname\'';
+ $conditions[] = array('User.last_name' => 'Lastname');
+ $result = $this->Dbo->conditions($conditions);
+ $expected = " WHERE `User`.`first_name` = 'Firstname' AND `User`.`last_name` = 'Lastname'";
+ $this->assertEquals($expected, $result);
+
+ $conditions = array(
+ 'Thread.project_id' => 5,
+ 'Thread.buyer_id' => 14,
+ '1=1 GROUP BY Thread.project_id'
+ );
+ $result = $this->Dbo->conditions($conditions);
+ $this->assertRegExp('/^\s*WHERE\s+`Thread`.`project_id`\s*=\s*5\s+AND\s+`Thread`.`buyer_id`\s*=\s*14\s+AND\s+1\s*=\s*1\s+GROUP BY `Thread`.`project_id`$/', $result);
+ }
+
+/**
+ * testConditionsOptionalArguments method
+ *
+ * @return void
+ */
+ public function testConditionsOptionalArguments() {
+ $result = $this->Dbo->conditions(array('Member.name' => 'Mariano'), true, false);
+ $this->assertRegExp('/^\s*`Member`.`name`\s*=\s*\'Mariano\'\s*$/', $result);
+
+ $result = $this->Dbo->conditions(array(), true, false);
+ $this->assertRegExp('/^\s*1\s*=\s*1\s*$/', $result);
+ }
+
+/**
+ * testConditionsWithModel
+ *
+ * @return void
+ */
+ public function testConditionsWithModel() {
+ $this->Model = new Article2();
+
+ $result = $this->Dbo->conditions(array('Article2.viewed >=' => 0), true, true, $this->Model);
+ $expected = " WHERE `Article2`.`viewed` >= 0";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Article2.viewed >=' => '0'), true, true, $this->Model);
+ $expected = " WHERE `Article2`.`viewed` >= 0";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Article2.viewed >=' => '1'), true, true, $this->Model);
+ $expected = " WHERE `Article2`.`viewed` >= 1";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array(0, 10)), true, true, $this->Model);
+ $expected = " WHERE `Article2`.`rate_sum` BETWEEN 0 AND 10";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array('0', '10')), true, true, $this->Model);
+ $expected = " WHERE `Article2`.`rate_sum` BETWEEN 0 AND 10";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->conditions(array('Article2.rate_sum BETWEEN ? AND ?' => array('1', '10')), true, true, $this->Model);
+ $expected = " WHERE `Article2`.`rate_sum` BETWEEN 1 AND 10";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFieldParsing method
+ *
+ * @return void
+ */
+ public function testFieldParsing() {
+ $this->Model = new TestModel();
+ $result = $this->Dbo->fields($this->Model, 'Vendor', "Vendor.id, COUNT(Model.vendor_id) AS `Vendor`.`count`");
+ $expected = array('`Vendor`.`id`', 'COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, 'Vendor', "`Vendor`.`id`, COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`");
+ $expected = array('`Vendor`.`id`', 'COUNT(`Model`.`vendor_id`) AS `Vendor`.`count`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, 'Post', "CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name, Node.created");
+ $expected = array("CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name", "`Node`.`created`");
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, 'round( (3.55441 * fooField), 3 ) AS test');
+ $this->assertEquals(array('round( (3.55441 * fooField), 3 ) AS test'), $result);
+
+ $result = $this->Dbo->fields($this->Model, null, 'ROUND(`Rating`.`rate_total` / `Rating`.`rate_count`,2) AS rating');
+ $this->assertEquals(array('ROUND(`Rating`.`rate_total` / `Rating`.`rate_count`,2) AS rating'), $result);
+
+ $result = $this->Dbo->fields($this->Model, null, 'ROUND(Rating.rate_total / Rating.rate_count,2) AS rating');
+ $this->assertEquals(array('ROUND(Rating.rate_total / Rating.rate_count,2) AS rating'), $result);
+
+ $result = $this->Dbo->fields($this->Model, 'Post', "Node.created, CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name");
+ $expected = array("`Node`.`created`", "CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name");
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, 'Post', "2.2,COUNT(*), SUM(Something.else) as sum, Node.created, CONCAT(REPEAT(' ', COUNT(Parent.name) - 1), Node.name) AS name,Post.title,Post.1,1.1");
+ $expected = array(
+ '2.2', 'COUNT(*)', 'SUM(`Something`.`else`) as sum', '`Node`.`created`',
+ "CONCAT(REPEAT(' ', COUNT(`Parent`.`name`) - 1), Node.name) AS name", '`Post`.`title`', '`Post`.`1`', '1.1'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, "(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
+ $expected = array("(`Provider`.`star_total` / `Provider`.`total_ratings`) as `rating`");
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, 'Post');
+ $expected = array(
+ '`Post`.`id`', '`Post`.`client_id`', '`Post`.`name`', '`Post`.`login`',
+ '`Post`.`passwd`', '`Post`.`addr_1`', '`Post`.`addr_2`', '`Post`.`zip_code`',
+ '`Post`.`city`', '`Post`.`country`', '`Post`.`phone`', '`Post`.`fax`',
+ '`Post`.`url`', '`Post`.`email`', '`Post`.`comments`', '`Post`.`last_login`',
+ '`Post`.`created`', '`Post`.`updated`'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, 'Other');
+ $expected = array(
+ '`Other`.`id`', '`Other`.`client_id`', '`Other`.`name`', '`Other`.`login`',
+ '`Other`.`passwd`', '`Other`.`addr_1`', '`Other`.`addr_2`', '`Other`.`zip_code`',
+ '`Other`.`city`', '`Other`.`country`', '`Other`.`phone`', '`Other`.`fax`',
+ '`Other`.`url`', '`Other`.`email`', '`Other`.`comments`', '`Other`.`last_login`',
+ '`Other`.`created`', '`Other`.`updated`'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, array(), false);
+ $expected = array('id', 'client_id', 'name', 'login', 'passwd', 'addr_1', 'addr_2', 'zip_code', 'city', 'country', 'phone', 'fax', 'url', 'email', 'comments', 'last_login', 'created', 'updated');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, 'COUNT(*)');
+ $expected = array('COUNT(*)');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, 'SUM(Thread.unread_buyer) AS ' . $this->Dbo->name('sum_unread_buyer'));
+ $expected = array('SUM(`Thread`.`unread_buyer`) AS `sum_unread_buyer`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, 'name, count(*)');
+ $expected = array('`TestModel`.`name`', 'count(*)');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, 'count(*), name');
+ $expected = array('count(*)', '`TestModel`.`name`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields(
+ $this->Model, null, 'field1, field2, field3, count(*), name'
+ );
+ $expected = array(
+ '`TestModel`.`field1`', '`TestModel`.`field2`',
+ '`TestModel`.`field3`', 'count(*)', '`TestModel`.`name`'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, array('dayofyear(now())'));
+ $expected = array('dayofyear(now())');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, array('MAX(Model.field) As Max'));
+ $expected = array('MAX(`Model`.`field`) As Max');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, array('Model.field AS AnotherName'));
+ $expected = array('`Model`.`field` AS `AnotherName`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, array('field AS AnotherName'));
+ $expected = array('`field` AS `AnotherName`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, null, array(
+ 'TestModel.field AS AnotherName'
+ ));
+ $expected = array('`TestModel`.`field` AS `AnotherName`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->Model, 'Foo', array(
+ 'id', 'title', '(user_count + discussion_count + post_count) AS score'
+ ));
+ $expected = array(
+ '`Foo`.`id`',
+ '`Foo`.`title`',
+ '(user_count + discussion_count + post_count) AS score'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that fields() will accept objects made from DboSource::expression
+ *
+ * @return void
+ */
+ public function testFieldsWithExpression() {
+ $this->Model = new TestModel;
+ $expression = $this->Dbo->expression("CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col");
+ $result = $this->Dbo->fields($this->Model, null, array("id", $expression));
+ $expected = array(
+ '`TestModel`.`id`',
+ "CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col"
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRenderStatement method
+ *
+ * @return void
+ */
+ public function testRenderStatement() {
+ $result = $this->Dbo->renderStatement('select', array(
+ 'fields' => 'id', 'table' => 'table', 'conditions' => 'WHERE 1=1',
+ 'alias' => '', 'joins' => '', 'order' => '', 'limit' => '', 'group' => ''
+ ));
+ $this->assertRegExp('/^\s*SELECT\s+id\s+FROM\s+table\s+WHERE\s+1=1\s*$/', $result);
+
+ $result = $this->Dbo->renderStatement('update', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => ''));
+ $this->assertRegExp('/^\s*UPDATE\s+table\s+SET\s+value=2\s+WHERE\s+1=1\s*$/', $result);
+
+ $result = $this->Dbo->renderStatement('update', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => 'alias', 'joins' => ''));
+ $this->assertRegExp('/^\s*UPDATE\s+table\s+AS\s+alias\s+SET\s+value=2\s+WHERE\s+1=1\s*$/', $result);
+
+ $result = $this->Dbo->renderStatement('delete', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => ''));
+ $this->assertRegExp('/^\s*DELETE\s+FROM\s+table\s+WHERE\s+1=1\s*$/', $result);
+
+ $result = $this->Dbo->renderStatement('delete', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => 'alias', 'joins' => ''));
+ $this->assertRegExp('/^\s*DELETE\s+alias\s+FROM\s+table\s+AS\s+alias\s+WHERE\s+1=1\s*$/', $result);
+ }
+
+/**
+ * testSchema method
+ *
+ * @return void
+ */
+ public function testSchema() {
+ $Schema = new CakeSchema();
+ $Schema->tables = array('table' => array(), 'anotherTable' => array());
+
+ $result = $this->Dbo->dropSchema($Schema, 'non_existing');
+ $this->assertTrue(empty($result));
+
+ $result = $this->Dbo->dropSchema($Schema, 'table');
+ $this->assertRegExp('/^\s*DROP TABLE IF EXISTS\s+' . $this->Dbo->fullTableName('table') . ';\s*$/s', $result);
+ }
+
+/**
+ * testDropSchemaNoSchema method
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testDropSchemaNoSchema() {
+ $result = $this->Dbo->dropSchema(null);
+ }
+
+/**
+ * testOrderParsing method
+ *
+ * @return void
+ */
+ public function testOrderParsing() {
+ $result = $this->Dbo->order("ADDTIME(Event.time_begin, '-06:00:00') ASC");
+ $expected = " ORDER BY ADDTIME(`Event`.`time_begin`, '-06:00:00') ASC";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->order("title, id");
+ $this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
+
+ $result = $this->Dbo->order("title desc, id desc");
+ $this->assertRegExp('/^\s*ORDER BY\s+`title`\s+desc,\s+`id`\s+desc\s*$/', $result);
+
+ $result = $this->Dbo->order(array("title desc, id desc"));
+ $this->assertRegExp('/^\s*ORDER BY\s+`title`\s+desc,\s+`id`\s+desc\s*$/', $result);
+
+ $result = $this->Dbo->order(array("title", "id"));
+ $this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
+
+ $result = $this->Dbo->order(array(array('title'), array('id')));
+ $this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC,\s+`id`\s+ASC\s*$/', $result);
+
+ $result = $this->Dbo->order(array("Post.title" => 'asc', "Post.id" => 'desc'));
+ $this->assertRegExp('/^\s*ORDER BY\s+`Post`.`title`\s+asc,\s+`Post`.`id`\s+desc\s*$/', $result);
+
+ $result = $this->Dbo->order(array(array("Post.title" => 'asc', "Post.id" => 'desc')));
+ $this->assertRegExp('/^\s*ORDER BY\s+`Post`.`title`\s+asc,\s+`Post`.`id`\s+desc\s*$/', $result);
+
+ $result = $this->Dbo->order(array("title"));
+ $this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC\s*$/', $result);
+
+ $result = $this->Dbo->order(array(array("title")));
+ $this->assertRegExp('/^\s*ORDER BY\s+`title`\s+ASC\s*$/', $result);
+
+ $result = $this->Dbo->order("Dealer.id = 7 desc, Dealer.id = 3 desc, Dealer.title asc");
+ $expected = " ORDER BY `Dealer`.`id` = 7 desc, `Dealer`.`id` = 3 desc, `Dealer`.`title` asc";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->order(array("Page.name" => "='test' DESC"));
+ $this->assertRegExp("/^\s*ORDER BY\s+`Page`\.`name`\s*='test'\s+DESC\s*$/", $result);
+
+ $result = $this->Dbo->order("Page.name = 'view' DESC");
+ $this->assertRegExp("/^\s*ORDER BY\s+`Page`\.`name`\s*=\s*'view'\s+DESC\s*$/", $result);
+
+ $result = $this->Dbo->order("(Post.views)");
+ $this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\)\s+ASC\s*$/", $result);
+
+ $result = $this->Dbo->order("(Post.views)*Post.views");
+ $this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\)\*`Post`\.`views`\s+ASC\s*$/", $result);
+
+ $result = $this->Dbo->order("(Post.views) * Post.views");
+ $this->assertRegExp("/^\s*ORDER BY\s+\(`Post`\.`views`\) \* `Post`\.`views`\s+ASC\s*$/", $result);
+
+ $result = $this->Dbo->order("(Model.field1 + Model.field2) * Model.field3");
+ $this->assertRegExp("/^\s*ORDER BY\s+\(`Model`\.`field1` \+ `Model`\.`field2`\) \* `Model`\.`field3`\s+ASC\s*$/", $result);
+
+ $result = $this->Dbo->order("Model.name+0 ASC");
+ $this->assertRegExp("/^\s*ORDER BY\s+`Model`\.`name`\+0\s+ASC\s*$/", $result);
+
+ $result = $this->Dbo->order("Anuncio.destaque & 2 DESC");
+ $expected = ' ORDER BY `Anuncio`.`destaque` & 2 DESC';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->order("3963.191 * id");
+ $expected = ' ORDER BY 3963.191 * id ASC';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->order(array('Property.sale_price IS NULL'));
+ $expected = ' ORDER BY `Property`.`sale_price` IS NULL ASC';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testComplexSortExpression method
+ *
+ * @return void
+ */
+ public function testComplexSortExpression() {
+ $result = $this->Dbo->order(array('(Model.field > 100) DESC', 'Model.field ASC'));
+ $this->assertRegExp("/^\s*ORDER BY\s+\(`Model`\.`field`\s+>\s+100\)\s+DESC,\s+`Model`\.`field`\s+ASC\s*$/", $result);
+ }
+
+/**
+ * testCalculations method
+ *
+ * @return void
+ */
+ public function testCalculations() {
+ $this->Model = new TestModel();
+ $result = $this->Dbo->calculate($this->Model, 'count');
+ $this->assertEquals('COUNT(*) AS `count`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'count', array('id'));
+ $this->assertEquals('COUNT(`id`) AS `count`', $result);
+
+ $result = $this->Dbo->calculate(
+ $this->Model,
+ 'count',
+ array($this->Dbo->expression('DISTINCT id'))
+ );
+ $this->assertEquals('COUNT(DISTINCT id) AS `count`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'count', array('id', 'id_count'));
+ $this->assertEquals('COUNT(`id`) AS `id_count`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'count', array('Model.id', 'id_count'));
+ $this->assertEquals('COUNT(`Model`.`id`) AS `id_count`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'max', array('id'));
+ $this->assertEquals('MAX(`id`) AS `id`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'max', array('Model.id', 'id'));
+ $this->assertEquals('MAX(`Model`.`id`) AS `id`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'max', array('`Model`.`id`', 'id'));
+ $this->assertEquals('MAX(`Model`.`id`) AS `id`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'min', array('`Model`.`id`', 'id'));
+ $this->assertEquals('MIN(`Model`.`id`) AS `id`', $result);
+
+ $result = $this->Dbo->calculate($this->Model, 'min', 'left');
+ $this->assertEquals('MIN(`left`) AS `left`', $result);
+ }
+
+/**
+ * testLength method
+ *
+ * @return void
+ */
+ public function testLength() {
+ $result = $this->Dbo->length('varchar(255)');
+ $expected = 255;
+ $this->assertSame($expected, $result);
+
+ $result = $this->Dbo->length('int(11)');
+ $expected = 11;
+ $this->assertSame($expected, $result);
+
+ $result = $this->Dbo->length('float(5,3)');
+ $expected = '5,3';
+ $this->assertSame($expected, $result);
+
+ $result = $this->Dbo->length('decimal(5,2)');
+ $expected = '5,2';
+ $this->assertSame($expected, $result);
+
+ $result = $this->Dbo->length("enum('test','me','now')");
+ $expected = 4;
+ $this->assertSame($expected, $result);
+
+ $result = $this->Dbo->length("set('a','b','cd')");
+ $expected = 2;
+ $this->assertSame($expected, $result);
+
+ $result = $this->Dbo->length(false);
+ $this->assertTrue($result === null);
+
+ $result = $this->Dbo->length('datetime');
+ $expected = null;
+ $this->assertSame($expected, $result);
+
+ $result = $this->Dbo->length('text');
+ $expected = null;
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testBuildIndex method
+ *
+ * @return void
+ */
+ public function testBuildIndex() {
+ $data = array(
+ 'PRIMARY' => array('column' => 'id')
+ );
+ $result = $this->Dbo->buildIndex($data);
+ $expected = array('PRIMARY KEY (`id`)');
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'MyIndex' => array('column' => 'id', 'unique' => true)
+ );
+ $result = $this->Dbo->buildIndex($data);
+ $expected = array('UNIQUE KEY `MyIndex` (`id`)');
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'MyIndex' => array('column' => array('id', 'name'), 'unique' => true)
+ );
+ $result = $this->Dbo->buildIndex($data);
+ $expected = array('UNIQUE KEY `MyIndex` (`id`, `name`)');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBuildColumn method
+ *
+ * @return void
+ */
+ public function testBuildColumn2() {
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'string',
+ 'length' => 255,
+ 'default',
+ 'null' => true,
+ 'key'
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`testName` varchar(255) DEFAULT NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'int_field',
+ 'type' => 'integer',
+ 'default' => '',
+ 'null' => false,
+ );
+ $restore = $this->Dbo->columns;
+
+ $this->Dbo->columns = array('integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'), );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`int_field` int(11) NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $this->Dbo->fieldParameters['param'] = array(
+ 'value' => 'COLLATE',
+ 'quote' => false,
+ 'join' => ' ',
+ 'column' => 'Collate',
+ 'position' => 'beforeDefault',
+ 'options' => array('GOOD', 'OK')
+ );
+ $data = array(
+ 'name' => 'int_field',
+ 'type' => 'integer',
+ 'default' => '',
+ 'null' => false,
+ 'param' => 'BAD'
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`int_field` int(11) NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'int_field',
+ 'type' => 'integer',
+ 'default' => '',
+ 'null' => false,
+ 'param' => 'GOOD'
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`int_field` int(11) COLLATE GOOD NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $this->Dbo->columns = $restore;
+
+ $data = array(
+ 'name' => 'created',
+ 'type' => 'timestamp',
+ 'default' => 'current_timestamp',
+ 'null' => false,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`created` timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'created',
+ 'type' => 'timestamp',
+ 'default' => 'CURRENT_TIMESTAMP',
+ 'null' => true,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`created` timestamp DEFAULT CURRENT_TIMESTAMP';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'modified',
+ 'type' => 'timestamp',
+ 'null' => true,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`modified` timestamp NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'modified',
+ 'type' => 'timestamp',
+ 'default' => null,
+ 'null' => true,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '`modified` timestamp NULL';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBuildColumnBadType method
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testBuildColumnBadType() {
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'varchar(255)',
+ 'default',
+ 'null' => true,
+ 'key'
+ );
+ $this->Dbo->buildColumn($data);
+ }
+
+/**
+ * test hasAny()
+ *
+ * @return void
+ */
+ public function testHasAny() {
+ $db = $this->Dbo->config['database'];
+ $this->Dbo = $this->getMock('Mysql', array('connect', '_execute', 'execute', 'value'));
+ $this->Dbo->config['database'] = $db;
+
+ $this->Model = $this->getMock('TestModel', array('getDataSource'));
+ $this->Model->expects($this->any())
+ ->method('getDataSource')
+ ->will($this->returnValue($this->Dbo));
+
+ $this->Dbo->expects($this->at(0))->method('value')
+ ->with('harry')
+ ->will($this->returnValue("'harry'"));
+
+ $modelTable = $this->Dbo->fullTableName($this->Model);
+ $this->Dbo->expects($this->at(1))->method('execute')
+ ->with('SELECT COUNT(`TestModel`.`id`) AS count FROM ' . $modelTable . ' AS `TestModel` WHERE `TestModel`.`name` = \'harry\'');
+ $this->Dbo->expects($this->at(2))->method('execute')
+ ->with('SELECT COUNT(`TestModel`.`id`) AS count FROM ' . $modelTable . ' AS `TestModel` WHERE 1 = 1');
+
+ $this->Dbo->hasAny($this->Model, array('TestModel.name' => 'harry'));
+ $this->Dbo->hasAny($this->Model, array());
+ }
+
+/**
+ * test fields generating usable virtual fields to use in query
+ *
+ * @return void
+ */
+ public function testVirtualFields() {
+ $this->loadFixtures('Article', 'Comment', 'Tag');
+ $this->Dbo->virtualFieldSeparator = '__';
+ $Article = ClassRegistry::init('Article');
+ $commentsTable = $this->Dbo->fullTableName('comments', false, false);
+ $Article->virtualFields = array(
+ 'this_moment' => 'NOW()',
+ 'two' => '1 + 1',
+ 'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
+ ' WHERE Article.id = ' . $commentsTable . '.article_id'
+ );
+ $result = $this->Dbo->fields($Article);
+ $expected = array(
+ '`Article`.`id`',
+ '`Article`.`user_id`',
+ '`Article`.`title`',
+ '`Article`.`body`',
+ '`Article`.`published`',
+ '`Article`.`created`',
+ '`Article`.`updated`',
+ '(NOW()) AS `Article__this_moment`',
+ '(1 + 1) AS `Article__two`',
+ "(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS `Article__comment_count`"
+ );
+
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($Article, null, array('this_moment', 'title'));
+ $expected = array(
+ '`Article`.`title`',
+ '(NOW()) AS `Article__this_moment`',
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($Article, null, array('Article.title', 'Article.this_moment'));
+ $expected = array(
+ '`Article`.`title`',
+ '(NOW()) AS `Article__this_moment`',
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($Article, null, array('Article.this_moment', 'Article.title'));
+ $expected = array(
+ '`Article`.`title`',
+ '(NOW()) AS `Article__this_moment`',
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($Article, null, array('Article.*'));
+ $expected = array(
+ '`Article`.*',
+ '(NOW()) AS `Article__this_moment`',
+ '(1 + 1) AS `Article__two`',
+ "(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS `Article__comment_count`"
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($Article, null, array('*'));
+ $expected = array(
+ '*',
+ '(NOW()) AS `Article__this_moment`',
+ '(1 + 1) AS `Article__two`',
+ "(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS `Article__comment_count`"
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test conditions to generate query conditions for virtual fields
+ *
+ * @return void
+ */
+ public function testVirtualFieldsInConditions() {
+ $Article = ClassRegistry::init('Article');
+ $commentsTable = $this->Dbo->fullTableName('comments', false, false);
+
+ $Article->virtualFields = array(
+ 'this_moment' => 'NOW()',
+ 'two' => '1 + 1',
+ 'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
+ ' WHERE Article.id = ' . $commentsTable . '.article_id'
+ );
+ $conditions = array('two' => 2);
+ $result = $this->Dbo->conditions($conditions, true, false, $Article);
+ $expected = '(1 + 1) = 2';
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('this_moment BETWEEN ? AND ?' => array(1,2));
+ $expected = 'NOW() BETWEEN 1 AND 2';
+ $result = $this->Dbo->conditions($conditions, true, false, $Article);
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('comment_count >' => 5);
+ $expected = "(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) > 5";
+ $result = $this->Dbo->conditions($conditions, true, false, $Article);
+ $this->assertEquals($expected, $result);
+
+ $conditions = array('NOT' => array('two' => 2));
+ $result = $this->Dbo->conditions($conditions, true, false, $Article);
+ $expected = 'NOT ((1 + 1) = 2)';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that virtualFields with complex functions and aliases work.
+ *
+ * @return void
+ */
+ public function testConditionsWithComplexVirtualFields() {
+ $Article = ClassRegistry::init('Article', 'Comment', 'Tag');
+ $Article->virtualFields = array(
+ 'distance' => 'ACOS(SIN(20 * PI() / 180)
+ * SIN(Article.latitude * PI() / 180)
+ + COS(20 * PI() / 180)
+ * COS(Article.latitude * PI() / 180)
+ * COS((50 - Article.longitude) * PI() / 180)
+ ) * 180 / PI() * 60 * 1.1515 * 1.609344'
+ );
+ $conditions = array('distance >=' => 20);
+ $result = $this->Dbo->conditions($conditions, true, true, $Article);
+
+ $this->assertRegExp('/\) >= 20/', $result);
+ $this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]latitude[`\'"]/', $result);
+ $this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]longitude[`\'"]/', $result);
+ }
+
+/**
+ * test calculate to generate claculate statements on virtual fields
+ *
+ * @return void
+ */
+ public function testVirtualFieldsInCalculate() {
+ $Article = ClassRegistry::init('Article');
+ $commentsTable = $this->Dbo->fullTableName('comments', false, false);
+ $Article->virtualFields = array(
+ 'this_moment' => 'NOW()',
+ 'two' => '1 + 1',
+ 'comment_count' => 'SELECT COUNT(*) FROM ' . $commentsTable .
+ ' WHERE Article.id = ' . $commentsTable . '.article_id'
+ );
+
+ $result = $this->Dbo->calculate($Article, 'count', array('this_moment'));
+ $expected = 'COUNT(NOW()) AS `count`';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->calculate($Article, 'max', array('comment_count'));
+ $expected = "MAX(SELECT COUNT(*) FROM $commentsTable WHERE `Article`.`id` = `$commentsTable`.`article_id`) AS `comment_count`";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test reading virtual fields containing newlines when recursive > 0
+ *
+ * @return void
+ */
+ public function testReadVirtualFieldsWithNewLines() {
+ $Article = new Article();
+ $Article->recursive = 1;
+ $Article->virtualFields = array(
+ 'test' => '
+ User.id + User.id
+ '
+ );
+ $result = $this->Dbo->fields($Article, null, array());
+ $result = $this->Dbo->fields($Article, $Article->alias, $result);
+ $this->assertRegExp('/[`\"]User[`\"]\.[`\"]id[`\"] \+ [`\"]User[`\"]\.[`\"]id[`\"]/', $result[7]);
+ }
+
+/**
+ * test group to generate GROUP BY statements on virtual fields
+ *
+ * @return void
+ */
+ public function testVirtualFieldsInGroup() {
+ $Article = ClassRegistry::init('Article');
+ $Article->virtualFields = array(
+ 'this_year' => 'YEAR(Article.created)'
+ );
+
+ $result = $this->Dbo->group('this_year', $Article);
+
+ $expected = " GROUP BY (YEAR(`Article`.`created`))";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that virtualFields with complex functions and aliases work.
+ *
+ * @return void
+ */
+ public function testFieldsWithComplexVirtualFields() {
+ $Article = new Article();
+ $Article->virtualFields = array(
+ 'distance' => 'ACOS(SIN(20 * PI() / 180)
+ * SIN(Article.latitude * PI() / 180)
+ + COS(20 * PI() / 180)
+ * COS(Article.latitude * PI() / 180)
+ * COS((50 - Article.longitude) * PI() / 180)
+ ) * 180 / PI() * 60 * 1.1515 * 1.609344'
+ );
+
+ $fields = array('id', 'distance');
+ $result = $this->Dbo->fields($Article, null, $fields);
+ $qs = $this->Dbo->startQuote;
+ $qe = $this->Dbo->endQuote;
+
+ $this->assertEquals("{$qs}Article{$qe}.{$qs}id{$qe}", $result[0]);
+ $this->assertRegExp('/Article__distance/', $result[1]);
+ $this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]latitude[`\'"]/', $result[1]);
+ $this->assertRegExp('/[`\'"]Article[`\'"].[`\'"]longitude[`\'"]/', $result[1]);
+ }
+
+/**
+ * test that execute runs queries.
+ *
+ * @return void
+ */
+ public function testExecute() {
+ $query = 'SELECT * FROM ' . $this->Dbo->fullTableName('articles') . ' WHERE 1 = 1';
+ $this->Dbo->took = null;
+ $this->Dbo->affected = null;
+ $result = $this->Dbo->execute($query, array('log' => false));
+ $this->assertNotNull($result, 'No query performed! %s');
+ $this->assertNull($this->Dbo->took, 'Stats were set %s');
+ $this->assertNull($this->Dbo->affected, 'Stats were set %s');
+
+ $result = $this->Dbo->execute($query);
+ $this->assertNotNull($result, 'No query performed! %s');
+ $this->assertNotNull($this->Dbo->took, 'Stats were not set %s');
+ $this->assertNotNull($this->Dbo->affected, 'Stats were not set %s');
+ }
+
+/**
+ * test a full example of using virtual fields
+ *
+ * @return void
+ */
+ public function testVirtualFieldsFetch() {
+ $this->loadFixtures('Article', 'Comment');
+
+ $Article = ClassRegistry::init('Article');
+ $Article->virtualFields = array(
+ 'comment_count' => 'SELECT COUNT(*) FROM ' . $this->Dbo->fullTableName('comments') .
+ ' WHERE Article.id = ' . $this->Dbo->fullTableName('comments') . '.article_id'
+ );
+
+ $conditions = array('comment_count >' => 2);
+ $query = 'SELECT ' . join(',', $this->Dbo->fields($Article, null, array('id', 'comment_count'))) .
+ ' FROM ' . $this->Dbo->fullTableName($Article) . ' Article ' . $this->Dbo->conditions($conditions, true, true, $Article);
+ $result = $this->Dbo->fetchAll($query);
+ $expected = array(array(
+ 'Article' => array('id' => 1, 'comment_count' => 4)
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test reading complex virtualFields with subqueries.
+ *
+ * @return void
+ */
+ public function testVirtualFieldsComplexRead() {
+ $this->loadFixtures('DataTest', 'Article', 'Comment', 'User', 'Tag', 'ArticlesTag');
+
+ $Article = ClassRegistry::init('Article');
+ $commentTable = $this->Dbo->fullTableName('comments');
+ $Article = ClassRegistry::init('Article');
+ $Article->virtualFields = array(
+ 'comment_count' => 'SELECT COUNT(*) FROM ' . $commentTable .
+ ' AS Comment WHERE Article.id = Comment.article_id'
+ );
+ $result = $Article->find('all');
+ $this->assertTrue(count($result) > 0);
+ $this->assertTrue($result[0]['Article']['comment_count'] > 0);
+
+ $DataTest = ClassRegistry::init('DataTest');
+ $DataTest->virtualFields = array(
+ 'complicated' => 'ACOS(SIN(20 * PI() / 180)
+ * SIN(DataTest.float * PI() / 180)
+ + COS(20 * PI() / 180)
+ * COS(DataTest.count * PI() / 180)
+ * COS((50 - DataTest.float) * PI() / 180)
+ ) * 180 / PI() * 60 * 1.1515 * 1.609344'
+ );
+ $result = $DataTest->find('all');
+ $this->assertTrue(count($result) > 0);
+ $this->assertTrue($result[0]['DataTest']['complicated'] > 0);
+ }
+
+/**
+ * testIntrospectType method
+ *
+ * @return void
+ */
+ public function testIntrospectType() {
+ $this->assertEquals('integer', $this->Dbo->introspectType(0));
+ $this->assertEquals('integer', $this->Dbo->introspectType(2));
+ $this->assertEquals('string', $this->Dbo->introspectType('2'));
+ $this->assertEquals('string', $this->Dbo->introspectType('2.2'));
+ $this->assertEquals('float', $this->Dbo->introspectType(2.2));
+ $this->assertEquals('string', $this->Dbo->introspectType('stringme'));
+ $this->assertEquals('string', $this->Dbo->introspectType('0stringme'));
+
+ $data = array(2.2);
+ $this->assertEquals('float', $this->Dbo->introspectType($data));
+
+ $data = array('2.2');
+ $this->assertEquals('float', $this->Dbo->introspectType($data));
+
+ $data = array(2);
+ $this->assertEquals('integer', $this->Dbo->introspectType($data));
+
+ $data = array('2');
+ $this->assertEquals('integer', $this->Dbo->introspectType($data));
+
+ $data = array('string');
+ $this->assertEquals('string', $this->Dbo->introspectType($data));
+
+ $data = array(2.2, '2.2');
+ $this->assertEquals('float', $this->Dbo->introspectType($data));
+
+ $data = array(2, '2');
+ $this->assertEquals('integer', $this->Dbo->introspectType($data));
+
+ $data = array('string one', 'string two');
+ $this->assertEquals('string', $this->Dbo->introspectType($data));
+
+ $data = array('2.2', 3);
+ $this->assertEquals('integer', $this->Dbo->introspectType($data));
+
+ $data = array('2.2', '0stringme');
+ $this->assertEquals('string', $this->Dbo->introspectType($data));
+
+ $data = array(2.2, 3);
+ $this->assertEquals('integer', $this->Dbo->introspectType($data));
+
+ $data = array(2.2, '0stringme');
+ $this->assertEquals('string', $this->Dbo->introspectType($data));
+
+ $data = array(2, 'stringme');
+ $this->assertEquals('string', $this->Dbo->introspectType($data));
+
+ $data = array(2, '2.2', 'stringgme');
+ $this->assertEquals('string', $this->Dbo->introspectType($data));
+
+ $data = array(2, '2.2');
+ $this->assertEquals('integer', $this->Dbo->introspectType($data));
+
+ $data = array(2, 2.2);
+ $this->assertEquals('integer', $this->Dbo->introspectType($data));
+
+ // null
+ $result = $this->Dbo->value(null, 'boolean');
+ $this->assertEquals('NULL', $result);
+
+ // EMPTY STRING
+ $result = $this->Dbo->value('', 'boolean');
+ $this->assertEquals("'0'", $result);
+
+ // BOOLEAN
+ $result = $this->Dbo->value('true', 'boolean');
+ $this->assertEquals("'1'", $result);
+
+ $result = $this->Dbo->value('false', 'boolean');
+ $this->assertEquals("'1'", $result);
+
+ $result = $this->Dbo->value(true, 'boolean');
+ $this->assertEquals("'1'", $result);
+
+ $result = $this->Dbo->value(false, 'boolean');
+ $this->assertEquals("'0'", $result);
+
+ $result = $this->Dbo->value(1, 'boolean');
+ $this->assertEquals("'1'", $result);
+
+ $result = $this->Dbo->value(0, 'boolean');
+ $this->assertEquals("'0'", $result);
+
+ $result = $this->Dbo->value('abc', 'boolean');
+ $this->assertEquals("'1'", $result);
+
+ $result = $this->Dbo->value(1.234, 'boolean');
+ $this->assertEquals("'1'", $result);
+
+ $result = $this->Dbo->value('1.234e05', 'boolean');
+ $this->assertEquals("'1'", $result);
+
+ // NUMBERS
+ $result = $this->Dbo->value(123, 'integer');
+ $this->assertEquals(123, $result);
+
+ $result = $this->Dbo->value('123', 'integer');
+ $this->assertEquals('123', $result);
+
+ $result = $this->Dbo->value('0123', 'integer');
+ $this->assertEquals("'0123'", $result);
+
+ $result = $this->Dbo->value('0x123ABC', 'integer');
+ $this->assertEquals("'0x123ABC'", $result);
+
+ $result = $this->Dbo->value('0x123', 'integer');
+ $this->assertEquals("'0x123'", $result);
+
+ $result = $this->Dbo->value(1.234, 'float');
+ $this->assertEquals(1.234, $result);
+
+ $result = $this->Dbo->value('1.234', 'float');
+ $this->assertEquals('1.234', $result);
+
+ $result = $this->Dbo->value(' 1.234 ', 'float');
+ $this->assertEquals("' 1.234 '", $result);
+
+ $result = $this->Dbo->value('1.234e05', 'float');
+ $this->assertEquals("'1.234e05'", $result);
+
+ $result = $this->Dbo->value('1.234e+5', 'float');
+ $this->assertEquals("'1.234e+5'", $result);
+
+ $result = $this->Dbo->value('1,234', 'float');
+ $this->assertEquals("'1,234'", $result);
+
+ $result = $this->Dbo->value('FFF', 'integer');
+ $this->assertEquals("'FFF'", $result);
+
+ $result = $this->Dbo->value('abc', 'integer');
+ $this->assertEquals("'abc'", $result);
+
+ // STRINGS
+ $result = $this->Dbo->value('123', 'string');
+ $this->assertEquals("'123'", $result);
+
+ $result = $this->Dbo->value(123, 'string');
+ $this->assertEquals("'123'", $result);
+
+ $result = $this->Dbo->value(1.234, 'string');
+ $this->assertEquals("'1.234'", $result);
+
+ $result = $this->Dbo->value('abc', 'string');
+ $this->assertEquals("'abc'", $result);
+
+ $result = $this->Dbo->value(' abc ', 'string');
+ $this->assertEquals("' abc '", $result);
+
+ $result = $this->Dbo->value('a bc', 'string');
+ $this->assertEquals("'a bc'", $result);
+ }
+
+/**
+ * testRealQueries method
+ *
+ * @return void
+ */
+ public function testRealQueries() {
+ $this->loadFixtures('Apple', 'Article', 'User', 'Comment', 'Tag', 'Sample', 'ArticlesTag');
+
+ $Apple = ClassRegistry::init('Apple');
+ $Article = ClassRegistry::init('Article');
+
+ $result = $this->Dbo->rawQuery('SELECT color, name FROM ' . $this->Dbo->fullTableName('apples'));
+ $this->assertTrue(!empty($result));
+
+ $result = $this->Dbo->fetchRow($result);
+ $expected = array($this->Dbo->fullTableName('apples', false, false) => array(
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fetchAll('SELECT name FROM ' . $this->Dbo->fullTableName('apples') . ' ORDER BY id');
+ $expected = array(
+ array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Red Apple 1')),
+ array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Bright Red Apple')),
+ array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'green blue')),
+ array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Test Name')),
+ array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Blue Green')),
+ array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'My new apple')),
+ array($this->Dbo->fullTableName('apples', false, false) => array('name' => 'Some odd color'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->field($this->Dbo->fullTableName('apples', false, false), 'SELECT color, name FROM ' . $this->Dbo->fullTableName('apples') . ' ORDER BY id');
+ $expected = array(
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1'
+ );
+ $this->assertEquals($expected, $result);
+
+ $Apple->unbindModel(array(), false);
+ $result = $this->Dbo->read($Apple, array(
+ 'fields' => array($Apple->escapeField('name')),
+ 'conditions' => null,
+ 'recursive' => -1
+ ));
+ $expected = array(
+ array('Apple' => array('name' => 'Red Apple 1')),
+ array('Apple' => array('name' => 'Bright Red Apple')),
+ array('Apple' => array('name' => 'green blue')),
+ array('Apple' => array('name' => 'Test Name')),
+ array('Apple' => array('name' => 'Blue Green')),
+ array('Apple' => array('name' => 'My new apple')),
+ array('Apple' => array('name' => 'Some odd color'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->read($Article, array(
+ 'fields' => array('id', 'user_id', 'title'),
+ 'conditions' => null,
+ 'recursive' => 1
+ ));
+
+ $this->assertTrue(Set::matches('/Article[id=1]', $result));
+ $this->assertTrue(Set::matches('/Comment[id=1]', $result));
+ $this->assertTrue(Set::matches('/Comment[id=2]', $result));
+ $this->assertFalse(Set::matches('/Comment[id=10]', $result));
+ }
+
+/**
+ * @expectedException MissingConnectionException
+ * @return void
+ */
+ public function testExceptionOnBrokenConnection() {
+ $dbo = new Mysql(array(
+ 'driver' => 'mysql',
+ 'host' => 'imaginary_host',
+ 'login' => 'mark',
+ 'password' => 'inyurdatabase',
+ 'database' => 'imaginary'
+ ));
+ }
+
+/**
+ * testStatements method
+ *
+ * @return void
+ */
+ public function testUpdateStatements() {
+ $this->loadFixtures('Article', 'User');
+ $test = ConnectionManager::getDatasource('test');
+ $db = $test->config['database'];
+
+ $this->Dbo = $this->getMock('Mysql', array('execute'), array($test->config));
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("UPDATE `$db`.`articles` SET `field1` = 'value1' WHERE 1 = 1");
+
+ $this->Dbo->expects($this->at(1))->method('execute')
+ ->with("UPDATE `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` ON " .
+ "(`Article`.`user_id` = `User`.`id`)" .
+ " SET `Article`.`field1` = 2 WHERE 2=2");
+
+ $this->Dbo->expects($this->at(2))->method('execute')
+ ->with("UPDATE `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` ON " .
+ "(`Article`.`user_id` = `User`.`id`)" .
+ " SET `Article`.`field1` = 'value' WHERE `index` = 'val'");
+
+ $Article = new Article();
+
+ $this->Dbo->update($Article, array('field1'), array('value1'));
+ $this->Dbo->update($Article, array('field1'), array('2'), '2=2');
+ $this->Dbo->update($Article, array('field1'), array("'value'"), array('index' => 'val'));
+ }
+
+/**
+ * Test deletes with a mock.
+ *
+ * @return void
+ */
+ public function testDeleteStatements() {
+ $this->loadFixtures('Article', 'User');
+ $test = ConnectionManager::getDatasource('test');
+ $db = $test->config['database'];
+
+ $this->Dbo = $this->getMock('Mysql', array('execute'), array($test->config));
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("DELETE FROM `$db`.`articles` WHERE 1 = 1");
+
+ $this->Dbo->expects($this->at(1))->method('execute')
+ ->with("DELETE `Article` FROM `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` " .
+ "ON (`Article`.`user_id` = `User`.`id`)" .
+ " WHERE 1 = 1");
+
+ $this->Dbo->expects($this->at(2))->method('execute')
+ ->with("DELETE `Article` FROM `$db`.`articles` AS `Article` LEFT JOIN `$db`.`users` AS `User` " .
+ "ON (`Article`.`user_id` = `User`.`id`)" .
+ " WHERE 2=2");
+ $Article = new Article();
+
+ $this->Dbo->delete($Article);
+ $this->Dbo->delete($Article, true);
+ $this->Dbo->delete($Article, '2=2');
+ }
+
+/**
+ * Test truncate with a mock.
+ *
+ * @return void
+ */
+ public function testTruncateStatements() {
+ $this->loadFixtures('Article', 'User');
+ $db = ConnectionManager::getDatasource('test');
+ $schema = $db->config['database'];
+ $Article = new Article();
+
+ $this->Dbo = $this->getMock('Mysql', array('execute'), array($db->config));
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("TRUNCATE TABLE `$schema`.`articles`");
+ $this->Dbo->truncate($Article);
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("TRUNCATE TABLE `$schema`.`articles`");
+ $this->Dbo->truncate('articles');
+
+ // #2355: prevent duplicate prefix
+ $this->Dbo->config['prefix'] = 'tbl_';
+ $Article->tablePrefix = 'tbl_';
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("TRUNCATE TABLE `$schema`.`tbl_articles`");
+ $this->Dbo->truncate($Article);
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("TRUNCATE TABLE `$schema`.`tbl_articles`");
+ $this->Dbo->truncate('articles');
+ }
+
+/**
+ * Test nested transaction
+ *
+ * @return void
+ */
+ public function testNestedTransaction() {
+ $nested = $this->Dbo->useNestedTransactions;
+ $this->Dbo->useNestedTransactions = true;
+ if ($this->Dbo->nestedTransactionSupported() === false) {
+ $this->Dbo->useNestedTransactions = $nested;
+ $this->skipIf(true, 'The MySQL server do not support nested transaction');
+ }
+
+ $this->loadFixtures('Inno');
+ $model = ClassRegistry::init('Inno');
+ $model->hasOne = $model->hasMany = $model->belongsTo = $model->hasAndBelongsToMany = array();
+ $model->cacheQueries = false;
+ $this->Dbo->cacheMethods = false;
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertNotEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertTrue($model->delete(1));
+ $this->assertEmpty($model->read(null, 1));
+ $this->assertTrue($this->Dbo->rollback());
+ $this->assertNotEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertTrue($model->delete(1));
+ $this->assertEmpty($model->read(null, 1));
+ $this->assertTrue($this->Dbo->commit());
+ $this->assertEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->rollback());
+ $this->assertNotEmpty($model->read(null, 1));
+
+ $this->Dbo->useNestedTransactions = $nested;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php
new file mode 100644
index 0000000..2046e6b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php
@@ -0,0 +1,945 @@
+<?php
+/**
+ * DboPostgresTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model.Datasource.Database
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('Postgres', 'Model/Datasource/Database');
+
+require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
+
+/**
+ * DboPostgresTestDb class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class DboPostgresTestDb extends Postgres {
+
+/**
+ * simulated property
+ *
+ * @var array
+ */
+ public $simulated = array();
+
+/**
+ * execute method
+ *
+ * @param mixed $sql
+ * @return void
+ */
+ protected function _execute($sql, $params = array(), $prepareOptions = array()) {
+ $this->simulated[] = $sql;
+ return null;
+ }
+
+/**
+ * getLastQuery method
+ *
+ * @return void
+ */
+ public function getLastQuery() {
+ return $this->simulated[count($this->simulated) - 1];
+ }
+
+}
+
+/**
+ * PostgresTestModel class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class PostgresTestModel extends Model {
+
+/**
+ * name property
+ *
+ * @var string 'PostgresTestModel'
+ */
+ public $name = 'PostgresTestModel';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'PostgresClientTestModel' => array(
+ 'foreignKey' => 'client_id'
+ )
+ );
+
+/**
+ * find method
+ *
+ * @param mixed $conditions
+ * @param mixed $fields
+ * @param mixed $order
+ * @param mixed $recursive
+ * @return void
+ */
+ public function find($conditions = null, $fields = null, $order = null, $recursive = null) {
+ return $conditions;
+ }
+
+/**
+ * findAll method
+ *
+ * @param mixed $conditions
+ * @param mixed $fields
+ * @param mixed $order
+ * @param mixed $recursive
+ * @return void
+ */
+ public function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
+ return $conditions;
+ }
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ return array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
+ 'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
+ 'last_login' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+
+}
+
+/**
+ * PostgresClientTestModel class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class PostgresClientTestModel extends Model {
+
+/**
+ * name property
+ *
+ * @var string 'PostgresClientTestModel'
+ */
+ public $name = 'PostgresClientTestModel';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ return array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'created' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+
+}
+
+/**
+ * PostgresTest class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class PostgresTest extends CakeTestCase {
+
+/**
+ * Do not automatically load fixtures for each test, they will be loaded manually
+ * using CakeTestCase::loadFixtures
+ *
+ * @var boolean
+ */
+ public $autoFixtures = false;
+
+/**
+ * Fixtures
+ *
+ * @var object
+ */
+ public $fixtures = array('core.user', 'core.binary_test', 'core.comment', 'core.article',
+ 'core.tag', 'core.articles_tag', 'core.attachment', 'core.person', 'core.post', 'core.author',
+ 'core.datatype',
+ );
+
+/**
+ * Actual DB connection used in testing
+ *
+ * @var DboSource
+ */
+ public $Dbo = null;
+
+/**
+ * Simulated DB connection used in testing
+ *
+ * @var DboSource
+ */
+ public $Dbo2 = null;
+
+/**
+ * Sets up a Dbo class instance for testing
+ *
+ */
+ public function setUp() {
+ Configure::write('Cache.disable', true);
+ $this->Dbo = ConnectionManager::getDataSource('test');
+ $this->skipIf(!($this->Dbo instanceof Postgres));
+ $this->Dbo2 = new DboPostgresTestDb($this->Dbo->config, false);
+ $this->model = new PostgresTestModel();
+ }
+
+/**
+ * Sets up a Dbo class instance for testing
+ *
+ */
+ public function tearDown() {
+ Configure::write('Cache.disable', false);
+ unset($this->Dbo2);
+ }
+
+/**
+ * Test field quoting method
+ *
+ */
+ public function testFieldQuoting() {
+ $fields = array(
+ '"PostgresTestModel"."id" AS "PostgresTestModel__id"',
+ '"PostgresTestModel"."client_id" AS "PostgresTestModel__client_id"',
+ '"PostgresTestModel"."name" AS "PostgresTestModel__name"',
+ '"PostgresTestModel"."login" AS "PostgresTestModel__login"',
+ '"PostgresTestModel"."passwd" AS "PostgresTestModel__passwd"',
+ '"PostgresTestModel"."addr_1" AS "PostgresTestModel__addr_1"',
+ '"PostgresTestModel"."addr_2" AS "PostgresTestModel__addr_2"',
+ '"PostgresTestModel"."zip_code" AS "PostgresTestModel__zip_code"',
+ '"PostgresTestModel"."city" AS "PostgresTestModel__city"',
+ '"PostgresTestModel"."country" AS "PostgresTestModel__country"',
+ '"PostgresTestModel"."phone" AS "PostgresTestModel__phone"',
+ '"PostgresTestModel"."fax" AS "PostgresTestModel__fax"',
+ '"PostgresTestModel"."url" AS "PostgresTestModel__url"',
+ '"PostgresTestModel"."email" AS "PostgresTestModel__email"',
+ '"PostgresTestModel"."comments" AS "PostgresTestModel__comments"',
+ '"PostgresTestModel"."last_login" AS "PostgresTestModel__last_login"',
+ '"PostgresTestModel"."created" AS "PostgresTestModel__created"',
+ '"PostgresTestModel"."updated" AS "PostgresTestModel__updated"'
+ );
+
+ $result = $this->Dbo->fields($this->model);
+ $expected = $fields;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->model, null, 'PostgresTestModel.*');
+ $expected = $fields;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->model, null, array('*', 'AnotherModel.id', 'AnotherModel.name'));
+ $expected = array_merge($fields, array(
+ '"AnotherModel"."id" AS "AnotherModel__id"',
+ '"AnotherModel"."name" AS "AnotherModel__name"'));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($this->model, null, array('*', 'PostgresClientTestModel.*'));
+ $expected = array_merge($fields, array(
+ '"PostgresClientTestModel"."id" AS "PostgresClientTestModel__id"',
+ '"PostgresClientTestModel"."name" AS "PostgresClientTestModel__name"',
+ '"PostgresClientTestModel"."email" AS "PostgresClientTestModel__email"',
+ '"PostgresClientTestModel"."created" AS "PostgresClientTestModel__created"',
+ '"PostgresClientTestModel"."updated" AS "PostgresClientTestModel__updated"'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testColumnParsing method
+ *
+ * @return void
+ */
+ public function testColumnParsing() {
+ $this->assertEquals('text', $this->Dbo2->column('text'));
+ $this->assertEquals('date', $this->Dbo2->column('date'));
+ $this->assertEquals('boolean', $this->Dbo2->column('boolean'));
+ $this->assertEquals('string', $this->Dbo2->column('character varying'));
+ $this->assertEquals('time', $this->Dbo2->column('time without time zone'));
+ $this->assertEquals('datetime', $this->Dbo2->column('timestamp without time zone'));
+ }
+
+/**
+ * testValueQuoting method
+ *
+ * @return void
+ */
+ public function testValueQuoting() {
+ $this->assertEquals("1.200000", $this->Dbo->value(1.2, 'float'));
+ $this->assertEquals("'1,2'", $this->Dbo->value('1,2', 'float'));
+
+ $this->assertEquals("0", $this->Dbo->value('0', 'integer'));
+ $this->assertEquals('NULL', $this->Dbo->value('', 'integer'));
+ $this->assertEquals('NULL', $this->Dbo->value('', 'float'));
+ $this->assertEquals("NULL", $this->Dbo->value('', 'integer', false));
+ $this->assertEquals("NULL", $this->Dbo->value('', 'float', false));
+ $this->assertEquals("'0.0'", $this->Dbo->value('0.0', 'float'));
+
+ $this->assertEquals("'TRUE'", $this->Dbo->value('t', 'boolean'));
+ $this->assertEquals("'FALSE'", $this->Dbo->value('f', 'boolean'));
+ $this->assertEquals("'TRUE'", $this->Dbo->value(true));
+ $this->assertEquals("'FALSE'", $this->Dbo->value(false));
+ $this->assertEquals("'t'", $this->Dbo->value('t'));
+ $this->assertEquals("'f'", $this->Dbo->value('f'));
+ $this->assertEquals("'TRUE'", $this->Dbo->value('true', 'boolean'));
+ $this->assertEquals("'FALSE'", $this->Dbo->value('false', 'boolean'));
+ $this->assertEquals("'FALSE'", $this->Dbo->value('', 'boolean'));
+ $this->assertEquals("'FALSE'", $this->Dbo->value(0, 'boolean'));
+ $this->assertEquals("'TRUE'", $this->Dbo->value(1, 'boolean'));
+ $this->assertEquals("'TRUE'", $this->Dbo->value('1', 'boolean'));
+ $this->assertEquals("NULL", $this->Dbo->value(null, 'boolean'));
+ $this->assertEquals("NULL", $this->Dbo->value(array()));
+ }
+
+/**
+ * test that localized floats don't cause trouble.
+ *
+ * @return void
+ */
+ public function testLocalizedFloats() {
+ $restore = setlocale(LC_NUMERIC, 0);
+ setlocale(LC_NUMERIC, 'de_DE');
+
+ $result = $this->db->value(3.141593, 'float');
+ $this->assertEquals("3.141593", $result);
+
+ $result = $this->db->value(3.14);
+ $this->assertEquals("3.140000", $result);
+
+ setlocale(LC_NUMERIC, $restore);
+ }
+
+/**
+ * test that date and time columns do not generate errors with null and nullish values.
+ *
+ * @return void
+ */
+ public function testDateAndTimeAsNull() {
+ $this->assertEquals('NULL', $this->Dbo->value(null, 'date'));
+ $this->assertEquals('NULL', $this->Dbo->value('', 'date'));
+
+ $this->assertEquals('NULL', $this->Dbo->value('', 'datetime'));
+ $this->assertEquals('NULL', $this->Dbo->value(null, 'datetime'));
+
+ $this->assertEquals('NULL', $this->Dbo->value('', 'timestamp'));
+ $this->assertEquals('NULL', $this->Dbo->value(null, 'timestamp'));
+
+ $this->assertEquals('NULL', $this->Dbo->value('', 'time'));
+ $this->assertEquals('NULL', $this->Dbo->value(null, 'time'));
+ }
+
+/**
+ * Tests that different Postgres boolean 'flavors' are properly returned as native PHP booleans
+ *
+ * @return void
+ */
+ public function testBooleanNormalization() {
+ $this->assertEquals(true, $this->Dbo2->boolean('t', false));
+ $this->assertEquals(true, $this->Dbo2->boolean('true', false));
+ $this->assertEquals(true, $this->Dbo2->boolean('TRUE', false));
+ $this->assertEquals(true, $this->Dbo2->boolean(true, false));
+ $this->assertEquals(true, $this->Dbo2->boolean(1, false));
+ $this->assertEquals(true, $this->Dbo2->boolean(" ", false));
+
+ $this->assertEquals(false, $this->Dbo2->boolean('f', false));
+ $this->assertEquals(false, $this->Dbo2->boolean('false', false));
+ $this->assertEquals(false, $this->Dbo2->boolean('FALSE', false));
+ $this->assertEquals(false, $this->Dbo2->boolean(false, false));
+ $this->assertEquals(false, $this->Dbo2->boolean(0, false));
+ $this->assertEquals(false, $this->Dbo2->boolean('', false));
+ }
+
+/**
+ * test that default -> false in schemas works correctly.
+ *
+ * @return void
+ */
+ public function testBooleanDefaultFalseInSchema() {
+ $this->loadFixtures('Datatype');
+
+ $model = new Model(array('name' => 'Datatype', 'table' => 'datatypes', 'ds' => 'test'));
+ $model->create();
+ $this->assertSame(false, $model->data['Datatype']['bool']);
+ }
+
+/**
+ * testLastInsertIdMultipleInsert method
+ *
+ * @return void
+ */
+ public function testLastInsertIdMultipleInsert() {
+ $this->loadFixtures('User');
+ $db1 = ConnectionManager::getDataSource('test');
+
+ $table = $db1->fullTableName('users', false);
+ $password = '5f4dcc3b5aa765d61d8327deb882cf99';
+ $db1->execute(
+ "INSERT INTO {$table} (\"user\", password) VALUES ('mariano', '{$password}')"
+ );
+
+ $this->assertEquals(5, $db1->lastInsertId($table));
+
+ $db1->execute("INSERT INTO {$table} (\"user\", password) VALUES ('hoge', '{$password}')");
+ $this->assertEquals(6, $db1->lastInsertId($table));
+ }
+
+/**
+ * Tests that column types without default lengths in $columns do not have length values
+ * applied when generating schemas.
+ *
+ * @return void
+ */
+ public function testColumnUseLength() {
+ $result = array('name' => 'foo', 'type' => 'string', 'length' => 100, 'default' => 'FOO');
+ $expected = '"foo" varchar(100) DEFAULT \'FOO\'';
+ $this->assertEquals($expected, $this->Dbo->buildColumn($result));
+
+ $result = array('name' => 'foo', 'type' => 'text', 'length' => 100, 'default' => 'FOO');
+ $expected = '"foo" text DEFAULT \'FOO\'';
+ $this->assertEquals($expected, $this->Dbo->buildColumn($result));
+ }
+
+/**
+ * Tests that binary data is escaped/unescaped properly on reads and writes
+ *
+ * @return void
+ */
+ public function testBinaryDataIntegrity() {
+ $this->loadFixtures('BinaryTest');
+ $data = '%PDF-1.3
+ %ƒÂÚÂÎßÛ†–ƒ∆
+ 4 0 obj
+ << /Length 5 0 R /Filter /FlateDecode >>
+ stream
+ xµYMì€∆Ω„WÃ%)nï0¯îâ-«é]Q"πXµáÿ•Ip - P V,]Ú#c˚ˇ‰ut¥†∏Ti9 Ü=”›Ø_˜4>à∑‚Épcé¢Pxæ®2q\'
+ 1UªbU ᡒ+ö«√[ıµ⁄ão"R∑"HiGæä€(å≠≈^Ãøsm?YlƒÃõªfi‹âEÚB&‚Î◊7bÒ^¸m°÷˛?2±Øs“fiu#®U√ˇú÷g¥C;ä")n})JºIÔ3ËSnÑÎ¥≤ıD∆¢∂Msx1üèG˚±Œ™⁄>¶ySïufØ ˝¸?UπÃã√6flÌÚC=øK?˝…s
+ ˛§¯ˇ:-˜ò7€ÓFæ∂∑Õ˛∆“V’>ılflëÅd«ÜQdI ›ÎB%W¿ΩıÉn~h vêCS>«é˛(ØôK!€¡zB!√
+ [œÜ"ûß ·iH¸[Àºæ∑¯¡L,ÀÚAlS∫ˆ=∫Œ≤cÄr&ˆÈ:√ÿ£˚È«4fl•À]vc›bÅôÿî=siXe4/¡p]ã]ôÆIœ™ Ωflà_ƒ‚G?«7 ùÿ ı¯K4ïIpV◊÷·\'éµóªÚæ>î
+ ;›sú!2fl¬F•/f∑j£
+ dw"IÊÜπ<ôÿˆ%IG1ytÛDflXg|Éòa§˜}C˛¿ÿe°G´Ú±jÍm~¿/∂hã<#-¥•ıùe87€t˜õ6w}´{æ
+ m‹ê– ∆¡ 6⁄\
+ rAÀBùZ3aË‚r$G·$ó0Ñ üâUY4È™¡%C∑Ÿ2rc<Iõ-cï.
+ [ŒöâFA†É‡+QglMÉîÉÄúÌ|¸»#x7¥«MgVÎ-GGÚ• I?Á‘”Lzw∞pHů◊nefqCî.nÕeè∆ÿÛy¡˙fb≤üŒHÜAëÕNq=´@ ’cQdÖúAÉIqñŸ˘+2&∏ Àù.gÅ‚ƒœ3EPƒOi—‰:>ÍCäı
+ =Õec=ëR˝”eñ=<V$ì˙+x+¢ïÒÕ<àeWå»–˚∫Õ d§&£àf ]fPA´âtënöå∏◊ó „Ë@∆≠K´÷˘}a_CI˚©yòHg,ôSSVìBƒl4 L.ÈY…á,2∂íäÙ.$ó¸CäŸ*€óy
+ π?G,_√·ÆÎç=^Vkvo±ó{§ƒ2»±¨Ïüo»ëD-ãé fió¥cVÙ\'™G~\'p¢%* ã˚÷
+ ªºnh˚ºO^∏…®[Ó“‚ÅfıÌ≥∫F!Eœ(π∑T6`¬tΩÆ0ì»rTÎ`»Ñ«
+ ]≈åp˝)=¿Ô0∆öVÂmˇˆ„ø~¯ÁÔ∏b*fc»‡Îı„Ú}∆tœs∂Y∫ÜaÆ˙X∏~<ÿ·Ù vé1‹p¿TD∆ÔîÄ“úhˆ*Ú€îe)K –p¨ÚJ3Ÿ∞ã>ÊuNê°“√Ü ‹Ê9iÙ0˙AAEÍ ˙`∂£\'ûce•åƒX›ŸÁ´1SK{qdá"tÏ[wQ#SµBe∞∑µó…ÌV`B"Ñ≥„!è_Óφ-º*ºú¿Ë0ˆeê∂´ë+HFj…‡zvHÓN|ÔL÷ûñ3õÜ$z%sá…pÎóV38âs Çoµ•ß3†<9B·¨û~¢3)ÂxóÿÁCÕòÆ ∫Í=»ÿSπS;∆~±êÆTEp∑óÈ÷ÀuìDHÈ $ÉõæÜjû§"≤ÃONM®RËíRr{õS ∏Ê™op±W;ÂUÔ P∫kÔˇflTæ∑óflË” ÆC©Ô[≥◊HÁ˚¨hê"ÆbF?ú%h˙ˇ4xèÕ(ó2ÙáíM])Ñd|=fë-cI0ñL¢kÖêk‰Rƒ«ıÄWñ8mO3∏&√æËX¯Hó—ì]yF2»–˜ádàà‡‹Çο„≥7mªHAS∑¶.;Œx(1} _kd©.fidç48M\'àáªCp^Krí<ɉXÓıïl!Ì$N<ı∞B»G]…∂Ó¯>˛ÔbõÒπÀ•:ôO<j∂™œ%âÏ—>@È$pÖu‹Ê´-QqV ?V≥JÆÍqÛX8(lπï@zgÖ}Fe<ˇ‡Sñ“ÿ˜ê?6‡L∫Oß~µ –?ËeäÚ®YîÕ =Ü=¢DÁu*GvBk;)L¬N«î:flö∂≠ÇΩq„Ñm하Ë∂‚"û≥§:±≤i^ΩÑ!)Wıyŧô á„RÄ÷Òôc’≠—s™rı‚Pdêãh˘ßHVç5fifiÈF€çÌÛuçÖ/M=gëµ±ÿGû1coÔuñæ‘z®. õ∑7ÉÏÜÆ,°’H†ÍÉÌ∂7e º® íˆ⁄◊øNWK”ÂYµ‚ñé;µ¶gV-fl>µtË¥áßN2 ¯¶BaP-)eW.àôt^∏1›C∑Ö?L„&”5’4jvã–ªZ ÷+4% ´0l…»ú^°´© ûiπ∑é®óܱÒÿ‰ïˆÌ–dˆ◊Æ19rQ=Í|ı•rMæ¬;ò‰Y‰é9.” ‹˝V«ã¯∏,+ë®j*¡·/';
+
+ $model = new AppModel(array('name' => 'BinaryTest', 'ds' => 'test'));
+ $model->save(compact('data'));
+
+ $result = $model->find('first');
+ $this->assertEquals($data, $result['BinaryTest']['data']);
+ }
+
+/**
+ * Tests the syntax of generated schema indexes
+ *
+ * @return void
+ */
+ public function testSchemaIndexSyntax() {
+ $schema = new CakeSchema();
+ $schema->tables = array('i18n' => array(
+ 'id' => array(
+ 'type' => 'integer', 'null' => false, 'default' => null,
+ 'length' => 10, 'key' => 'primary'
+ ),
+ 'locale' => array('type' => 'string', 'null' => false, 'length' => 6, 'key' => 'index'),
+ 'model' => array('type' => 'string', 'null' => false, 'key' => 'index'),
+ 'foreign_key' => array(
+ 'type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'
+ ),
+ 'field' => array('type' => 'string', 'null' => false, 'key' => 'index'),
+ 'content' => array('type' => 'text', 'null' => true, 'default' => null),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'locale' => array('column' => 'locale', 'unique' => 0),
+ 'model' => array('column' => 'model', 'unique' => 0),
+ 'row_id' => array('column' => 'foreign_key', 'unique' => 0),
+ 'field' => array('column' => 'field', 'unique' => 0)
+ )
+ ));
+
+ $result = $this->Dbo->createSchema($schema);
+ $this->assertNotRegExp('/^CREATE INDEX(.+);,$/', $result);
+ }
+
+/**
+ * testCakeSchema method
+ *
+ * Test that schema generated postgresql queries are valid. ref #5696
+ * Check that the create statement for a schema generated table is the same as the original sql
+ *
+ * @return void
+ */
+ public function testCakeSchema() {
+ $db1 = ConnectionManager::getDataSource('test');
+ $db1->cacheSources = false;
+
+ $db1->rawQuery('CREATE TABLE ' . $db1->fullTableName('datatype_tests') . ' (
+ id serial NOT NULL,
+ "varchar" character varying(40) NOT NULL,
+ "full_length" character varying NOT NULL,
+ "timestamp" timestamp without time zone,
+ "date" date,
+ CONSTRAINT test_data_types_pkey PRIMARY KEY (id)
+ )');
+
+ $model = new Model(array('name' => 'DatatypeTest', 'ds' => 'test'));
+ $schema = new CakeSchema(array('connection' => 'test'));
+ $result = $schema->read(array(
+ 'connection' => 'test',
+ 'models' => array('DatatypeTest')
+ ));
+ $schema->tables = array('datatype_tests' => $result['tables']['missing']['datatype_tests']);
+ $result = $db1->createSchema($schema, 'datatype_tests');
+
+ $this->assertNotRegExp('/timestamp DEFAULT/', $result);
+ $this->assertRegExp('/\"full_length\"\s*text\s.*,/', $result);
+ $this->assertRegExp('/timestamp\s*,/', $result);
+
+ $db1->query('DROP TABLE ' . $db1->fullTableName('datatype_tests'));
+
+ $db1->query($result);
+ $result2 = $schema->read(array(
+ 'connection' => 'test',
+ 'models' => array('DatatypeTest')
+ ));
+ $schema->tables = array('datatype_tests' => $result2['tables']['missing']['datatype_tests']);
+ $result2 = $db1->createSchema($schema, 'datatype_tests');
+ $this->assertEquals($result, $result2);
+
+ $db1->query('DROP TABLE ' . $db1->fullTableName('datatype_tests'));
+ }
+
+/**
+ * Test index generation from table info.
+ *
+ * @return void
+ */
+ public function testIndexGeneration() {
+ $name = $this->Dbo->fullTableName('index_test', false, false);
+ $this->Dbo->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
+ $this->Dbo->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
+ $this->Dbo->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
+ $expected = array(
+ 'PRIMARY' => array('unique' => true, 'column' => 'id'),
+ 'pointless_bool' => array('unique' => false, 'column' => 'bool'),
+ 'char_index' => array('unique' => true, 'column' => 'small_char'),
+ );
+ $result = $this->Dbo->index($name);
+ $this->Dbo->query('DROP TABLE ' . $name);
+ $this->assertEquals($expected, $result);
+
+ $name = $this->Dbo->fullTableName('index_test_2', false, false);
+ $this->Dbo->query('CREATE TABLE ' . $name . ' ("id" serial NOT NULL PRIMARY KEY, "bool" integer, "small_char" varchar(50), "description" varchar(40) )');
+ $this->Dbo->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
+ $expected = array(
+ 'PRIMARY' => array('unique' => true, 'column' => 'id'),
+ 'multi_col' => array('unique' => true, 'column' => array('small_char', 'bool')),
+ );
+ $result = $this->Dbo->index($name);
+ $this->Dbo->query('DROP TABLE ' . $name);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the alterSchema capabilities of postgres
+ *
+ * @return void
+ */
+ public function testAlterSchema() {
+ $Old = new CakeSchema(array(
+ 'connection' => 'test',
+ 'name' => 'AlterPosts',
+ 'alter_posts' => array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => true),
+ 'body' => array('type' => 'text'),
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => array('type' => 'datetime'),
+ 'updated' => array('type' => 'datetime'),
+ )
+ ));
+ $this->Dbo->query($this->Dbo->createSchema($Old));
+
+ $New = new CakeSchema(array(
+ 'connection' => 'test',
+ 'name' => 'AlterPosts',
+ 'alter_posts' => array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => true),
+ 'title' => array('type' => 'string', 'null' => false, 'default' => 'my title'),
+ 'body' => array('type' => 'string', 'length' => 500),
+ 'status' => array('type' => 'integer', 'length' => 3, 'default' => 1),
+ 'created' => array('type' => 'datetime'),
+ 'updated' => array('type' => 'datetime'),
+ )
+ ));
+ $this->Dbo->query($this->Dbo->alterSchema($New->compare($Old), 'alter_posts'));
+
+ $model = new CakeTestModel(array('table' => 'alter_posts', 'ds' => 'test'));
+ $result = $model->schema();
+ $this->assertTrue(isset($result['status']));
+ $this->assertFalse(isset($result['published']));
+ $this->assertEquals('string', $result['body']['type']);
+ $this->assertEquals(1, $result['status']['default']);
+ $this->assertEquals(true, $result['author_id']['null']);
+ $this->assertEquals(false, $result['title']['null']);
+
+ $this->Dbo->query($this->Dbo->dropSchema($New));
+
+ $New = new CakeSchema(array(
+ 'connection' => 'test_suite',
+ 'name' => 'AlterPosts',
+ 'alter_posts' => array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => true),
+ 'body' => array('type' => 'text'),
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => array('type' => 'datetime'),
+ 'updated' => array('type' => 'datetime'),
+ )
+ ));
+ $result = $this->Dbo->alterSchema($New->compare($Old), 'alter_posts');
+ $this->assertNotRegExp('/varchar\(36\) NOT NULL/i', $result);
+ }
+
+/**
+ * Test the alter index capabilities of postgres
+ *
+ * @return void
+ */
+ public function testAlterIndexes() {
+ $this->Dbo->cacheSources = false;
+
+ $schema1 = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'group1' => array('type' => 'integer', 'null' => true),
+ 'group2' => array('type' => 'integer', 'null' => true)
+ )
+ ));
+
+ $this->Dbo->rawQuery($this->Dbo->createSchema($schema1));
+
+ $schema2 = new CakeSchema(array(
+ 'name' => 'AlterTest2',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'group1' => array('type' => 'integer', 'null' => true),
+ 'group2' => array('type' => 'integer', 'null' => true),
+ 'indexes' => array(
+ 'name_idx' => array('unique' => false, 'column' => 'name'),
+ 'group_idx' => array('unique' => false, 'column' => 'group1'),
+ 'compound_idx' => array('unique' => false, 'column' => array('group1', 'group2')),
+ 'PRIMARY' => array('unique' => true, 'column' => 'id')
+ )
+ )
+ ));
+ $this->Dbo->query($this->Dbo->alterSchema($schema2->compare($schema1)));
+
+ $indexes = $this->Dbo->index('altertest');
+ $this->assertEquals($schema2->tables['altertest']['indexes'], $indexes);
+
+ // Change three indexes, delete one and add another one
+ $schema3 = new CakeSchema(array(
+ 'name' => 'AlterTest3',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ 'group1' => array('type' => 'integer', 'null' => true),
+ 'group2' => array('type' => 'integer', 'null' => true),
+ 'indexes' => array(
+ 'name_idx' => array('unique' => true, 'column' => 'name'),
+ 'group_idx' => array('unique' => false, 'column' => 'group2'),
+ 'compound_idx' => array('unique' => false, 'column' => array('group2', 'group1')),
+ 'another_idx' => array('unique' => false, 'column' => array('group1', 'name')))
+ )));
+
+ $this->Dbo->query($this->Dbo->alterSchema($schema3->compare($schema2)));
+
+ $indexes = $this->Dbo->index('altertest');
+ $this->assertEquals($schema3->tables['altertest']['indexes'], $indexes);
+
+ // Compare us to ourself.
+ $this->assertEquals(array(), $schema3->compare($schema3));
+
+ // Drop the indexes
+ $this->Dbo->query($this->Dbo->alterSchema($schema1->compare($schema3)));
+
+ $indexes = $this->Dbo->index('altertest');
+ $this->assertEquals(array(), $indexes);
+
+ $this->Dbo->query($this->Dbo->dropSchema($schema1));
+ }
+
+/**
+ * Test it is possible to use virtual field with postgresql
+ *
+ * @return void
+ */
+ public function testVirtualFields() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment', 'Tag', 'ArticlesTag');
+ $Article = new Article;
+ $Article->virtualFields = array(
+ 'next_id' => 'Article.id + 1',
+ 'complex' => 'Article.title || Article.body',
+ 'functional' => 'COALESCE(User.user, Article.title)',
+ 'subquery' => 'SELECT count(*) FROM ' . $Article->Comment->table
+ );
+ $result = $Article->find('first');
+ $this->assertEquals(2, $result['Article']['next_id']);
+ $this->assertEquals($result['Article']['complex'], $result['Article']['title'] . $result['Article']['body']);
+ $this->assertEquals($result['Article']['functional'], $result['User']['user']);
+ $this->assertEquals(6, $result['Article']['subquery']);
+ }
+
+/**
+ * Test that virtual fields work with SQL constants
+ *
+ * @return void
+ */
+ public function testVirtualFieldAsAConstant() {
+ $this->loadFixtures('Article', 'Comment');
+ $Article = ClassRegistry::init('Article');
+ $Article->virtualFields = array(
+ 'empty' => "NULL",
+ 'number' => 43,
+ 'truth' => 'TRUE'
+ );
+ $result = $Article->find('first');
+ $this->assertNull($result['Article']['empty']);
+ $this->assertTrue($result['Article']['truth']);
+ $this->assertEquals(43, $result['Article']['number']);
+ }
+
+/**
+ * Tests additional order options for postgres
+ *
+ * @return void
+ */
+ public function testOrderAdditionalParams() {
+ $result = $this->Dbo->order(array('title' => 'DESC NULLS FIRST', 'body' => 'DESC'));
+ $expected = ' ORDER BY "title" DESC NULLS FIRST, "body" DESC';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test it is possible to do a SELECT COUNT(DISTINCT Model.field)
+ * query in postgres and it gets correctly quoted
+ *
+ * @return void
+ */
+ public function testQuoteDistinctInFunction() {
+ $this->loadFixtures('Article');
+ $Article = new Article;
+ $result = $this->Dbo->fields($Article, null, array('COUNT(DISTINCT Article.id)'));
+ $expected = array('COUNT(DISTINCT "Article"."id")');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($Article, null, array('COUNT(DISTINCT id)'));
+ $expected = array('COUNT(DISTINCT "id")');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->fields($Article, null, array('COUNT(DISTINCT FUNC(id))'));
+ $expected = array('COUNT(DISTINCT FUNC("id"))');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that saveAll works even with conditions that lack a model name.
+ *
+ * @return void
+ */
+ public function testUpdateAllWithNonQualifiedConditions() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+ $result = $Article->updateAll(array('title' => "'Awesome'"), array('title' => 'Third Article'));
+ $this->assertTrue($result);
+
+ $result = $Article->find('count', array(
+ 'conditions' => array('Article.title' => 'Awesome')
+ ));
+ $this->assertEquals(1, $result, 'Article count is wrong or fixture has changed.');
+ }
+
+/**
+ * test alterSchema on two tables.
+ *
+ * @return void
+ */
+ public function testAlteringTwoTables() {
+ $schema1 = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ ),
+ 'other_table' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 50),
+ )
+ ));
+ $schema2 = new CakeSchema(array(
+ 'name' => 'AlterTest1',
+ 'connection' => 'test',
+ 'altertest' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
+ ),
+ 'other_table' => array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0),
+ 'field_two' => array('type' => 'string', 'null' => false, 'length' => 50),
+ )
+ ));
+ $result = $this->db->alterSchema($schema2->compare($schema1));
+ $this->assertEquals(2, substr_count($result, 'field_two'), 'Too many fields');
+ $this->assertFalse(strpos(';ALTER', $result), 'Too many semi colons');
+ }
+
+/**
+ * test encoding setting.
+ *
+ * @return void
+ */
+ public function testEncoding() {
+ $result = $this->Dbo->setEncoding('UTF8');
+ $this->assertTrue($result);
+
+ $result = $this->Dbo->getEncoding();
+ $this->assertEquals('UTF8', $result);
+
+ $result = $this->Dbo->setEncoding('EUC_JP'); /* 'EUC_JP' is right character code name in PostgreSQL */
+ $this->assertTrue($result);
+
+ $result = $this->Dbo->getEncoding();
+ $this->assertEquals('EUC_JP', $result);
+ }
+
+/**
+ * Test truncate with a mock.
+ *
+ * @return void
+ */
+ public function testTruncateStatements() {
+ $this->loadFixtures('Article', 'User');
+ $db = ConnectionManager::getDatasource('test');
+ $schema = $db->config['schema'];
+ $Article = new Article();
+
+ $this->Dbo = $this->getMock('Postgres', array('execute'), array($db->config));
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("DELETE FROM \"$schema\".\"articles\"");
+ $this->Dbo->truncate($Article);
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("DELETE FROM \"$schema\".\"articles\"");
+ $this->Dbo->truncate('articles');
+
+ // #2355: prevent duplicate prefix
+ $this->Dbo->config['prefix'] = 'tbl_';
+ $Article->tablePrefix = 'tbl_';
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("DELETE FROM \"$schema\".\"tbl_articles\"");
+ $this->Dbo->truncate($Article);
+
+ $this->Dbo->expects($this->at(0))->method('execute')
+ ->with("DELETE FROM \"$schema\".\"tbl_articles\"");
+ $this->Dbo->truncate('articles');
+ }
+
+/**
+ * Test nested transaction
+ *
+ * @return void
+ */
+ public function testNestedTransaction() {
+ $this->skipIf($this->Dbo->nestedTransactionSupported() === false, 'The Postgres server do not support nested transaction');
+
+ $this->loadFixtures('Article');
+ $model = new Article();
+ $model->hasOne = $model->hasMany = $model->belongsTo = $model->hasAndBelongsToMany = array();
+ $model->cacheQueries = false;
+ $this->Dbo->cacheMethods = false;
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertNotEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertTrue($model->delete(1));
+ $this->assertEmpty($model->read(null, 1));
+ $this->assertTrue($this->Dbo->rollback());
+ $this->assertNotEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertTrue($model->delete(1));
+ $this->assertEmpty($model->read(null, 1));
+ $this->assertTrue($this->Dbo->commit());
+ $this->assertEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->rollback());
+ $this->assertNotEmpty($model->read(null, 1));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php
new file mode 100644
index 0000000..f590cc7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqliteTest.php
@@ -0,0 +1,419 @@
+<?php
+/**
+ * DboSqliteTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model.Datasource.Database
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('Sqlite', 'Model/Datasource/Database');
+
+require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
+
+/**
+ * DboSqliteTestDb class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class DboSqliteTestDb extends Sqlite {
+
+/**
+ * simulated property
+ *
+ * @var array
+ */
+ public $simulated = array();
+
+/**
+ * execute method
+ *
+ * @param mixed $sql
+ * @return void
+ */
+ protected function _execute($sql, $params = array(), $prepareOptions = array()) {
+ $this->simulated[] = $sql;
+ return null;
+ }
+
+/**
+ * getLastQuery method
+ *
+ * @return void
+ */
+ public function getLastQuery() {
+ return $this->simulated[count($this->simulated) - 1];
+ }
+
+}
+
+/**
+ * DboSqliteTest class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class SqliteTest extends CakeTestCase {
+
+/**
+ * Do not automatically load fixtures for each test, they will be loaded manually using CakeTestCase::loadFixtures
+ *
+ * @var boolean
+ */
+ public $autoFixtures = false;
+
+/**
+ * Fixtures
+ *
+ * @var object
+ */
+ public $fixtures = array('core.user', 'core.uuid');
+
+/**
+ * Actual DB connection used in testing
+ *
+ * @var DboSource
+ */
+ public $Dbo = null;
+
+/**
+ * Sets up a Dbo class instance for testing
+ *
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Cache.disable', true);
+ $this->Dbo = ConnectionManager::getDataSource('test');
+ if (!$this->Dbo instanceof Sqlite) {
+ $this->markTestSkipped('The Sqlite extension is not available.');
+ }
+ }
+
+/**
+ * Sets up a Dbo class instance for testing
+ *
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('Cache.disable', false);
+ }
+
+/**
+ * Tests that SELECT queries from DboSqlite::listSources() are not cached
+ *
+ */
+ public function testTableListCacheDisabling() {
+ $this->assertFalse(in_array('foo_test', $this->Dbo->listSources()));
+
+ $this->Dbo->query('CREATE TABLE foo_test (test VARCHAR(255))');
+ $this->assertTrue(in_array('foo_test', $this->Dbo->listSources()));
+
+ $this->Dbo->cacheSources = false;
+ $this->Dbo->query('DROP TABLE foo_test');
+ $this->assertFalse(in_array('foo_test', $this->Dbo->listSources()));
+ }
+
+/**
+ * test Index introspection.
+ *
+ * @return void
+ */
+ public function testIndex() {
+ $name = $this->Dbo->fullTableName('with_a_key', false, false);
+ $this->Dbo->query('CREATE TABLE ' . $name . ' ("id" int(11) PRIMARY KEY, "bool" int(1), "small_char" varchar(50), "description" varchar(40) );');
+ $this->Dbo->query('CREATE INDEX pointless_bool ON ' . $name . '("bool")');
+ $this->Dbo->query('CREATE UNIQUE INDEX char_index ON ' . $name . '("small_char")');
+ $expected = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'pointless_bool' => array('column' => 'bool', 'unique' => 0),
+ 'char_index' => array('column' => 'small_char', 'unique' => 1),
+
+ );
+ $result = $this->Dbo->index($name);
+ $this->assertEquals($expected, $result);
+ $this->Dbo->query('DROP TABLE ' . $name);
+
+ $this->Dbo->query('CREATE TABLE ' . $name . ' ("id" int(11) PRIMARY KEY, "bool" int(1), "small_char" varchar(50), "description" varchar(40) );');
+ $this->Dbo->query('CREATE UNIQUE INDEX multi_col ON ' . $name . '("small_char", "bool")');
+ $expected = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'multi_col' => array('column' => array('small_char', 'bool'), 'unique' => 1),
+ );
+ $result = $this->Dbo->index($name);
+ $this->assertEquals($expected, $result);
+ $this->Dbo->query('DROP TABLE ' . $name);
+ }
+
+/**
+ * Tests that cached table descriptions are saved under the sanitized key name
+ *
+ */
+ public function testCacheKeyName() {
+ Configure::write('Cache.disable', false);
+
+ $dbName = 'db' . rand() . '$(*%&).db';
+ $this->assertFalse(file_exists(TMP . $dbName));
+
+ $config = $this->Dbo->config;
+ $db = new Sqlite(array_merge($this->Dbo->config, array('database' => TMP . $dbName)));
+ $this->assertTrue(file_exists(TMP . $dbName));
+
+ $db->execute("CREATE TABLE test_list (id VARCHAR(255));");
+
+ $db->cacheSources = true;
+ $this->assertEquals(array('test_list'), $db->listSources());
+ $db->cacheSources = false;
+
+ $fileName = '_' . preg_replace('/[^A-Za-z0-9_\-+]/', '_', TMP . $dbName) . '_list';
+
+ $result = Cache::read($fileName, '_cake_model_');
+ $this->assertEquals(array('test_list'), $result);
+
+ Cache::delete($fileName, '_cake_model_');
+ Configure::write('Cache.disable', true);
+ }
+
+/**
+ * test building columns with SQLite
+ *
+ * @return void
+ */
+ public function testBuildColumn() {
+ $data = array(
+ 'name' => 'int_field',
+ 'type' => 'integer',
+ 'null' => false,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '"int_field" integer NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'name',
+ 'type' => 'string',
+ 'length' => 20,
+ 'null' => false,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '"name" varchar(20) NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'string',
+ 'length' => 20,
+ 'default' => null,
+ 'null' => true,
+ 'collate' => 'NOCASE'
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '"testName" varchar(20) DEFAULT NULL COLLATE NOCASE';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'string',
+ 'length' => 20,
+ 'default' => 'test-value',
+ 'null' => false,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '"testName" varchar(20) DEFAULT \'test-value\' NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'integer',
+ 'length' => 10,
+ 'default' => 10,
+ 'null' => false,
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '"testName" integer(10) DEFAULT 10 NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'name' => 'testName',
+ 'type' => 'integer',
+ 'length' => 10,
+ 'default' => 10,
+ 'null' => false,
+ 'collate' => 'BADVALUE'
+ );
+ $result = $this->Dbo->buildColumn($data);
+ $expected = '"testName" integer(10) DEFAULT 10 NOT NULL';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test describe() and normal results.
+ *
+ * @return void
+ */
+ public function testDescribe() {
+ $this->loadFixtures('User');
+ $Model = new Model(array('name' => 'User', 'ds' => 'test', 'table' => 'users'));
+
+ $this->Dbo->cacheSources = true;
+ Configure::write('Cache.disable', false);
+
+ $result = $this->Dbo->describe($Model);
+ $expected = array(
+ 'id' => array(
+ 'type' => 'integer',
+ 'key' => 'primary',
+ 'null' => false,
+ 'default' => null,
+ 'length' => 11
+ ),
+ 'user' => array(
+ 'type' => 'string',
+ 'length' => 255,
+ 'null' => true,
+ 'default' => null
+ ),
+ 'password' => array(
+ 'type' => 'string',
+ 'length' => 255,
+ 'null' => true,
+ 'default' => null
+ ),
+ 'created' => array(
+ 'type' => 'datetime',
+ 'null' => true,
+ 'default' => null,
+ 'length' => null,
+ ),
+ 'updated' => array(
+ 'type' => 'datetime',
+ 'null' => true,
+ 'default' => null,
+ 'length' => null,
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Dbo->describe($Model->useTable);
+ $this->assertEquals($expected, $result);
+
+ $result = Cache::read('test_users', '_cake_model_');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that describe does not corrupt UUID primary keys
+ *
+ * @return void
+ */
+ public function testDescribeWithUuidPrimaryKey() {
+ $tableName = 'uuid_tests';
+ $this->Dbo->query("CREATE TABLE {$tableName} (id VARCHAR(36) PRIMARY KEY, name VARCHAR, created DATETIME, modified DATETIME)");
+ $Model = new Model(array('name' => 'UuidTest', 'ds' => 'test', 'table' => 'uuid_tests'));
+ $result = $this->Dbo->describe($Model);
+ $expected = array(
+ 'type' => 'string',
+ 'length' => 36,
+ 'null' => false,
+ 'default' => null,
+ 'key' => 'primary',
+ );
+ $this->assertEquals($expected, $result['id']);
+ $this->Dbo->query('DROP TABLE ' . $tableName);
+
+ $tableName = 'uuid_tests';
+ $this->Dbo->query("CREATE TABLE {$tableName} (id CHAR(36) PRIMARY KEY, name VARCHAR, created DATETIME, modified DATETIME)");
+ $Model = new Model(array('name' => 'UuidTest', 'ds' => 'test', 'table' => 'uuid_tests'));
+ $result = $this->Dbo->describe($Model);
+ $expected = array(
+ 'type' => 'string',
+ 'length' => 36,
+ 'null' => false,
+ 'default' => null,
+ 'key' => 'primary',
+ );
+ $this->assertEquals($expected, $result['id']);
+ $this->Dbo->query('DROP TABLE ' . $tableName);
+ }
+
+/**
+ * Test virtualFields with functions.
+ *
+ * @return void
+ */
+ public function testVirtualFieldWithFunction() {
+ $this->loadFixtures('User');
+ $User = ClassRegistry::init('User');
+ $User->virtualFields = array('name' => 'SUBSTR(User.user, 5, LENGTH(User.user) - 4)');
+
+ $result = $User->find('first', array(
+ 'conditions' => array('User.user' => 'garrett')
+ ));
+ $this->assertEquals('ett', $result['User']['name']);
+ }
+
+/**
+ * Test that records can be inserted with uuid primary keys, and
+ * that the primary key is not blank
+ *
+ * @return void
+ */
+ public function testUuidPrimaryKeyInsertion() {
+ $this->loadFixtures('Uuid');
+ $Model = ClassRegistry::init('Uuid');
+
+ $data = array(
+ 'title' => 'A uuid should work',
+ 'count' => 10
+ );
+ $Model->create($data);
+ $this->assertTrue((bool)$Model->save());
+ $result = $Model->read();
+
+ $this->assertEquals($data['title'], $result['Uuid']['title']);
+ $this->assertTrue(Validation::uuid($result['Uuid']['id']), 'Not a uuid');
+ }
+
+/**
+ * Test nested transaction
+ *
+ * @return void
+ */
+ public function testNestedTransaction() {
+ $this->skipIf($this->Dbo->nestedTransactionSupported() === false, 'The Sqlite version do not support nested transaction');
+
+ $this->loadFixtures('User');
+ $model = new User();
+ $model->hasOne = $model->hasMany = $model->belongsTo = $model->hasAndBelongsToMany = array();
+ $model->cacheQueries = false;
+ $this->Dbo->cacheMethods = false;
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertNotEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertTrue($model->delete(1));
+ $this->assertEmpty($model->read(null, 1));
+ $this->assertTrue($this->Dbo->rollback());
+ $this->assertNotEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->begin());
+ $this->assertTrue($model->delete(1));
+ $this->assertEmpty($model->read(null, 1));
+ $this->assertTrue($this->Dbo->commit());
+ $this->assertEmpty($model->read(null, 1));
+
+ $this->assertTrue($this->Dbo->rollback());
+ $this->assertNotEmpty($model->read(null, 1));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php
new file mode 100644
index 0000000..e31595b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Database/SqlserverTest.php
@@ -0,0 +1,679 @@
+<?php
+/**
+ * SqlserverTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model.Datasource.Database
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('Sqlserver', 'Model/Datasource/Database');
+
+require_once dirname(dirname(dirname(__FILE__))) . DS . 'models.php';
+
+/**
+ * SqlserverTestDb class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class SqlserverTestDb extends Sqlserver {
+
+/**
+ * simulated property
+ *
+ * @var array
+ */
+ public $simulated = array();
+
+/**
+ * execute results stack
+ *
+ * @var array
+ */
+ public $executeResultsStack = array();
+
+/**
+ * execute method
+ *
+ * @param mixed $sql
+ * @param mixed $params
+ * @param mixed $prepareOptions
+ * @return mixed
+ */
+ protected function _execute($sql, $params = array(), $prepareOptions = array()) {
+ $this->simulated[] = $sql;
+ return empty($this->executeResultsStack) ? null : array_pop($this->executeResultsStack);
+ }
+
+/**
+ * fetchAll method
+ *
+ * @param mixed $sql
+ * @return void
+ */
+ protected function _matchRecords(Model $model, $conditions = null) {
+ return $this->conditions(array('id' => array(1, 2)));
+ }
+
+/**
+ * getLastQuery method
+ *
+ * @return string
+ */
+ public function getLastQuery() {
+ return $this->simulated[count($this->simulated) - 1];
+ }
+
+/**
+ * getPrimaryKey method
+ *
+ * @param mixed $model
+ * @return string
+ */
+ public function getPrimaryKey($model) {
+ return parent::_getPrimaryKey($model);
+ }
+
+/**
+ * clearFieldMappings method
+ *
+ * @return void
+ */
+ public function clearFieldMappings() {
+ $this->_fieldMappings = array();
+ }
+
+/**
+ * describe method
+ *
+ * @param object $model
+ * @return void
+ */
+ public function describe($model) {
+ return empty($this->describe) ? parent::describe($model) : $this->describe;
+ }
+
+}
+
+/**
+ * SqlserverTestModel class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class SqlserverTestModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SqlserverTestModel'
+ */
+ public $name = 'SqlserverTestModel';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * _schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8', 'key' => 'primary'),
+ 'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
+ 'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
+ 'last_login' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'SqlserverClientTestModel' => array(
+ 'foreignKey' => 'client_id'
+ )
+ );
+
+/**
+ * find method
+ *
+ * @param mixed $conditions
+ * @param mixed $fields
+ * @param mixed $order
+ * @param mixed $recursive
+ * @return void
+ */
+ public function find($conditions = null, $fields = null, $order = null, $recursive = null) {
+ return $conditions;
+ }
+
+}
+
+/**
+ * SqlserverClientTestModel class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class SqlserverClientTestModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SqlserverAssociatedTestModel'
+ */
+ public $name = 'SqlserverClientTestModel';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * _schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'created' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+}
+
+/**
+ * SqlserverTestResultIterator class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class SqlserverTestResultIterator extends ArrayIterator {
+
+/**
+ * closeCursor method
+ *
+ * @return void
+ */
+ public function closeCursor() {
+ }
+
+/**
+ * fetch method
+ *
+ * @return void
+ */
+ public function fetch() {
+ if (!$this->valid()) {
+ return null;
+ }
+ $current = $this->current();
+ $this->next();
+ return $current;
+ }
+
+}
+
+/**
+ * SqlserverTest class
+ *
+ * @package Cake.Test.Case.Model.Datasource.Database
+ */
+class SqlserverTest extends CakeTestCase {
+
+/**
+ * The Dbo instance to be tested
+ *
+ * @var DboSource
+ */
+ public $db = null;
+
+/**
+ * autoFixtures property
+ *
+ * @var bool false
+ */
+ public $autoFixtures = false;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.user', 'core.category', 'core.author', 'core.post');
+
+/**
+ * Sets up a Dbo class instance for testing
+ *
+ */
+ public function setUp() {
+ $this->Dbo = ConnectionManager::getDataSource('test');
+ if (!($this->Dbo instanceof Sqlserver)) {
+ $this->markTestSkipped('Please configure the test datasource to use SQL Server.');
+ }
+ $this->db = new SqlserverTestDb($this->Dbo->config);
+ $this->model = new SqlserverTestModel();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->Dbo);
+ unset($this->model);
+ }
+
+/**
+ * testQuoting method
+ *
+ * @return void
+ */
+ public function testQuoting() {
+ $expected = "1.2";
+ $result = $this->db->value(1.2, 'float');
+ $this->assertSame($expected, $result);
+
+ $expected = "'1,2'";
+ $result = $this->db->value('1,2', 'float');
+ $this->assertSame($expected, $result);
+
+ $expected = 'NULL';
+ $result = $this->db->value('', 'integer');
+ $this->assertSame($expected, $result);
+
+ $expected = 'NULL';
+ $result = $this->db->value('', 'float');
+ $this->assertSame($expected, $result);
+
+ $expected = "''";
+ $result = $this->db->value('', 'binary');
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testFields method
+ *
+ * @return void
+ */
+ public function testFields() {
+ $fields = array(
+ '[SqlserverTestModel].[id] AS [SqlserverTestModel__id]',
+ '[SqlserverTestModel].[client_id] AS [SqlserverTestModel__client_id]',
+ '[SqlserverTestModel].[name] AS [SqlserverTestModel__name]',
+ '[SqlserverTestModel].[login] AS [SqlserverTestModel__login]',
+ '[SqlserverTestModel].[passwd] AS [SqlserverTestModel__passwd]',
+ '[SqlserverTestModel].[addr_1] AS [SqlserverTestModel__addr_1]',
+ '[SqlserverTestModel].[addr_2] AS [SqlserverTestModel__addr_2]',
+ '[SqlserverTestModel].[zip_code] AS [SqlserverTestModel__zip_code]',
+ '[SqlserverTestModel].[city] AS [SqlserverTestModel__city]',
+ '[SqlserverTestModel].[country] AS [SqlserverTestModel__country]',
+ '[SqlserverTestModel].[phone] AS [SqlserverTestModel__phone]',
+ '[SqlserverTestModel].[fax] AS [SqlserverTestModel__fax]',
+ '[SqlserverTestModel].[url] AS [SqlserverTestModel__url]',
+ '[SqlserverTestModel].[email] AS [SqlserverTestModel__email]',
+ '[SqlserverTestModel].[comments] AS [SqlserverTestModel__comments]',
+ 'CONVERT(VARCHAR(20), [SqlserverTestModel].[last_login], 20) AS [SqlserverTestModel__last_login]',
+ '[SqlserverTestModel].[created] AS [SqlserverTestModel__created]',
+ 'CONVERT(VARCHAR(20), [SqlserverTestModel].[updated], 20) AS [SqlserverTestModel__updated]'
+ );
+
+ $result = $this->db->fields($this->model);
+ $expected = $fields;
+ $this->assertEquals($expected, $result);
+
+ $this->db->clearFieldMappings();
+ $result = $this->db->fields($this->model, null, 'SqlserverTestModel.*');
+ $expected = $fields;
+ $this->assertEquals($expected, $result);
+
+ $this->db->clearFieldMappings();
+ $result = $this->db->fields($this->model, null, array('*', 'AnotherModel.id', 'AnotherModel.name'));
+ $expected = array_merge($fields, array(
+ '[AnotherModel].[id] AS [AnotherModel__id]',
+ '[AnotherModel].[name] AS [AnotherModel__name]'));
+ $this->assertEquals($expected, $result);
+
+ $this->db->clearFieldMappings();
+ $result = $this->db->fields($this->model, null, array('*', 'SqlserverClientTestModel.*'));
+ $expected = array_merge($fields, array(
+ '[SqlserverClientTestModel].[id] AS [SqlserverClientTestModel__id]',
+ '[SqlserverClientTestModel].[name] AS [SqlserverClientTestModel__name]',
+ '[SqlserverClientTestModel].[email] AS [SqlserverClientTestModel__email]',
+ 'CONVERT(VARCHAR(20), [SqlserverClientTestModel].[created], 20) AS [SqlserverClientTestModel__created]',
+ 'CONVERT(VARCHAR(20), [SqlserverClientTestModel].[updated], 20) AS [SqlserverClientTestModel__updated]'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testDistinctFields method
+ *
+ * @return void
+ */
+ public function testDistinctFields() {
+ $result = $this->db->fields($this->model, null, array('DISTINCT Car.country_code'));
+ $expected = array('DISTINCT [Car].[country_code] AS [Car__country_code]');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->fields($this->model, null, 'DISTINCT Car.country_code');
+ $expected = array('DISTINCT [Car].[country_code] AS [Car__country_code]');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testDistinctWithLimit method
+ *
+ * @return void
+ */
+ public function testDistinctWithLimit() {
+ $this->db->read($this->model, array(
+ 'fields' => array('DISTINCT SqlserverTestModel.city', 'SqlserverTestModel.country'),
+ 'limit' => 5
+ ));
+ $result = $this->db->getLastQuery();
+ $this->assertRegExp('/^SELECT DISTINCT TOP 5/', $result);
+ }
+
+/**
+ * testDescribe method
+ *
+ * @return void
+ */
+ public function testDescribe() {
+ $SqlserverTableDescription = new SqlserverTestResultIterator(array(
+ (object)array(
+ 'Default' => '((0))',
+ 'Field' => 'count',
+ 'Key' => 0,
+ 'Length' => '4',
+ 'Null' => 'NO',
+ 'Type' => 'integer'
+ ),
+ (object)array(
+ 'Default' => '',
+ 'Field' => 'body',
+ 'Key' => 0,
+ 'Length' => '-1',
+ 'Null' => 'YES',
+ 'Type' => 'nvarchar'
+ ),
+ (object)array(
+ 'Default' => '',
+ 'Field' => 'published',
+ 'Key' => 0,
+ 'Type' => 'datetime2',
+ 'Length' => 8,
+ 'Null' => 'YES',
+ 'Size' => ''
+ ),
+ (object)array(
+ 'Default' => '',
+ 'Field' => 'id',
+ 'Key' => 1,
+ 'Type' => 'nchar',
+ 'Length' => 72,
+ 'Null' => 'NO',
+ 'Size' => ''
+ )
+ ));
+ $this->db->executeResultsStack = array($SqlserverTableDescription);
+ $dummyModel = $this->model;
+ $result = $this->db->describe($dummyModel);
+ $expected = array(
+ 'count' => array(
+ 'type' => 'integer',
+ 'null' => false,
+ 'default' => '0',
+ 'length' => 4
+ ),
+ 'body' => array(
+ 'type' => 'text',
+ 'null' => true,
+ 'default' => null,
+ 'length' => null
+ ),
+ 'published' => array(
+ 'type' => 'datetime',
+ 'null' => true,
+ 'default' => '',
+ 'length' => null
+ ),
+ 'id' => array(
+ 'type' => 'string',
+ 'null' => false,
+ 'default' => '',
+ 'length' => 36,
+ 'key' => 'primary'
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBuildColumn
+ *
+ * @return void
+ */
+ public function testBuildColumn() {
+ $column = array('name' => 'id', 'type' => 'integer', 'null' => false, 'default' => '', 'length' => '8', 'key' => 'primary');
+ $result = $this->db->buildColumn($column);
+ $expected = '[id] int IDENTITY (1, 1) NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'client_id', 'type' => 'integer', 'null' => false, 'default' => '0', 'length' => '11');
+ $result = $this->db->buildColumn($column);
+ $expected = '[client_id] int DEFAULT 0 NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'client_id', 'type' => 'integer', 'null' => true);
+ $result = $this->db->buildColumn($column);
+ $expected = '[client_id] int NULL';
+ $this->assertEquals($expected, $result);
+
+ // 'name' => 'type' format for columns
+ $column = array('type' => 'integer', 'name' => 'client_id');
+ $result = $this->db->buildColumn($column);
+ $expected = '[client_id] int NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('type' => 'string', 'name' => 'name');
+ $result = $this->db->buildColumn($column);
+ $expected = '[name] nvarchar(255) NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'name', 'type' => 'string', 'null' => false, 'default' => '', 'length' => '255');
+ $result = $this->db->buildColumn($column);
+ $expected = '[name] nvarchar(255) DEFAULT \'\' NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'name', 'type' => 'string', 'null' => false, 'length' => '255');
+ $result = $this->db->buildColumn($column);
+ $expected = '[name] nvarchar(255) NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'name', 'type' => 'string', 'null' => false, 'default' => null, 'length' => '255');
+ $result = $this->db->buildColumn($column);
+ $expected = '[name] nvarchar(255) NOT NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'name', 'type' => 'string', 'null' => true, 'default' => null, 'length' => '255');
+ $result = $this->db->buildColumn($column);
+ $expected = '[name] nvarchar(255) NULL';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'name', 'type' => 'string', 'null' => true, 'default' => '', 'length' => '255');
+ $result = $this->db->buildColumn($column);
+ $expected = '[name] nvarchar(255) DEFAULT \'\'';
+ $this->assertEquals($expected, $result);
+
+ $column = array('name' => 'body', 'type' => 'text');
+ $result = $this->db->buildColumn($column);
+ $expected = '[body] nvarchar(MAX)';
+ $this->assertEquals($expected, $result);
+
+ $column = array(
+ 'name' => 'checked',
+ 'type' => 'boolean',
+ 'length' => 10,
+ 'default' => '1'
+ );
+ $result = $this->db->buildColumn($column);
+ $expected = "[checked] bit DEFAULT '1'";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBuildIndex method
+ *
+ * @return void
+ */
+ public function testBuildIndex() {
+ $indexes = array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'client_id' => array('column' => 'client_id', 'unique' => 1)
+ );
+ $result = $this->db->buildIndex($indexes, 'items');
+ $expected = array(
+ 'PRIMARY KEY ([id])',
+ 'ALTER TABLE items ADD CONSTRAINT client_id UNIQUE([client_id]);'
+ );
+ $this->assertEquals($expected, $result);
+
+ $indexes = array('client_id' => array('column' => 'client_id'));
+ $result = $this->db->buildIndex($indexes, 'items');
+ $this->assertEquals(array(), $result);
+
+ $indexes = array('client_id' => array('column' => array('client_id', 'period_id'), 'unique' => 1));
+ $result = $this->db->buildIndex($indexes, 'items');
+ $expected = array('ALTER TABLE items ADD CONSTRAINT client_id UNIQUE([client_id], [period_id]);');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUpdateAllSyntax method
+ *
+ * @return void
+ */
+ public function testUpdateAllSyntax() {
+ $fields = array('SqlserverTestModel.client_id' => '[SqlserverTestModel].[client_id] + 1');
+ $conditions = array('SqlserverTestModel.updated <' => date('2009-01-01 00:00:00'));
+ $this->db->update($this->model, $fields, null, $conditions);
+
+ $result = $this->db->getLastQuery();
+ $this->assertNotRegExp('/SqlserverTestModel/', $result);
+ $this->assertRegExp('/^UPDATE \[sqlserver_test_models\]/', $result);
+ $this->assertRegExp('/SET \[client_id\] = \[client_id\] \+ 1/', $result);
+ }
+
+/**
+ * testGetPrimaryKey method
+ *
+ * @return void
+ */
+ public function testGetPrimaryKey() {
+ $schema = $this->model->schema();
+
+ $this->db->describe = $schema;
+ $result = $this->db->getPrimaryKey($this->model);
+ $this->assertEquals('id', $result);
+
+ unset($schema['id']['key']);
+ $this->db->describe = $schema;
+ $result = $this->db->getPrimaryKey($this->model);
+ $this->assertNull($result);
+ }
+
+/**
+ * SQL server < 11 doesn't have proper limit/offset support, test that our hack works.
+ *
+ * @return void
+ */
+ public function testLimitOffsetHack() {
+ $this->loadFixtures('Author', 'Post', 'User');
+ $query = array(
+ 'limit' => 2,
+ 'page' => 1,
+ 'order' => 'User.user ASC',
+ );
+ $User = ClassRegistry::init('User');
+ $results = $User->find('all', $query);
+
+ $this->assertEquals(2, count($results));
+ $this->assertEquals('garrett', $results[0]['User']['user']);
+ $this->assertEquals('larry', $results[1]['User']['user']);
+
+ $query = array(
+ 'limit' => 2,
+ 'page' => 2,
+ 'order' => 'User.user ASC',
+ );
+ $User = ClassRegistry::init('User');
+ $results = $User->find('all', $query);
+
+ $this->assertEquals(2, count($results));
+ $this->assertFalse(isset($results[0][0]));
+ $this->assertEquals('mariano', $results[0]['User']['user']);
+ $this->assertEquals('nate', $results[1]['User']['user']);
+ }
+
+/**
+ * Test that the return of stored procedures is honoured
+ *
+ * @return void
+ */
+ public function testStoredProcedureReturn() {
+ $sql = <<<SQL
+CREATE PROCEDURE cake_test_procedure
+AS
+BEGIN
+RETURN 2;
+END
+SQL;
+ $this->Dbo->execute($sql);
+
+ $sql = <<<SQL
+DECLARE @return_value int
+EXEC @return_value = [cake_test_procedure]
+SELECT 'value' = @return_value
+SQL;
+ $query = $this->Dbo->execute($sql);
+ $this->Dbo->execute('DROP PROC cake_test_procedure');
+
+ $result = $query->fetch();
+ $this->assertEquals(2, $result['value']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php
new file mode 100644
index 0000000..c6cef46
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php
@@ -0,0 +1,1102 @@
+<?php
+/**
+ * DboSourceTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Datasource
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('DataSource', 'Model/Datasource');
+App::uses('DboSource', 'Model/Datasource');
+require_once dirname(dirname(__FILE__)) . DS . 'models.php';
+
+class MockPDO extends PDO {
+
+ public function __construct() {
+ }
+
+}
+
+class MockDataSource extends DataSource {
+}
+
+class DboTestSource extends DboSource {
+
+ public $nestedSupport = false;
+
+ public function connect($config = array()) {
+ $this->connected = true;
+ }
+
+ public function mergeAssociation(&$data, &$merge, $association, $type, $selfJoin = false) {
+ return parent::_mergeAssociation($data, $merge, $association, $type, $selfJoin);
+ }
+
+ public function setConfig($config = array()) {
+ $this->config = $config;
+ }
+
+ public function setConnection($conn) {
+ $this->_connection = $conn;
+ }
+
+ public function nestedTransactionSupported() {
+ return $this->useNestedTransactions && $this->nestedSupport;
+ }
+
+}
+
+class DboSecondTestSource extends DboSource {
+
+ public $startQuote = '_';
+
+ public $endQuote = '_';
+
+ public function connect($config = array()) {
+ $this->connected = true;
+ }
+
+ public function mergeAssociation(&$data, &$merge, $association, $type, $selfJoin = false) {
+ return parent::_mergeAssociation($data, $merge, $association, $type, $selfJoin);
+ }
+
+ public function setConfig($config = array()) {
+ $this->config = $config;
+ }
+
+ public function setConnection($conn) {
+ $this->_connection = $conn;
+ }
+
+}
+
+/**
+ * DboSourceTest class
+ *
+ * @package Cake.Test.Case.Model.Datasource
+ */
+class DboSourceTest extends CakeTestCase {
+
+/**
+ * autoFixtures property
+ *
+ * @var bool false
+ */
+ public $autoFixtures = false;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.apple', 'core.article', 'core.articles_tag', 'core.attachment', 'core.comment',
+ 'core.sample', 'core.tag', 'core.user', 'core.post', 'core.author', 'core.data_test'
+ );
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->__config = $this->db->config;
+
+ $this->testDb = new DboTestSource();
+ $this->testDb->cacheSources = false;
+ $this->testDb->startQuote = '`';
+ $this->testDb->endQuote = '`';
+
+ $this->Model = new TestModel();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Model);
+ }
+
+/**
+ * test that booleans and null make logical condition strings.
+ *
+ * @return void
+ */
+ public function testBooleanNullConditionsParsing() {
+ $result = $this->testDb->conditions(true);
+ $this->assertEquals(' WHERE 1 = 1', $result, 'true conditions failed %s');
+
+ $result = $this->testDb->conditions(false);
+ $this->assertEquals(' WHERE 0 = 1', $result, 'false conditions failed %s');
+
+ $result = $this->testDb->conditions(null);
+ $this->assertEquals(' WHERE 1 = 1', $result, 'null conditions failed %s');
+
+ $result = $this->testDb->conditions(array());
+ $this->assertEquals(' WHERE 1 = 1', $result, 'array() conditions failed %s');
+
+ $result = $this->testDb->conditions('');
+ $this->assertEquals(' WHERE 1 = 1', $result, '"" conditions failed %s');
+
+ $result = $this->testDb->conditions(' ', '" " conditions failed %s');
+ $this->assertEquals(' WHERE 1 = 1', $result);
+ }
+
+/**
+ * test that order() will accept objects made from DboSource::expression
+ *
+ * @return void
+ */
+ public function testOrderWithExpression() {
+ $expression = $this->testDb->expression("CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col");
+ $result = $this->testDb->order($expression);
+ $expected = " ORDER BY CASE Sample.id WHEN 1 THEN 'Id One' ELSE 'Other Id' END AS case_col";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMergeAssociations method
+ *
+ * @return void
+ */
+ public function testMergeAssociations() {
+ $data = array('Article2' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article',
+ 'body' => 'First Article Body', 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ));
+ $merge = array('Topic' => array(array(
+ 'id' => '1', 'topic' => 'Topic', 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )));
+ $expected = array(
+ 'Article2' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article',
+ 'body' => 'First Article Body', 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Topic' => array(
+ 'id' => '1', 'topic' => 'Topic', 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'Topic', 'hasOne');
+ $this->assertEquals($expected, $data);
+
+ $data = array('Article2' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article',
+ 'body' => 'First Article Body', 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ));
+ $merge = array('User2' => array(array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )));
+
+ $expected = array(
+ 'Article2' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article',
+ 'body' => 'First Article Body', 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'User2', 'belongsTo');
+ $this->assertEquals($expected, $data);
+
+ $data = array(
+ 'Article2' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ )
+ );
+ $merge = array(array('Comment' => false));
+ $expected = array(
+ 'Article2' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Comment' => array()
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'Comment', 'hasMany');
+ $this->assertEquals($expected, $data);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ )
+ );
+ $merge = array(
+ array(
+ 'Comment' => array(
+ 'id' => '1', 'comment' => 'Comment 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Comment' => array(
+ 'id' => '2', 'comment' => 'Comment 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $expected = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1', 'comment' => 'Comment 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ array(
+ 'id' => '2', 'comment' => 'Comment 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'Comment', 'hasMany');
+ $this->assertEquals($expected, $data);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ )
+ );
+ $merge = array(
+ array(
+ 'Comment' => array(
+ 'id' => '1', 'comment' => 'Comment 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Comment' => array(
+ 'id' => '2', 'comment' => 'Comment 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $expected = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1', 'comment' => 'Comment 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'id' => '2', 'comment' => 'Comment 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ )
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'Comment', 'hasMany');
+ $this->assertEquals($expected, $data);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ )
+ );
+ $merge = array(
+ array(
+ 'Comment' => array(
+ 'id' => '1', 'comment' => 'Comment 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Tag' => array(
+ array('id' => 1, 'tag' => 'Tag 1'),
+ array('id' => 2, 'tag' => 'Tag 2')
+ )
+ ),
+ array(
+ 'Comment' => array(
+ 'id' => '2', 'comment' => 'Comment 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Tag' => array()
+ )
+ );
+ $expected = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1', 'comment' => 'Comment 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Tag' => array(
+ array('id' => 1, 'tag' => 'Tag 1'),
+ array('id' => 2, 'tag' => 'Tag 2')
+ )
+ ),
+ array(
+ 'id' => '2', 'comment' => 'Comment 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31',
+ 'User2' => array(
+ 'id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Tag' => array()
+ )
+ )
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'Comment', 'hasMany');
+ $this->assertEquals($expected, $data);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ )
+ );
+ $merge = array(
+ array(
+ 'Tag' => array(
+ 'id' => '1', 'tag' => 'Tag 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Tag' => array(
+ 'id' => '2', 'tag' => 'Tag 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Tag' => array(
+ 'id' => '3', 'tag' => 'Tag 3', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $expected = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1', 'tag' => 'Tag 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ array(
+ 'id' => '2', 'tag' => 'Tag 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ ),
+ array(
+ 'id' => '3', 'tag' => 'Tag 3', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'Tag', 'hasAndBelongsToMany');
+ $this->assertEquals($expected, $data);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ )
+ );
+ $merge = array(
+ array(
+ 'Tag' => array(
+ 'id' => '1', 'tag' => 'Tag 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Tag' => array(
+ 'id' => '2', 'tag' => 'Tag 2', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ ),
+ array(
+ 'Tag' => array(
+ 'id' => '3', 'tag' => 'Tag 3', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'
+ )
+ )
+ );
+ $expected = array(
+ 'Article' => array(
+ 'id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Tag' => array('id' => '1', 'tag' => 'Tag 1', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31')
+ );
+ $this->testDb->mergeAssociation($data, $merge, 'Tag', 'hasOne');
+ $this->assertEquals($expected, $data);
+ }
+
+/**
+ * testMagicMethodQuerying method
+ *
+ * @return void
+ */
+ public function testMagicMethodQuerying() {
+ $result = $this->db->query('findByFieldName', array('value'), $this->Model);
+ $expected = array('first', array(
+ 'conditions' => array('TestModel.field_name' => 'value'),
+ 'fields' => null, 'order' => null, 'recursive' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->query('findByFindBy', array('value'), $this->Model);
+ $expected = array('first', array(
+ 'conditions' => array('TestModel.find_by' => 'value'),
+ 'fields' => null, 'order' => null, 'recursive' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->query('findAllByFieldName', array('value'), $this->Model);
+ $expected = array('all', array(
+ 'conditions' => array('TestModel.field_name' => 'value'),
+ 'fields' => null, 'order' => null, 'limit' => null,
+ 'page' => null, 'recursive' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->query('findAllById', array('a'), $this->Model);
+ $expected = array('all', array(
+ 'conditions' => array('TestModel.id' => 'a'),
+ 'fields' => null, 'order' => null, 'limit' => null,
+ 'page' => null, 'recursive' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->query('findByFieldName', array(array('value1', 'value2', 'value3')), $this->Model);
+ $expected = array('first', array(
+ 'conditions' => array('TestModel.field_name' => array('value1', 'value2', 'value3')),
+ 'fields' => null, 'order' => null, 'recursive' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->query('findByFieldName', array(null), $this->Model);
+ $expected = array('first', array(
+ 'conditions' => array('TestModel.field_name' => null),
+ 'fields' => null, 'order' => null, 'recursive' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->query('findByFieldName', array('= a'), $this->Model);
+ $expected = array('first', array(
+ 'conditions' => array('TestModel.field_name' => '= a'),
+ 'fields' => null, 'order' => null, 'recursive' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->db->query('findByFieldName', array(), $this->Model);
+ $expected = false;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ *
+ * @expectedException PDOException
+ * @return void
+ */
+ public function testDirectCallThrowsException() {
+ $result = $this->db->query('directCall', array(), $this->Model);
+ }
+
+/**
+ * testValue method
+ *
+ * @return void
+ */
+ public function testValue() {
+ if ($this->db instanceof Sqlserver) {
+ $this->markTestSkipped('Cannot run this test with SqlServer');
+ }
+ $result = $this->db->value('{$__cakeForeignKey__$}');
+ $this->assertEquals('{$__cakeForeignKey__$}', $result);
+
+ $result = $this->db->value(array('first', 2, 'third'));
+ $expected = array('\'first\'', 2, '\'third\'');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testReconnect method
+ *
+ * @return void
+ */
+ public function testReconnect() {
+ $this->testDb->reconnect(array('prefix' => 'foo'));
+ $this->assertTrue($this->testDb->connected);
+ $this->assertEquals('foo', $this->testDb->config['prefix']);
+ }
+
+/**
+ * testName method
+ *
+ * @return void
+ */
+ public function testName() {
+ $result = $this->testDb->name('name');
+ $expected = '`name`';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name(array('name', 'Model.*'));
+ $expected = array('`name`', '`Model`.*');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('MTD()');
+ $expected = 'MTD()';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('(sm)');
+ $expected = '(sm)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('name AS x');
+ $expected = '`name` AS `x`';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('Model.name AS x');
+ $expected = '`Model`.`name` AS `x`';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('Function(Something.foo)');
+ $expected = 'Function(`Something`.`foo`)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('Function(SubFunction(Something.foo))');
+ $expected = 'Function(SubFunction(`Something`.`foo`))';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('Function(Something.foo) AS x');
+ $expected = 'Function(`Something`.`foo`) AS `x`';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('name-with-minus');
+ $expected = '`name-with-minus`';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name(array('my-name', 'Foo-Model.*'));
+ $expected = array('`my-name`', '`Foo-Model`.*');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name(array('Team.P%', 'Team.G/G'));
+ $expected = array('`Team`.`P%`', '`Team`.`G/G`');
+ $this->assertEquals($expected, $result);
+
+ $result = $this->testDb->name('Model.name as y');
+ $expected = '`Model`.`name` AS `y`';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that cacheMethod works as expected
+ *
+ * @return void
+ */
+ public function testCacheMethod() {
+ $this->testDb->cacheMethods = true;
+ $result = $this->testDb->cacheMethod('name', 'some-key', 'stuff');
+ $this->assertEquals('stuff', $result);
+
+ $result = $this->testDb->cacheMethod('name', 'some-key');
+ $this->assertEquals('stuff', $result);
+
+ $result = $this->testDb->cacheMethod('conditions', 'some-key');
+ $this->assertNull($result);
+
+ $result = $this->testDb->cacheMethod('name', 'other-key');
+ $this->assertNull($result);
+
+ $this->testDb->cacheMethods = false;
+ $result = $this->testDb->cacheMethod('name', 'some-key', 'stuff');
+ $this->assertEquals('stuff', $result);
+
+ $result = $this->testDb->cacheMethod('name', 'some-key');
+ $this->assertNull($result);
+ }
+
+/**
+ * Test that rare collisions do not happen with method caching
+ *
+ * @return void
+ */
+ public function testNameMethodCacheCollisions() {
+ $this->testDb->cacheMethods = true;
+ $this->testDb->flushMethodCache();
+ $this->testDb->name('Model.fieldlbqndkezcoapfgirmjsh');
+ $result = $this->testDb->name('Model.fieldkhdfjmelarbqnzsogcpi');
+ $expected = '`Model`.`fieldkhdfjmelarbqnzsogcpi`';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testLog method
+ *
+ * @outputBuffering enabled
+ * @return void
+ */
+ public function testLog() {
+ $this->testDb->logQuery('Query 1');
+ $this->testDb->logQuery('Query 2');
+
+ $log = $this->testDb->getLog(false, false);
+ $result = Hash::extract($log['log'], '{n}.query');
+ $expected = array('Query 1', 'Query 2');
+ $this->assertEquals($expected, $result);
+
+ $oldDebug = Configure::read('debug');
+ Configure::write('debug', 2);
+ ob_start();
+ $this->testDb->showLog();
+ $contents = ob_get_clean();
+
+ $this->assertRegExp('/Query 1/s', $contents);
+ $this->assertRegExp('/Query 2/s', $contents);
+
+ ob_start();
+ $this->testDb->showLog(true);
+ $contents = ob_get_clean();
+
+ $this->assertRegExp('/Query 1/s', $contents);
+ $this->assertRegExp('/Query 2/s', $contents);
+
+ Configure::write('debug', $oldDebug);
+ }
+
+/**
+ * test getting the query log as an array.
+ *
+ * @return void
+ */
+ public function testGetLog() {
+ $this->testDb->logQuery('Query 1');
+ $this->testDb->logQuery('Query 2');
+
+ $log = $this->testDb->getLog();
+ $expected = array('query' => 'Query 1', 'params' => array(), 'affected' => '', 'numRows' => '', 'took' => '');
+
+ $this->assertEquals($expected, $log['log'][0]);
+ $expected = array('query' => 'Query 2', 'params' => array(), 'affected' => '', 'numRows' => '', 'took' => '');
+ $this->assertEquals($expected, $log['log'][1]);
+ $expected = array('query' => 'Error 1', 'affected' => '', 'numRows' => '', 'took' => '');
+ }
+
+/**
+ * test getting the query log as an array, setting bind params.
+ *
+ * @return void
+ */
+ public function testGetLogParams() {
+ $this->testDb->logQuery('Query 1', array(1,2,'abc'));
+ $this->testDb->logQuery('Query 2', array('field1' => 1, 'field2' => 'abc'));
+
+ $log = $this->testDb->getLog();
+ $expected = array('query' => 'Query 1', 'params' => array(1,2,'abc'), 'affected' => '', 'numRows' => '', 'took' => '');
+ $this->assertEquals($expected, $log['log'][0]);
+ $expected = array('query' => 'Query 2', 'params' => array('field1' => 1, 'field2' => 'abc'), 'affected' => '', 'numRows' => '', 'took' => '');
+ $this->assertEquals($expected, $log['log'][1]);
+ }
+
+/**
+ * test that query() returns boolean values from operations like CREATE TABLE
+ *
+ * @return void
+ */
+ public function testFetchAllBooleanReturns() {
+ $name = $this->db->fullTableName('test_query');
+ $query = "CREATE TABLE {$name} (name varchar(10));";
+ $result = $this->db->query($query);
+ $this->assertTrue($result, 'Query did not return a boolean');
+
+ $query = "DROP TABLE {$name};";
+ $result = $this->db->query($query);
+ $this->assertTrue($result, 'Query did not return a boolean');
+ }
+
+/**
+ * test order to generate query order clause for virtual fields
+ *
+ * @return void
+ */
+ public function testVirtualFieldsInOrder() {
+ $Article = ClassRegistry::init('Article');
+ $Article->virtualFields = array(
+ 'this_moment' => 'NOW()',
+ 'two' => '1 + 1',
+ );
+ $order = array('two', 'this_moment');
+ $result = $this->db->order($order, 'ASC', $Article);
+ $expected = ' ORDER BY (1 + 1) ASC, (NOW()) ASC';
+ $this->assertEquals($expected, $result);
+
+ $order = array('Article.two', 'Article.this_moment');
+ $result = $this->db->order($order, 'ASC', $Article);
+ $expected = ' ORDER BY (1 + 1) ASC, (NOW()) ASC';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test the permutations of fullTableName()
+ *
+ * @return void
+ */
+ public function testFullTablePermutations() {
+ $Article = ClassRegistry::init('Article');
+ $result = $this->testDb->fullTableName($Article, false, false);
+ $this->assertEquals('articles', $result);
+
+ $Article->tablePrefix = 'tbl_';
+ $result = $this->testDb->fullTableName($Article, false, false);
+ $this->assertEquals('tbl_articles', $result);
+
+ $Article->useTable = $Article->table = 'with spaces';
+ $Article->tablePrefix = '';
+ $result = $this->testDb->fullTableName($Article, true, false);
+ $this->assertEquals('`with spaces`', $result);
+
+ $this->loadFixtures('Article');
+ $Article->useTable = $Article->table = 'articles';
+ $Article->setDataSource('test');
+ $testdb = $Article->getDataSource();
+ $result = $testdb->fullTableName($Article, false, true);
+ $this->assertEquals($testdb->getSchemaName() . '.articles', $result);
+
+ // tests for empty schemaName
+ $noschema = ConnectionManager::create('noschema', array(
+ 'datasource' => 'DboTestSource'
+ ));
+ $Article->setDataSource('noschema');
+ $Article->schemaName = null;
+ $result = $noschema->fullTableName($Article, false, true);
+ $this->assertEquals('articles', $result);
+
+ $this->testDb->config['prefix'] = 't_';
+ $result = $this->testDb->fullTableName('post_tag', false, false);
+ $this->assertEquals('t_post_tag', $result);
+ }
+
+/**
+ * test that read() only calls queryAssociation on db objects when the method is defined.
+ *
+ * @return void
+ */
+ public function testReadOnlyCallingQueryAssociationWhenDefined() {
+ $this->loadFixtures('Article', 'User', 'ArticlesTag', 'Tag');
+ ConnectionManager::create('test_no_queryAssociation', array(
+ 'datasource' => 'MockDataSource'
+ ));
+ $Article = ClassRegistry::init('Article');
+ $Article->Comment->useDbConfig = 'test_no_queryAssociation';
+ $result = $Article->find('all');
+ $this->assertTrue(is_array($result));
+ }
+
+/**
+ * test that queryAssociation() reuse already joined data for 'belongsTo' and 'hasOne' associations
+ * instead of running unneeded queries for each record
+ *
+ * @return void
+ */
+ public function testQueryAssociationUnneededQueries() {
+ $this->loadFixtures('Article', 'User', 'Comment', 'Attachment', 'Tag', 'ArticlesTag');
+ $Comment = new Comment;
+
+ $fullDebug = $this->db->fullDebug;
+ $this->db->fullDebug = true;
+
+ $Comment->find('all', array('recursive' => 2)); // ensure Model descriptions are saved
+ $this->db->getLog();
+
+ // case: Comment belongsTo User and Article
+ $Comment->unbindModel(array(
+ 'hasOne' => array('Attachment')
+ ));
+ $Comment->Article->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment'),
+ 'hasAndBelongsToMany' => array('Tag')
+ ));
+ $Comment->find('all', array('recursive' => 2));
+ $log = $this->db->getLog();
+ $this->assertEquals(1, count($log['log']));
+
+ // case: Comment belongsTo Article, Article belongsTo User
+ $Comment->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasOne' => array('Attachment')
+ ));
+ $Comment->Article->unbindModel(array(
+ 'hasMany' => array('Comment'),
+ 'hasAndBelongsToMany' => array('Tag'),
+ ));
+ $Comment->find('all', array('recursive' => 2));
+ $log = $this->db->getLog();
+ $this->assertEquals(7, count($log['log']));
+
+ // case: Comment hasOne Attachment
+ $Comment->unbindModel(array(
+ 'belongsTo' => array('Article', 'User'),
+ ));
+ $Comment->Attachment->unbindModel(array(
+ 'belongsTo' => array('Comment'),
+ ));
+ $Comment->find('all', array('recursive' => 2));
+ $log = $this->db->getLog();
+ $this->assertEquals(1, count($log['log']));
+
+ $this->db->fullDebug = $fullDebug;
+ }
+
+/**
+ * test that fields() is using methodCache()
+ *
+ * @return void
+ */
+ public function testFieldsUsingMethodCache() {
+ $this->testDb->cacheMethods = false;
+ DboTestSource::$methodCache = array();
+
+ $Article = ClassRegistry::init('Article');
+ $this->testDb->fields($Article, null, array('title', 'body', 'published'));
+ $this->assertTrue(empty(DboTestSource::$methodCache['fields']), 'Cache not empty');
+ }
+
+/**
+ * test that fields() method cache detects datasource changes
+ *
+ * @return void
+ */
+ public function testFieldsCacheKeyWithDatasourceChange() {
+ ConnectionManager::create('firstschema', array(
+ 'datasource' => 'DboTestSource'
+ ));
+ ConnectionManager::create('secondschema', array(
+ 'datasource' => 'DboSecondTestSource'
+ ));
+ Cache::delete('method_cache', '_cake_core_');
+ DboTestSource::$methodCache = array();
+ $Article = ClassRegistry::init('Article');
+
+ $Article->setDataSource('firstschema');
+ $ds = $Article->getDataSource();
+ $ds->cacheMethods = true;
+ $first = $ds->fields($Article, null, array('title', 'body', 'published'));
+
+ $Article->setDataSource('secondschema');
+ $ds = $Article->getDataSource();
+ $ds->cacheMethods = true;
+ $second = $ds->fields($Article, null, array('title', 'body', 'published'));
+
+ $this->assertNotEquals($first, $second);
+ $this->assertEquals(2, count(DboTestSource::$methodCache['fields']));
+ }
+
+/**
+ * Test that group works without a model
+ *
+ * @return void
+ */
+ public function testGroupNoModel() {
+ $result = $this->db->group('created');
+ $this->assertEquals(' GROUP BY created', $result);
+ }
+
+/**
+ * Test getting the last error.
+ */
+ public function testLastError() {
+ $stmt = $this->getMock('PDOStatement');
+ $stmt->expects($this->any())
+ ->method('errorInfo')
+ ->will($this->returnValue(array('', 'something', 'bad')));
+
+ $result = $this->db->lastError($stmt);
+ $expected = 'something: bad';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests that transaction commands are logged
+ *
+ * @return void
+ **/
+ public function testTransactionLogging() {
+ $conn = $this->getMock('MockPDO');
+ $db = new DboTestSource;
+ $db->setConnection($conn);
+ $conn->expects($this->exactly(2))->method('beginTransaction')
+ ->will($this->returnValue(true));
+ $conn->expects($this->once())->method('commit')->will($this->returnValue(true));
+ $conn->expects($this->once())->method('rollback')->will($this->returnValue(true));
+
+ $db->begin();
+ $log = $db->getLog();
+ $expected = array('query' => 'BEGIN', 'params' => array(), 'affected' => '', 'numRows' => '', 'took' => '');
+ $this->assertEquals($expected, $log['log'][0]);
+
+ $db->commit();
+ $expected = array('query' => 'COMMIT', 'params' => array(), 'affected' => '', 'numRows' => '', 'took' => '');
+ $log = $db->getLog();
+ $this->assertEquals($expected, $log['log'][0]);
+
+ $db->begin();
+ $expected = array('query' => 'BEGIN', 'params' => array(), 'affected' => '', 'numRows' => '', 'took' => '');
+ $log = $db->getLog();
+ $this->assertEquals($expected, $log['log'][0]);
+
+ $db->rollback();
+ $expected = array('query' => 'ROLLBACK', 'params' => array(), 'affected' => '', 'numRows' => '', 'took' => '');
+ $log = $db->getLog();
+ $this->assertEquals($expected, $log['log'][0]);
+ }
+
+/**
+ * Test nested transaction calls
+ *
+ * @return void
+ */
+ public function testTransactionNested() {
+ $conn = $this->getMock('MockPDO');
+ $db = new DboTestSource();
+ $db->setConnection($conn);
+ $db->useNestedTransactions = true;
+ $db->nestedSupport = true;
+
+ $conn->expects($this->at(0))->method('beginTransaction')->will($this->returnValue(true));
+ $conn->expects($this->at(1))->method('exec')->with($this->equalTo('SAVEPOINT LEVEL1'))->will($this->returnValue(true));
+ $conn->expects($this->at(2))->method('exec')->with($this->equalTo('RELEASE SAVEPOINT LEVEL1'))->will($this->returnValue(true));
+ $conn->expects($this->at(3))->method('exec')->with($this->equalTo('SAVEPOINT LEVEL1'))->will($this->returnValue(true));
+ $conn->expects($this->at(4))->method('exec')->with($this->equalTo('ROLLBACK TO SAVEPOINT LEVEL1'))->will($this->returnValue(true));
+ $conn->expects($this->at(5))->method('commit')->will($this->returnValue(true));
+
+ $this->_runTransactions($db);
+ }
+
+/**
+ * Test nested transaction calls without support
+ *
+ * @return void
+ */
+ public function testTransactionNestedWithoutSupport() {
+ $conn = $this->getMock('MockPDO');
+ $db = new DboTestSource();
+ $db->setConnection($conn);
+ $db->useNestedTransactions = true;
+ $db->nestedSupport = false;
+
+ $conn->expects($this->once())->method('beginTransaction')->will($this->returnValue(true));
+ $conn->expects($this->never())->method('exec');
+ $conn->expects($this->once())->method('commit')->will($this->returnValue(true));
+
+ $this->_runTransactions($db);
+ }
+
+/**
+ * Test nested transaction disabled
+ *
+ * @return void
+ */
+ public function testTransactionNestedDisabled() {
+ $conn = $this->getMock('MockPDO');
+ $db = new DboTestSource();
+ $db->setConnection($conn);
+ $db->useNestedTransactions = false;
+ $db->nestedSupport = true;
+
+ $conn->expects($this->once())->method('beginTransaction')->will($this->returnValue(true));
+ $conn->expects($this->never())->method('exec');
+ $conn->expects($this->once())->method('commit')->will($this->returnValue(true));
+
+ $this->_runTransactions($db);
+ }
+
+/**
+ * Nested transaction calls
+ *
+ * @param DboTestSource $db
+ * @return void
+ */
+ protected function _runTransactions($db) {
+ $db->begin();
+ $db->begin();
+ $db->commit();
+ $db->begin();
+ $db->rollback();
+ $db->commit();
+ }
+
+/**
+ * Test build statement with some fields missing
+ *
+ * @return void
+ */
+ public function testBuildStatementDefaults() {
+ $conn = $this->getMock('MockPDO');
+ $db = new DboTestSource;
+ $db->setConnection($conn);
+ $subQuery = $db->buildStatement(
+ array(
+ 'fields' => array('DISTINCT(AssetsTag.asset_id)'),
+ 'table' => "assets_tags",
+ 'alias' => "AssetsTag",
+ 'conditions' => array("Tag.name" => 'foo bar'),
+ 'limit' => null,
+ 'group' => "AssetsTag.asset_id"
+ ),
+ $this->Model
+ );
+ }
+
+/**
+ * data provider for testBuildJoinStatement
+ *
+ * @return array
+ */
+ public static function joinStatements($schema) {
+ return array(
+ array(array(
+ 'type' => 'LEFT',
+ 'alias' => 'PostsTag',
+ 'table' => 'posts_tags',
+ 'conditions' => array('PostsTag.post_id = Post.id')
+ ), 'LEFT JOIN cakephp.posts_tags AS PostsTag ON (PostsTag.post_id = Post.id)'),
+ array(array(
+ 'type' => 'LEFT',
+ 'alias' => 'Stock',
+ 'table' => '(SELECT Stock.article_id, sum(quantite) quantite FROM stocks AS Stock GROUP BY Stock.article_id)',
+ 'conditions' => 'Stock.article_id = Article.id'
+ ), 'LEFT JOIN (SELECT Stock.article_id, sum(quantite) quantite FROM stocks AS Stock GROUP BY Stock.article_id) AS Stock ON (Stock.article_id = Article.id)')
+ );
+ }
+
+/**
+ * Test buildJoinStatement()
+ * ensure that schemaName is not added when table value is a subquery
+ *
+ * @dataProvider joinStatements
+ * @return void
+ */
+ public function testBuildJoinStatement($join, $expected) {
+ $db = $this->getMock('DboTestSource', array('getSchemaName'));
+ $db->expects($this->any())
+ ->method('getSchemaName')
+ ->will($this->returnValue('cakephp'));
+ $result = $db->buildJoinStatement($join);
+ $this->assertEquals($expected, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php
new file mode 100644
index 0000000..d696d7c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/CacheSessionTest.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * CacheSessionTest
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model.Datasource.Session
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeSession', 'Model/Datasource');
+App::uses('CacheSession', 'Model/Datasource/Session');
+class_exists('CakeSession');
+
+class CacheSessionTest extends CakeTestCase {
+
+ protected static $_sessionBackup;
+
+/**
+ * test case startup
+ *
+ * @return void
+ */
+ public static function setupBeforeClass() {
+ Cache::config('session_test', array(
+ 'engine' => 'File',
+ 'prefix' => 'session_test_'
+ ));
+ self::$_sessionBackup = Configure::read('Session');
+
+ Configure::write('Session.handler.config', 'session_test');
+ }
+
+/**
+ * cleanup after test case.
+ *
+ * @return void
+ */
+ public static function teardownAfterClass() {
+ Cache::clear(false, 'session_test');
+ Cache::drop('session_test');
+
+ Configure::write('Session', self::$_sessionBackup);
+ }
+
+/**
+ * setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->storage = new CacheSession();
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->storage);
+ }
+
+/**
+ * test open
+ *
+ * @return void
+ */
+ public function testOpen() {
+ $this->assertTrue($this->storage->open());
+ }
+
+/**
+ * test write()
+ *
+ * @return void
+ */
+ public function testWrite() {
+ $this->storage->write('abc', 'Some value');
+ $this->assertEquals('Some value', Cache::read('abc', 'session_test'), 'Value was not written.');
+ $this->assertFalse(Cache::read('abc', 'default'), 'Cache should only write to the given config.');
+ }
+
+/**
+ * test reading.
+ *
+ * @return void
+ */
+ public function testRead() {
+ $this->storage->write('test_one', 'Some other value');
+ $this->assertEquals('Some other value', $this->storage->read('test_one'), 'Incorrect value.');
+ }
+
+/**
+ * test destroy
+ *
+ * @return void
+ */
+ public function testDestroy() {
+ $this->storage->write('test_one', 'Some other value');
+ $this->assertTrue($this->storage->destroy('test_one'), 'Value was not deleted.');
+
+ $this->assertFalse(Cache::read('test_one', 'session_test'), 'Value stuck around.');
+ }
+
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php
new file mode 100644
index 0000000..3276ae8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Datasource/Session/DatabaseSessionTest.php
@@ -0,0 +1,188 @@
+<?php
+/**
+ * DatabaseSessionTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Model.Datasource.Session
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('CakeSession', 'Model/Datasource');
+App::uses('DatabaseSession', 'Model/Datasource/Session');
+class_exists('CakeSession');
+
+class SessionTestModel extends Model {
+
+ public $name = 'SessionTestModel';
+
+ public $useTable = 'sessions';
+
+}
+
+/**
+ * Database session test.
+ *
+ * @package Cake.Test.Case.Model.Datasource.Session
+ */
+class DatabaseSessionTest extends CakeTestCase {
+
+ protected static $_sessionBackup;
+
+/**
+ * fixtures
+ *
+ * @var string
+ */
+ public $fixtures = array('core.session');
+
+/**
+ * test case startup
+ *
+ * @return void
+ */
+ public static function setupBeforeClass() {
+ self::$_sessionBackup = Configure::read('Session');
+ Configure::write('Session.handler', array(
+ 'model' => 'SessionTestModel',
+ ));
+ Configure::write('Session.timeout', 100);
+ }
+
+/**
+ * cleanup after test case.
+ *
+ * @return void
+ */
+ public static function teardownAfterClass() {
+ Configure::write('Session', self::$_sessionBackup);
+ }
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->storage = new DatabaseSession();
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->storage);
+ ClassRegistry::flush();
+ parent::tearDown();
+ }
+
+/**
+ * test that constructor sets the right things up.
+ *
+ * @return void
+ */
+ public function testConstructionSettings() {
+ ClassRegistry::flush();
+ $storage = new DatabaseSession();
+
+ $session = ClassRegistry::getObject('session');
+ $this->assertInstanceOf('SessionTestModel', $session);
+ $this->assertEquals('Session', $session->alias);
+ $this->assertEquals('test', $session->useDbConfig);
+ $this->assertEquals('sessions', $session->useTable);
+ }
+
+/**
+ * test opening the session
+ *
+ * @return void
+ */
+ public function testOpen() {
+ $this->assertTrue($this->storage->open());
+ }
+
+/**
+ * test write()
+ *
+ * @return void
+ */
+ public function testWrite() {
+ $result = $this->storage->write('foo', 'Some value');
+ $expected = array(
+ 'Session' => array(
+ 'id' => 'foo',
+ 'data' => 'Some value',
+ 'expires' => time() + (Configure::read('Session.timeout') * 60)
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testReadAndWriteWithDatabaseStorage method
+ *
+ * @return void
+ */
+ public function testWriteEmptySessionId() {
+ $result = $this->storage->write('', 'This is a Test');
+ $this->assertFalse($result);
+ }
+
+/**
+ * test read()
+ *
+ * @return void
+ */
+ public function testRead() {
+ $this->storage->write('foo', 'Some value');
+
+ $result = $this->storage->read('foo');
+ $expected = 'Some value';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->storage->read('made up value');
+ $this->assertFalse($result);
+ }
+
+/**
+ * test blowing up the session.
+ *
+ * @return void
+ */
+ public function testDestroy() {
+ $this->storage->write('foo', 'Some value');
+
+ $this->assertTrue($this->storage->destroy('foo'), 'Destroy failed');
+ $this->assertFalse($this->storage->read('foo'), 'Value still present.');
+ }
+
+/**
+ * test the garbage collector
+ *
+ * @return void
+ */
+ public function testGc() {
+ ClassRegistry::flush();
+ Configure::write('Session.timeout', 0);
+
+ $storage = new DatabaseSession();
+ $storage->write('foo', 'Some value');
+
+ sleep(1);
+ $storage->gc();
+ $this->assertFalse($storage->read('foo'));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelCrossSchemaHabtmTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelCrossSchemaHabtmTest.php
new file mode 100644
index 0000000..57f1bc3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelCrossSchemaHabtmTest.php
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Tests cross database HABTM. Requires $test and $test2 to both be set in DATABASE_CONFIG
+ * NOTE: When testing on MySQL, you must set 'persistent' => false on *both* database connections,
+ * or one connection will step on the other.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
+
+class ModelCrossSchemaHabtmTest extends BaseModelTest {
+
+/**
+ * Fixtures to be used
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.player', 'core.guild', 'core.guilds_player',
+ 'core.armor', 'core.armors_player',
+ );
+
+/**
+ * Don't drop tables if they exist
+ *
+ * @var boolean
+ */
+ public $dropTables = false;
+
+/**
+ * Don't auto load fixtures
+ *
+ * @var boolean
+ */
+ public $autoFixtures = false;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->_checkConfigs();
+ }
+
+/**
+ * Check if primary and secondary test databases are configured.
+ *
+ * @return void
+ */
+ protected function _checkConfigs() {
+ $config = ConnectionManager::enumConnectionObjects();
+ $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with Sqlite.');
+ $this->skipIf(
+ !isset($config['test']) || !isset($config['test2']),
+ 'Primary and secondary test databases not configured, ' .
+ 'skipping cross-database join tests.' .
+ ' To run these tests, you must define $test and $test2 in your database configuration.'
+ );
+ }
+
+/**
+ * testModelDatasources method
+ *
+ * @return void
+ */
+ public function testModelDatasources() {
+ $this->loadFixtures('Player', 'Guild', 'GuildsPlayer');
+
+ $Player = ClassRegistry::init('Player');
+ $this->assertEquals('test', $Player->useDbConfig);
+ $this->assertEquals('test', $Player->Guild->useDbConfig);
+ $this->assertEquals('test2', $Player->GuildsPlayer->useDbConfig);
+
+ $this->assertEquals('test', $Player->getDataSource()->configKeyName);
+ $this->assertEquals('test', $Player->Guild->getDataSource()->configKeyName);
+ $this->assertEquals('test2', $Player->GuildsPlayer->getDataSource()->configKeyName);
+ }
+
+/**
+ * testHabtmFind method
+ *
+ * @return void
+ */
+ public function testHabtmFind() {
+ $this->loadFixtures('Player', 'Guild', 'GuildsPlayer');
+ $Player = ClassRegistry::init('Player');
+
+ $players = $Player->find('all', array(
+ 'fields' => array('id', 'name'),
+ 'contain' => array(
+ 'Guild' => array(
+ 'conditions' => array(
+ 'Guild.name' => 'Wizards',
+ ),
+ ),
+ ),
+ ));
+ $this->assertEquals(4, count($players));
+ $wizards = Hash::extract($players, '{n}.Guild.{n}[name=Wizards]');
+ $this->assertEquals(1, count($wizards));
+
+ $players = $Player->find('all', array(
+ 'fields' => array('id', 'name'),
+ 'conditions' => array(
+ 'Player.id' => 1,
+ ),
+ ));
+ $this->assertEquals(1, count($players));
+ $wizards = Hash::extract($players, '{n}.Guild.{n}');
+ $this->assertEquals(2, count($wizards));
+ }
+
+/**
+ * testHabtmSave method
+ *
+ * @return void
+ */
+ public function testHabtmSave() {
+ $this->loadFixtures('Player', 'Guild', 'GuildsPlayer');
+ $Player = ClassRegistry::init('Player');
+ $players = $Player->find('count');
+ $this->assertEquals(4, $players);
+
+ $player = $Player->create(array(
+ 'name' => 'rchavik',
+ ));
+
+ $results = $Player->saveAll($player, array('validate' => 'first'));
+ $this->assertNotEqual(false, $results);
+ $count = $Player->find('count');
+ $this->assertEquals(5, $count);
+
+ $count = $Player->GuildsPlayer->find('count');
+ $this->assertEquals(3, $count);
+
+ $player = $Player->findByName('rchavik');
+ $this->assertEmpty($player['Guild']);
+
+ $player['Guild']['Guild'] = array(1, 2, 3);
+ $Player->save($player);
+
+ $player = $Player->findByName('rchavik');
+ $this->assertEquals(3, count($player['Guild']));
+
+ $players = $Player->find('all', array(
+ 'contain' => array(
+ 'conditions' => array(
+ 'Guild.name' => 'Rangers',
+ ),
+ ),
+ ));
+ $rangers = Hash::extract($players, '{n}.Guild.{n}[name=Rangers]');
+ $this->assertEquals(2, count($rangers));
+ }
+
+/**
+ * testHabtmWithThreeDatabases method
+ *
+ * @return void
+ */
+ public function testHabtmWithThreeDatabases() {
+ $config = ConnectionManager::enumConnectionObjects();
+ $this->skipIf(
+ !isset($config['test']) || !isset($config['test2']) || !isset($config['test_database_three']),
+ 'Primary, secondary, and tertiary test databases not configured,' .
+ ' skipping test. To run these tests, you must define ' .
+ '$test, $test2, and $test_database_three in your database configuration.'
+ );
+
+ $this->loadFixtures('Player', 'Guild', 'GuildsPlayer', 'Armor', 'ArmorsPlayer');
+
+ $Player = ClassRegistry::init('Player');
+ $Player->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'Armor' => array(
+ 'with' => 'ArmorsPlayer',
+ 'unique' => true,
+ ),
+ ),
+ ), false);
+ $this->assertEquals('test', $Player->useDbConfig);
+ $this->assertEquals('test2', $Player->Armor->useDbConfig);
+ $this->assertEquals('test_database_three', $Player->ArmorsPlayer->useDbConfig);
+ $players = $Player->find('count');
+ $this->assertEquals(4, $players);
+
+ $spongebob = $Player->create(array(
+ 'id' => 10,
+ 'name' => 'spongebob',
+ ));
+ $spongebob['Armor'] = array('Armor' => array(1, 2, 3, 4));
+ $result = $Player->save($spongebob);
+
+ $expected = array(
+ 'Player' => array(
+ 'id' => 10,
+ 'name' => 'spongebob',
+ ),
+ 'Armor' => array(
+ 'Armor' => array(
+ 1, 2, 3, 4,
+ 1, 2, 3, 4,
+ ),
+ ),
+ );
+ unset($result['Player']['created']);
+ unset($result['Player']['updated']);
+ $this->assertEquals($expected, $result);
+
+ $spongebob = $Player->find('all', array(
+ 'conditions' => array(
+ 'Player.id' => 10,
+ )
+ ));
+ $spongeBobsArmors = Hash::extract($spongebob, '{n}.Armor.{n}');
+ $this->assertEquals(4, count($spongeBobsArmors));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelDeleteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelDeleteTest.php
new file mode 100644
index 0000000..329eef3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelDeleteTest.php
@@ -0,0 +1,865 @@
+<?php
+/**
+ * ModelDeleteTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
+
+/**
+ * ModelDeleteTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelDeleteTest extends BaseModelTest {
+
+/**
+ * testDeleteHabtmReferenceWithConditions method
+ *
+ * @return void
+ */
+ public function testDeleteHabtmReferenceWithConditions() {
+ $this->loadFixtures('Portfolio', 'Item', 'ItemsPortfolio', 'Syfile', 'Image');
+
+ $Portfolio = new Portfolio();
+ $Portfolio->hasAndBelongsToMany['Item']['conditions'] = array('ItemsPortfolio.item_id >' => 1);
+
+ $result = $Portfolio->find('first', array(
+ 'conditions' => array('Portfolio.id' => 1)
+ ));
+ $expected = array(
+ array(
+ 'id' => 3,
+ 'syfile_id' => 3,
+ 'published' => false,
+ 'name' => 'Item 3',
+ 'ItemsPortfolio' => array(
+ 'id' => 3,
+ 'item_id' => 3,
+ 'portfolio_id' => 1
+ )),
+ array(
+ 'id' => 4,
+ 'syfile_id' => 4,
+ 'published' => false,
+ 'name' => 'Item 4',
+ 'ItemsPortfolio' => array(
+ 'id' => 4,
+ 'item_id' => 4,
+ 'portfolio_id' => 1
+ )),
+ array(
+ 'id' => 5,
+ 'syfile_id' => 5,
+ 'published' => false,
+ 'name' => 'Item 5',
+ 'ItemsPortfolio' => array(
+ 'id' => 5,
+ 'item_id' => 5,
+ 'portfolio_id' => 1
+ )));
+ $this->assertEquals($expected, $result['Item']);
+
+ $result = $Portfolio->ItemsPortfolio->find('all', array(
+ 'conditions' => array('ItemsPortfolio.portfolio_id' => 1)
+ ));
+ $expected = array(
+ array(
+ 'ItemsPortfolio' => array(
+ 'id' => 1,
+ 'item_id' => 1,
+ 'portfolio_id' => 1
+ )),
+ array(
+ 'ItemsPortfolio' => array(
+ 'id' => 3,
+ 'item_id' => 3,
+ 'portfolio_id' => 1
+ )),
+ array(
+ 'ItemsPortfolio' => array(
+ 'id' => 4,
+ 'item_id' => 4,
+ 'portfolio_id' => 1
+ )),
+ array(
+ 'ItemsPortfolio' => array(
+ 'id' => 5,
+ 'item_id' => 5,
+ 'portfolio_id' => 1
+ )));
+ $this->assertEquals($expected, $result);
+
+ $Portfolio->delete(1);
+
+ $result = $Portfolio->find('first', array(
+ 'conditions' => array('Portfolio.id' => 1)
+ ));
+ $this->assertFalse($result);
+
+ $result = $Portfolio->ItemsPortfolio->find('all', array(
+ 'conditions' => array('ItemsPortfolio.portfolio_id' => 1)
+ ));
+ $this->assertEquals(array(), $result);
+ }
+
+/**
+ * testDeleteArticleBLinks method
+ *
+ * @return void
+ */
+ public function testDeleteArticleBLinks() {
+ $this->loadFixtures('Article', 'ArticlesTag', 'Tag', 'User');
+ $TestModel = new ArticleB();
+
+ $result = $TestModel->ArticlesTag->find('all');
+ $expected = array(
+ array('ArticlesTag' => array('article_id' => '1', 'tag_id' => '1')),
+ array('ArticlesTag' => array('article_id' => '1', 'tag_id' => '2')),
+ array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '1')),
+ array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '3'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->delete(1);
+ $result = $TestModel->ArticlesTag->find('all');
+
+ $expected = array(
+ array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '1')),
+ array('ArticlesTag' => array('article_id' => '2', 'tag_id' => '3'))
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testDeleteDependentWithConditions method
+ *
+ * @return void
+ */
+ public function testDeleteDependentWithConditions() {
+ $this->loadFixtures('Cd','Book','OverallFavorite');
+
+ $Cd = new Cd();
+ $Book = new Book();
+ $OverallFavorite = new OverallFavorite();
+
+ $Cd->delete(1);
+
+ $result = $OverallFavorite->find('all', array(
+ 'fields' => array('model_type', 'model_id', 'priority')
+ ));
+ $expected = array(
+ array(
+ 'OverallFavorite' => array(
+ 'model_type' => 'Book',
+ 'model_id' => 1,
+ 'priority' => 2
+ )));
+
+ $this->assertTrue(is_array($result));
+ $this->assertEquals($expected, $result);
+
+ $Book->delete(1);
+
+ $result = $OverallFavorite->find('all', array(
+ 'fields' => array('model_type', 'model_id', 'priority')
+ ));
+ $expected = array();
+
+ $this->assertTrue(is_array($result));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testDel method
+ *
+ * @return void
+ */
+ public function testDelete() {
+ $this->loadFixtures('Article', 'Comment', 'Attachment');
+ $TestModel = new Article();
+
+ $result = $TestModel->delete(2);
+ $this->assertTrue($result);
+
+ $result = $TestModel->read(null, 2);
+ $this->assertFalse($result);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'title')
+ ));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'title' => 'First Article'
+ )),
+ array('Article' => array(
+ 'id' => 3,
+ 'title' => 'Third Article'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->delete(3);
+ $this->assertTrue($result);
+
+ $result = $TestModel->read(null, 3);
+ $this->assertFalse($result);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'title')
+ ));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'title' => 'First Article'
+ )));
+
+ $this->assertEquals($expected, $result);
+
+ // make sure deleting a non-existent record doesn't break save()
+ // ticket #6293
+ $this->loadFixtures('Uuid');
+ $Uuid = new Uuid();
+ $data = array(
+ 'B607DAB9-88A2-46CF-B57C-842CA9E3B3B3',
+ '52C8865C-10EE-4302-AE6C-6E7D8E12E2C8',
+ '8208C7FE-E89C-47C5-B378-DED6C271F9B8');
+ foreach ($data as $id) {
+ $Uuid->save(array('id' => $id));
+ }
+ $Uuid->delete('52C8865C-10EE-4302-AE6C-6E7D8E12E2C8');
+ $Uuid->delete('52C8865C-10EE-4302-AE6C-6E7D8E12E2C8');
+ foreach ($data as $id) {
+ $Uuid->save(array('id' => $id));
+ }
+ $result = $Uuid->find('all', array(
+ 'conditions' => array('id' => $data),
+ 'fields' => array('id'),
+ 'order' => 'id'));
+ $expected = array(
+ array('Uuid' => array(
+ 'id' => '52C8865C-10EE-4302-AE6C-6E7D8E12E2C8')),
+ array('Uuid' => array(
+ 'id' => '8208C7FE-E89C-47C5-B378-DED6C271F9B8')),
+ array('Uuid' => array(
+ 'id' => 'B607DAB9-88A2-46CF-B57C-842CA9E3B3B3')));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that delete() updates the correct records counterCache() records.
+ *
+ * @return void
+ */
+ public function testDeleteUpdatingCounterCacheCorrectly() {
+ $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
+ $User = new CounterCacheUser();
+
+ $User->Post->delete(3);
+ $result = $User->read(null, 301);
+ $this->assertEquals(0, $result['User']['post_count']);
+
+ $result = $User->read(null, 66);
+ $this->assertEquals(2, $result['User']['post_count']);
+ }
+
+/**
+ * testDeleteAll method
+ *
+ * @return void
+ */
+ public function testDeleteAll() {
+ $this->loadFixtures('Article');
+ $TestModel = new Article();
+
+ $data = array('Article' => array(
+ 'user_id' => 2,
+ 'id' => 4,
+ 'title' => 'Fourth Article',
+ 'published' => 'N'
+ ));
+ $result = $TestModel->set($data) && $TestModel->save();
+ $this->assertTrue($result);
+
+ $data = array('Article' => array(
+ 'user_id' => 2,
+ 'id' => 5,
+ 'title' => 'Fifth Article',
+ 'published' => 'Y'
+ ));
+ $result = $TestModel->set($data) && $TestModel->save();
+ $this->assertTrue($result);
+
+ $data = array('Article' => array(
+ 'user_id' => 1,
+ 'id' => 6,
+ 'title' => 'Sixth Article',
+ 'published' => 'N'
+ ));
+ $result = $TestModel->set($data) && $TestModel->save();
+ $this->assertTrue($result);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'user_id', 'title', 'published'),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'published' => 'Y'
+ )),
+ array('Article' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'published' => 'Y'
+ )),
+ array('Article' => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'published' => 'Y')),
+ array('Article' => array(
+ 'id' => 4,
+ 'user_id' => 2,
+ 'title' => 'Fourth Article',
+ 'published' => 'N'
+ )),
+ array('Article' => array(
+ 'id' => 5,
+ 'user_id' => 2,
+ 'title' => 'Fifth Article',
+ 'published' => 'Y'
+ )),
+ array('Article' => array(
+ 'id' => 6,
+ 'user_id' => 1,
+ 'title' => 'Sixth Article',
+ 'published' => 'N'
+ )));
+
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->deleteAll(array('Article.published' => 'N'));
+ $this->assertTrue($result);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'user_id', 'title', 'published'),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'published' => 'Y'
+ )),
+ array('Article' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'published' => 'Y'
+ )),
+ array('Article' => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'published' => 'Y'
+ )),
+ array('Article' => array(
+ 'id' => 5,
+ 'user_id' => 2,
+ 'title' => 'Fifth Article',
+ 'published' => 'Y'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array('Article.user_id' => array(2, 3));
+ $result = $TestModel->deleteAll($data, true, true);
+ $this->assertTrue($result);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'user_id', 'title', 'published'),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'published' => 'Y'
+ )),
+ array('Article' => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'published' => 'Y'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->deleteAll(array('Article.user_id' => 999));
+ $this->assertTrue($result, 'deleteAll returned false when all no records matched conditions. %s');
+ }
+
+/**
+ * testDeleteAllUnknownColumn method
+ *
+ * @expectedException PDOException
+ * @return void
+ */
+ public function testDeleteAllUnknownColumn() {
+ $this->loadFixtures('Article');
+ $TestModel = new Article();
+ $result = $TestModel->deleteAll(array('Article.non_existent_field' => 999));
+ $this->assertFalse($result, 'deleteAll returned true when find query generated sql error. %s');
+ }
+
+/**
+ * testRecursiveDel method
+ *
+ * @return void
+ */
+ public function testRecursiveDel() {
+ $this->loadFixtures('Article', 'Comment', 'Attachment');
+ $TestModel = new Article();
+
+ $result = $TestModel->delete(2);
+ $this->assertTrue($result);
+
+ $TestModel->recursive = 2;
+ $result = $TestModel->read(null, 2);
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->read(null, 5);
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->read(null, 6);
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->read(null, 1);
+ $this->assertFalse($result);
+
+ $result = $TestModel->find('count');
+ $this->assertEquals(2, $result);
+
+ $result = $TestModel->Comment->find('count');
+ $this->assertEquals(4, $result);
+
+ $result = $TestModel->Comment->Attachment->find('count');
+ $this->assertEquals(0, $result);
+ }
+
+/**
+ * testDependentExclusiveDelete method
+ *
+ * @return void
+ */
+ public function testDependentExclusiveDelete() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article10();
+
+ $result = $TestModel->find('all');
+ $this->assertEquals(4, count($result[0]['Comment']));
+ $this->assertEquals(2, count($result[1]['Comment']));
+ $this->assertEquals(6, $TestModel->Comment->find('count'));
+
+ $TestModel->delete(1);
+ $this->assertEquals(2, $TestModel->Comment->find('count'));
+ }
+
+/**
+ * testDeleteLinks method
+ *
+ * @return void
+ */
+ public function testDeleteLinks() {
+ $this->loadFixtures('Article', 'ArticlesTag', 'Tag');
+ $TestModel = new Article();
+
+ $result = $TestModel->ArticlesTag->find('all');
+ $expected = array(
+ array('ArticlesTag' => array(
+ 'article_id' => '1',
+ 'tag_id' => '1'
+ )),
+ array('ArticlesTag' => array(
+ 'article_id' => '1',
+ 'tag_id' => '2'
+ )),
+ array('ArticlesTag' => array(
+ 'article_id' => '2',
+ 'tag_id' => '1'
+ )),
+ array('ArticlesTag' => array(
+ 'article_id' => '2',
+ 'tag_id' => '3'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->delete(1);
+ $result = $TestModel->ArticlesTag->find('all');
+
+ $expected = array(
+ array('ArticlesTag' => array(
+ 'article_id' => '2',
+ 'tag_id' => '1'
+ )),
+ array('ArticlesTag' => array(
+ 'article_id' => '2',
+ 'tag_id' => '3'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->deleteAll(array('Article.user_id' => 999));
+ $this->assertTrue($result, 'deleteAll returned false when all no records matched conditions. %s');
+ }
+
+/**
+ * test that a plugin model as the 'with' model doesn't have issues
+ *
+ * @return void
+ */
+ public function testDeleteLinksWithPLuginJoinModel() {
+ $this->loadFixtures('Article', 'ArticlesTag', 'Tag');
+ $Article = new Article();
+ $Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')), false);
+ unset($Article->Tag, $Article->ArticleTags);
+ $Article->bindModel(array('hasAndBelongsToMany' => array(
+ 'Tag' => array('with' => 'TestPlugin.ArticlesTag')
+ )), false);
+
+ $this->assertTrue($Article->delete(1));
+ }
+
+/**
+ * testDeleteDependent method
+ *
+ * @return void
+ */
+ public function testDeleteDependent() {
+ $this->loadFixtures('Bidding', 'BiddingMessage', 'Article',
+ 'ArticlesTag', 'Comment', 'User', 'Attachment'
+ );
+ $Bidding = new Bidding();
+ $result = $Bidding->find('all', array('order' => array('Bidding.id' => 'ASC')));
+ $expected = array(
+ array(
+ 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'),
+ 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'),
+ ),
+ array(
+ 'Bidding' => array('id' => 2, 'bid' => 'Two', 'name' => 'Bid 2'),
+ 'BiddingMessage' => array('bidding' => 'Two', 'name' => 'Message 2'),
+ ),
+ array(
+ 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'),
+ 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'),
+ ),
+ array(
+ 'Bidding' => array('id' => 4, 'bid' => 'Five', 'name' => 'Bid 5'),
+ 'BiddingMessage' => array('bidding' => '', 'name' => ''),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ $Bidding->delete(4, true);
+ $result = $Bidding->find('all', array('order' => array('Bidding.id' => 'ASC')));
+ $expected = array(
+ array(
+ 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'),
+ 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'),
+ ),
+ array(
+ 'Bidding' => array('id' => 2, 'bid' => 'Two', 'name' => 'Bid 2'),
+ 'BiddingMessage' => array('bidding' => 'Two', 'name' => 'Message 2'),
+ ),
+ array(
+ 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'),
+ 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ $Bidding->delete(2, true);
+ $result = $Bidding->find('all', array('order' => array('Bidding.id' => 'ASC')));
+ $expected = array(
+ array(
+ 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'),
+ 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'),
+ ),
+ array(
+ 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'),
+ 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $Bidding->BiddingMessage->find('all', array('order' => array('BiddingMessage.name' => 'ASC')));
+ $expected = array(
+ array(
+ 'BiddingMessage' => array('bidding' => 'One', 'name' => 'Message 1'),
+ 'Bidding' => array('id' => 1, 'bid' => 'One', 'name' => 'Bid 1'),
+ ),
+ array(
+ 'BiddingMessage' => array('bidding' => 'Three', 'name' => 'Message 3'),
+ 'Bidding' => array('id' => 3, 'bid' => 'Three', 'name' => 'Bid 3'),
+ ),
+ array(
+ 'BiddingMessage' => array('bidding' => 'Four', 'name' => 'Message 4'),
+ 'Bidding' => array('id' => '', 'bid' => '', 'name' => ''),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ $Article = new Article();
+ $result = $Article->Comment->find('count', array(
+ 'conditions' => array('Comment.article_id' => 1)
+ ));
+ $this->assertEquals(4, $result);
+
+ $result = $Article->delete(1, true);
+ $this->assertSame($result, true);
+
+ $result = $Article->Comment->find('count', array(
+ 'conditions' => array('Comment.article_id' => 1)
+ ));
+ $this->assertEquals(0, $result);
+ }
+
+/**
+ * test deleteLinks with Multiple habtm associations
+ *
+ * @return void
+ */
+ public function testDeleteLinksWithMultipleHabtmAssociations() {
+ $this->loadFixtures('JoinA', 'JoinB', 'JoinC', 'JoinAB', 'JoinAC');
+ $JoinA = new JoinA();
+
+ //create two new join records to expose the issue.
+ $JoinA->JoinAsJoinC->create(array(
+ 'join_a_id' => 1,
+ 'join_c_id' => 2,
+ ));
+ $JoinA->JoinAsJoinC->save();
+ $JoinA->JoinAsJoinB->create(array(
+ 'join_a_id' => 1,
+ 'join_b_id' => 2,
+ ));
+ $JoinA->JoinAsJoinB->save();
+
+ $result = $JoinA->delete(1);
+ $this->assertTrue($result, 'Delete failed %s');
+
+ $joinedBs = $JoinA->JoinAsJoinB->find('count', array(
+ 'conditions' => array('JoinAsJoinB.join_a_id' => 1)
+ ));
+ $this->assertEquals(0, $joinedBs, 'JoinA/JoinB link records left over. %s');
+
+ $joinedBs = $JoinA->JoinAsJoinC->find('count', array(
+ 'conditions' => array('JoinAsJoinC.join_a_id' => 1)
+ ));
+ $this->assertEquals(0, $joinedBs, 'JoinA/JoinC link records left over. %s');
+ }
+
+/**
+ * testHabtmDeleteLinksWhenNoPrimaryKeyInJoinTable method
+ *
+ * @return void
+ */
+ public function testHabtmDeleteLinksWhenNoPrimaryKeyInJoinTable() {
+ $this->loadFixtures('Apple', 'Device', 'ThePaperMonkies');
+ $ThePaper = new ThePaper();
+ $ThePaper->id = 1;
+ $ThePaper->save(array('Monkey' => array(2, 3)));
+
+ $result = $ThePaper->findById(1);
+ $expected = array(
+ array(
+ 'id' => '2',
+ 'device_type_id' => '1',
+ 'name' => 'Device 2',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '3',
+ 'device_type_id' => '1',
+ 'name' => 'Device 3',
+ 'typ' => '2'
+ ));
+ $this->assertEquals($expected, $result['Monkey']);
+
+ $ThePaper = new ThePaper();
+ $ThePaper->id = 2;
+ $ThePaper->save(array('Monkey' => array(2, 3)));
+
+ $result = $ThePaper->findById(2);
+ $expected = array(
+ array(
+ 'id' => '2',
+ 'device_type_id' => '1',
+ 'name' => 'Device 2',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '3',
+ 'device_type_id' => '1',
+ 'name' => 'Device 3',
+ 'typ' => '2'
+ ));
+ $this->assertEquals($expected, $result['Monkey']);
+
+ $ThePaper->delete(1);
+ $result = $ThePaper->findById(2);
+ $expected = array(
+ array(
+ 'id' => '2',
+ 'device_type_id' => '1',
+ 'name' => 'Device 2',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '3',
+ 'device_type_id' => '1',
+ 'name' => 'Device 3',
+ 'typ' => '2'
+ ));
+ $this->assertEquals($expected, $result['Monkey']);
+ }
+
+/**
+ * test that beforeDelete returning false can abort deletion.
+ *
+ * @return void
+ */
+ public function testBeforeDeleteDeleteAbortion() {
+ $this->loadFixtures('Post');
+ $Model = new CallbackPostTestModel();
+ $Model->beforeDeleteReturn = false;
+
+ $result = $Model->delete(1);
+ $this->assertFalse($result);
+
+ $exists = $Model->findById(1);
+ $this->assertTrue(is_array($exists));
+ }
+
+/**
+ * test for a habtm deletion error that occurs in postgres but should not.
+ * And should not occur in any dbo.
+ *
+ * @return void
+ */
+ public function testDeleteHabtmPostgresFailure() {
+ $this->loadFixtures('Article', 'Tag', 'ArticlesTag');
+
+ $Article = ClassRegistry::init('Article');
+ $Article->hasAndBelongsToMany['Tag']['unique'] = true;
+
+ $Tag = ClassRegistry::init('Tag');
+ $Tag->bindModel(array('hasAndBelongsToMany' => array(
+ 'Article' => array(
+ 'className' => 'Article',
+ 'unique' => true
+ )
+ )), true);
+
+ // Article 1 should have Tag.1 and Tag.2
+ $before = $Article->find("all", array(
+ "conditions" => array("Article.id" => 1),
+ ));
+ $this->assertEquals(2, count($before[0]['Tag']), 'Tag count for Article.id = 1 is incorrect, should be 2 %s');
+
+ // From now on, Tag #1 is only associated with Post #1
+ $submittedData = array(
+ "Tag" => array("id" => 1, 'tag' => 'tag1'),
+ "Article" => array(
+ "Article" => array(1)
+ )
+ );
+ $Tag->save($submittedData);
+
+ // One more submission (The other way around) to make sure the reverse save looks good.
+ $submittedData = array(
+ "Article" => array("id" => 2, 'title' => 'second article'),
+ "Tag" => array(
+ "Tag" => array(2, 3)
+ )
+ );
+
+ // ERROR:
+ // Postgresql: DELETE FROM "articles_tags" WHERE tag_id IN ('1', '3')
+ // MySQL: DELETE `ArticlesTag` FROM `articles_tags` AS `ArticlesTag` WHERE `ArticlesTag`.`article_id` = 2 AND `ArticlesTag`.`tag_id` IN (1, 3)
+ $Article->save($submittedData);
+
+ // Want to make sure Article #1 has Tag #1 and Tag #2 still.
+ $after = $Article->find("all", array(
+ "conditions" => array("Article.id" => 1),
+ ));
+
+ // Removing Article #2 from Tag #1 is all that should have happened.
+ $this->assertEquals(count($before[0]["Tag"]), count($after[0]["Tag"]));
+ }
+
+/**
+ * test that deleting records inside the beforeDelete doesn't truncate the table.
+ *
+ * @return void
+ */
+ public function testBeforeDeleteWipingTable() {
+ $this->loadFixtures('Comment');
+
+ $Comment = new BeforeDeleteComment();
+ // Delete 3 records.
+ $Comment->delete(4);
+ $result = $Comment->find('count');
+
+ $this->assertTrue($result > 1, 'Comments are all gone.');
+ $Comment->create(array(
+ 'article_id' => 1,
+ 'user_id' => 2,
+ 'comment' => 'new record',
+ 'published' => 'Y'
+ ));
+ $Comment->save();
+
+ $Comment->delete(5);
+ $result = $Comment->find('count');
+
+ $this->assertTrue($result > 1, 'Comments are all gone.');
+ }
+
+/**
+ * test that deleting the same record from the beforeDelete and the delete doesn't truncate the table.
+ *
+ * @return void
+ */
+ public function testBeforeDeleteWipingTableWithDuplicateDelete() {
+ $this->loadFixtures('Comment');
+
+ $Comment = new BeforeDeleteComment();
+ $Comment->delete(1);
+
+ $result = $Comment->find('count');
+ $this->assertTrue($result > 1, 'Comments are all gone.');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelIntegrationTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelIntegrationTest.php
new file mode 100644
index 0000000..a7063c0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelIntegrationTest.php
@@ -0,0 +1,2426 @@
+<?php
+/**
+ * ModelIntegrationTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
+App::uses('DboSource', 'Model/Datasource');
+
+/**
+ * DboMock class
+ * A Dbo Source driver to mock a connection and a identity name() method
+ */
+class DboMock extends DboSource {
+
+/**
+ * Returns the $field without modifications
+ */
+ public function name($field) {
+ return $field;
+ }
+
+/**
+ * Returns true to fake a database connection
+ */
+ public function connect() {
+ return true;
+ }
+
+}
+
+/**
+ * ModelIntegrationTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelIntegrationTest extends BaseModelTest {
+
+/**
+ * testAssociationLazyLoading
+ *
+ * @group lazyloading
+ * @return void
+ */
+ public function testAssociationLazyLoading() {
+ $this->loadFixtures('ArticleFeaturedsTags');
+ $Article = new ArticleFeatured();
+ $this->assertTrue(isset($Article->belongsTo['User']));
+ $this->assertFalse(property_exists($Article, 'User'));
+ $this->assertInstanceOf('User', $Article->User);
+
+ $this->assertTrue(isset($Article->belongsTo['Category']));
+ $this->assertFalse(property_exists($Article, 'Category'));
+ $this->assertTrue(isset($Article->Category));
+ $this->assertInstanceOf('Category', $Article->Category);
+
+ $this->assertTrue(isset($Article->hasMany['Comment']));
+ $this->assertFalse(property_exists($Article, 'Comment'));
+ $this->assertTrue(isset($Article->Comment));
+ $this->assertInstanceOf('Comment', $Article->Comment);
+
+ $this->assertTrue(isset($Article->hasAndBelongsToMany['Tag']));
+ //There was not enough information to setup the association (joinTable and associationForeignKey)
+ //so the model was not lazy loaded
+ $this->assertTrue(property_exists($Article, 'Tag'));
+ $this->assertTrue(isset($Article->Tag));
+ $this->assertInstanceOf('Tag', $Article->Tag);
+
+ $this->assertFalse(property_exists($Article, 'ArticleFeaturedsTag'));
+ $this->assertInstanceOf('AppModel', $Article->ArticleFeaturedsTag);
+ $this->assertEquals('article_featureds_tags', $Article->hasAndBelongsToMany['Tag']['joinTable']);
+ $this->assertEquals('tag_id', $Article->hasAndBelongsToMany['Tag']['associationForeignKey']);
+ }
+
+/**
+ * testAssociationLazyLoadWithHABTM
+ *
+ * @group lazyloading
+ * @return void
+ */
+ public function testAssociationLazyLoadWithHABTM() {
+ $this->loadFixtures('FruitsUuidTag', 'ArticlesTag');
+ $this->db->cacheSources = false;
+ $Article = new ArticleB();
+ $this->assertTrue(isset($Article->hasAndBelongsToMany['TagB']));
+ $this->assertFalse(property_exists($Article, 'TagB'));
+ $this->assertInstanceOf('TagB', $Article->TagB);
+
+ $this->assertFalse(property_exists($Article, 'ArticlesTag'));
+ $this->assertInstanceOf('AppModel', $Article->ArticlesTag);
+
+ $UuidTag = new UuidTag();
+ $this->assertTrue(isset($UuidTag->hasAndBelongsToMany['Fruit']));
+ $this->assertFalse(property_exists($UuidTag, 'Fruit'));
+ $this->assertFalse(property_exists($UuidTag, 'FruitsUuidTag'));
+ $this->assertTrue(isset($UuidTag->Fruit));
+
+ $this->assertFalse(property_exists($UuidTag, 'FruitsUuidTag'));
+ $this->assertTrue(isset($UuidTag->FruitsUuidTag));
+ $this->assertInstanceOf('FruitsUuidTag', $UuidTag->FruitsUuidTag);
+ }
+
+/**
+ * testAssociationLazyLoadWithBindModel
+ *
+ * @group lazyloading
+ * @return void
+ */
+ public function testAssociationLazyLoadWithBindModel() {
+ $this->loadFixtures('Article', 'User');
+ $Article = new ArticleB();
+
+ $this->assertFalse(isset($Article->belongsTo['User']));
+ $this->assertFalse(property_exists($Article, 'User'));
+
+ $Article->bindModel(array('belongsTo' => array('User')));
+ $this->assertTrue(isset($Article->belongsTo['User']));
+ $this->assertFalse(property_exists($Article, 'User'));
+ $this->assertInstanceOf('User', $Article->User);
+ }
+
+/**
+ * Tests that creating a model with no existent database table associated will throw an exception
+ *
+ * @expectedException MissingTableException
+ * @return void
+ */
+ public function testMissingTable() {
+ $Article = new ArticleB(false, uniqid());
+ $Article->schema();
+ }
+
+/**
+ * testPkInHAbtmLinkModelArticleB
+ *
+ * @return void
+ */
+ public function testPkInHabtmLinkModelArticleB() {
+ $this->loadFixtures('Article', 'Tag', 'ArticlesTag');
+ $TestModel = new ArticleB();
+ $this->assertEquals('article_id', $TestModel->ArticlesTag->primaryKey);
+ }
+
+/**
+ * Tests that $cacheSources can only be disabled in the db using model settings, not enabled
+ *
+ * @return void
+ */
+ public function testCacheSourcesDisabling() {
+ $this->loadFixtures('JoinA', 'JoinB', 'JoinAB', 'JoinC', 'JoinAC');
+ $this->db->cacheSources = true;
+ $TestModel = new JoinA();
+ $TestModel->cacheSources = false;
+ $TestModel->setSource('join_as');
+ $this->assertFalse($this->db->cacheSources);
+
+ $this->db->cacheSources = false;
+ $TestModel = new JoinA();
+ $TestModel->cacheSources = true;
+ $TestModel->setSource('join_as');
+ $this->assertFalse($this->db->cacheSources);
+ }
+
+/**
+ * testPkInHabtmLinkModel method
+ *
+ * @return void
+ */
+ public function testPkInHabtmLinkModel() {
+ //Test Nonconformant Models
+ $this->loadFixtures('Content', 'ContentAccount', 'Account', 'JoinC', 'JoinAC', 'ItemsPortfolio');
+ $TestModel = new Content();
+ $this->assertEquals('iContentAccountsId', $TestModel->ContentAccount->primaryKey);
+
+ //test conformant models with no PK in the join table
+ $this->loadFixtures('Article', 'Tag');
+ $TestModel = new Article();
+ $this->assertEquals('article_id', $TestModel->ArticlesTag->primaryKey);
+
+ //test conformant models with PK in join table
+ $TestModel = new Portfolio();
+ $this->assertEquals('id', $TestModel->ItemsPortfolio->primaryKey);
+
+ //test conformant models with PK in join table - join table contains extra field
+ $this->loadFixtures('JoinA', 'JoinB', 'JoinAB');
+ $TestModel = new JoinA();
+ $this->assertEquals('id', $TestModel->JoinAsJoinB->primaryKey);
+ }
+
+/**
+ * testDynamicBehaviorAttachment method
+ *
+ * @return void
+ */
+ public function testDynamicBehaviorAttachment() {
+ $this->loadFixtures('Apple', 'Sample', 'Author');
+ $TestModel = new Apple();
+ $this->assertEquals(array(), $TestModel->Behaviors->attached());
+
+ $TestModel->Behaviors->attach('Tree', array('left' => 'left_field', 'right' => 'right_field'));
+ $this->assertTrue(is_object($TestModel->Behaviors->Tree));
+ $this->assertEquals(array('Tree'), $TestModel->Behaviors->attached());
+
+ $expected = array(
+ 'parent' => 'parent_id',
+ 'left' => 'left_field',
+ 'right' => 'right_field',
+ 'scope' => '1 = 1',
+ 'type' => 'nested',
+ '__parentChange' => false,
+ 'recursive' => -1
+ );
+ $this->assertEquals($expected, $TestModel->Behaviors->Tree->settings['Apple']);
+
+ $TestModel->Behaviors->attach('Tree', array('enabled' => false));
+ $this->assertEquals($expected, $TestModel->Behaviors->Tree->settings['Apple']);
+ $this->assertEquals(array('Tree'), $TestModel->Behaviors->attached());
+
+ $TestModel->Behaviors->detach('Tree');
+ $this->assertEquals(array(), $TestModel->Behaviors->attached());
+ $this->assertFalse(isset($TestModel->Behaviors->Tree));
+ }
+
+/**
+ * testFindWithJoinsOption method
+ *
+ * @access public
+ * @return void
+ */
+ public function testFindWithJoinsOption() {
+ $this->loadFixtures('Article', 'User');
+ $TestUser = new User();
+
+ $options = array(
+ 'fields' => array(
+ 'user',
+ 'Article.published',
+ ),
+ 'joins' => array(
+ array(
+ 'table' => 'articles',
+ 'alias' => 'Article',
+ 'type' => 'LEFT',
+ 'conditions' => array(
+ 'User.id = Article.user_id',
+ ),
+ ),
+ ),
+ 'group' => array('User.user', 'Article.published'),
+ 'recursive' => -1,
+ 'order' => array('User.user')
+ );
+ $result = $TestUser->find('all', $options);
+ $expected = array(
+ array('User' => array('user' => 'garrett'), 'Article' => array('published' => '')),
+ array('User' => array('user' => 'larry'), 'Article' => array('published' => 'Y')),
+ array('User' => array('user' => 'mariano'), 'Article' => array('published' => 'Y')),
+ array('User' => array('user' => 'nate'), 'Article' => array('published' => ''))
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests cross database joins. Requires $test and $test2 to both be set in DATABASE_CONFIG
+ * NOTE: When testing on MySQL, you must set 'persistent' => false on *both* database connections,
+ * or one connection will step on the other.
+ */
+ public function testCrossDatabaseJoins() {
+ $config = ConnectionManager::enumConnectionObjects();
+
+ $skip = (!isset($config['test']) || !isset($config['test2']));
+ if ($skip) {
+ $this->markTestSkipped('Primary and secondary test databases not configured, skipping cross-database
+ join tests. To run theses tests defined $test and $test2 in your database configuration.'
+ );
+ }
+
+ $this->loadFixtures('Article', 'Tag', 'ArticlesTag', 'User', 'Comment');
+ $TestModel = new Article();
+
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ),
+ array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => '4',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ )),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ))),
+ array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ )),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ ))),
+ array(
+ 'Article' => array(
+ 'id' => '3',
+ 'user_id' => '1',
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ ));
+ $this->assertEquals($expected, $TestModel->find('all'));
+
+ $db2 = ConnectionManager::getDataSource('test2');
+ $this->fixtureManager->loadSingle('User', $db2);
+ $this->fixtureManager->loadSingle('Comment', $db2);
+ $this->assertEquals(3, $TestModel->find('count'));
+
+ $TestModel->User->setDataSource('test2');
+ $TestModel->Comment->setDataSource('test2');
+
+ foreach ($expected as $key => $value) {
+ unset($value['Comment'], $value['Tag']);
+ $expected[$key] = $value;
+ }
+
+ $TestModel->recursive = 0;
+ $result = $TestModel->find('all');
+ $this->assertEquals($expected, $result);
+
+ foreach ($expected as $key => $value) {
+ unset($value['Comment'], $value['Tag']);
+ $expected[$key] = $value;
+ }
+
+ $TestModel->recursive = 0;
+ $result = $TestModel->find('all');
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($TestModel->User->find('all'), '{n}.User.id');
+ $this->assertEquals(array('1', '2', '3', '4'), $result);
+ $this->assertEquals($expected, $TestModel->find('all'));
+
+ $TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')));
+ $expected = array(
+ array(
+ 'Comment' => array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array(
+ 'Comment' => array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ),
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23',
+ 'updated' => '2007-03-17 01:24:31'
+ ),
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array(
+ 'Comment' => array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array(
+ 'Comment' => array(
+ 'id' => '4',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array(
+ 'Comment' => array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )),
+ array(
+ 'Comment' => array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ),
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )));
+ $this->assertEquals($expected, $TestModel->Comment->find('all'));
+ }
+
+/**
+ * test HABM operations without clobbering existing records #275
+ *
+ * @return void
+ */
+ public function testHABTMKeepExisting() {
+ $this->loadFixtures('Site', 'Domain', 'DomainsSite');
+
+ $Site = new Site();
+ $results = $Site->find('count');
+ $expected = 3;
+ $this->assertEquals($expected, $results);
+
+ $data = $Site->findById(1);
+
+ // include api.cakephp.org
+ $data['Domain'] = array('Domain' => array(1, 2, 3));
+ $Site->save($data);
+
+ $Site->id = 1;
+ $results = $Site->read();
+ $expected = 3; // 3 domains belonging to cakephp
+ $this->assertEquals($expected, count($results['Domain']));
+
+ $Site->id = 2;
+ $results = $Site->read();
+ $expected = 2; // 2 domains belonging to markstory
+ $this->assertEquals($expected, count($results['Domain']));
+
+ $Site->id = 3;
+ $results = $Site->read();
+ $expected = 2;
+ $this->assertEquals($expected, count($results['Domain']));
+ $results['Domain'] = array('Domain' => array(7));
+ $Site->save($results); // remove association from domain 6
+ $results = $Site->read();
+ $expected = 1; // only 1 domain left belonging to rchavik
+ $this->assertEquals($expected, count($results['Domain']));
+
+ // add deleted domain back
+ $results['Domain'] = array('Domain' => array(6, 7));
+ $Site->save($results);
+ $results = $Site->read();
+ $expected = 2; // 2 domains belonging to rchavik
+ $this->assertEquals($expected, count($results['Domain']));
+
+ $Site->DomainsSite->id = $results['Domain'][0]['DomainsSite']['id'];
+ $Site->DomainsSite->saveField('active', true);
+
+ $results = $Site->Domain->DomainsSite->find('count', array(
+ 'conditions' => array(
+ 'DomainsSite.active' => true,
+ ),
+ ));
+ $expected = 5;
+ $this->assertEquals($expected, $results);
+
+ // activate api.cakephp.org
+ $activated = $Site->DomainsSite->findByDomainId(3);
+ $activated['DomainsSite']['active'] = true;
+ $Site->DomainsSite->save($activated);
+
+ $results = $Site->DomainsSite->find('count', array(
+ 'conditions' => array(
+ 'DomainsSite.active' => true,
+ ),
+ ));
+ $expected = 6;
+ $this->assertEquals($expected, $results);
+
+ // remove 2 previously active domains, and leave $activated alone
+ $data = array(
+ 'Site' => array('id' => 1, 'name' => 'cakephp (modified)'),
+ 'Domain' => array(
+ 'Domain' => array(3),
+ )
+ );
+ $Site->create($data);
+ $Site->save($data);
+
+ // tests that record is still identical prior to removal
+ $Site->id = 1;
+ $results = $Site->read();
+ unset($results['Domain'][0]['DomainsSite']['updated']);
+ unset($activated['DomainsSite']['updated']);
+ $this->assertEquals($activated['DomainsSite'], $results['Domain'][0]['DomainsSite']);
+ }
+
+/**
+ * testHABTMKeepExistingAlternateDataFormat
+ *
+ * @return void
+ */
+ public function testHABTMKeepExistingAlternateDataFormat() {
+ $this->loadFixtures('Site', 'Domain', 'DomainsSite');
+
+ $Site = new Site();
+
+ $expected = array(
+ array(
+ 'DomainsSite' => array(
+ 'id' => 1,
+ 'site_id' => 1,
+ 'domain_id' => 1,
+ 'active' => true,
+ 'created' => '2007-03-17 01:16:23'
+ )
+ ),
+ array(
+ 'DomainsSite' => array(
+ 'id' => 2,
+ 'site_id' => 1,
+ 'domain_id' => 2,
+ 'active' => true,
+ 'created' => '2007-03-17 01:16:23'
+ )
+ )
+ );
+ $result = $Site->DomainsSite->find('all', array(
+ 'conditions' => array('DomainsSite.site_id' => 1),
+ 'fields' => array(
+ 'DomainsSite.id',
+ 'DomainsSite.site_id',
+ 'DomainsSite.domain_id',
+ 'DomainsSite.active',
+ 'DomainsSite.created'
+ ),
+ 'order' => 'DomainsSite.id'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $time = date('Y-m-d H:i:s');
+ $data = array(
+ 'Site' => array(
+ 'id' => 1
+ ),
+ 'Domain' => array(
+ array(
+ 'site_id' => 1,
+ 'domain_id' => 3,
+ 'created' => $time,
+ ),
+ array(
+ 'id' => 2,
+ 'site_id' => 1,
+ 'domain_id' => 2
+ ),
+ )
+ );
+ $Site->save($data);
+ $expected = array(
+ array(
+ 'DomainsSite' => array(
+ 'id' => 2,
+ 'site_id' => 1,
+ 'domain_id' => 2,
+ 'active' => true,
+ 'created' => '2007-03-17 01:16:23'
+ )
+ ),
+ array(
+ 'DomainsSite' => array(
+ 'id' => 7,
+ 'site_id' => 1,
+ 'domain_id' => 3,
+ 'active' => false,
+ 'created' => $time
+ )
+ )
+ );
+ $result = $Site->DomainsSite->find('all', array(
+ 'conditions' => array('DomainsSite.site_id' => 1),
+ 'fields' => array(
+ 'DomainsSite.id',
+ 'DomainsSite.site_id',
+ 'DomainsSite.domain_id',
+ 'DomainsSite.active',
+ 'DomainsSite.created'
+ ),
+ 'order' => 'DomainsSite.id'
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test HABM operations without clobbering existing records #275
+ *
+ * @return void
+ */
+ public function testHABTMKeepExistingWithThreeDbs() {
+ $config = ConnectionManager::enumConnectionObjects();
+ $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with Sqlite.');
+ $this->skipIf(
+ !isset($config['test']) || !isset($config['test2']) || !isset($config['test_database_three']),
+ 'Primary, secondary, and tertiary test databases not configured, skipping test. To run this test define $test, $test2, and $test_database_three in your database configuration.'
+ );
+
+ $this->loadFixtures('Player', 'Guild', 'GuildsPlayer', 'Armor', 'ArmorsPlayer');
+ $Player = ClassRegistry::init('Player');
+ $Player->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'Armor' => array(
+ 'with' => 'ArmorsPlayer',
+ 'unique' => 'keepExisting',
+ ),
+ ),
+ ), false);
+ $this->assertEquals('test', $Player->useDbConfig);
+ $this->assertEquals('test', $Player->Guild->useDbConfig);
+ $this->assertEquals('test2', $Player->Guild->GuildsPlayer->useDbConfig);
+ $this->assertEquals('test2', $Player->Armor->useDbConfig);
+ $this->assertEquals('test_database_three', $Player->ArmorsPlayer->useDbConfig);
+
+ $players = $Player->find('all');
+ $this->assertEquals(4 , count($players));
+ $playersGuilds = Hash::extract($players, '{n}.Guild.{n}.GuildsPlayer');
+ $this->assertEquals(3 , count($playersGuilds));
+ $playersArmors = Hash::extract($players, '{n}.Armor.{n}.ArmorsPlayer');
+ $this->assertEquals(3 , count($playersArmors));
+ unset($players);
+
+ $larry = $Player->findByName('larry');
+ $larrysArmor = Hash::extract($larry, 'Armor.{n}.ArmorsPlayer');
+ $this->assertEquals(1 , count($larrysArmor));
+
+ $larry['Guild']['Guild'] = array(1, 3); // larry joins another guild
+ $larry['Armor']['Armor'] = array(2, 3); // purchases chainmail
+ $Player->save($larry);
+ unset($larry);
+
+ $larry = $Player->findByName('larry');
+ $larrysGuild = Hash::extract($larry, 'Guild.{n}.GuildsPlayer');
+ $this->assertEquals(2 , count($larrysGuild));
+ $larrysArmor = Hash::extract($larry, 'Armor.{n}.ArmorsPlayer');
+ $this->assertEquals(2 , count($larrysArmor));
+
+ $larrysArmorsPlayersIds = Hash::extract($larry, 'Armor.{n}.ArmorsPlayer.id');
+
+ $Player->ArmorsPlayer->id = 3;
+ $Player->ArmorsPlayer->saveField('broken', true); // larry's cloak broke
+
+ $larry = $Player->findByName('larry');
+ $larrysCloak = Hash::extract($larry, 'Armor.{n}.ArmorsPlayer[armor_id=3]', $larry);
+ $this->assertNotEmpty($larrysCloak);
+ $this->assertTrue($larrysCloak[0]['broken']); // still broken
+ }
+
+/**
+ * testDisplayField method
+ *
+ * @return void
+ */
+ public function testDisplayField() {
+ $this->loadFixtures('Post', 'Comment', 'Person', 'User');
+ $Post = new Post();
+ $Comment = new Comment();
+ $Person = new Person();
+
+ $this->assertEquals('title', $Post->displayField);
+ $this->assertEquals('name', $Person->displayField);
+ $this->assertEquals('id', $Comment->displayField);
+ }
+
+/**
+ * testSchema method
+ *
+ * @return void
+ */
+ public function testSchema() {
+ $Post = new Post();
+
+ $result = $Post->schema();
+ $columns = array('id', 'author_id', 'title', 'body', 'published', 'created', 'updated');
+ $this->assertEquals($columns, array_keys($result));
+
+ $types = array('integer', 'integer', 'string', 'text', 'string', 'datetime', 'datetime');
+ $this->assertEquals(Hash::extract(array_values($result), '{n}.type'), $types);
+
+ $result = $Post->schema('body');
+ $this->assertEquals('text', $result['type']);
+ $this->assertNull($Post->schema('foo'));
+
+ $this->assertEquals($Post->getColumnTypes(), array_combine($columns, $types));
+ }
+
+/**
+ * data provider for time tests.
+ *
+ * @return array
+ */
+ public static function timeProvider() {
+ $db = ConnectionManager::getDataSource('test');
+ $now = $db->expression('NOW()');
+ return array(
+ // blank
+ array(
+ array('hour' => '', 'min' => '', 'meridian' => ''),
+ ''
+ ),
+ // missing hour
+ array(
+ array('hour' => '', 'min' => '00', 'meridian' => 'pm'),
+ ''
+ ),
+ // all blank
+ array(
+ array('hour' => '', 'min' => '', 'sec' => ''),
+ ''
+ ),
+ // set and empty merdian
+ array(
+ array('hour' => '1', 'min' => '00', 'meridian' => ''),
+ ''
+ ),
+ // midnight
+ array(
+ array('hour' => '12', 'min' => '0', 'meridian' => 'am'),
+ '00:00:00'
+ ),
+ array(
+ array('hour' => '00', 'min' => '00'),
+ '00:00:00'
+ ),
+ // 3am
+ array(
+ array('hour' => '03', 'min' => '04', 'sec' => '04'),
+ '03:04:04'
+ ),
+ array(
+ array('hour' => '3', 'min' => '4', 'sec' => '4'),
+ '03:04:04'
+ ),
+ array(
+ array('hour' => '03', 'min' => '4', 'sec' => '4'),
+ '03:04:04'
+ ),
+ array(
+ $now,
+ $now
+ )
+ );
+ }
+
+/**
+ * test deconstruct with time fields.
+ *
+ * @dataProvider timeProvider
+ * @return void
+ */
+ public function testDeconstructFieldsTime($input, $result) {
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $this->loadFixtures('Apple');
+ $TestModel = new Apple();
+
+ $data = array(
+ 'Apple' => array(
+ 'mytime' => $input
+ )
+ );
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('mytime' => $result));
+ $this->assertEquals($expected, $TestModel->data);
+ }
+
+/**
+ * testDeconstructFields with datetime, timestamp, and date fields
+ *
+ * @return void
+ */
+ public function testDeconstructFieldsDateTime() {
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $this->loadFixtures('Apple');
+ $TestModel = new Apple();
+
+ //test null/empty values first
+ $data['Apple']['created']['year'] = '';
+ $data['Apple']['created']['month'] = '';
+ $data['Apple']['created']['day'] = '';
+ $data['Apple']['created']['hour'] = '';
+ $data['Apple']['created']['min'] = '';
+ $data['Apple']['created']['sec'] = '';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => ''));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['date']['year'] = '';
+ $data['Apple']['date']['month'] = '';
+ $data['Apple']['date']['day'] = '';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('date' => ''));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['year'] = '2007';
+ $data['Apple']['created']['month'] = '08';
+ $data['Apple']['created']['day'] = '20';
+ $data['Apple']['created']['hour'] = '';
+ $data['Apple']['created']['min'] = '';
+ $data['Apple']['created']['sec'] = '';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => '2007-08-20 00:00:00'));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['year'] = '2007';
+ $data['Apple']['created']['month'] = '08';
+ $data['Apple']['created']['day'] = '20';
+ $data['Apple']['created']['hour'] = '10';
+ $data['Apple']['created']['min'] = '12';
+ $data['Apple']['created']['sec'] = '';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => '2007-08-20 10:12:00'));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['year'] = '2007';
+ $data['Apple']['created']['month'] = '';
+ $data['Apple']['created']['day'] = '12';
+ $data['Apple']['created']['hour'] = '20';
+ $data['Apple']['created']['min'] = '';
+ $data['Apple']['created']['sec'] = '';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => ''));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['hour'] = '20';
+ $data['Apple']['created']['min'] = '33';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => ''));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['hour'] = '20';
+ $data['Apple']['created']['min'] = '33';
+ $data['Apple']['created']['sec'] = '33';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => ''));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['hour'] = '13';
+ $data['Apple']['created']['min'] = '00';
+ $data['Apple']['date']['year'] = '2006';
+ $data['Apple']['date']['month'] = '12';
+ $data['Apple']['date']['day'] = '25';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array(
+ 'Apple' => array(
+ 'created' => '',
+ 'date' => '2006-12-25'
+ ));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['year'] = '2007';
+ $data['Apple']['created']['month'] = '08';
+ $data['Apple']['created']['day'] = '20';
+ $data['Apple']['created']['hour'] = '10';
+ $data['Apple']['created']['min'] = '12';
+ $data['Apple']['created']['sec'] = '09';
+ $data['Apple']['date']['year'] = '2006';
+ $data['Apple']['date']['month'] = '12';
+ $data['Apple']['date']['day'] = '25';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array(
+ 'Apple' => array(
+ 'created' => '2007-08-20 10:12:09',
+ 'date' => '2006-12-25'
+ ));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['year'] = '--';
+ $data['Apple']['created']['month'] = '--';
+ $data['Apple']['created']['day'] = '--';
+ $data['Apple']['created']['hour'] = '--';
+ $data['Apple']['created']['min'] = '--';
+ $data['Apple']['created']['sec'] = '--';
+ $data['Apple']['date']['year'] = '--';
+ $data['Apple']['date']['month'] = '--';
+ $data['Apple']['date']['day'] = '--';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => '', 'date' => ''));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['created']['year'] = '2007';
+ $data['Apple']['created']['month'] = '--';
+ $data['Apple']['created']['day'] = '20';
+ $data['Apple']['created']['hour'] = '10';
+ $data['Apple']['created']['min'] = '12';
+ $data['Apple']['created']['sec'] = '09';
+ $data['Apple']['date']['year'] = '2006';
+ $data['Apple']['date']['month'] = '12';
+ $data['Apple']['date']['day'] = '25';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('created' => '', 'date' => '2006-12-25'));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $data = array();
+ $data['Apple']['date']['year'] = '2006';
+ $data['Apple']['date']['month'] = '12';
+ $data['Apple']['date']['day'] = '25';
+
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $expected = array('Apple' => array('date' => '2006-12-25'));
+ $this->assertEquals($expected, $TestModel->data);
+
+ $db = ConnectionManager::getDataSource('test');
+ $data = array();
+ $data['Apple']['modified'] = $db->expression('NOW()');
+ $TestModel->data = null;
+ $TestModel->set($data);
+ $this->assertEquals($TestModel->data, $data);
+ }
+
+/**
+ * testTablePrefixSwitching method
+ *
+ * @return void
+ */
+ public function testTablePrefixSwitching() {
+ ConnectionManager::create('database1',
+ array_merge($this->db->config, array('prefix' => 'aaa_')
+ ));
+ ConnectionManager::create('database2',
+ array_merge($this->db->config, array('prefix' => 'bbb_')
+ ));
+
+ $db1 = ConnectionManager::getDataSource('database1');
+ $db2 = ConnectionManager::getDataSource('database2');
+
+ $TestModel = new Apple();
+ $TestModel->setDataSource('database1');
+ $this->assertContains('aaa_apples', $this->db->fullTableName($TestModel));
+ $this->assertContains('aaa_apples', $db1->fullTableName($TestModel));
+ $this->assertContains('aaa_apples', $db2->fullTableName($TestModel));
+
+ $TestModel->setDataSource('database2');
+ $this->assertContains('bbb_apples', $this->db->fullTableName($TestModel));
+ $this->assertContains('bbb_apples', $db1->fullTableName($TestModel));
+ $this->assertContains('bbb_apples', $db2->fullTableName($TestModel));
+
+ $TestModel = new Apple();
+ $TestModel->tablePrefix = 'custom_';
+ $this->assertContains('custom_apples', $this->db->fullTableName($TestModel));
+ $TestModel->setDataSource('database1');
+ $this->assertContains('custom_apples', $this->db->fullTableName($TestModel));
+ $this->assertContains('custom_apples', $db1->fullTableName($TestModel));
+
+ $TestModel = new Apple();
+ $TestModel->setDataSource('database1');
+ $this->assertContains('aaa_apples', $this->db->fullTableName($TestModel));
+ $TestModel->tablePrefix = '';
+ $TestModel->setDataSource('database2');
+ $this->assertContains('apples', $db2->fullTableName($TestModel));
+ $this->assertContains('apples', $db1->fullTableName($TestModel));
+
+ $TestModel->tablePrefix = null;
+ $TestModel->setDataSource('database1');
+ $this->assertContains('aaa_apples', $db2->fullTableName($TestModel));
+ $this->assertContains('aaa_apples', $db1->fullTableName($TestModel));
+
+ $TestModel->tablePrefix = false;
+ $TestModel->setDataSource('database2');
+ $this->assertContains('apples', $db2->fullTableName($TestModel));
+ $this->assertContains('apples', $db1->fullTableName($TestModel));
+ }
+
+/**
+ * Tests validation parameter order in custom validation methods
+ *
+ * @return void
+ */
+ public function testInvalidAssociation() {
+ $TestModel = new ValidationTest1();
+ $this->assertNull($TestModel->getAssociated('Foo'));
+ }
+
+/**
+ * testLoadModelSecondIteration method
+ *
+ * @return void
+ */
+ public function testLoadModelSecondIteration() {
+ $this->loadFixtures('Apple', 'Message', 'Thread', 'Bid');
+ $model = new ModelA();
+ $this->assertInstanceOf('ModelA', $model);
+
+ $this->assertInstanceOf('ModelB', $model->ModelB);
+ $this->assertInstanceOf('ModelD', $model->ModelB->ModelD);
+
+ $this->assertInstanceOf('ModelC', $model->ModelC);
+ $this->assertInstanceOf('ModelD', $model->ModelC->ModelD);
+ }
+
+/**
+ * ensure that exists() does not persist between method calls reset on create
+ *
+ * @return void
+ */
+ public function testResetOfExistsOnCreate() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+ $Article->id = 1;
+ $Article->saveField('title', 'Reset me');
+ $Article->delete();
+ $Article->id = 1;
+ $this->assertFalse($Article->exists());
+
+ $Article->create();
+ $this->assertFalse($Article->exists());
+ $Article->id = 2;
+ $Article->saveField('title', 'Staying alive');
+ $result = $Article->read(null, 2);
+ $this->assertEquals('Staying alive', $result['Article']['title']);
+ }
+
+/**
+ * testUseTableFalseExistsCheck method
+ *
+ * @return void
+ */
+ public function testUseTableFalseExistsCheck() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+ $Article->id = 1337;
+ $result = $Article->exists();
+ $this->assertFalse($result);
+
+ $Article->useTable = false;
+ $Article->id = null;
+ $result = $Article->exists();
+ $this->assertFalse($result);
+
+ // An article with primary key of '1' has been loaded by the fixtures.
+ $Article->useTable = false;
+ $Article->id = 1;
+ $result = $Article->exists();
+ $this->assertTrue($result);
+ }
+
+/**
+ * testPluginAssociations method
+ *
+ * @return void
+ */
+ public function testPluginAssociations() {
+ $this->loadFixtures('TestPluginArticle', 'User', 'TestPluginComment');
+ $TestModel = new TestPluginArticle();
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'TestPluginArticle' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Plugin Article',
+ 'body' => 'First Plugin Article Body',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:39:23',
+ 'updated' => '2008-09-24 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'TestPluginComment' => array(
+ array(
+ 'id' => 1,
+ 'article_id' => 1,
+ 'user_id' => 2,
+ 'comment' => 'First Comment for First Plugin Article',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:45:23',
+ 'updated' => '2008-09-24 10:47:31'
+ ),
+ array(
+ 'id' => 2,
+ 'article_id' => 1,
+ 'user_id' => 4,
+ 'comment' => 'Second Comment for First Plugin Article',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:47:23',
+ 'updated' => '2008-09-24 10:49:31'
+ ),
+ array(
+ 'id' => 3,
+ 'article_id' => 1,
+ 'user_id' => 1,
+ 'comment' => 'Third Comment for First Plugin Article',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:49:23',
+ 'updated' => '2008-09-24 10:51:31'
+ ),
+ array(
+ 'id' => 4,
+ 'article_id' => 1,
+ 'user_id' => 1,
+ 'comment' => 'Fourth Comment for First Plugin Article',
+ 'published' => 'N',
+ 'created' => '2008-09-24 10:51:23',
+ 'updated' => '2008-09-24 10:53:31'
+ ))),
+ array(
+ 'TestPluginArticle' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Plugin Article',
+ 'body' => 'Second Plugin Article Body',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:41:23',
+ 'updated' => '2008-09-24 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => 3,
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'TestPluginComment' => array(
+ array(
+ 'id' => 5,
+ 'article_id' => 2,
+ 'user_id' => 1,
+ 'comment' => 'First Comment for Second Plugin Article',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:53:23',
+ 'updated' => '2008-09-24 10:55:31'
+ ),
+ array(
+ 'id' => 6,
+ 'article_id' => 2,
+ 'user_id' => 2,
+ 'comment' => 'Second Comment for Second Plugin Article',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:55:23',
+ 'updated' => '2008-09-24 10:57:31'
+ ))),
+ array(
+ 'TestPluginArticle' => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Plugin Article',
+ 'body' => 'Third Plugin Article Body',
+ 'published' => 'Y',
+ 'created' => '2008-09-24 10:43:23',
+ 'updated' => '2008-09-24 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'TestPluginComment' => array()
+ ));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests getAssociated method
+ *
+ * @return void
+ */
+ public function testGetAssociated() {
+ $this->loadFixtures('Article', 'Tag');
+ $Article = ClassRegistry::init('Article');
+
+ $assocTypes = array('hasMany', 'hasOne', 'belongsTo', 'hasAndBelongsToMany');
+ foreach ($assocTypes as $type) {
+ $this->assertEquals($Article->getAssociated($type), array_keys($Article->{$type}));
+ }
+
+ $Article->bindModel(array('hasMany' => array('Category')));
+ $this->assertEquals(array('Comment', 'Category'), $Article->getAssociated('hasMany'));
+
+ $results = $Article->getAssociated();
+ $results = array_keys($results);
+ sort($results);
+ $this->assertEquals(array('Category', 'Comment', 'Tag', 'User'), $results);
+
+ $Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')));
+ $this->assertEquals(array(), $Article->getAssociated('hasAndBelongsToMany'));
+
+ $result = $Article->getAssociated('Category');
+ $expected = array(
+ 'className' => 'Category',
+ 'foreignKey' => 'article_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'dependent' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => '',
+ 'association' => 'hasMany',
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testAutoConstructAssociations method
+ *
+ * @return void
+ */
+ public function testAutoConstructAssociations() {
+ $this->loadFixtures('User', 'ArticleFeatured', 'Featured', 'ArticleFeaturedsTags');
+ $TestModel = new AssociationTest1();
+
+ $result = $TestModel->hasAndBelongsToMany;
+ $expected = array('AssociationTest2' => array(
+ 'unique' => false,
+ 'joinTable' => 'join_as_join_bs',
+ 'foreignKey' => false,
+ 'className' => 'AssociationTest2',
+ 'with' => 'JoinAsJoinB',
+ 'dynamicWith' => true,
+ 'associationForeignKey' => 'join_b_id',
+ 'conditions' => '', 'fields' => '', 'order' => '', 'limit' => '', 'offset' => '',
+ 'finderQuery' => '', 'deleteQuery' => '', 'insertQuery' => ''
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new ArticleFeatured();
+ $TestFakeModel = new ArticleFeatured(array('table' => false));
+
+ $expected = array(
+ 'User' => array(
+ 'className' => 'User', 'foreignKey' => 'user_id',
+ 'conditions' => '', 'fields' => '', 'order' => '', 'counterCache' => ''
+ ),
+ 'Category' => array(
+ 'className' => 'Category', 'foreignKey' => 'category_id',
+ 'conditions' => '', 'fields' => '', 'order' => '', 'counterCache' => ''
+ )
+ );
+ $this->assertSame($TestModel->belongsTo, $expected);
+ $this->assertSame($TestFakeModel->belongsTo, $expected);
+
+ $this->assertEquals('User', $TestModel->User->name);
+ $this->assertEquals('User', $TestFakeModel->User->name);
+ $this->assertEquals('Category', $TestModel->Category->name);
+ $this->assertEquals('Category', $TestFakeModel->Category->name);
+
+ $expected = array(
+ 'Featured' => array(
+ 'className' => 'Featured',
+ 'foreignKey' => 'article_featured_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'dependent' => ''
+ ));
+
+ $this->assertSame($TestModel->hasOne, $expected);
+ $this->assertSame($TestFakeModel->hasOne, $expected);
+
+ $this->assertEquals('Featured', $TestModel->Featured->name);
+ $this->assertEquals('Featured', $TestFakeModel->Featured->name);
+
+ $expected = array(
+ 'Comment' => array(
+ 'className' => 'Comment',
+ 'dependent' => true,
+ 'foreignKey' => 'article_featured_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ ));
+
+ $this->assertSame($TestModel->hasMany, $expected);
+ $this->assertSame($TestFakeModel->hasMany, $expected);
+
+ $this->assertEquals('Comment', $TestModel->Comment->name);
+ $this->assertEquals('Comment', $TestFakeModel->Comment->name);
+
+ $expected = array(
+ 'Tag' => array(
+ 'className' => 'Tag',
+ 'joinTable' => 'article_featureds_tags',
+ 'with' => 'ArticleFeaturedsTag',
+ 'dynamicWith' => true,
+ 'foreignKey' => 'article_featured_id',
+ 'associationForeignKey' => 'tag_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'unique' => true,
+ 'finderQuery' => '',
+ 'deleteQuery' => '',
+ 'insertQuery' => ''
+ ));
+
+ $this->assertSame($TestModel->hasAndBelongsToMany, $expected);
+ $this->assertSame($TestFakeModel->hasAndBelongsToMany, $expected);
+
+ $this->assertEquals('Tag', $TestModel->Tag->name);
+ $this->assertEquals('Tag', $TestFakeModel->Tag->name);
+ }
+
+/**
+ * test creating associations with plugins. Ensure a double alias isn't created
+ *
+ * @return void
+ */
+ public function testAutoConstructPluginAssociations() {
+ $Comment = ClassRegistry::init('TestPluginComment');
+
+ $this->assertEquals(2, count($Comment->belongsTo), 'Too many associations');
+ $this->assertFalse(isset($Comment->belongsTo['TestPlugin.User']));
+ $this->assertTrue(isset($Comment->belongsTo['User']), 'Missing association');
+ $this->assertTrue(isset($Comment->belongsTo['TestPluginArticle']), 'Missing association');
+ }
+
+/**
+ * test Model::__construct
+ *
+ * ensure that $actsAS and $findMethods are merged.
+ *
+ * @return void
+ */
+ public function testConstruct() {
+ $this->loadFixtures('Post');
+
+ $TestModel = ClassRegistry::init('MergeVarPluginPost');
+ $this->assertEquals(array('Containable' => null, 'Tree' => null), $TestModel->actsAs);
+ $this->assertTrue(isset($TestModel->Behaviors->Containable));
+ $this->assertTrue(isset($TestModel->Behaviors->Tree));
+
+ $TestModel = ClassRegistry::init('MergeVarPluginComment');
+ $expected = array('Containable' => array('some_settings'));
+ $this->assertEquals($expected, $TestModel->actsAs);
+ $this->assertTrue(isset($TestModel->Behaviors->Containable));
+ }
+
+/**
+ * test Model::__construct
+ *
+ * ensure that $actsAS and $findMethods are merged.
+ *
+ * @return void
+ */
+ public function testConstructWithAlternateDataSource() {
+ $TestModel = ClassRegistry::init(array(
+ 'class' => 'DoesntMatter', 'ds' => 'test', 'table' => false
+ ));
+ $this->assertEquals('test', $TestModel->useDbConfig);
+
+ //deprecated but test it anyway
+ $NewVoid = new TheVoid(null, false, 'other');
+ $this->assertEquals('other', $NewVoid->useDbConfig);
+ }
+
+/**
+ * testColumnTypeFetching method
+ *
+ * @return void
+ */
+ public function testColumnTypeFetching() {
+ $model = new Test();
+ $this->assertEquals('integer', $model->getColumnType('id'));
+ $this->assertEquals('text', $model->getColumnType('notes'));
+ $this->assertEquals('datetime', $model->getColumnType('updated'));
+ $this->assertEquals(null, $model->getColumnType('unknown'));
+
+ $model = new Article();
+ $this->assertEquals('datetime', $model->getColumnType('User.created'));
+ $this->assertEquals('integer', $model->getColumnType('Tag.id'));
+ $this->assertEquals('integer', $model->getColumnType('Article.id'));
+ }
+
+/**
+ * testHabtmUniqueKey method
+ *
+ * @return void
+ */
+ public function testHabtmUniqueKey() {
+ $model = new Item();
+ $this->assertFalse($model->hasAndBelongsToMany['Portfolio']['unique']);
+ }
+
+/**
+ * testIdentity method
+ *
+ * @return void
+ */
+ public function testIdentity() {
+ $TestModel = new Test();
+ $result = $TestModel->alias;
+ $expected = 'Test';
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new TestAlias();
+ $result = $TestModel->alias;
+ $expected = 'TestAlias';
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new Test(array('alias' => 'AnotherTest'));
+ $result = $TestModel->alias;
+ $expected = 'AnotherTest';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testWithAssociation method
+ *
+ * @return void
+ */
+ public function testWithAssociation() {
+ $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
+ $TestModel = new Something();
+ $result = $TestModel->SomethingElse->find('all');
+
+ $expected = array(
+ array(
+ 'SomethingElse' => array(
+ 'id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Something' => array(
+ array(
+ 'id' => '3',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31',
+ 'JoinThing' => array(
+ 'id' => '3',
+ 'something_id' => '3',
+ 'something_else_id' => '1',
+ 'doomed' => true,
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )))),
+ array(
+ 'SomethingElse' => array(
+ 'id' => '2',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Something' => array(
+ array(
+ 'id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'JoinThing' => array(
+ 'id' => '1',
+ 'something_id' => '1',
+ 'something_else_id' => '2',
+ 'doomed' => true,
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )))),
+ array(
+ 'SomethingElse' => array(
+ 'id' => '3',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'Something' => array(
+ array(
+ 'id' => '2',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31',
+ 'JoinThing' => array(
+ 'id' => '2',
+ 'something_id' => '2',
+ 'something_else_id' => '3',
+ 'doomed' => false,
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )))));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Something' => array(
+ 'id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'SomethingElse' => array(
+ array(
+ 'id' => '2',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31',
+ 'JoinThing' => array(
+ 'doomed' => true,
+ 'something_id' => '1',
+ 'something_else_id' => '2'
+ )))),
+ array(
+ 'Something' => array(
+ 'id' => '2',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'SomethingElse' => array(
+ array(
+ 'id' => '3',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31',
+ 'JoinThing' => array(
+ 'doomed' => false,
+ 'something_id' => '2',
+ 'something_else_id' => '3'
+ )))),
+ array(
+ 'Something' => array(
+ 'id' => '3',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'SomethingElse' => array(
+ array(
+ 'id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'JoinThing' => array(
+ 'doomed' => true,
+ 'something_id' => '3',
+ 'something_else_id' => '1'
+ )))));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->findById(1);
+ $expected = array(
+ 'Something' => array(
+ 'id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'SomethingElse' => array(
+ array(
+ 'id' => '2',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31',
+ 'JoinThing' => array(
+ 'doomed' => true,
+ 'something_id' => '1',
+ 'something_else_id' => '2'
+ ))));
+ $this->assertEquals($expected, $result);
+
+ $expected = $TestModel->findById(1);
+ $TestModel->set($expected);
+ $TestModel->save();
+ $result = $TestModel->findById(1);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->hasAndBelongsToMany['SomethingElse']['unique'] = false;
+ $TestModel->create(array(
+ 'Something' => array('id' => 1),
+ 'SomethingElse' => array(3, array(
+ 'something_else_id' => 1,
+ 'doomed' => true
+ ))));
+
+ $TestModel->save();
+
+ $TestModel->hasAndBelongsToMany['SomethingElse']['order'] = 'SomethingElse.id ASC';
+ $result = $TestModel->findById(1);
+ $expected = array(
+ 'Something' => array(
+ 'id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23'
+ ),
+ 'SomethingElse' => array(
+ array(
+ 'id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'JoinThing' => array(
+ 'doomed' => true,
+ 'something_id' => '1',
+ 'something_else_id' => '1'
+ )
+ ),
+ array(
+ 'id' => '2',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31',
+ 'JoinThing' => array(
+ 'doomed' => true,
+ 'something_id' => '1',
+ 'something_else_id' => '2'
+ )
+ ),
+ array(
+ 'id' => '3',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31',
+ 'JoinThing' => array(
+ 'doomed' => false,
+ 'something_id' => '1',
+ 'something_else_id' => '3')
+ )
+ )
+ );
+ $this->assertEquals(self::date(), $result['Something']['updated']);
+ unset($result['Something']['updated']);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindSelfAssociations method
+ *
+ * @return void
+ */
+ public function testFindSelfAssociations() {
+ $this->loadFixtures('Person');
+
+ $TestModel = new Person();
+ $TestModel->recursive = 2;
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'Person' => array(
+ 'id' => 1,
+ 'name' => 'person',
+ 'mother_id' => 2,
+ 'father_id' => 3
+ ),
+ 'Mother' => array(
+ 'id' => 2,
+ 'name' => 'mother',
+ 'mother_id' => 4,
+ 'father_id' => 5,
+ 'Mother' => array(
+ 'id' => 4,
+ 'name' => 'mother - grand mother',
+ 'mother_id' => 0,
+ 'father_id' => 0
+ ),
+ 'Father' => array(
+ 'id' => 5,
+ 'name' => 'mother - grand father',
+ 'mother_id' => 0,
+ 'father_id' => 0
+ )),
+ 'Father' => array(
+ 'id' => 3,
+ 'name' => 'father',
+ 'mother_id' => 6,
+ 'father_id' => 7,
+ 'Father' => array(
+ 'id' => 7,
+ 'name' => 'father - grand father',
+ 'mother_id' => 0,
+ 'father_id' => 0
+ ),
+ 'Mother' => array(
+ 'id' => 6,
+ 'name' => 'father - grand mother',
+ 'mother_id' => 0,
+ 'father_id' => 0
+ )));
+
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = 3;
+ $result = $TestModel->read(null, 1);
+ $expected = array(
+ 'Person' => array(
+ 'id' => 1,
+ 'name' => 'person',
+ 'mother_id' => 2,
+ 'father_id' => 3
+ ),
+ 'Mother' => array(
+ 'id' => 2,
+ 'name' => 'mother',
+ 'mother_id' => 4,
+ 'father_id' => 5,
+ 'Mother' => array(
+ 'id' => 4,
+ 'name' => 'mother - grand mother',
+ 'mother_id' => 0,
+ 'father_id' => 0,
+ 'Mother' => array(),
+ 'Father' => array()),
+ 'Father' => array(
+ 'id' => 5,
+ 'name' => 'mother - grand father',
+ 'mother_id' => 0,
+ 'father_id' => 0,
+ 'Father' => array(),
+ 'Mother' => array()
+ )),
+ 'Father' => array(
+ 'id' => 3,
+ 'name' => 'father',
+ 'mother_id' => 6,
+ 'father_id' => 7,
+ 'Father' => array(
+ 'id' => 7,
+ 'name' => 'father - grand father',
+ 'mother_id' => 0,
+ 'father_id' => 0,
+ 'Father' => array(),
+ 'Mother' => array()
+ ),
+ 'Mother' => array(
+ 'id' => 6,
+ 'name' => 'father - grand mother',
+ 'mother_id' => 0,
+ 'father_id' => 0,
+ 'Mother' => array(),
+ 'Father' => array()
+ )));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testDynamicAssociations method
+ *
+ * @return void
+ */
+ public function testDynamicAssociations() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->hasOne = array();
+ $TestModel->hasMany['Comment'] = array_merge($TestModel->hasMany['Comment'], array(
+ 'foreignKey' => false,
+ 'conditions' => array('Comment.user_id =' => '2')
+ ));
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))),
+ array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))),
+ array(
+ 'Article' => array(
+ 'id' => '3',
+ 'user_id' => '1',
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCreation method
+ *
+ * @return void
+ */
+ public function testCreation() {
+ $this->loadFixtures('Article', 'ArticleFeaturedsTags', 'User', 'Featured');
+ $TestModel = new Test();
+ $result = $TestModel->create();
+ $expected = array('Test' => array('notes' => 'write some notes here'));
+ $this->assertEquals($expected, $result);
+ $TestModel = new User();
+ $result = $TestModel->schema();
+
+ if (isset($this->db->columns['primary_key']['length'])) {
+ $intLength = $this->db->columns['primary_key']['length'];
+ } elseif (isset($this->db->columns['integer']['length'])) {
+ $intLength = $this->db->columns['integer']['length'];
+ } else {
+ $intLength = 11;
+ }
+ foreach (array('collate', 'charset', 'comment') as $type) {
+ foreach ($result as $i => $r) {
+ unset($result[$i][$type]);
+ }
+ }
+
+ $expected = array(
+ 'id' => array(
+ 'type' => 'integer',
+ 'null' => false,
+ 'default' => null,
+ 'length' => $intLength,
+ 'key' => 'primary'
+ ),
+ 'user' => array(
+ 'type' => 'string',
+ 'null' => true,
+ 'default' => '',
+ 'length' => 255
+ ),
+ 'password' => array(
+ 'type' => 'string',
+ 'null' => true,
+ 'default' => '',
+ 'length' => 255
+ ),
+ 'created' => array(
+ 'type' => 'datetime',
+ 'null' => true,
+ 'default' => null,
+ 'length' => null
+ ),
+ 'updated' => array(
+ 'type' => 'datetime',
+ 'null' => true,
+ 'default' => null,
+ 'length' => null
+ ));
+
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new Article();
+ $result = $TestModel->create();
+ $expected = array('Article' => array('published' => 'N'));
+ $this->assertEquals($expected, $result);
+
+ $FeaturedModel = new Featured();
+ $data = array(
+ 'article_featured_id' => 1,
+ 'category_id' => 1,
+ 'published_date' => array(
+ 'year' => 2008,
+ 'month' => 06,
+ 'day' => 11
+ ),
+ 'end_date' => array(
+ 'year' => 2008,
+ 'month' => 06,
+ 'day' => 20
+ ));
+
+ $expected = array(
+ 'Featured' => array(
+ 'article_featured_id' => 1,
+ 'category_id' => 1,
+ 'published_date' => '2008-06-11 00:00:00',
+ 'end_date' => '2008-06-20 00:00:00'
+ ));
+
+ $this->assertEquals($expected, $FeaturedModel->create($data));
+
+ $data = array(
+ 'published_date' => array(
+ 'year' => 2008,
+ 'month' => 06,
+ 'day' => 11
+ ),
+ 'end_date' => array(
+ 'year' => 2008,
+ 'month' => 06,
+ 'day' => 20
+ ),
+ 'article_featured_id' => 1,
+ 'category_id' => 1
+ );
+
+ $expected = array(
+ 'Featured' => array(
+ 'published_date' => '2008-06-11 00:00:00',
+ 'end_date' => '2008-06-20 00:00:00',
+ 'article_featured_id' => 1,
+ 'category_id' => 1
+ ));
+
+ $this->assertEquals($expected, $FeaturedModel->create($data));
+ }
+
+/**
+ * testEscapeField to prove it escapes the field well even when it has part of the alias on it
+ *
+ * @return void
+ */
+ public function testEscapeField() {
+ $TestModel = new Test();
+ $db = $TestModel->getDataSource();
+
+ $result = $TestModel->escapeField('test_field');
+ $expected = $db->name('Test.test_field');
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->escapeField('TestField');
+ $expected = $db->name('Test.TestField');
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->escapeField('DomainHandle', 'Domain');
+ $expected = $db->name('Domain.DomainHandle');
+ $this->assertEquals($expected, $result);
+
+ ConnectionManager::create('mock', array('datasource' => 'DboMock'));
+ $TestModel->setDataSource('mock');
+ $db = $TestModel->getDataSource();
+
+ $result = $TestModel->escapeField('DomainHandle', 'Domain');
+ $expected = $db->name('Domain.DomainHandle');
+ $this->assertEquals($expected, $result);
+ ConnectionManager::drop('mock');
+ }
+
+/**
+ * testGetID
+ *
+ * @return void
+ */
+ public function testGetID() {
+ $TestModel = new Test();
+
+ $result = $TestModel->getID();
+ $this->assertFalse($result);
+
+ $TestModel->id = 9;
+ $result = $TestModel->getID();
+ $this->assertEquals(9, $result);
+
+ $TestModel->id = array(10, 9, 8, 7);
+ $result = $TestModel->getID(2);
+ $this->assertEquals(8, $result);
+
+ $TestModel->id = array(array(), 1, 2, 3);
+ $result = $TestModel->getID();
+ $this->assertFalse($result);
+ }
+
+/**
+ * test that model->hasMethod checks self and behaviors.
+ *
+ * @return void
+ */
+ public function testHasMethod() {
+ $Article = new Article();
+ $Article->Behaviors = $this->getMock('BehaviorCollection');
+
+ $Article->Behaviors->expects($this->at(0))
+ ->method('hasMethod')
+ ->will($this->returnValue(true));
+
+ $Article->Behaviors->expects($this->at(1))
+ ->method('hasMethod')
+ ->will($this->returnValue(false));
+
+ $this->assertTrue($Article->hasMethod('find'));
+
+ $this->assertTrue($Article->hasMethod('pass'));
+ $this->assertFalse($Article->hasMethod('fail'));
+ }
+
+/**
+ * testMultischemaFixture
+ *
+ * @return void
+ */
+ public function testMultischemaFixture() {
+ $config = ConnectionManager::enumConnectionObjects();
+ $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with Sqlite.');
+ $this->skipIf(!isset($config['test']) || !isset($config['test2']),
+ 'Primary and secondary test databases not configured, skipping cross-database join tests. To run these tests define $test and $test2 in your database configuration.'
+ );
+
+ $this->loadFixtures('Player', 'Guild', 'GuildsPlayer');
+
+ $Player = ClassRegistry::init('Player');
+ $this->assertEquals('test', $Player->useDbConfig);
+ $this->assertEquals('test', $Player->Guild->useDbConfig);
+ $this->assertEquals('test2', $Player->Guild->GuildsPlayer->useDbConfig);
+ $this->assertEquals('test2', $Player->GuildsPlayer->useDbConfig);
+
+ $players = $Player->find('all', array('recursive' => -1));
+ $guilds = $Player->Guild->find('all', array('recursive' => -1));
+ $guildsPlayers = $Player->GuildsPlayer->find('all', array('recursive' => -1));
+
+ $this->assertEquals(true, count($players) > 1);
+ $this->assertEquals(true, count($guilds) > 1);
+ $this->assertEquals(true, count($guildsPlayers) > 1);
+ }
+
+/**
+ * testMultischemaFixtureWithThreeDatabases, three databases
+ *
+ * @return void
+ */
+ public function testMultischemaFixtureWithThreeDatabases() {
+ $config = ConnectionManager::enumConnectionObjects();
+ $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with Sqlite.');
+ $this->skipIf(
+ !isset($config['test']) || !isset($config['test2']) || !isset($config['test_database_three']),
+ 'Primary, secondary, and tertiary test databases not configured, skipping test. To run this test define $test, $test2, and $test_database_three in your database configuration.'
+ );
+
+ $this->loadFixtures('Player', 'Guild', 'GuildsPlayer', 'Armor', 'ArmorsPlayer');
+
+ $Player = ClassRegistry::init('Player');
+ $Player->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'Armor' => array(
+ 'with' => 'ArmorsPlayer',
+ ),
+ ),
+ ), false);
+ $this->assertEquals('test', $Player->useDbConfig);
+ $this->assertEquals('test', $Player->Guild->useDbConfig);
+ $this->assertEquals('test2', $Player->Guild->GuildsPlayer->useDbConfig);
+ $this->assertEquals('test2', $Player->GuildsPlayer->useDbConfig);
+ $this->assertEquals('test2', $Player->Armor->useDbConfig);
+ $this->assertEquals('test_database_three', $Player->Armor->ArmorsPlayer->useDbConfig);
+ $this->assertEquals('test', $Player->getDataSource()->configKeyName);
+ $this->assertEquals('test', $Player->Guild->getDataSource()->configKeyName);
+ $this->assertEquals('test2', $Player->GuildsPlayer->getDataSource()->configKeyName);
+ $this->assertEquals('test2', $Player->Armor->getDataSource()->configKeyName);
+ $this->assertEquals('test_database_three', $Player->Armor->ArmorsPlayer->getDataSource()->configKeyName);
+
+ $players = $Player->find('all', array('recursive' => -1));
+ $guilds = $Player->Guild->find('all', array('recursive' => -1));
+ $guildsPlayers = $Player->GuildsPlayer->find('all', array('recursive' => -1));
+ $armorsPlayers = $Player->ArmorsPlayer->find('all', array('recursive' => -1));
+
+ $this->assertEquals(true, count($players) > 1);
+ $this->assertEquals(true, count($guilds) > 1);
+ $this->assertEquals(true, count($guildsPlayers) > 1);
+ $this->assertEquals(true, count($armorsPlayers) > 1);
+ }
+
+/**
+ * Tests that calling schema() on a model that is not supposed to use a table
+ * does not trigger any calls on any datasource
+ *
+ * @return void
+ **/
+ public function testSchemaNoDB() {
+ $model = $this->getMock('Article', array('getDataSource'));
+ $model->useTable = false;
+ $model->expects($this->never())->method('getDataSource');
+ $this->assertEmpty($model->schema());
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelReadTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelReadTest.php
new file mode 100644
index 0000000..58a2ff4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelReadTest.php
@@ -0,0 +1,7881 @@
+<?php
+/**
+ * ModelReadTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
+/**
+ * ModelReadTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelReadTest extends BaseModelTest {
+
+/**
+ * testExists function
+ * @retun void
+ */
+ public function testExists() {
+ $this->loadFixtures('User');
+ $TestModel = new User();
+
+ $this->assertTrue($TestModel->exists(1));
+
+ $TestModel->id = 2;
+ $this->assertTrue($TestModel->exists());
+
+ $TestModel->delete();
+ $this->assertFalse($TestModel->exists());
+
+ $this->assertFalse($TestModel->exists(2));
+ }
+
+/**
+ * testFetchingNonUniqueFKJoinTableRecords()
+ *
+ * Tests if the results are properly returned in the case there are non-unique FK's
+ * in the join table but another fields value is different. For example:
+ * something_id | something_else_id | doomed = 1
+ * something_id | something_else_id | doomed = 0
+ * Should return both records and not just one.
+ *
+ * @return void
+ */
+ public function testFetchingNonUniqueFKJoinTableRecords() {
+ $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
+ $Something = new Something();
+
+ $joinThingData = array(
+ 'JoinThing' => array(
+ 'something_id' => 1,
+ 'something_else_id' => 2,
+ 'doomed' => '0',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )
+ );
+
+ $Something->JoinThing->create($joinThingData);
+ $Something->JoinThing->save();
+
+ $result = $Something->JoinThing->find('all', array('conditions' => array('something_else_id' => 2)));
+
+ $this->assertEquals(true, $result[0]['JoinThing']['doomed']);
+ $this->assertEquals(false, $result[1]['JoinThing']['doomed']);
+
+ $result = $Something->find('first');
+
+ $this->assertEquals(2, count($result['SomethingElse']));
+
+ $doomed = Hash::extract($result['SomethingElse'], '{n}.JoinThing.doomed');
+ $this->assertTrue(in_array(true, $doomed));
+ $this->assertTrue(in_array(false, $doomed));
+ }
+
+/**
+ * testGroupBy method
+ *
+ * These tests will never pass with Postgres or Oracle as all fields in a select must be
+ * part of an aggregate function or in the GROUP BY statement.
+ *
+ * @return void
+ */
+ public function testGroupBy() {
+ $isStrictGroupBy = $this->db instanceof Postgres || $this->db instanceof Sqlite || $this->db instanceof Oracle || $this->db instanceof Sqlserver;
+ $message = 'Postgres, Oracle, SQLite and SQL Server have strict GROUP BY and are incompatible with this test.';
+
+ $this->skipIf($isStrictGroupBy, $message);
+
+ $this->loadFixtures('Project', 'Product', 'Thread', 'Message', 'Bid');
+ $Thread = new Thread();
+ $Product = new Product();
+
+ $result = $Thread->find('all', array(
+ 'group' => 'Thread.project_id',
+ 'order' => 'Thread.id ASC'
+ ));
+
+ $expected = array(
+ array(
+ 'Thread' => array(
+ 'id' => 1,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 1'
+ ),
+ 'Project' => array(
+ 'id' => 1,
+ 'name' => 'Project 1'
+ ),
+ 'Message' => array(
+ array(
+ 'id' => 1,
+ 'thread_id' => 1,
+ 'name' => 'Thread 1, Message 1'
+ ))),
+ array(
+ 'Thread' => array(
+ 'id' => 3,
+ 'project_id' => 2,
+ 'name' => 'Project 2, Thread 1'
+ ),
+ 'Project' => array(
+ 'id' => 2,
+ 'name' => 'Project 2'
+ ),
+ 'Message' => array(
+ array(
+ 'id' => 3,
+ 'thread_id' => 3,
+ 'name' => 'Thread 3, Message 1'
+ ))));
+ $this->assertEquals($expected, $result);
+
+ $rows = $Thread->find('all', array(
+ 'group' => 'Thread.project_id',
+ 'fields' => array('Thread.project_id', 'COUNT(*) AS total')
+ ));
+ $result = array();
+ foreach ($rows as $row) {
+ $result[$row['Thread']['project_id']] = $row[0]['total'];
+ }
+ $expected = array(
+ 1 => 2,
+ 2 => 1
+ );
+ $this->assertEquals($expected, $result);
+
+ $rows = $Thread->find('all', array(
+ 'group' => 'Thread.project_id',
+ 'fields' => array('Thread.project_id', 'COUNT(*) AS total'),
+ 'order' => 'Thread.project_id'
+ ));
+ $result = array();
+ foreach ($rows as $row) {
+ $result[$row['Thread']['project_id']] = $row[0]['total'];
+ }
+ $expected = array(
+ 1 => 2,
+ 2 => 1
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $Thread->find('all', array(
+ 'conditions' => array('Thread.project_id' => 1),
+ 'group' => 'Thread.project_id'
+ ));
+ $expected = array(
+ array(
+ 'Thread' => array(
+ 'id' => 1,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 1'
+ ),
+ 'Project' => array(
+ 'id' => 1,
+ 'name' => 'Project 1'
+ ),
+ 'Message' => array(
+ array(
+ 'id' => 1,
+ 'thread_id' => 1,
+ 'name' => 'Thread 1, Message 1'
+ ))));
+ $this->assertEquals($expected, $result);
+
+ $result = $Thread->find('all', array(
+ 'conditions' => array('Thread.project_id' => 1),
+ 'group' => 'Thread.project_id, Project.id'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $Thread->find('all', array(
+ 'conditions' => array('Thread.project_id' => 1),
+ 'group' => 'project_id'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $Thread->find('all', array(
+ 'conditions' => array('Thread.project_id' => 1),
+ 'group' => array('project_id')
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $Thread->find('all', array(
+ 'conditions' => array('Thread.project_id' => 1),
+ 'group' => array('project_id', 'Project.id')
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $Thread->find('all', array(
+ 'conditions' => array('Thread.project_id' => 1),
+ 'group' => array('Thread.project_id', 'Project.id')
+ ));
+ $this->assertEquals($expected, $result);
+
+ $expected = array(
+ array('Product' => array('type' => 'Clothing'), array('price' => 32)),
+ array('Product' => array('type' => 'Food'), array('price' => 9)),
+ array('Product' => array('type' => 'Music'), array('price' => 4)),
+ array('Product' => array('type' => 'Toy'), array('price' => 3))
+ );
+ $result = $Product->find('all',array(
+ 'fields' => array('Product.type', 'MIN(Product.price) as price'),
+ 'group' => 'Product.type',
+ 'order' => 'Product.type ASC'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $Product->find('all', array(
+ 'fields' => array('Product.type', 'MIN(Product.price) as price'),
+ 'group' => array('Product.type'),
+ 'order' => 'Product.type ASC'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testOldQuery method
+ *
+ * @return void
+ */
+ public function testOldQuery() {
+ $this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag', 'Comment', 'Attachment');
+ $Article = new Article();
+
+ $query = 'SELECT title FROM ';
+ $query .= $this->db->fullTableName('articles');
+ $query .= ' WHERE ' . $this->db->fullTableName('articles') . '.id IN (1,2)';
+
+ $results = $Article->query($query);
+ $this->assertTrue(is_array($results));
+ $this->assertEquals(2, count($results));
+
+ $query = 'SELECT title, body FROM ';
+ $query .= $this->db->fullTableName('articles');
+ $query .= ' WHERE ' . $this->db->fullTableName('articles') . '.id = 1';
+
+ $results = $Article->query($query, false);
+ $this->assertFalse($this->db->getQueryCache($query));
+ $this->assertTrue(is_array($results));
+
+ $query = 'SELECT title, id FROM ';
+ $query .= $this->db->fullTableName('articles');
+ $query .= ' WHERE ' . $this->db->fullTableName('articles');
+ $query .= '.published = ' . $this->db->value('Y');
+
+ $results = $Article->query($query, true);
+ $result = $this->db->getQueryCache($query);
+ $this->assertFalse(empty($result));
+ $this->assertTrue(is_array($results));
+ }
+
+/**
+ * testPreparedQuery method
+ *
+ * @return void
+ */
+ public function testPreparedQuery() {
+ $this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag');
+ $Article = new Article();
+
+ $query = 'SELECT title, published FROM ';
+ $query .= $this->db->fullTableName('articles');
+ $query .= ' WHERE ' . $this->db->fullTableName('articles');
+ $query .= '.id = ? AND ' . $this->db->fullTableName('articles') . '.published = ?';
+
+ $params = array(1, 'Y');
+ $result = $Article->query($query, $params);
+ $expected = array(
+ '0' => array(
+ $this->db->fullTableName('articles', false, false) => array(
+ 'title' => 'First Article', 'published' => 'Y')
+ ));
+
+ if (isset($result[0][0])) {
+ $expected[0][0] = $expected[0][$this->db->fullTableName('articles', false, false)];
+ unset($expected[0][$this->db->fullTableName('articles', false, false)]);
+ }
+
+ $this->assertEquals($expected, $result);
+ $result = $this->db->getQueryCache($query, $params);
+ $this->assertFalse(empty($result));
+
+ $query = 'SELECT id, created FROM ';
+ $query .= $this->db->fullTableName('articles');
+ $query .= ' WHERE ' . $this->db->fullTableName('articles') . '.title = ?';
+
+ $params = array('First Article');
+ $result = $Article->query($query, $params, false);
+ $this->assertTrue(is_array($result));
+ $this->assertTrue(
+ isset($result[0][$this->db->fullTableName('articles', false, false)]) ||
+ isset($result[0][0])
+ );
+ $result = $this->db->getQueryCache($query, $params);
+ $this->assertTrue(empty($result));
+
+ $query = 'SELECT title FROM ';
+ $query .= $this->db->fullTableName('articles');
+ $query .= ' WHERE ' . $this->db->fullTableName('articles') . '.title LIKE ?';
+
+ $params = array('%First%');
+ $result = $Article->query($query, $params);
+ $this->assertTrue(is_array($result));
+ $this->assertTrue(
+ isset($result[0][$this->db->fullTableName('articles', false, false)]['title']) ||
+ isset($result[0][0]['title'])
+ );
+
+ //related to ticket #5035
+ $query = 'SELECT title FROM ';
+ $query .= $this->db->fullTableName('articles') . ' WHERE title = ? AND published = ?';
+ $params = array('First? Article', 'Y');
+ $Article->query($query, $params);
+
+ $result = $this->db->getQueryCache($query, $params);
+ $this->assertFalse($result === false);
+ }
+
+/**
+ * testParameterMismatch method
+ *
+ * @expectedException PDOException
+ * @return void
+ */
+ public function testParameterMismatch() {
+ $this->skipIf($this->db instanceof Sqlite, 'Sqlite does not accept real prepared statements, no way to check this');
+ $this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag');
+ $Article = new Article();
+
+ $query = 'SELECT * FROM ' . $this->db->fullTableName('articles');
+ $query .= ' WHERE ' . $this->db->fullTableName('articles');
+ $query .= '.published = ? AND ' . $this->db->fullTableName('articles') . '.user_id = ?';
+ $params = array('Y');
+
+ $result = $Article->query($query, $params);
+ }
+
+/**
+ * testVeryStrangeUseCase method
+ *
+ * @expectedException PDOException
+ * @return void
+ */
+ public function testVeryStrangeUseCase() {
+ $this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag');
+ $Article = new Article();
+
+ $query = 'SELECT * FROM ? WHERE ? = ? AND ? = ?';
+ $param = array(
+ $this->db->fullTableName('articles'),
+ $this->db->fullTableName('articles') . '.user_id', '3',
+ $this->db->fullTableName('articles') . '.published', 'Y'
+ );
+
+ $result = $Article->query($query, $param);
+ }
+
+/**
+ * testRecursiveUnbind method
+ *
+ * @return void
+ */
+ public function testRecursiveUnbind() {
+ $this->skipIf($this->db instanceof Sqlserver, 'The test of testRecursiveUnbind test is not compatible with SQL Server, because it check for time columns.');
+
+ $this->loadFixtures('Apple', 'Sample');
+ $TestModel = new Apple();
+ $TestModel->recursive = 2;
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Apple' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2',
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 1,
+ 'apple_id' => 3,
+ 'name' => 'sample1'
+ )),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 1,
+ 'apple_id' => 3,
+ 'name' => 'sample1',
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array()
+ ),
+ array(
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26', 'mytime' => '22:57:17'),
+ 'Sample' => array('id' => 2, 'apple_id' => 2, 'name' => 'sample2'),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3',
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4',
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array()
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' =>
+ 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ ),
+ 'Child' => array()));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Parent->unbindModel(array('hasOne' => array('Sample')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Apple' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2',
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01', 'modified' =>
+ '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 1,
+ 'apple_id' => 3,
+ 'name' => 'sample1'
+ )),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 1,
+ 'apple_id' => 3,
+ 'name' => 'sample1',
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array()
+ ),
+ array(
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3',
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4',
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ )),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))))),
+ array(
+ 'Apple' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array()
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ ),
+ 'Child' => array()
+ ));
+
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Parent->unbindModel(array('hasOne' => array('Sample')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->unbindModel(array('hasMany' => array('Child')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Apple' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2',
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 1,
+ 'apple_id' => 3,
+ 'name' => 'sample1',
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3',
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4',
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )));
+
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->unbindModel(array('hasMany' => array('Child')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Sample->unbindModel(array('belongsTo' => array('Apple')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Apple' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 1,
+ 'apple_id' => 3,
+ 'name' => 'sample1'
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3'
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4'
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17',
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Parent->unbindModel(array('belongsTo' => array('Parent')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->unbindModel(array('hasMany' => array('Child')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Apple' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17',
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2',
+ 'Apple' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 1,
+ 'apple_id' => 3,
+ 'name' => 'sample1',
+ 'Apple' => array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 2,
+ 'apple_id' => 1,
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17',
+ 'Sample' => array(
+ 'id' => 2,
+ 'apple_id' => 2,
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 1,
+ 'apple_id' => 2,
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 3,
+ 'apple_id' => 2,
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3',
+ 'Apple' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' =>
+ '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17',
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => 4,
+ 'apple_id' => 5,
+ 'name' => 'sample4',
+ 'Apple' => array(
+ 'id' => 5,
+ 'apple_id' => 5,
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'),
+ 'Parent' => array(
+ 'id' => 4,
+ 'apple_id' => 2,
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17',
+ 'Sample' => array(
+ 'id' => 3,
+ 'apple_id' => 4,
+ 'name' => 'sample3'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )),
+ array(
+ 'Apple' => array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => 6,
+ 'apple_id' => 4,
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17',
+ 'Sample' => array(),
+ 'Child' => array(
+ array(
+ 'id' => 7,
+ 'apple_id' => 6,
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25', 'modified' =>
+ '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))),
+ 'Sample' => array(
+ 'id' => '',
+ 'apple_id' => '',
+ 'name' => ''
+ )));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSelfAssociationAfterFind method
+ *
+ * @return void
+ */
+ public function testSelfAssociationAfterFind() {
+ $this->loadFixtures('Apple', 'Sample');
+ $afterFindModel = new NodeAfterFind();
+ $afterFindModel->recursive = 3;
+ $afterFindData = $afterFindModel->find('all');
+
+ $duplicateModel = new NodeAfterFind();
+ $duplicateModel->recursive = 3;
+ $duplicateModelData = $duplicateModel->find('all');
+
+ $noAfterFindModel = new NodeNoAfterFind();
+ $noAfterFindModel->recursive = 3;
+ $noAfterFindData = $noAfterFindModel->find('all');
+
+ $this->assertFalse($afterFindModel == $noAfterFindModel);
+ $this->assertEquals($afterFindData, $noAfterFindData);
+ }
+
+/**
+ * testFindThreadedNoParent method
+ *
+ * @return void
+ */
+ public function testFindThreadedNoParent() {
+ $this->loadFixtures('Apple', 'Sample');
+ $Apple = new Apple();
+ $result = $Apple->find('threaded');
+ $result = Hash::extract($result, '{n}.children');
+ $expected = array(array(), array(), array(), array(), array(), array(), array());
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindThreaded method
+ *
+ * @return void
+ */
+ public function testFindThreaded() {
+ $this->loadFixtures('Person');
+ $Model = new Person();
+ $Model->recursive = -1;
+ $result = $Model->find('threaded');
+ $result = Hash::extract($result, '{n}.children');
+ $expected = array(array(), array(), array(), array(), array(), array(), array());
+ $this->assertEquals($expected, $result);
+
+ $result = $Model->find('threaded', array('parent' => 'mother_id'));
+ $expected = array(
+ array(
+ 'Person' => array(
+ 'id' => '4',
+ 'name' => 'mother - grand mother',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array(
+ array(
+ 'Person' => array(
+ 'id' => '2',
+ 'name' => 'mother',
+ 'mother_id' => '4',
+ 'father_id' => '5'
+ ),
+ 'children' => array(
+ array(
+ 'Person' => array(
+ 'id' => '1',
+ 'name' => 'person',
+ 'mother_id' => '2',
+ 'father_id' => '3'
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'Person' => array(
+ 'id' => '5',
+ 'name' => 'mother - grand father',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'Person' => array(
+ 'id' => '6',
+ 'name' => 'father - grand mother',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array(
+ array(
+ 'Person' => array(
+ 'id' => '3',
+ 'name' => 'father',
+ 'mother_id' => '6',
+ 'father_id' => '7'
+ ),
+ 'children' => array()
+ )
+ )
+ ),
+ array(
+ 'Person' => array(
+ 'id' => '7',
+ 'name' => 'father - grand father',
+ 'mother_id' => '0',
+ 'father_id' => '0'
+ ),
+ 'children' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindAllThreaded method
+ *
+ * @return void
+ */
+ public function testFindAllThreaded() {
+ $this->loadFixtures('Category');
+ $TestModel = new Category();
+
+ $result = $TestModel->find('threaded');
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => '1',
+ 'parent_id' => '0',
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '2',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array('Category' => array(
+ 'id' => '7',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()),
+ array('Category' => array(
+ 'id' => '8',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()))
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '3',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ )
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '4',
+ 'parent_id' => '0',
+ 'name' => 'Category 2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '5',
+ 'parent_id' => '0',
+ 'name' => 'Category 3',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '6',
+ 'parent_id' => '5',
+ 'name' => 'Category 3.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('threaded', array(
+ 'conditions' => array('Category.name LIKE' => 'Category 1%')
+ ));
+
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => '1',
+ 'parent_id' => '0',
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '2',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array('Category' => array(
+ 'id' => '7',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()),
+ array('Category' => array(
+ 'id' => '8',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()))
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '3',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('threaded', array(
+ 'fields' => 'id, parent_id, name'
+ ));
+
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => '1',
+ 'parent_id' => '0',
+ 'name' => 'Category 1'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '2',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.1'
+ ),
+ 'children' => array(
+ array('Category' => array(
+ 'id' => '7',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.1'),
+ 'children' => array()),
+ array('Category' => array(
+ 'id' => '8',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.2'),
+ 'children' => array()))
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '3',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.2'
+ ),
+ 'children' => array()
+ )
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '4',
+ 'parent_id' => '0',
+ 'name' => 'Category 2'
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '5',
+ 'parent_id' => '0',
+ 'name' => 'Category 3'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '6',
+ 'parent_id' => '5',
+ 'name' => 'Category 3.1'
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('threaded', array('order' => 'id DESC'));
+
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => 5,
+ 'parent_id' => 0,
+ 'name' => 'Category 3',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => 6,
+ 'parent_id' => 5,
+ 'name' => 'Category 3.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ )
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'id' => 4,
+ 'parent_id' => 0,
+ 'name' => 'Category 2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'Category' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => 3,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'Category' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array('Category' => array(
+ 'id' => '8',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()),
+ array('Category' => array(
+ 'id' => '7',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()))
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('threaded', array(
+ 'conditions' => array('Category.name LIKE' => 'Category 3%')
+ ));
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => '5',
+ 'parent_id' => '0',
+ 'name' => 'Category 3',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '6',
+ 'parent_id' => '5',
+ 'name' => 'Category 3.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('threaded', array(
+ 'conditions' => array('Category.name LIKE' => 'Category 1.1%')
+ ));
+ $expected = array(
+ array('Category' =>
+ array(
+ 'id' => '2',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array(
+ array('Category' => array(
+ 'id' => '7',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()),
+ array('Category' => array(
+ 'id' => '8',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'),
+ 'children' => array()))));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('threaded', array(
+ 'fields' => 'id, parent_id, name',
+ 'conditions' => array('Category.id !=' => 2)
+ ));
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => '1',
+ 'parent_id' => '0',
+ 'name' => 'Category 1'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '3',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.2'
+ ),
+ 'children' => array()
+ )
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '4',
+ 'parent_id' => '0',
+ 'name' => 'Category 2'
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '5',
+ 'parent_id' => '0',
+ 'name' => 'Category 3'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'id' => '6',
+ 'parent_id' => '5',
+ 'name' => 'Category 3.1'
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => 'id, name, parent_id',
+ 'conditions' => array('Category.id !=' => 1)
+ ));
+ $expected = array(
+ array('Category' => array(
+ 'id' => '2',
+ 'name' => 'Category 1.1',
+ 'parent_id' => '1'
+ )),
+ array('Category' => array(
+ 'id' => '3',
+ 'name' => 'Category 1.2',
+ 'parent_id' => '1'
+ )),
+ array('Category' => array(
+ 'id' => '4',
+ 'name' => 'Category 2',
+ 'parent_id' => '0'
+ )),
+ array('Category' => array(
+ 'id' => '5',
+ 'name' => 'Category 3',
+ 'parent_id' => '0'
+ )),
+ array('Category' => array(
+ 'id' => '6',
+ 'name' => 'Category 3.1',
+ 'parent_id' => '5'
+ )),
+ array('Category' => array(
+ 'id' => '7',
+ 'name' => 'Category 1.1.1',
+ 'parent_id' => '2'
+ )),
+ array('Category' => array(
+ 'id' => '8',
+ 'name' => 'Category 1.1.2',
+ 'parent_id' => '2'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('threaded', array(
+ 'fields' => 'id, parent_id, name',
+ 'conditions' => array('Category.id !=' => 1)
+ ));
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => '2',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.1'
+ ),
+ 'children' => array(
+ array('Category' => array(
+ 'id' => '7',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.1'),
+ 'children' => array()),
+ array('Category' => array(
+ 'id' => '8',
+ 'parent_id' => '2',
+ 'name' => 'Category 1.1.2'),
+ 'children' => array()))
+ ),
+ array(
+ 'Category' => array(
+ 'id' => '3',
+ 'parent_id' => '1',
+ 'name' => 'Category 1.2'
+ ),
+ 'children' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test find('neighbors')
+ *
+ * @return void
+ */
+ public function testFindNeighbors() {
+ $this->loadFixtures('User', 'Article', 'Comment', 'Tag', 'ArticlesTag', 'Attachment');
+ $TestModel = new Article();
+
+ $TestModel->id = 1;
+ $result = $TestModel->find('neighbors', array('fields' => array('id')));
+
+ $this->assertNull($result['prev']);
+ $this->assertEquals(array('id' => 2), $result['next']['Article']);
+ $this->assertEquals(2, count($result['next']['Comment']));
+ $this->assertEquals(2, count($result['next']['Tag']));
+
+ $TestModel->id = 2;
+ $TestModel->recursive = 0;
+ $result = $TestModel->find('neighbors', array(
+ 'fields' => array('id')
+ ));
+
+ $expected = array(
+ 'prev' => array(
+ 'Article' => array(
+ 'id' => 1
+ )),
+ 'next' => array(
+ 'Article' => array(
+ 'id' => 3
+ )));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 3;
+ $TestModel->recursive = 1;
+ $result = $TestModel->find('neighbors', array('fields' => array('id')));
+
+ $this->assertNull($result['next']);
+ $this->assertEquals(array('id' => 2), $result['prev']['Article']);
+ $this->assertEquals(2, count($result['prev']['Comment']));
+ $this->assertEquals(2, count($result['prev']['Tag']));
+
+ $TestModel->id = 1;
+ $result = $TestModel->find('neighbors', array('recursive' => -1));
+ $expected = array(
+ 'prev' => null,
+ 'next' => array(
+ 'Article' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 2;
+ $result = $TestModel->find('neighbors', array('recursive' => -1));
+ $expected = array(
+ 'prev' => array(
+ 'Article' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )
+ ),
+ 'next' => array(
+ 'Article' => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 3;
+ $result = $TestModel->find('neighbors', array('recursive' => -1));
+ $expected = array(
+ 'prev' => array(
+ 'Article' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ 'next' => null
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = 0;
+ $TestModel->id = 1;
+ $one = $TestModel->read();
+ $TestModel->id = 2;
+ $two = $TestModel->read();
+ $TestModel->id = 3;
+ $three = $TestModel->read();
+
+ $TestModel->id = 1;
+ $result = $TestModel->find('neighbors');
+ $expected = array('prev' => null, 'next' => $two);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 2;
+ $result = $TestModel->find('neighbors');
+ $expected = array('prev' => $one, 'next' => $three);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 3;
+ $result = $TestModel->find('neighbors');
+ $expected = array('prev' => $two, 'next' => null);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = 2;
+ $TestModel->id = 1;
+ $one = $TestModel->read();
+ $TestModel->id = 2;
+ $two = $TestModel->read();
+ $TestModel->id = 3;
+ $three = $TestModel->read();
+
+ $TestModel->id = 1;
+ $result = $TestModel->find('neighbors', array('recursive' => 2));
+ $expected = array('prev' => null, 'next' => $two);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 2;
+ $result = $TestModel->find('neighbors', array('recursive' => 2));
+ $expected = array('prev' => $one, 'next' => $three);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 3;
+ $result = $TestModel->find('neighbors', array('recursive' => 2));
+ $expected = array('prev' => $two, 'next' => null);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindCombinedRelations method
+ *
+ * @return void
+ */
+ public function testFindCombinedRelations() {
+ $this->skipIf($this->db instanceof Sqlserver, 'The test of testRecursiveUnbind test is not compatible with SQL Server, because it check for time columns.');
+
+ $this->loadFixtures('Apple', 'Sample');
+ $TestModel = new Apple();
+
+ $result = $TestModel->find('all');
+
+ $expected = array(
+ array(
+ 'Apple' => array(
+ 'id' => '1',
+ 'apple_id' => '2',
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => '2',
+ 'apple_id' => '1',
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => null,
+ 'apple_id' => null,
+ 'name' => null
+ ),
+ 'Child' => array(
+ array(
+ 'id' => '2',
+ 'apple_id' => '1',
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => '2',
+ 'apple_id' => '1',
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => '1',
+ 'apple_id' => '2',
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => '2',
+ 'apple_id' => '2',
+ 'name' => 'sample2'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => '1',
+ 'apple_id' => '2',
+ 'color' => 'Red 1',
+ 'name' => 'Red Apple 1',
+ 'created' => '2006-11-22 10:38:58',
+ 'date' => '1951-01-04',
+ 'modified' => '2006-12-01 13:31:26',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => '3',
+ 'apple_id' => '2',
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ array(
+ 'id' => '4',
+ 'apple_id' => '2',
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => '3',
+ 'apple_id' => '2',
+ 'color' => 'blue green',
+ 'name' => 'green blue',
+ 'created' => '2006-12-25 05:13:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:24',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => '2',
+ 'apple_id' => '1',
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => '1',
+ 'apple_id' => '3',
+ 'name' => 'sample1'
+ ),
+ 'Child' => array()
+ ),
+ array(
+ 'Apple' => array(
+ 'id' => '4',
+ 'apple_id' => '2',
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => '2',
+ 'apple_id' => '1',
+ 'color' => 'Bright Red 1',
+ 'name' => 'Bright Red Apple',
+ 'created' => '2006-11-22 10:43:13',
+ 'date' => '2014-01-01',
+ 'modified' => '2006-11-30 18:38:10',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => '3',
+ 'apple_id' => '4',
+ 'name' => 'sample3'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => '6',
+ 'apple_id' => '4',
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => '5',
+ 'apple_id' => '5',
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => '5',
+ 'apple_id' => '5',
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => '4',
+ 'apple_id' => '5',
+ 'name' => 'sample4'
+ ),
+ 'Child' => array(
+ array(
+ 'id' => '5',
+ 'apple_id' => '5',
+ 'color' => 'Green',
+ 'name' => 'Blue Green',
+ 'created' => '2006-12-25 05:24:06',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:16',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => '6',
+ 'apple_id' => '4',
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => '4',
+ 'apple_id' => '2',
+ 'color' => 'Blue Green',
+ 'name' => 'Test Name',
+ 'created' => '2006-12-25 05:23:36',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:23:36',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => null,
+ 'apple_id' => null,
+ 'name' => null
+ ),
+ 'Child' => array(
+ array(
+ 'id' => '7',
+ 'apple_id' => '6',
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ))),
+ array(
+ 'Apple' => array(
+ 'id' => '7',
+ 'apple_id' => '6',
+ 'color' => 'Some wierd color',
+ 'name' => 'Some odd color',
+ 'created' => '2006-12-25 05:34:21',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:34:21',
+ 'mytime' => '22:57:17'
+ ),
+ 'Parent' => array(
+ 'id' => '6',
+ 'apple_id' => '4',
+ 'color' => 'My new appleOrange',
+ 'name' => 'My new apple',
+ 'created' => '2006-12-25 05:29:39',
+ 'date' => '2006-12-25',
+ 'modified' => '2006-12-25 05:29:39',
+ 'mytime' => '22:57:17'
+ ),
+ 'Sample' => array(
+ 'id' => null,
+ 'apple_id' => null,
+ 'name' => null
+ ),
+ 'Child' => array()
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveEmpty method
+ *
+ * @return void
+ */
+ public function testSaveEmpty() {
+ $this->loadFixtures('Thread');
+ $TestModel = new Thread();
+ $data = array();
+ $expected = $TestModel->save($data);
+ $this->assertFalse($expected);
+ }
+
+/**
+ * testFindAllWithConditionInChildQuery
+ *
+ * @todo external conditions like this are going to need to be revisited at some point
+ * @return void
+ */
+ public function testFindAllWithConditionInChildQuery() {
+ $this->loadFixtures('Basket', 'FilmFile');
+
+ $TestModel = new Basket();
+ $recursive = 3;
+ $result = $TestModel->find('all', compact('recursive'));
+
+ $expected = array(
+ array(
+ 'Basket' => array(
+ 'id' => 1,
+ 'type' => 'nonfile',
+ 'name' => 'basket1',
+ 'object_id' => 1,
+ 'user_id' => 1,
+ ),
+ 'FilmFile' => array(
+ 'id' => '',
+ 'name' => '',
+ )
+ ),
+ array(
+ 'Basket' => array(
+ 'id' => 2,
+ 'type' => 'file',
+ 'name' => 'basket2',
+ 'object_id' => 2,
+ 'user_id' => 1,
+ ),
+ 'FilmFile' => array(
+ 'id' => 2,
+ 'name' => 'two',
+ )
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindAllWithConditionsHavingMixedDataTypes method
+ *
+ * @return void
+ */
+ public function testFindAllWithConditionsHavingMixedDataTypes() {
+ $this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag');
+ $TestModel = new Article();
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )
+ )
+ );
+ $conditions = array('id' => array('1', 2));
+ $recursive = -1;
+ $order = 'Article.id ASC';
+ $result = $TestModel->find('all', compact('conditions', 'recursive', 'order'));
+ $this->assertEquals($expected, $result);
+
+ $this->skipIf($this->db instanceof Postgres, 'The rest of testFindAllWithConditionsHavingMixedDataTypes test is not compatible with Postgres.');
+
+ $conditions = array('id' => array('1', 2, '3.0'));
+ $order = 'Article.id ASC';
+ $result = $TestModel->find('all', compact('recursive', 'conditions', 'order'));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBindUnbind method
+ *
+ * @return void
+ */
+ public function testBindUnbind() {
+ $this->loadFixtures(
+ 'User',
+ 'Comment',
+ 'FeatureSet',
+ 'DeviceType',
+ 'DeviceTypeCategory',
+ 'ExteriorTypeCategory',
+ 'Device',
+ 'Document',
+ 'DocumentDirectory'
+ );
+ $TestModel = new User();
+
+ $result = $TestModel->hasMany;
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->bindModel(array('hasMany' => array('Comment')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => 'User.id, User.user'
+ ));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => '4',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry'
+ ),
+ 'Comment' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ))));
+
+ $this->assertEquals($expected, $result);
+
+ $TestModel->resetAssociations();
+ $result = $TestModel->hasMany;
+ $this->assertEquals(array(), $result);
+
+ $result = $TestModel->bindModel(array('hasMany' => array('Comment')), false);
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => 'User.id, User.user'
+ ));
+
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => '4',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry'
+ ),
+ 'Comment' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ))));
+
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->hasMany;
+ $expected = array(
+ 'Comment' => array(
+ 'className' => 'Comment',
+ 'foreignKey' => 'user_id',
+ 'conditions' => null,
+ 'fields' => null,
+ 'order' => null,
+ 'limit' => null,
+ 'offset' => null,
+ 'dependent' => null,
+ 'exclusive' => null,
+ 'finderQuery' => null,
+ 'counterQuery' => null
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->unbindModel(array('hasMany' => array('Comment')));
+ $this->assertTrue($result);
+
+ $result = $TestModel->hasMany;
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => 'User.id, User.user'
+ ));
+ $expected = array(
+ array('User' => array('id' => '1', 'user' => 'mariano')),
+ array('User' => array('id' => '2', 'user' => 'nate')),
+ array('User' => array('id' => '3', 'user' => 'larry')),
+ array('User' => array('id' => '4', 'user' => 'garrett')));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => 'User.id, User.user'
+ ));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => '4',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry'
+ ),
+ 'Comment' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' =>
+ 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ))));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->unbindModel(array('hasMany' => array('Comment')), false);
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all', array('fields' => 'User.id, User.user'));
+ $expected = array(
+ array('User' => array('id' => '1', 'user' => 'mariano')),
+ array('User' => array('id' => '2', 'user' => 'nate')),
+ array('User' => array('id' => '3', 'user' => 'larry')),
+ array('User' => array('id' => '4', 'user' => 'garrett')));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->hasMany;
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->bindModel(array('hasMany' => array(
+ 'Comment' => array('className' => 'Comment', 'conditions' => 'Comment.published = \'Y\'')
+ )));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all', array('fields' => 'User.id, User.user'));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry'
+ ),
+ 'Comment' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ))));
+
+ $this->assertEquals($expected, $result);
+
+ $TestModel2 = new DeviceType();
+
+ $expected = array(
+ 'className' => 'FeatureSet',
+ 'foreignKey' => 'feature_set_id',
+ 'conditions' => '',
+ 'fields' => '',
+ 'order' => '',
+ 'counterCache' => ''
+ );
+ $this->assertEquals($expected, $TestModel2->belongsTo['FeatureSet']);
+
+ $TestModel2->bindModel(array(
+ 'belongsTo' => array(
+ 'FeatureSet' => array(
+ 'className' => 'FeatureSet',
+ 'conditions' => array('active' => true)
+ )
+ )
+ ));
+ $expected['conditions'] = array('active' => true);
+ $this->assertEquals($expected, $TestModel2->belongsTo['FeatureSet']);
+
+ $TestModel2->bindModel(array(
+ 'belongsTo' => array(
+ 'FeatureSet' => array(
+ 'className' => 'FeatureSet',
+ 'foreignKey' => false,
+ 'conditions' => array('Feature.name' => 'DeviceType.name')
+ )
+ )
+ ));
+ $expected['conditions'] = array('Feature.name' => 'DeviceType.name');
+ $expected['foreignKey'] = false;
+ $this->assertEquals($expected, $TestModel2->belongsTo['FeatureSet']);
+
+ $TestModel2->bindModel(array(
+ 'hasMany' => array(
+ 'NewFeatureSet' => array(
+ 'className' => 'FeatureSet',
+ 'conditions' => array('active' => true)
+ )
+ )
+ ));
+
+ $expected = array(
+ 'className' => 'FeatureSet',
+ 'conditions' => array('active' => true),
+ 'foreignKey' => 'device_type_id',
+ 'fields' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'offset' => '',
+ 'dependent' => '',
+ 'exclusive' => '',
+ 'finderQuery' => '',
+ 'counterQuery' => ''
+ );
+ $this->assertEquals($expected, $TestModel2->hasMany['NewFeatureSet']);
+ $this->assertTrue(is_object($TestModel2->NewFeatureSet));
+ }
+
+/**
+ * testBindMultipleTimes method
+ *
+ * @return void
+ */
+ public function testBindMultipleTimes() {
+ $this->loadFixtures('User', 'Comment', 'Article', 'Tag', 'ArticlesTag');
+ $TestModel = new User();
+
+ $result = $TestModel->hasMany;
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->bindModel(array(
+ 'hasMany' => array(
+ 'Items' => array('className' => 'Comment')
+ )));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => 'User.id, User.user'
+ ));
+
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Items' => array(
+ array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => '4',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ ),
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate'
+ ),
+ 'Items' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry'
+ ),
+ 'Items' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett'
+ ),
+ 'Items' => array(
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ))));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->bindModel(array(
+ 'hasMany' => array(
+ 'Items' => array('className' => 'Article')
+ )));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => 'User.id, User.user'
+ ));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Items' => array(
+ array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate'
+ ),
+ 'Items' => array()
+ ),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry'
+ ),
+ 'Items' => array(
+ array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ))),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett'
+ ),
+ 'Items' => array()
+ ));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that multiple reset = true calls to bindModel() result in the original associations.
+ *
+ * @return void
+ */
+ public function testBindModelMultipleTimesResetCorrectly() {
+ $this->loadFixtures('User', 'Comment', 'Article');
+ $TestModel = new User();
+
+ $TestModel->bindModel(array('hasMany' => array('Comment')));
+ $TestModel->bindModel(array('hasMany' => array('Comment')));
+ $TestModel->resetAssociations();
+
+ $this->assertFalse(isset($TestModel->hasMany['Comment']), 'Association left behind');
+ }
+
+/**
+ * testBindMultipleTimes method with different reset settings
+ *
+ * @return void
+ */
+ public function testBindMultipleTimesWithDifferentResetSettings() {
+ $this->loadFixtures('User', 'Comment', 'Article');
+ $TestModel = new User();
+
+ $result = $TestModel->hasMany;
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->bindModel(array(
+ 'hasMany' => array('Comment')
+ ));
+ $this->assertTrue($result);
+ $result = $TestModel->bindModel(
+ array('hasMany' => array('Article')),
+ false
+ );
+ $this->assertTrue($result);
+
+ $result = array_keys($TestModel->hasMany);
+ $expected = array('Comment', 'Article');
+ $this->assertEquals($expected, $result);
+
+ $TestModel->resetAssociations();
+
+ $result = array_keys($TestModel->hasMany);
+ $expected = array('Article');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that bindModel behaves with Custom primary Key associations
+ *
+ * @return void
+ */
+ public function testBindWithCustomPrimaryKey() {
+ $this->loadFixtures('Story', 'StoriesTag', 'Tag');
+ $Model = ClassRegistry::init('StoriesTag');
+ $Model->bindModel(array(
+ 'belongsTo' => array(
+ 'Tag' => array(
+ 'className' => 'Tag',
+ 'foreignKey' => 'story'
+ ))));
+
+ $result = $Model->find('all');
+ $this->assertFalse(empty($result));
+ }
+
+/**
+ * test that calling unbindModel() with reset == true multiple times
+ * leaves associations in the correct state.
+ *
+ * @return void
+ */
+ public function testUnbindMultipleTimesResetCorrectly() {
+ $this->loadFixtures('User', 'Comment', 'Article');
+ $TestModel = new Article10();
+
+ $TestModel->unbindModel(array('hasMany' => array('Comment')));
+ $TestModel->unbindModel(array('hasMany' => array('Comment')));
+ $TestModel->resetAssociations();
+
+ $this->assertTrue(isset($TestModel->hasMany['Comment']), 'Association permanently removed');
+ }
+
+/**
+ * testBindMultipleTimes method with different reset settings
+ *
+ * @return void
+ */
+ public function testUnBindMultipleTimesWithDifferentResetSettings() {
+ $this->loadFixtures('User', 'Comment', 'Article');
+ $TestModel = new Comment();
+
+ $result = array_keys($TestModel->belongsTo);
+ $expected = array('Article', 'User');
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->unbindModel(array(
+ 'belongsTo' => array('User')
+ ));
+ $this->assertTrue($result);
+ $result = $TestModel->unbindModel(
+ array('belongsTo' => array('Article')),
+ false
+ );
+ $this->assertTrue($result);
+
+ $result = array_keys($TestModel->belongsTo);
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $TestModel->resetAssociations();
+
+ $result = array_keys($TestModel->belongsTo);
+ $expected = array('User');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testAssociationAfterFind method
+ *
+ * @return void
+ */
+ public function testAssociationAfterFind() {
+ $this->loadFixtures('Post', 'Author', 'Comment');
+ $TestModel = new Post();
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Author' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31',
+ 'test' => 'working'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '3',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Author' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31',
+ 'test' => 'working'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '3',
+ 'author_id' => '1',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'Author' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31',
+ 'test' => 'working'
+ )));
+ $this->assertEquals($expected, $result);
+ unset($TestModel);
+
+ $Author = new Author();
+ $Author->Post->bindModel(array(
+ 'hasMany' => array(
+ 'Comment' => array(
+ 'className' => 'ModifiedComment',
+ 'foreignKey' => 'article_id',
+ )
+ )));
+ $result = $Author->find('all', array(
+ 'conditions' => array('Author.id' => 1),
+ 'recursive' => 2
+ ));
+ $expected = array(
+ 'id' => 1,
+ 'article_id' => 1,
+ 'user_id' => 2,
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31',
+ 'callback' => 'Fire'
+ );
+ $this->assertEquals($expected, $result[0]['Post'][0]['Comment'][0]);
+ }
+
+/**
+ * testDeeperAssociationAfterFind method
+ *
+ * @return void
+ */
+ public function testDeeperAssociationAfterFind() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article');
+
+ $Post = new Post();
+ $Post->bindModel(array(
+ 'hasMany' => array(
+ 'Comment' => array(
+ 'className' => 'ModifiedComment',
+ 'foreignKey' => 'article_id',
+ )
+ )));
+ $Post->Comment->bindModel(array(
+ 'hasOne' => array(
+ 'Attachment' => array(
+ 'className' => 'ModifiedAttachment',
+ )
+ )));
+
+ $result = $Post->find('first', array(
+ 'conditions' => array('Post.id' => 2),
+ 'recursive' => 2
+ ));
+ $this->assertTrue(isset($result['Comment'][0]['callback']));
+ $this->assertEquals('Fire', $result['Comment'][0]['callback']);
+ $this->assertTrue(isset($result['Comment'][0]['Attachment']['callback']));
+ $this->assertEquals('Fired', $result['Comment'][0]['Attachment']['callback']);
+ }
+
+/**
+ * Tests that callbacks can be properly disabled
+ *
+ * @return void
+ */
+ public function testCallbackDisabling() {
+ $this->loadFixtures('Author');
+ $TestModel = new ModifiedAuthor();
+
+ $result = Hash::extract($TestModel->find('all'), '{n}.Author.user');
+ $expected = array('mariano (CakePHP)', 'nate (CakePHP)', 'larry (CakePHP)', 'garrett (CakePHP)');
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($TestModel->find('all', array('callbacks' => 'after')), '{n}.Author.user');
+ $expected = array('mariano (CakePHP)', 'nate (CakePHP)', 'larry (CakePHP)', 'garrett (CakePHP)');
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($TestModel->find('all', array('callbacks' => 'before')), '{n}.Author.user');
+ $expected = array('mariano', 'nate', 'larry', 'garrett');
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($TestModel->find('all', array('callbacks' => false)), '{n}.Author.user');
+ $expected = array('mariano', 'nate', 'larry', 'garrett');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testAssociationAfterFindCallbacksDisabled method
+ *
+ * @return void
+ */
+ public function testAssociationAfterFindCalbacksDisabled() {
+ $this->loadFixtures('Post', 'Author', 'Comment');
+ $TestModel = new Post();
+ $result = $TestModel->find('all', array('callbacks' => false));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Author' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '3',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Author' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '3',
+ 'author_id' => '1',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'Author' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )));
+ $this->assertEquals($expected, $result);
+ unset($TestModel);
+
+ $Author = new Author();
+ $Author->Post->bindModel(array(
+ 'hasMany' => array(
+ 'Comment' => array(
+ 'className' => 'ModifiedComment',
+ 'foreignKey' => 'article_id',
+ )
+ )));
+ $result = $Author->find('all', array(
+ 'conditions' => array('Author.id' => 1),
+ 'recursive' => 2,
+ 'callbacks' => false
+ ));
+ $expected = array(
+ 'id' => 1,
+ 'article_id' => 1,
+ 'user_id' => 2,
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ );
+ $this->assertEquals($expected, $result[0]['Post'][0]['Comment'][0]);
+ }
+
+/**
+ * Tests that the database configuration assigned to the model can be changed using
+ * (before|after)Find callbacks
+ *
+ * @return void
+ */
+ public function testCallbackSourceChange() {
+ $this->loadFixtures('Post');
+ $TestModel = new Post();
+ $this->assertEquals(3, count($TestModel->find('all')));
+ }
+
+/**
+ * testCallbackSourceChangeUnknownDatasource method
+ *
+ * @expectedException MissingDatasourceConfigException
+ * @return void
+ */
+ public function testCallbackSourceChangeUnknownDatasource() {
+ $this->loadFixtures('Post', 'Author');
+ $TestModel = new Post();
+ $this->assertFalse($TestModel->find('all', array('connection' => 'foo')));
+ }
+
+/**
+ * testMultipleBelongsToWithSameClass method
+ *
+ * @return void
+ */
+ public function testMultipleBelongsToWithSameClass() {
+ $this->loadFixtures(
+ 'DeviceType',
+ 'DeviceTypeCategory',
+ 'FeatureSet',
+ 'ExteriorTypeCategory',
+ 'Document',
+ 'Device',
+ 'DocumentDirectory'
+ );
+
+ $DeviceType = new DeviceType();
+
+ $DeviceType->recursive = 2;
+ $result = $DeviceType->read(null, 1);
+
+ $expected = array(
+ 'DeviceType' => array(
+ 'id' => 1,
+ 'device_type_category_id' => 1,
+ 'feature_set_id' => 1,
+ 'exterior_type_category_id' => 1,
+ 'image_id' => 1,
+ 'extra1_id' => 1,
+ 'extra2_id' => 1,
+ 'name' => 'DeviceType 1',
+ 'order' => 0
+ ),
+ 'Image' => array(
+ 'id' => 1,
+ 'document_directory_id' => 1,
+ 'name' => 'Document 1',
+ 'DocumentDirectory' => array(
+ 'id' => 1,
+ 'name' => 'DocumentDirectory 1'
+ )),
+ 'Extra1' => array(
+ 'id' => 1,
+ 'document_directory_id' => 1,
+ 'name' => 'Document 1',
+ 'DocumentDirectory' => array(
+ 'id' => 1,
+ 'name' => 'DocumentDirectory 1'
+ )),
+ 'Extra2' => array(
+ 'id' => 1,
+ 'document_directory_id' => 1,
+ 'name' => 'Document 1',
+ 'DocumentDirectory' => array(
+ 'id' => 1,
+ 'name' => 'DocumentDirectory 1'
+ )),
+ 'DeviceTypeCategory' => array(
+ 'id' => 1,
+ 'name' => 'DeviceTypeCategory 1'
+ ),
+ 'FeatureSet' => array(
+ 'id' => 1,
+ 'name' => 'FeatureSet 1'
+ ),
+ 'ExteriorTypeCategory' => array(
+ 'id' => 1,
+ 'image_id' => 1,
+ 'name' => 'ExteriorTypeCategory 1',
+ 'Image' => array(
+ 'id' => 1,
+ 'device_type_id' => 1,
+ 'name' => 'Device 1',
+ 'typ' => 1
+ )),
+ 'Device' => array(
+ array(
+ 'id' => 1,
+ 'device_type_id' => 1,
+ 'name' => 'Device 1',
+ 'typ' => 1
+ ),
+ array(
+ 'id' => 2,
+ 'device_type_id' => 1,
+ 'name' => 'Device 2',
+ 'typ' => 1
+ ),
+ array(
+ 'id' => 3,
+ 'device_type_id' => 1,
+ 'name' => 'Device 3',
+ 'typ' => 2
+ )));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testHabtmRecursiveBelongsTo method
+ *
+ * @return void
+ */
+ public function testHabtmRecursiveBelongsTo() {
+ $this->loadFixtures('Portfolio', 'Item', 'ItemsPortfolio', 'Syfile', 'Image');
+ $Portfolio = new Portfolio();
+
+ $result = $Portfolio->find('first', array('conditions' => array('id' => 2), 'recursive' => 3));
+ $expected = array(
+ 'Portfolio' => array(
+ 'id' => 2,
+ 'seller_id' => 1,
+ 'name' => 'Portfolio 2'
+ ),
+ 'Item' => array(
+ array(
+ 'id' => 2,
+ 'syfile_id' => 2,
+ 'published' => false,
+ 'name' => 'Item 2',
+ 'ItemsPortfolio' => array(
+ 'id' => 2,
+ 'item_id' => 2,
+ 'portfolio_id' => 2
+ ),
+ 'Syfile' => array(
+ 'id' => 2,
+ 'image_id' => 2,
+ 'name' => 'Syfile 2',
+ 'item_count' => null,
+ 'Image' => array(
+ 'id' => 2,
+ 'name' => 'Image 2'
+ )
+ )),
+ array(
+ 'id' => 6,
+ 'syfile_id' => 6,
+ 'published' => false,
+ 'name' => 'Item 6',
+ 'ItemsPortfolio' => array(
+ 'id' => 6,
+ 'item_id' => 6,
+ 'portfolio_id' => 2
+ ),
+ 'Syfile' => array(
+ 'id' => 6,
+ 'image_id' => null,
+ 'name' => 'Syfile 6',
+ 'item_count' => null,
+ 'Image' => array()
+ ))));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testNonNumericHabtmJoinKey method
+ *
+ * @return void
+ */
+ public function testNonNumericHabtmJoinKey() {
+ $this->loadFixtures('Post', 'Tag', 'PostsTag', 'Author');
+ $Post = new Post();
+ $Post->bindModel(array(
+ 'hasAndBelongsToMany' => array('Tag')
+ ));
+ $Post->Tag->primaryKey = 'tag';
+
+ $result = $Post->find('all');
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '1',
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'Author' => array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31',
+ 'test' => 'working'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ))),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '3',
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Author' => array(
+ 'id' => 3,
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31',
+ 'test' => 'working'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ ))),
+ array(
+ 'Post' => array(
+ 'id' => '3',
+ 'author_id' => '1',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'Author' => array(
+ 'id' => 1,
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31',
+ 'test' => 'working'
+ ),
+ 'Tag' => array()
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testHabtmFinderQuery method
+ *
+ * @return void
+ */
+ public function testHabtmFinderQuery() {
+ $this->loadFixtures('Article', 'Tag', 'ArticlesTag');
+ $Article = new Article();
+
+ $sql = $this->db->buildStatement(
+ array(
+ 'fields' => $this->db->fields($Article->Tag, null, array(
+ 'Tag.id', 'Tag.tag', 'ArticlesTag.article_id', 'ArticlesTag.tag_id'
+ )),
+ 'table' => $this->db->fullTableName('tags'),
+ 'alias' => 'Tag',
+ 'limit' => null,
+ 'offset' => null,
+ 'group' => null,
+ 'joins' => array(array(
+ 'alias' => 'ArticlesTag',
+ 'table' => 'articles_tags',
+ 'conditions' => array(
+ array("ArticlesTag.article_id" => '{$__cakeID__$}'),
+ array("ArticlesTag.tag_id" => $this->db->identifier('Tag.id'))
+ )
+ )),
+ 'conditions' => array(),
+ 'order' => null
+ ),
+ $Article
+ );
+
+ $Article->hasAndBelongsToMany['Tag']['finderQuery'] = $sql;
+ $result = $Article->find('first');
+ $expected = array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2'
+ ));
+
+ $this->assertEquals($expected, $result['Tag']);
+ }
+
+/**
+ * testHabtmLimitOptimization method
+ *
+ * @return void
+ */
+ public function testHabtmLimitOptimization() {
+ $this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
+ $TestModel = new Article();
+
+ $TestModel->hasAndBelongsToMany['Tag']['limit'] = 2;
+ $result = $TestModel->read(null, 2);
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ )),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+
+ $this->assertEquals($expected, $result);
+
+ $TestModel->hasAndBelongsToMany['Tag']['limit'] = 1;
+ $result = $TestModel->read(null, 2);
+ unset($expected['Tag'][1]);
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testHasManyLimitOptimization method
+ *
+ * @return void
+ */
+ public function testHasManyLimitOptimization() {
+ $this->loadFixtures('Project', 'Thread', 'Message', 'Bid');
+ $Project = new Project();
+ $Project->recursive = 3;
+
+ $result = $Project->find('all');
+ $expected = array(
+ array(
+ 'Project' => array(
+ 'id' => 1,
+ 'name' => 'Project 1'
+ ),
+ 'Thread' => array(
+ array(
+ 'id' => 1,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 1',
+ 'Project' => array(
+ 'id' => 1,
+ 'name' => 'Project 1',
+ 'Thread' => array(
+ array(
+ 'id' => 1,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 1'
+ ),
+ array(
+ 'id' => 2,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 2'
+ ))),
+ 'Message' => array(
+ array(
+ 'id' => 1,
+ 'thread_id' => 1,
+ 'name' => 'Thread 1, Message 1',
+ 'Bid' => array(
+ 'id' => 1,
+ 'message_id' => 1,
+ 'name' => 'Bid 1.1'
+ )))),
+ array(
+ 'id' => 2,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 2',
+ 'Project' => array(
+ 'id' => 1,
+ 'name' => 'Project 1',
+ 'Thread' => array(
+ array(
+ 'id' => 1,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 1'
+ ),
+ array(
+ 'id' => 2,
+ 'project_id' => 1,
+ 'name' => 'Project 1, Thread 2'
+ ))),
+ 'Message' => array(
+ array(
+ 'id' => 2,
+ 'thread_id' => 2,
+ 'name' => 'Thread 2, Message 1',
+ 'Bid' => array(
+ 'id' => 4,
+ 'message_id' => 2,
+ 'name' => 'Bid 2.1'
+ )))))),
+ array(
+ 'Project' => array(
+ 'id' => 2,
+ 'name' => 'Project 2'
+ ),
+ 'Thread' => array(
+ array(
+ 'id' => 3,
+ 'project_id' => 2,
+ 'name' => 'Project 2, Thread 1',
+ 'Project' => array(
+ 'id' => 2,
+ 'name' => 'Project 2',
+ 'Thread' => array(
+ array(
+ 'id' => 3,
+ 'project_id' => 2,
+ 'name' => 'Project 2, Thread 1'
+ ))),
+ 'Message' => array(
+ array(
+ 'id' => 3,
+ 'thread_id' => 3,
+ 'name' => 'Thread 3, Message 1',
+ 'Bid' => array(
+ 'id' => 3,
+ 'message_id' => 3,
+ 'name' => 'Bid 3.1'
+ )))))),
+ array(
+ 'Project' => array(
+ 'id' => 3,
+ 'name' => 'Project 3'
+ ),
+ 'Thread' => array()
+ ));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindAllRecursiveSelfJoin method
+ *
+ * @return void
+ */
+ public function testFindAllRecursiveSelfJoin() {
+ $this->loadFixtures('Home', 'AnotherArticle', 'Advertisement');
+ $TestModel = new Home();
+ $TestModel->recursive = 2;
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'Home' => array(
+ 'id' => '1',
+ 'another_article_id' => '1',
+ 'advertisement_id' => '1',
+ 'title' => 'First Home',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'AnotherArticle' => array(
+ 'id' => '1',
+ 'title' => 'First Article',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'Home' => array(
+ array(
+ 'id' => '1',
+ 'another_article_id' => '1',
+ 'advertisement_id' => '1',
+ 'title' => 'First Home',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ))),
+ 'Advertisement' => array(
+ 'id' => '1',
+ 'title' => 'First Ad',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'Home' => array(
+ array(
+ 'id' => '1',
+ 'another_article_id' => '1',
+ 'advertisement_id' => '1',
+ 'title' => 'First Home',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => '2',
+ 'another_article_id' => '3',
+ 'advertisement_id' => '1',
+ 'title' => 'Second Home',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )))),
+ array(
+ 'Home' => array(
+ 'id' => '2',
+ 'another_article_id' => '3',
+ 'advertisement_id' => '1',
+ 'title' => 'Second Home',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'AnotherArticle' => array(
+ 'id' => '3',
+ 'title' => 'Third Article',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31',
+ 'Home' => array(
+ array(
+ 'id' => '2',
+ 'another_article_id' => '3',
+ 'advertisement_id' => '1',
+ 'title' => 'Second Home',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ))),
+ 'Advertisement' => array(
+ 'id' => '1',
+ 'title' => 'First Ad',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31',
+ 'Home' => array(
+ array(
+ 'id' => '1',
+ 'another_article_id' => '1',
+ 'advertisement_id' => '1',
+ 'title' => 'First Home',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => '2',
+ 'another_article_id' => '3',
+ 'advertisement_id' => '1',
+ 'title' => 'Second Home',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )))));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindAllRecursiveWithHabtm method
+ *
+ * @return void
+ */
+ public function testFindAllRecursiveWithHabtm() {
+ $this->loadFixtures(
+ 'MyCategoriesMyUsers',
+ 'MyCategoriesMyProducts',
+ 'MyCategory',
+ 'MyUser',
+ 'MyProduct'
+ );
+
+ $MyUser = new MyUser();
+ $MyUser->recursive = 2;
+
+ $result = $MyUser->find('all');
+ $expected = array(
+ array(
+ 'MyUser' => array('id' => '1', 'firstname' => 'userA'),
+ 'MyCategory' => array(
+ array(
+ 'id' => '1',
+ 'name' => 'A',
+ 'MyProduct' => array(
+ array(
+ 'id' => '1',
+ 'name' => 'book'
+ ))),
+ array(
+ 'id' => '3',
+ 'name' => 'C',
+ 'MyProduct' => array(
+ array(
+ 'id' => '2',
+ 'name' => 'computer'
+ ))))),
+ array(
+ 'MyUser' => array(
+ 'id' => '2',
+ 'firstname' => 'userB'
+ ),
+ 'MyCategory' => array(
+ array(
+ 'id' => '1',
+ 'name' => 'A',
+ 'MyProduct' => array(
+ array(
+ 'id' => '1',
+ 'name' => 'book'
+ ))),
+ array(
+ 'id' => '2',
+ 'name' => 'B',
+ 'MyProduct' => array(
+ array(
+ 'id' => '1',
+ 'name' => 'book'
+ ),
+ array(
+ 'id' => '2',
+ 'name' => 'computer'
+ ))))));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testReadFakeThread method
+ *
+ * @return void
+ */
+ public function testReadFakeThread() {
+ $this->loadFixtures('CategoryThread');
+ $TestModel = new CategoryThread();
+
+ $fullDebug = $this->db->fullDebug;
+ $this->db->fullDebug = true;
+ $TestModel->recursive = 6;
+ $TestModel->id = 7;
+ $result = $TestModel->read();
+ $expected = array(
+ 'CategoryThread' => array(
+ 'id' => 7,
+ 'parent_id' => 6,
+ 'name' => 'Category 2.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 6,
+ 'parent_id' => 5,
+ 'name' => 'Category 2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 5,
+ 'parent_id' => 4,
+ 'name' => 'Category 1.1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 4,
+ 'parent_id' => 3,
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 3,
+ 'parent_id' => 2,
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ )))))));
+
+ $this->db->fullDebug = $fullDebug;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindFakeThread method
+ *
+ * @return void
+ */
+ public function testFindFakeThread() {
+ $this->loadFixtures('CategoryThread');
+ $TestModel = new CategoryThread();
+
+ $fullDebug = $this->db->fullDebug;
+ $this->db->fullDebug = true;
+ $TestModel->recursive = 6;
+ $result = $TestModel->find('first', array('conditions' => array('CategoryThread.id' => 7)));
+
+ $expected = array(
+ 'CategoryThread' => array(
+ 'id' => 7,
+ 'parent_id' => 6,
+ 'name' => 'Category 2.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 6,
+ 'parent_id' => 5,
+ 'name' => 'Category 2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 5,
+ 'parent_id' => 4,
+ 'name' => 'Category 1.1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 4,
+ 'parent_id' => 3,
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 3,
+ 'parent_id' => 2,
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ )))))));
+
+ $this->db->fullDebug = $fullDebug;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindAllFakeThread method
+ *
+ * @return void
+ */
+ public function testFindAllFakeThread() {
+ $this->loadFixtures('CategoryThread');
+ $TestModel = new CategoryThread();
+
+ $fullDebug = $this->db->fullDebug;
+ $this->db->fullDebug = true;
+ $TestModel->recursive = 6;
+ $result = $TestModel->find('all', null, null, 'CategoryThread.id ASC');
+ $expected = array(
+ array(
+ 'CategoryThread' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => null,
+ 'parent_id' => null,
+ 'name' => null,
+ 'created' => null,
+ 'updated' => null,
+ 'ParentCategory' => array()
+ )),
+ array(
+ 'CategoryThread' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array()
+ )),
+ array(
+ 'CategoryThread' => array(
+ 'id' => 3,
+ 'parent_id' => 2,
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array()
+ ))),
+ array(
+ 'CategoryThread' => array(
+ 'id' => 4,
+ 'parent_id' => 3,
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 3,
+ 'parent_id' => 2,
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array()
+ )))),
+ array(
+ 'CategoryThread' => array(
+ 'id' => 5,
+ 'parent_id' => 4,
+ 'name' => 'Category 1.1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 4,
+ 'parent_id' => 3,
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 3,
+ 'parent_id' => 2,
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array()
+ ))))),
+ array(
+ 'CategoryThread' => array(
+ 'id' => 6,
+ 'parent_id' => 5,
+ 'name' => 'Category 2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 5,
+ 'parent_id' => 4,
+ 'name' => 'Category 1.1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 4,
+ 'parent_id' => 3,
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 3,
+ 'parent_id' => 2,
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array()
+ )))))),
+ array(
+ 'CategoryThread' => array(
+ 'id' => 7,
+ 'parent_id' => 6,
+ 'name' => 'Category 2.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ),
+ 'ParentCategory' => array(
+ 'id' => 6,
+ 'parent_id' => 5,
+ 'name' => 'Category 2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 5,
+ 'parent_id' => 4,
+ 'name' => 'Category 1.1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 4,
+ 'parent_id' => 3,
+ 'name' => 'Category 1.1.2',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 3,
+ 'parent_id' => 2,
+ 'name' => 'Category 1.1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'name' => 'Category 1.1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31',
+ 'ParentCategory' => array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ ))))))));
+
+ $this->db->fullDebug = $fullDebug;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testConditionalNumerics method
+ *
+ * @return void
+ */
+ public function testConditionalNumerics() {
+ $this->loadFixtures('NumericArticle');
+ $NumericArticle = new NumericArticle();
+ $data = array('conditions' => array('title' => '12345abcde'));
+ $result = $NumericArticle->find('first', $data);
+ $this->assertTrue(!empty($result));
+
+ $data = array('conditions' => array('title' => '12345'));
+ $result = $NumericArticle->find('first', $data);
+ $this->assertTrue(empty($result));
+ }
+
+/**
+ * test buildQuery()
+ *
+ * @return void
+ */
+ public function testBuildQuery() {
+ $this->loadFixtures('User');
+ $TestModel = new User();
+ $TestModel->cacheQueries = false;
+
+ $expected = array(
+ 'conditions' => array(
+ 'user' => 'larry'
+ ),
+ 'fields' => null,
+ 'joins' => array(),
+ 'limit' => null,
+ 'offset' => null,
+ 'order' => array(
+ 0 => null
+ ),
+ 'page' => 1,
+ 'group' => null,
+ 'callbacks' => true,
+ 'returnQuery' => true
+ );
+ $result = $TestModel->buildQuery('all', array('returnQuery' => true, 'conditions' => array('user' => 'larry')));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test find('all') method
+ *
+ * @return void
+ */
+ public function testFindAll() {
+ $this->loadFixtures('User');
+ $TestModel = new User();
+ $TestModel->cacheQueries = false;
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23',
+ 'updated' => '2007-03-17 01:24:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('conditions' => 'User.id > 2'));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23',
+ 'updated' => '2007-03-17 01:24:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array(
+ 'conditions' => array('User.id !=' => '0', 'User.user LIKE' => '%arr%')
+ ));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23',
+ 'updated' => '2007-03-17 01:24:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('conditions' => array('User.id' => '0')));
+ $expected = array();
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array(
+ 'conditions' => array('or' => array('User.id' => '0', 'User.user LIKE' => '%a%')
+ )));
+
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23',
+ 'updated' => '2007-03-17 01:24:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('fields' => 'User.id, User.user'));
+ $expected = array(
+ array('User' => array('id' => '1', 'user' => 'mariano')),
+ array('User' => array('id' => '2', 'user' => 'nate')),
+ array('User' => array('id' => '3', 'user' => 'larry')),
+ array('User' => array('id' => '4', 'user' => 'garrett')));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('fields' => 'User.user', 'order' => 'User.user ASC'));
+ $expected = array(
+ array('User' => array('user' => 'garrett')),
+ array('User' => array('user' => 'larry')),
+ array('User' => array('user' => 'mariano')),
+ array('User' => array('user' => 'nate')));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('fields' => 'User.user', 'order' => 'User.user DESC'));
+ $expected = array(
+ array('User' => array('user' => 'nate')),
+ array('User' => array('user' => 'mariano')),
+ array('User' => array('user' => 'larry')),
+ array('User' => array('user' => 'garrett')));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('limit' => 3, 'page' => 1));
+
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $ids = array(4 => 1, 5 => 3);
+ $result = $TestModel->find('all', array(
+ 'conditions' => array('User.id' => $ids),
+ 'order' => 'User.id'
+ ));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ )),
+ array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ // These tests are expected to fail on SQL Server since the LIMIT/OFFSET
+ // hack can't handle small record counts.
+ if (!($this->db instanceof Sqlserver)) {
+ $result = $TestModel->find('all', array('limit' => 3, 'page' => 2));
+ $expected = array(
+ array(
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'garrett',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:22:23',
+ 'updated' => '2007-03-17 01:24:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array('limit' => 3, 'page' => 3));
+ $expected = array();
+ $this->assertEquals($expected, $result);
+ }
+ }
+
+/**
+ * test find('list') method
+ *
+ * @return void
+ */
+ public function testGenerateFindList() {
+ $this->loadFixtures('Article', 'Apple', 'Post', 'Author', 'User', 'Comment');
+
+ $TestModel = new Article();
+ $TestModel->displayField = 'title';
+
+ $result = $TestModel->find('list', array(
+ 'order' => 'Article.title ASC'
+ ));
+
+ $expected = array(
+ 1 => 'First Article',
+ 2 => 'Second Article',
+ 3 => 'Third Article'
+ );
+ $this->assertEquals($expected, $result);
+
+ $db = ConnectionManager::getDataSource('test');
+ if ($db instanceof Mysql) {
+ $result = $TestModel->find('list', array(
+ 'order' => array('FIELD(Article.id, 3, 2) ASC', 'Article.title ASC')
+ ));
+ $expected = array(
+ 1 => 'First Article',
+ 3 => 'Third Article',
+ 2 => 'Second Article'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+ $result = Hash::combine(
+ $TestModel->find('all', array(
+ 'order' => 'Article.title ASC',
+ 'fields' => array('id', 'title')
+ )),
+ '{n}.Article.id', '{n}.Article.title'
+ );
+ $expected = array(
+ 1 => 'First Article',
+ 2 => 'Second Article',
+ 3 => 'Third Article'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine(
+ $TestModel->find('all', array(
+ 'order' => 'Article.title ASC'
+ )),
+ '{n}.Article.id', '{n}.Article'
+ );
+ $expected = array(
+ 1 => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 2 => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 3 => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ));
+
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine(
+ $TestModel->find('all', array(
+ 'order' => 'Article.title ASC'
+ )),
+ '{n}.Article.id', '{n}.Article', '{n}.Article.user_id'
+ );
+ $expected = array(
+ 1 => array(
+ 1 => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 3 => array(
+ 'id' => 3,
+ 'user_id' => 1,
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )),
+ 3 => array(
+ 2 => array(
+ 'id' => 2,
+ 'user_id' => 3,
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )));
+
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine(
+ $TestModel->find('all', array(
+ 'order' => 'Article.title ASC',
+ 'fields' => array('id', 'title', 'user_id')
+ )),
+ '{n}.Article.id', '{n}.Article.title', '{n}.Article.user_id'
+ );
+
+ $expected = array(
+ 1 => array(
+ 1 => 'First Article',
+ 3 => 'Third Article'
+ ),
+ 3 => array(
+ 2 => 'Second Article'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new Apple();
+ $expected = array(
+ 1 => 'Red Apple 1',
+ 2 => 'Bright Red Apple',
+ 3 => 'green blue',
+ 4 => 'Test Name',
+ 5 => 'Blue Green',
+ 6 => 'My new apple',
+ 7 => 'Some odd color'
+ );
+
+ $this->assertEquals($expected, $TestModel->find('list'));
+ $this->assertEquals($expected, $TestModel->Parent->find('list'));
+
+ $TestModel = new Post();
+ $result = $TestModel->find('list', array(
+ 'fields' => 'Post.title'
+ ));
+ $expected = array(
+ 1 => 'First Post',
+ 2 => 'Second Post',
+ 3 => 'Third Post'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('list', array(
+ 'fields' => 'title'
+ ));
+ $expected = array(
+ 1 => 'First Post',
+ 2 => 'Second Post',
+ 3 => 'Third Post'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('list', array(
+ 'fields' => array('title', 'id')
+ ));
+ $expected = array(
+ 'First Post' => '1',
+ 'Second Post' => '2',
+ 'Third Post' => '3'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('list', array(
+ 'fields' => array('title', 'id', 'created')
+ ));
+ $expected = array(
+ '2007-03-18 10:39:23' => array(
+ 'First Post' => '1'
+ ),
+ '2007-03-18 10:41:23' => array(
+ 'Second Post' => '2'
+ ),
+ '2007-03-18 10:43:23' => array(
+ 'Third Post' => '3'
+ ),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('list', array(
+ 'fields' => array('Post.body')
+ ));
+ $expected = array(
+ 1 => 'First Post Body',
+ 2 => 'Second Post Body',
+ 3 => 'Third Post Body'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('list', array(
+ 'fields' => array('Post.title', 'Post.body')
+ ));
+ $expected = array(
+ 'First Post' => 'First Post Body',
+ 'Second Post' => 'Second Post Body',
+ 'Third Post' => 'Third Post Body'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('list', array(
+ 'fields' => array('Post.id', 'Post.title', 'Author.user'),
+ 'recursive' => 1
+ ));
+ $expected = array(
+ 'mariano' => array(
+ 1 => 'First Post',
+ 3 => 'Third Post'
+ ),
+ 'larry' => array(
+ 2 => 'Second Post'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new User();
+ $result = $TestModel->find('list', array(
+ 'fields' => array('User.user', 'User.password')
+ ));
+ $expected = array(
+ 'mariano' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'nate' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'larry' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'garrett' => '5f4dcc3b5aa765d61d8327deb882cf99'
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new ModifiedAuthor();
+ $result = $TestModel->find('list', array(
+ 'fields' => array('Author.id', 'Author.user')
+ ));
+ $expected = array(
+ 1 => 'mariano (CakePHP)',
+ 2 => 'nate (CakePHP)',
+ 3 => 'larry (CakePHP)',
+ 4 => 'garrett (CakePHP)'
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new Article();
+ $TestModel->displayField = 'title';
+ $result = $TestModel->find('list', array(
+ 'conditions' => array('User.user' => 'mariano'),
+ 'recursive' => 0
+ ));
+ $expected = array(
+ 1 => 'First Article',
+ 3 => 'Third Article'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFindField method
+ *
+ * @return void
+ */
+ public function testFindField() {
+ $this->loadFixtures('User');
+ $TestModel = new User();
+
+ $TestModel->id = 1;
+ $result = $TestModel->field('user');
+ $this->assertEquals('mariano', $result);
+
+ $result = $TestModel->field('User.user');
+ $this->assertEquals('mariano', $result);
+
+ $TestModel->id = false;
+ $result = $TestModel->field('user', array(
+ 'user' => 'mariano'
+ ));
+ $this->assertEquals('mariano', $result);
+
+ $result = $TestModel->field('COUNT(*) AS count', true);
+ $this->assertEquals(4, $result);
+
+ $result = $TestModel->field('COUNT(*)', true);
+ $this->assertEquals(4, $result);
+ }
+
+/**
+ * testFindUnique method
+ *
+ * @return void
+ */
+ public function testFindUnique() {
+ $this->loadFixtures('User');
+ $TestModel = new User();
+
+ $this->assertFalse($TestModel->isUnique(array(
+ 'user' => 'nate'
+ )));
+ $TestModel->id = 2;
+ $this->assertTrue($TestModel->isUnique(array(
+ 'user' => 'nate'
+ )));
+ $this->assertFalse($TestModel->isUnique(array(
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99'
+ )));
+ }
+
+/**
+ * test find('count') method
+ *
+ * @return void
+ */
+ public function testFindCount() {
+ $this->loadFixtures('User', 'Article', 'Comment', 'Tag', 'ArticlesTag');
+
+ $TestModel = new User();
+ $this->db->getLog(false, true);
+ $result = $TestModel->find('count');
+ $this->assertEquals(4, $result);
+
+ $this->db->getLog(false, true);
+ $fullDebug = $this->db->fullDebug;
+ $this->db->fullDebug = true;
+ $TestModel->order = 'User.id';
+ $result = $TestModel->find('count');
+ $this->db->fullDebug = $fullDebug;
+ $this->assertEquals(4, $result);
+
+ $log = $this->db->getLog();
+ $this->assertTrue(isset($log['log'][0]['query']));
+ $this->assertNotRegExp('/ORDER\s+BY/', $log['log'][0]['query']);
+
+ $Article = new Article();
+ $Article->recursive = -1;
+ $expected = count($Article->find('all', array(
+ 'fields' => array('Article.user_id'),
+ 'group' => 'Article.user_id')
+ ));
+ $result = $Article->find('count', array('group' => array('Article.user_id')));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that find('first') does not use the id set to the object.
+ *
+ * @return void
+ */
+ public function testFindFirstNoIdUsed() {
+ $this->loadFixtures('Project');
+
+ $Project = new Project();
+ $Project->id = 3;
+ $result = $Project->find('first');
+
+ $this->assertEquals('Project 1', $result['Project']['name'], 'Wrong record retrieved');
+ }
+
+/**
+ * test find with COUNT(DISTINCT field)
+ *
+ * @return void
+ */
+ public function testFindCountDistinct() {
+ $this->skipIf($this->db instanceof Sqlite, 'SELECT COUNT(DISTINCT field) is not compatible with SQLite.');
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $this->loadFixtures('Project');
+ $TestModel = new Project();
+ $TestModel->create(array('name' => 'project')) && $TestModel->save();
+ $TestModel->create(array('name' => 'project')) && $TestModel->save();
+ $TestModel->create(array('name' => 'project')) && $TestModel->save();
+
+ $result = $TestModel->find('count', array('fields' => 'DISTINCT name'));
+ $this->assertEquals(4, $result);
+ }
+
+/**
+ * Test find(count) with Db::expression
+ *
+ * @return void
+ */
+ public function testFindCountWithDbExpressions() {
+ $this->skipIf($this->db instanceof Postgres, 'testFindCountWithDbExpressions is not compatible with Postgres.');
+
+ $this->loadFixtures('Project', 'Thread');
+ $db = ConnectionManager::getDataSource('test');
+ $TestModel = new Project();
+
+ $result = $TestModel->find('count', array('conditions' => array(
+ $db->expression('Project.name = \'Project 3\'')
+ )));
+ $this->assertEquals(1, $result);
+
+ $result = $TestModel->find('count', array('conditions' => array(
+ 'Project.name' => $db->expression('\'Project 3\'')
+ )));
+ $this->assertEquals(1, $result);
+ }
+
+/**
+ * testFindMagic method
+ *
+ * @return void
+ */
+ public function testFindMagic() {
+ $this->loadFixtures('User');
+ $TestModel = new User();
+
+ $result = $TestModel->findByUser('mariano');
+ $expected = array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->findByPassword('5f4dcc3b5aa765d61d8327deb882cf99');
+ $expected = array('User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRead method
+ *
+ * @return void
+ */
+ public function testRead() {
+ $this->loadFixtures('User', 'Article');
+ $TestModel = new User();
+
+ $result = $TestModel->read();
+ $this->assertFalse($result);
+
+ $TestModel->id = 2;
+ $result = $TestModel->read();
+ $expected = array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->read(null, 2);
+ $expected = array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 2;
+ $result = $TestModel->read(array('id', 'user'));
+ $expected = array('User' => array('id' => '2', 'user' => 'nate'));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->read('id, user', 2);
+ $expected = array(
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->bindModel(array('hasMany' => array('Article')));
+ $this->assertTrue($result);
+
+ $TestModel->id = 1;
+ $result = $TestModel->read('id, user');
+ $expected = array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => '3',
+ 'user_id' => '1',
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRecursiveRead method
+ *
+ * @return void
+ */
+ public function testRecursiveRead() {
+ $this->loadFixtures(
+ 'User',
+ 'Article',
+ 'Comment',
+ 'Tag',
+ 'ArticlesTag',
+ 'Featured',
+ 'ArticleFeatured'
+ );
+ $TestModel = new User();
+
+ $result = $TestModel->bindModel(array('hasMany' => array('Article')), false);
+ $this->assertTrue($result);
+
+ $TestModel->recursive = 0;
+ $result = $TestModel->read('id, user', 1);
+ $expected = array(
+ 'User' => array('id' => '1', 'user' => 'mariano'),
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = 1;
+ $result = $TestModel->read('id, user', 1);
+ $expected = array(
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ array(
+ 'id' => '3',
+ 'user_id' => '1',
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = 2;
+ $result = $TestModel->read('id, user', 3);
+ $expected = array(
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry'
+ ),
+ 'Article' => array(
+ array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31',
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ )),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )))));
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testRecursiveFindAll() {
+ $this->loadFixtures(
+ 'User',
+ 'Article',
+ 'Comment',
+ 'Tag',
+ 'ArticlesTag',
+ 'Attachment',
+ 'ArticleFeatured',
+ 'ArticleFeaturedsTags',
+ 'Featured',
+ 'Category'
+ );
+ $TestModel = new Article();
+
+ $result = $TestModel->find('all', array('conditions' => array('Article.user_id' => 1)));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ),
+ array(
+ 'id' => '3',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:49:23',
+ 'updated' => '2007-03-18 10:51:31'
+ ),
+ array(
+ 'id' => '4',
+ 'article_id' => '1',
+ 'user_id' => '1',
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ))),
+ array(
+ 'Article' => array(
+ 'id' => '3',
+ 'user_id' => '1',
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->find('all', array(
+ 'conditions' => array('Article.user_id' => 3),
+ 'limit' => 1,
+ 'recursive' => 2
+ ));
+
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31',
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Attachment' => array(
+ 'id' => '1',
+ 'comment_id' => 5,
+ 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ )
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31',
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Attachment' => array()
+ )
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ ))));
+
+ $this->assertEquals($expected, $result);
+
+ $Featured = new Featured();
+
+ $Featured->recursive = 2;
+ $Featured->bindModel(array(
+ 'belongsTo' => array(
+ 'ArticleFeatured' => array(
+ 'conditions' => "ArticleFeatured.published = 'Y'",
+ 'fields' => 'id, title, user_id, published'
+ )
+ )
+ ));
+
+ $Featured->ArticleFeatured->unbindModel(array(
+ 'hasMany' => array('Attachment', 'Comment'),
+ 'hasAndBelongsToMany' => array('Tag'))
+ );
+
+ $orderBy = 'ArticleFeatured.id ASC';
+ $result = $Featured->find('all', array(
+ 'order' => $orderBy, 'limit' => 3
+ ));
+
+ $expected = array(
+ array(
+ 'Featured' => array(
+ 'id' => '1',
+ 'article_featured_id' => '1',
+ 'category_id' => '1',
+ 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'ArticleFeatured' => array(
+ 'id' => '1',
+ 'title' => 'First Article',
+ 'user_id' => '1',
+ 'published' => 'Y',
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Category' => array(),
+ 'Featured' => array(
+ 'id' => '1',
+ 'article_featured_id' => '1',
+ 'category_id' => '1',
+ 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ 'Category' => array(
+ 'id' => '1',
+ 'parent_id' => '0',
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ )),
+ array(
+ 'Featured' => array(
+ 'id' => '2',
+ 'article_featured_id' => '2',
+ 'category_id' => '1',
+ 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'ArticleFeatured' => array(
+ 'id' => '2',
+ 'title' => 'Second Article',
+ 'user_id' => '3',
+ 'published' => 'Y',
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Category' => array(),
+ 'Featured' => array(
+ 'id' => '2',
+ 'article_featured_id' => '2',
+ 'category_id' => '1',
+ 'published_date' => '2007-03-31 10:39:23',
+ 'end_date' => '2007-05-15 10:39:23',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ 'Category' => array(
+ 'id' => '1',
+ 'parent_id' => '0',
+ 'name' => 'Category 1',
+ 'created' => '2007-03-18 15:30:23',
+ 'updated' => '2007-03-18 15:32:31'
+ )));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRecursiveFindAllWithLimit method
+ *
+ * @return void
+ */
+ public function testRecursiveFindAllWithLimit() {
+ $this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag', 'Comment', 'Attachment');
+ $TestModel = new Article();
+
+ $TestModel->hasMany['Comment']['limit'] = 2;
+
+ $result = $TestModel->find('all', array(
+ 'conditions' => array('Article.user_id' => 1)
+ ));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:45:23',
+ 'updated' => '2007-03-18 10:47:31'
+ ),
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:47:23',
+ 'updated' => '2007-03-18 10:49:31'
+ ),
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ))),
+ array(
+ 'Article' => array(
+ 'id' => '3',
+ 'user_id' => '1',
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->hasMany['Comment']['limit'] = 1;
+
+ $result = $TestModel->find('all', array(
+ 'conditions' => array('Article.user_id' => 3),
+ 'limit' => 1,
+ 'recursive' => 2
+ ));
+ $expected = array(
+ array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31',
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Attachment' => array(
+ 'id' => '1',
+ 'comment_id' => 5,
+ 'attachment' => 'attachment.zip',
+ 'created' => '2007-03-18 10:51:23',
+ 'updated' => '2007-03-18 10:53:31'
+ )
+ )
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Testing availability of $this->findQueryType in Model callbacks
+ *
+ * @return void
+ */
+ public function testFindQueryTypeInCallbacks() {
+ $this->loadFixtures('Comment');
+ $Comment = new AgainModifiedComment();
+ $comments = $Comment->find('all');
+ $this->assertEquals('all', $comments[0]['Comment']['querytype']);
+ $comments = $Comment->find('first');
+ $this->assertEquals('first', $comments['Comment']['querytype']);
+ }
+
+/**
+ * testVirtualFields()
+ *
+ * Test correct fetching of virtual fields
+ * currently is not possible to do Relation.virtualField
+ *
+ * @return void
+ */
+ public function testVirtualFields() {
+ $this->loadFixtures('Post', 'Author');
+ $Post = ClassRegistry::init('Post');
+ $Post->virtualFields = array('two' => "1 + 1");
+ $result = $Post->find('first');
+ $this->assertEquals(2, $result['Post']['two']);
+
+ // SQL Server does not support operators in expressions
+ if (!($this->db instanceof Sqlserver)) {
+ $Post->Author->virtualFields = array('false' => '1 = 2');
+ $result = $Post->find('first');
+ $this->assertEquals(2, $result['Post']['two']);
+ $this->assertFalse((bool)$result['Author']['false']);
+ }
+
+ $result = $Post->find('first',array('fields' => array('author_id')));
+ $this->assertFalse(isset($result['Post']['two']));
+ $this->assertFalse(isset($result['Author']['false']));
+
+ $result = $Post->find('first',array('fields' => array('author_id', 'two')));
+ $this->assertEquals(2, $result['Post']['two']);
+ $this->assertFalse(isset($result['Author']['false']));
+
+ $result = $Post->find('first',array('fields' => array('two')));
+ $this->assertEquals(2, $result['Post']['two']);
+
+ $Post->id = 1;
+ $result = $Post->field('two');
+ $this->assertEquals(2, $result);
+
+ $result = $Post->find('first',array(
+ 'conditions' => array('two' => 2),
+ 'limit' => 1
+ ));
+ $this->assertEquals(2, $result['Post']['two']);
+
+ $result = $Post->find('first',array(
+ 'conditions' => array('two <' => 3),
+ 'limit' => 1
+ ));
+ $this->assertEquals(2, $result['Post']['two']);
+
+ $result = $Post->find('first',array(
+ 'conditions' => array('NOT' => array('two >' => 3)),
+ 'limit' => 1
+ ));
+ $this->assertEquals(2, $result['Post']['two']);
+
+ $dbo = $Post->getDataSource();
+ $Post->virtualFields = array('other_field' => 'Post.id + 1');
+ $result = $Post->find('first', array(
+ 'conditions' => array('other_field' => 3),
+ 'limit' => 1
+ ));
+ $this->assertEquals(2, $result['Post']['id']);
+
+ $Post->virtualFields = array('other_field' => 'Post.id + 1');
+ $result = $Post->find('all', array(
+ 'fields' => array($dbo->calculate($Post, 'max', array('other_field')))
+ ));
+ $this->assertEquals(4, $result[0][0]['other_field']);
+
+ ClassRegistry::flush();
+ $Writing = ClassRegistry::init(array('class' => 'Post', 'alias' => 'Writing'), 'Model');
+ $Writing->virtualFields = array('two' => "1 + 1");
+ $result = $Writing->find('first');
+ $this->assertEquals(2, $result['Writing']['two']);
+
+ $Post->create();
+ $Post->virtualFields = array('other_field' => 'COUNT(Post.id) + 1');
+ $result = $Post->field('other_field');
+ $this->assertEquals(4, $result);
+ }
+
+/**
+ * testVirtualFieldsOrder()
+ *
+ * Test correct order on virtual fields
+ *
+ * @return void
+ */
+ public function testVirtualFieldsOrder() {
+ $this->loadFixtures('Post', 'Author');
+ $Post = ClassRegistry::init('Post');
+ $Post->virtualFields = array('other_field' => '10 - Post.id');
+ $result = $Post->find('list', array('order' => array('Post.other_field' => 'ASC')));
+ $expected = array(
+ '3' => 'Third Post',
+ '2' => 'Second Post',
+ '1' => 'First Post'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $Post->find('list', array('order' => array('Post.other_field' => 'DESC')));
+ $expected = array(
+ '1' => 'First Post',
+ '2' => 'Second Post',
+ '3' => 'Third Post'
+ );
+ $this->assertEquals($expected, $result);
+
+ $Post->Author->virtualFields = array('joined' => 'Post.id * Author.id');
+ $result = $Post->find('all');
+ $result = Hash::extract($result, '{n}.Author.joined');
+ $expected = array(1, 6, 3);
+ $this->assertEquals($expected, $result);
+
+ $result = $Post->find('all', array('order' => array('Author.joined' => 'ASC')));
+ $result = Hash::extract($result, '{n}.Author.joined');
+ $expected = array(1, 3, 6);
+ $this->assertEquals($expected, $result);
+
+ $result = $Post->find('all', array('order' => array('Author.joined' => 'DESC')));
+ $result = Hash::extract($result, '{n}.Author.joined');
+ $expected = array(6, 3, 1);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testVirtualFieldsMysql()
+ *
+ * Test correct fetching of virtual fields
+ * currently is not possible to do Relation.virtualField
+ *
+ */
+ public function testVirtualFieldsMysql() {
+ $this->skipIf(!($this->db instanceof Mysql), 'The rest of virtualFields test only compatible with Mysql.');
+
+ $this->loadFixtures('Post', 'Author');
+ $Post = ClassRegistry::init('Post');
+
+ $Post->create();
+ $Post->virtualFields = array(
+ 'low_title' => 'lower(Post.title)',
+ 'unique_test_field' => 'COUNT(Post.id)'
+ );
+
+ $expectation = array(
+ 'Post' => array(
+ 'low_title' => 'first post',
+ 'unique_test_field' => 1
+ )
+ );
+
+ $result = $Post->find('first', array(
+ 'fields' => array_keys($Post->virtualFields),
+ 'group' => array('low_title')
+ ));
+
+ $this->assertEquals($expectation, $result);
+
+ $Author = ClassRegistry::init('Author');
+ $Author->virtualFields = array(
+ 'full_name' => 'CONCAT(Author.user, " ", Author.id)'
+ );
+
+ $result = $Author->find('first', array(
+ 'conditions' => array('Author.user' => 'mariano'),
+ 'fields' => array('Author.password', 'Author.full_name'),
+ 'recursive' => -1
+ ));
+ $this->assertTrue(isset($result['Author']['full_name']));
+
+ $result = $Author->find('first', array(
+ 'conditions' => array('Author.user' => 'mariano'),
+ 'fields' => array('Author.full_name', 'Author.password'),
+ 'recursive' => -1
+ ));
+ $this->assertTrue(isset($result['Author']['full_name']));
+ }
+
+/**
+ * test that virtual fields work when they don't contain functions.
+ *
+ * @return void
+ */
+ public function testVirtualFieldAsAString() {
+ $this->loadFixtures('Post', 'Author');
+ $Post = new Post();
+ $Post->virtualFields = array(
+ 'writer' => 'Author.user'
+ );
+ $result = $Post->find('first');
+ $this->assertTrue(isset($result['Post']['writer']), 'virtual field not fetched %s');
+ }
+
+/**
+ * test that isVirtualField will accept both aliased and non aliased fieldnames
+ *
+ * @return void
+ */
+ public function testIsVirtualField() {
+ $this->loadFixtures('Post');
+ $Post = ClassRegistry::init('Post');
+ $Post->virtualFields = array('other_field' => 'COUNT(Post.id) + 1');
+
+ $this->assertTrue($Post->isVirtualField('other_field'));
+ $this->assertTrue($Post->isVirtualField('Post.other_field'));
+ $this->assertFalse($Post->isVirtualField('Comment.other_field'), 'Other models should not match.');
+ $this->assertFalse($Post->isVirtualField('id'));
+ $this->assertFalse($Post->isVirtualField('Post.id'));
+ $this->assertFalse($Post->isVirtualField(array()));
+ }
+
+/**
+ * test that getting virtual fields works with and without model alias attached
+ *
+ * @return void
+ */
+ public function testGetVirtualField() {
+ $this->loadFixtures('Post');
+ $Post = ClassRegistry::init('Post');
+ $Post->virtualFields = array('other_field' => 'COUNT(Post.id) + 1');
+
+ $this->assertEquals($Post->getVirtualField('other_field'), $Post->virtualFields['other_field']);
+ $this->assertEquals($Post->getVirtualField('Post.other_field'), $Post->virtualFields['other_field']);
+ }
+
+/**
+ * test that checks for error when NOT condition passed in key and a 1 element array value
+ *
+ * @return void
+ */
+ public function testNotInArrayWithOneValue() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+ $Article->recursive = -1;
+
+ $result = $Article->find(
+ 'all',
+ array(
+ 'conditions' => array(
+ 'Article.id NOT' => array(1)
+ )
+ )
+ );
+ $this->assertTrue(is_array($result) && !empty($result));
+ }
+
+/**
+ * test custom find method
+ *
+ * @return void
+ */
+ public function testfindCustom() {
+ $this->loadFixtures('Article');
+ $Article = new CustomArticle();
+ $data = array('user_id' => 3, 'title' => 'Fourth Article', 'body' => 'Article Body, unpublished', 'published' => 'N');
+ $Article->create($data);
+ $Article->save(null, false);
+ $this->assertEquals(4, $Article->id);
+
+ $result = $Article->find('published');
+ $this->assertEquals(3, count($result));
+
+ $result = $Article->find('unPublished');
+ $this->assertEquals(1, count($result));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTest.php
new file mode 100644
index 0000000..e489d5b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * ModelTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * ModelTest class
+ *
+ * This test group will run model class tests
+ *
+ * @package Cake.Test.Case
+ */
+class ModelTest extends PHPUnit_Framework_TestSuite {
+
+/**
+ * suite method, defines tests for this suite.
+ *
+ * @return void
+ */
+ public static function suite() {
+ $suite = new PHPUnit_Framework_TestSuite('All Model related class tests');
+
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'Validator' . DS . 'CakeValidationSetTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'Validator' . DS . 'CakeValidationRuleTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'ModelReadTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'ModelWriteTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'ModelDeleteTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'ModelValidationTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'ModelIntegrationTest.php');
+ $suite->addTestFile(CORE_TEST_CASES . DS . 'Model' . DS . 'ModelCrossSchemaHabtmTest.php');
+ return $suite;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTestBase.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTestBase.php
new file mode 100644
index 0000000..371e27b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelTestBase.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * ModelTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+require_once dirname(__FILE__) . DS . 'models.php';
+
+/**
+ * ModelBaseTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+abstract class BaseModelTest extends CakeTestCase {
+
+/**
+ * autoFixtures property
+ *
+ * @var bool false
+ */
+ public $autoFixtures = false;
+
+/**
+ * Whether backup global state for each test method or not
+ *
+ * @var bool false
+ */
+ public $backupGlobals = false;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.category', 'core.category_thread', 'core.user', 'core.my_category', 'core.my_product',
+ 'core.my_user', 'core.my_categories_my_users', 'core.my_categories_my_products',
+ 'core.article', 'core.featured', 'core.article_featureds_tags', 'core.article_featured',
+ 'core.numeric_article', 'core.tag', 'core.articles_tag', 'core.comment',
+ 'core.attachment', 'core.apple', 'core.sample', 'core.another_article', 'core.item',
+ 'core.advertisement', 'core.home', 'core.post', 'core.author', 'core.bid', 'core.portfolio',
+ 'core.product', 'core.project', 'core.thread', 'core.message', 'core.items_portfolio',
+ 'core.syfile', 'core.image', 'core.device_type', 'core.device_type_category',
+ 'core.feature_set', 'core.exterior_type_category', 'core.document', 'core.device',
+ 'core.document_directory', 'core.primary_model', 'core.secondary_model', 'core.something',
+ 'core.something_else', 'core.join_thing', 'core.join_a', 'core.join_b', 'core.join_c',
+ 'core.join_a_b', 'core.join_a_c', 'core.uuid', 'core.data_test', 'core.posts_tag',
+ 'core.the_paper_monkies', 'core.person', 'core.underscore_field', 'core.node',
+ 'core.dependency', 'core.story', 'core.stories_tag', 'core.cd', 'core.book', 'core.basket',
+ 'core.overall_favorite', 'core.account', 'core.content', 'core.content_account',
+ 'core.film_file', 'core.test_plugin_article', 'core.test_plugin_comment', 'core.uuiditem',
+ 'core.counter_cache_user', 'core.counter_cache_post',
+ 'core.counter_cache_user_nonstandard_primary_key',
+ 'core.counter_cache_post_nonstandard_primary_key', 'core.uuidportfolio',
+ 'core.uuiditems_uuidportfolio', 'core.uuiditems_uuidportfolio_numericid', 'core.fruit',
+ 'core.fruits_uuid_tag', 'core.uuid_tag', 'core.product_update_all', 'core.group_update_all',
+ 'core.player', 'core.guild', 'core.guilds_player', 'core.armor', 'core.armors_player',
+ 'core.bidding', 'core.bidding_message', 'core.site', 'core.domain', 'core.domains_site',
+ );
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->debug = Configure::read('debug');
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('debug', $this->debug);
+ ClassRegistry::flush();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelValidationTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelValidationTest.php
new file mode 100644
index 0000000..713e578
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelValidationTest.php
@@ -0,0 +1,2201 @@
+<?php
+/**
+ * ModelValidationTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
+
+/**
+ * ModelValidationTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelValidationTest extends BaseModelTest {
+
+/**
+ * Tests validation parameter order in custom validation methods
+ *
+ * @return void
+ */
+ public function testValidationParams() {
+ $TestModel = new ValidationTest1();
+ $TestModel->validate['title'] = array(
+ 'rule' => 'customValidatorWithParams',
+ 'required' => true
+ );
+ $TestModel->create(array('title' => 'foo'));
+ $TestModel->invalidFields();
+
+ $expected = array(
+ 'data' => array(
+ 'title' => 'foo'
+ ),
+ 'validator' => array(
+ 'rule' => 'customValidatorWithParams',
+ 'on' => null,
+ 'last' => true,
+ 'allowEmpty' => false,
+ 'required' => true,
+ 'message' => null
+ ),
+ 'or' => true,
+ 'ignoreOnSame' => 'id'
+ );
+ $this->assertEquals($expected, $TestModel->validatorParams);
+
+ $TestModel->validate['title'] = array(
+ 'rule' => 'customValidatorWithMessage',
+ 'required' => true
+ );
+ $expected = array(
+ 'title' => array('This field will *never* validate! Muhahaha!')
+ );
+
+ $this->assertEquals($expected, $TestModel->invalidFields());
+
+ $TestModel->validate['title'] = array(
+ 'rule' => array('customValidatorWithSixParams', 'one', 'two', null, 'four'),
+ 'required' => true
+ );
+ $TestModel->create(array('title' => 'foo'));
+ $TestModel->invalidFields();
+ $expected = array(
+ 'data' => array(
+ 'title' => 'foo'
+ ),
+ 'one' => 'one',
+ 'two' => 'two',
+ 'three' => null,
+ 'four' => 'four',
+ 'five' => array(
+ 'rule' => array(1 => 'one', 2 => 'two', 3 => null, 4 => 'four'),
+ 'on' => null,
+ 'last' => true,
+ 'allowEmpty' => false,
+ 'required' => true,
+ 'message' => null
+ ),
+ 'six' => 6
+ );
+ $this->assertEquals($expected, $TestModel->validatorParams);
+
+ $TestModel->validate['title'] = array(
+ 'rule' => array('customValidatorWithSixParams', 'one', array('two'), null, 'four', array('five' => 5)),
+ 'required' => true
+ );
+ $TestModel->create(array('title' => 'foo'));
+ $TestModel->invalidFields();
+ $expected = array(
+ 'data' => array(
+ 'title' => 'foo'
+ ),
+ 'one' => 'one',
+ 'two' => array('two'),
+ 'three' => null,
+ 'four' => 'four',
+ 'five' => array('five' => 5),
+ 'six' => array(
+ 'rule' => array(1 => 'one', 2 => array('two'), 3 => null, 4 => 'four', 5 => array('five' => 5)),
+ 'on' => null,
+ 'last' => true,
+ 'allowEmpty' => false,
+ 'required' => true,
+ 'message' => null
+ )
+ );
+ $this->assertEquals($expected, $TestModel->validatorParams);
+ }
+
+/**
+ * Tests validation parameter fieldList in invalidFields
+ *
+ * @return void
+ */
+ public function testInvalidFieldsWithFieldListParams() {
+ $TestModel = new ValidationTest1();
+ $TestModel->validate = $validate = array(
+ 'title' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true
+ ),
+ 'name' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true
+ ));
+ $TestModel->set(array('title' => '$$', 'name' => '##'));
+ $TestModel->invalidFields(array('fieldList' => array('title')));
+ $expected = array(
+ 'title' => array('This field cannot be left blank')
+ );
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ $TestModel->validationErrors = array();
+
+ $TestModel->invalidFields(array('fieldList' => array('name')));
+ $expected = array(
+ 'name' => array('This field cannot be left blank')
+ );
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ $TestModel->validationErrors = array();
+
+ $TestModel->invalidFields(array('fieldList' => array('name', 'title')));
+ $expected = array(
+ 'name' => array('This field cannot be left blank'),
+ 'title' => array('This field cannot be left blank')
+ );
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ $TestModel->validationErrors = array();
+
+ $TestModel->whitelist = array('name');
+ $TestModel->invalidFields();
+ $expected = array('name' => array('This field cannot be left blank'));
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $this->assertEquals($TestModel->validate, $validate);
+ }
+
+/**
+ * Test that invalidFields() integrates well with save(). And that fieldList can be an empty type.
+ *
+ * @return void
+ */
+ public function testInvalidFieldsWhitelist() {
+ $TestModel = new ValidationTest1();
+ $TestModel->validate = array(
+ 'title' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true
+ ),
+ 'name' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true
+ ));
+
+ $TestModel->whitelist = array('name');
+ $TestModel->save(array('name' => '#$$#', 'title' => '$$$$'));
+
+ $expected = array('name' => array('This field cannot be left blank'));
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ }
+
+/**
+ * testValidates method
+ *
+ * @return void
+ */
+ public function testValidates() {
+ $TestModel = new TestValidate();
+
+ $TestModel->validate = array(
+ 'user_id' => 'numeric',
+ 'title' => array('allowEmpty' => false, 'rule' => 'notEmpty'),
+ 'body' => 'notEmpty'
+ );
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => '',
+ 'body' => 'body'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 'title',
+ 'body' => 'body'
+ ));
+ $result = $TestModel->create($data) && $TestModel->validates();
+ $this->assertTrue($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => '0',
+ 'body' => 'body'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $TestModel->validate['modified'] = array('allowEmpty' => true, 'rule' => 'date');
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'modified' => ''
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'modified' => '2007-05-01'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'modified' => 'invalid-date-here'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'modified' => 0
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'modified' => '0'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $TestModel->validate['modified'] = array('allowEmpty' => false, 'rule' => 'date');
+
+ $data = array('TestValidate' => array('modified' => null));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array('modified' => false));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array('modified' => ''));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'modified' => '2007-05-01'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $TestModel->validate['slug'] = array('allowEmpty' => false, 'rule' => array('maxLength', 45));
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'slug' => ''
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'slug' => 'slug-right-here'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $data = array('TestValidate' => array(
+ 'user_id' => '1',
+ 'title' => 0,
+ 'body' => 'body',
+ 'slug' => 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $TestModel->validate = array(
+ 'number' => array(
+ 'rule' => 'validateNumber',
+ 'min' => 3,
+ 'max' => 5
+ ),
+ 'title' => array(
+ 'allowEmpty' => false,
+ 'rule' => 'notEmpty'
+ ));
+
+ $data = array('TestValidate' => array(
+ 'title' => 'title',
+ 'number' => '0'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'title' => 'title',
+ 'number' => 0
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'title' => 'title',
+ 'number' => '3'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $data = array('TestValidate' => array(
+ 'title' => 'title',
+ 'number' => 3
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $TestModel->validate = array(
+ 'number' => array(
+ 'rule' => 'validateNumber',
+ 'min' => 5,
+ 'max' => 10
+ ),
+ 'title' => array(
+ 'allowEmpty' => false,
+ 'rule' => 'notEmpty'
+ ));
+
+ $data = array('TestValidate' => array(
+ 'title' => 'title',
+ 'number' => '3'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'title' => 'title',
+ 'number' => 3
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $TestModel->validate = array(
+ 'title' => array(
+ 'allowEmpty' => false,
+ 'rule' => 'validateTitle'
+ ));
+
+ $data = array('TestValidate' => array('title' => ''));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array('title' => 'new title'));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array('title' => 'title-new'));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $TestModel->validate = array('title' => array(
+ 'allowEmpty' => true,
+ 'rule' => 'validateTitle'
+ ));
+ $data = array('TestValidate' => array('title' => ''));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $TestModel->validate = array(
+ 'title' => array(
+ 'length' => array(
+ 'allowEmpty' => true,
+ 'rule' => array('maxLength', 10)
+ )));
+ $data = array('TestValidate' => array('title' => ''));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $TestModel->validate = array(
+ 'title' => array(
+ 'rule' => array('userDefined', 'Article', 'titleDuplicate')
+ ));
+ $data = array('TestValidate' => array('title' => 'My Article Title'));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+
+ $data = array('TestValidate' => array(
+ 'title' => 'My Article With a Different Title'
+ ));
+ $result = $TestModel->create($data);
+ $this->assertEquals($data, $result);
+ $result = $TestModel->validates();
+ $this->assertTrue($result);
+
+ $TestModel->validate = array(
+ 'title' => array(
+ 'tooShort' => array('rule' => array('minLength', 50)),
+ 'onlyLetters' => array('rule' => '/^[a-z]+$/i')
+ ),
+ );
+ $data = array('TestValidate' => array(
+ 'title' => 'I am a short string'
+ ));
+ $TestModel->create($data);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+ $result = $TestModel->validationErrors;
+ $expected = array(
+ 'title' => array('tooShort')
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->validate = array(
+ 'title' => array(
+ 'tooShort' => array(
+ 'rule' => array('minLength', 50),
+ 'last' => false
+ ),
+ 'onlyLetters' => array('rule' => '/^[a-z]+$/i')
+ ),
+ );
+ $data = array('TestValidate' => array(
+ 'title' => 'I am a short string'
+ ));
+ $TestModel->create($data);
+ $result = $TestModel->validates();
+ $this->assertFalse($result);
+ $result = $TestModel->validationErrors;
+ $expected = array(
+ 'title' => array('tooShort', 'onlyLetters')
+ );
+ $this->assertEquals($expected, $result);
+ $result = $TestModel->validationErrors;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that validates() checks all the 'with' associations as well for validation
+ * as this can cause partial/wrong data insertion.
+ *
+ * @return void
+ */
+ public function testValidatesWithAssociations() {
+ $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
+ $data = array(
+ 'Something' => array(
+ 'id' => 5,
+ 'title' => 'Extra Fields',
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ ),
+ 'SomethingElse' => array(
+ array('something_else_id' => 1, 'doomed' => '')
+ )
+ );
+
+ $Something = new Something();
+ $JoinThing = $Something->JoinThing;
+
+ $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
+
+ $expectedError = array('doomed' => array('This field cannot be left blank'));
+
+ $Something->create();
+ $result = $Something->save($data);
+ $this->assertFalse($result, 'Save occurred even when with models failed. %s');
+ $this->assertEquals($expectedError, $JoinThing->validationErrors);
+ $count = $Something->find('count', array('conditions' => array('Something.id' => $data['Something']['id'])));
+ $this->assertSame($count, 0);
+
+ $data = array(
+ 'Something' => array(
+ 'id' => 5,
+ 'title' => 'Extra Fields',
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ ),
+ 'SomethingElse' => array(
+ array('something_else_id' => 1, 'doomed' => 1),
+ array('something_else_id' => 1, 'doomed' => '')
+ )
+ );
+ $Something->create();
+ $result = $Something->save($data);
+ $this->assertFalse($result, 'Save occurred even when with models failed. %s');
+
+ $joinRecords = $JoinThing->find('count', array(
+ 'conditions' => array('JoinThing.something_id' => $data['Something']['id'])
+ ));
+ $this->assertEquals(0, $joinRecords, 'Records were saved on the join table. %s');
+ }
+
+/**
+ * test that saveAll and with models with validation interact well
+ *
+ * @return void
+ */
+ public function testValidatesWithModelsAndSaveAll() {
+ $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
+ $data = array(
+ 'Something' => array(
+ 'id' => 5,
+ 'title' => 'Extra Fields',
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ ),
+ 'SomethingElse' => array(
+ array('something_else_id' => 1, 'doomed' => '')
+ )
+ );
+ $Something = new Something();
+ $JoinThing = $Something->JoinThing;
+
+ $JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
+ $expectedError = array('doomed' => array('This field cannot be left blank'));
+
+ $Something->create();
+ $result = $Something->saveAll($data, array('validate' => 'only'));
+ $this->assertFalse($result);
+ $result = $Something->validateAssociated($data);
+ $this->assertFalse($result);
+ $this->assertEquals($expectedError, $JoinThing->validationErrors);
+ $result = $Something->validator()->validateAssociated($data);
+ $this->assertFalse($result);
+
+ $Something->create();
+ $result = $Something->saveAll($data, array('validate' => 'first'));
+ $this->assertFalse($result);
+ $this->assertEquals($expectedError, $JoinThing->validationErrors);
+
+ $count = $Something->find('count', array('conditions' => array('Something.id' => $data['Something']['id'])));
+ $this->assertSame($count, 0);
+
+ $joinRecords = $JoinThing->find('count', array(
+ 'conditions' => array('JoinThing.something_id' => $data['Something']['id'])
+ ));
+ $this->assertEquals(0, $joinRecords, 'Records were saved on the join table. %s');
+ }
+
+/**
+ * test that saveAll and with models at initial insert (no id has set yet)
+ * with validation interact well
+ *
+ * @return void
+ */
+ public function testValidatesWithModelsAndSaveAllWithoutId() {
+ $this->loadFixtures('Post', 'Author');
+
+ $data = array(
+ 'Author' => array(
+ 'name' => 'Foo Bar',
+ ),
+ 'Post' => array(
+ array('title' => 'Hello'),
+ array('title' => 'World'),
+ )
+ );
+ $Author = new Author();
+ $Post = $Author->Post;
+
+ $Post->validate = array('author_id' => array('rule' => 'numeric'));
+
+ $Author->create();
+ $result = $Author->saveAll($data, array('validate' => 'only'));
+ $this->assertTrue($result);
+ $result = $Author->validateAssociated($data);
+ $this->assertTrue($result);
+ $this->assertTrue($result);
+
+ $Author->create();
+ $result = $Author->saveAll($data, array('validate' => 'first'));
+ $this->assertTrue($result);
+ $this->assertFalse(is_null($Author->id));
+
+ $id = $Author->id;
+ $count = $Author->find('count', array('conditions' => array('Author.id' => $id)));
+ $this->assertSame($count, 1);
+
+ $count = $Post->find('count', array(
+ 'conditions' => array('Post.author_id' => $id)
+ ));
+ $this->assertEquals($count, count($data['Post']));
+ }
+
+/**
+ * Test that missing validation methods trigger errors in development mode.
+ * Helps to make development easier.
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testMissingValidationErrorTriggering() {
+ Configure::write('debug', 2);
+
+ $TestModel = new ValidationTest1();
+ $TestModel->create(array('title' => 'foo'));
+ $TestModel->validate = array(
+ 'title' => array(
+ 'rule' => array('thisOneBringsThePain'),
+ 'required' => true
+ )
+ );
+ $TestModel->invalidFields(array('fieldList' => array('title')));
+ }
+
+/**
+ * Test that missing validation methods does not trigger errors in production mode.
+ *
+ * @return void
+ */
+ public function testMissingValidationErrorNoTriggering() {
+ Configure::write('debug', 0);
+ $TestModel = new ValidationTest1();
+ $TestModel->create(array('title' => 'foo'));
+ $TestModel->validate = array(
+ 'title' => array(
+ 'rule' => array('thisOneBringsThePain'),
+ 'required' => true
+ )
+ );
+ $TestModel->invalidFields(array('fieldList' => array('title')));
+ $this->assertEquals(array(), $TestModel->validationErrors);
+ }
+
+/**
+ * Test placeholder replacement when validation message is an array
+ *
+ * @return void
+ */
+ public function testValidationMessageAsArray() {
+ $TestModel = new ValidationTest1();
+ $TestModel->validate = array(
+ 'title' => array(
+ 'minLength' => array(
+ 'rule' => array('minLength', 6),
+ 'required' => true,
+ 'message' => 'Minimum length allowed is %d chars',
+ 'last' => false
+ ),
+ 'between' => array(
+ 'rule' => array('between', 5, 15),
+ 'message' => array('You may enter up to %s chars (minimum is %s chars)', 14, 6)
+ )
+ )
+ );
+
+ $TestModel->create();
+ $expected = array(
+ 'title' => array(
+ 'Minimum length allowed is 6 chars',
+ )
+ );
+ $TestModel->invalidFields();
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $TestModel->create(array('title' => 'foo'));
+ $expected = array(
+ 'title' => array(
+ 'Minimum length allowed is 6 chars',
+ 'You may enter up to 14 chars (minimum is 6 chars)'
+ )
+ );
+ $TestModel->invalidFields();
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ }
+
+/**
+ * Test validation message translation
+ *
+ * @return void
+ */
+ public function testValidationMessageTranslation() {
+ $lang = Configure::read('Config.language');
+ Configure::write('Config.language', 'en');
+ App::build(array(
+ 'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS),
+ ), App::RESET);
+
+ $TestModel = new ValidationTest1();
+ $TestModel->validationDomain = 'validation_messages';
+ $TestModel->validate = array(
+ 'title' => array(
+ array(
+ 'rule' => array('customValidationMethod', 'arg1'),
+ 'required' => true,
+ 'message' => 'Validation failed: %s'
+ )
+ )
+ );
+
+ $TestModel->create();
+ $expected = array(
+ 'title' => array(
+ 'Translated validation failed: Translated arg1',
+ )
+ );
+ $TestModel->invalidFields();
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $TestModel->validationDomain = 'default';
+ Configure::write('Config.language', $lang);
+ App::build();
+ }
+
+/**
+ * Test for 'on' => [create|update] in validation rules.
+ *
+ * @return void
+ */
+ public function testStateValidation() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+
+ $data = array(
+ 'Article' => array(
+ 'title' => '',
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ )
+ );
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'on' => 'create'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertFalse($Article->validates());
+
+ $Article->save(null, array('validate' => false));
+ $data['Article']['id'] = $Article->id;
+ $Article->set($data);
+ $this->assertTrue($Article->validates());
+
+ unset($data['Article']['id']);
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'on' => 'update'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->save(null, array('validate' => false));
+ $data['Article']['id'] = $Article->id;
+ $Article->set($data);
+ $this->assertFalse($Article->validates());
+ }
+
+/**
+ * Test for 'required' => [create|update] in validation rules.
+ *
+ * @return void
+ */
+ public function testStateRequiredValidation() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+
+ // no title field present
+ $data = array(
+ 'Article' => array(
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ )
+ );
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'create'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertFalse($Article->validates());
+
+ $Article->save(null, array('validate' => false));
+ $data['Article']['id'] = $Article->id;
+ $Article->set($data);
+ $this->assertTrue($Article->validates());
+
+ unset($data['Article']['id']);
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'update'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->save(null, array('validate' => false));
+ $data['Article']['id'] = $Article->id;
+ $Article->set($data);
+ $this->assertFalse($Article->validates());
+ }
+
+/**
+ * Test that 'required' and 'on' are not conflicting
+ *
+ * @return void
+ */
+ public function testOnRequiredConflictValidation() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+
+ // no title field present
+ $data = array(
+ 'Article' => array(
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ )
+ );
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'create',
+ 'on' => 'create'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertFalse($Article->validates());
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'update',
+ 'on' => 'create'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'create',
+ 'on' => 'update'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'update',
+ 'on' => 'update'
+ )
+ )
+ );
+
+ $Article->create($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'create',
+ 'on' => 'create'
+ )
+ )
+ );
+
+ $Article->save(null, array('validate' => false));
+ $data['Article']['id'] = $Article->id;
+ $Article->set($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'update',
+ 'on' => 'create'
+ )
+ )
+ );
+
+ $Article->set($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'create',
+ 'on' => 'update'
+ )
+ )
+ );
+
+ $Article->set($data);
+ $this->assertTrue($Article->validates());
+
+ $Article->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => 'update',
+ 'on' => 'update'
+ )
+ )
+ );
+
+ $Article->set($data);
+ $this->assertFalse($Article->validates());
+ }
+
+/**
+ * testSaveAllDeepValidateOnly
+ * tests the validate methods with deeper recursive data
+ *
+ * @return void
+ */
+ public function testSaveAllDeepValidateOnly() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
+ $TestModel->Comment->validate['comment'] = 'notEmpty';
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertTrue($result);
+ $result = $TestModel->validateAssociated($data, array('deep' => true));
+ $this->assertTrue($result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+ $result = $TestModel->validateAssociated($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ false,
+ true
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertTrue($result);
+ $result = $TestModel->validateAssociated($data, array('deep' => true));
+ $this->assertTrue($result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+ $result = $TestModel->validateAssociated($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsave'))
+ )
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ false
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Comment' => array(
+ 1 => array(
+ 'Attachment' => array(
+ 'attachment' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 5,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => 'deepsave',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertTrue($result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
+ $this->assertTrue($result);
+
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => true
+ );
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 5,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => '',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'Comment' => array(
+ 'Article' => array(
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => false
+ );
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+
+ $data['Comment']['Article']['body'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'Comment' => array(
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => false
+ );
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+
+ $data['Comment']['comment'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'Comment' => array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => false
+ );
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+
+ $data['Attachment']['attachment'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'attachment' => array('This field cannot be left blank'),
+ 'Comment' => array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->validationErrors;
+ $expected = array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Attachment' => false,
+ 'Comment' => false
+ );
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllNotDeepValidateOnly
+ * tests the validate methods to not validate deeper recursive data
+ *
+ * @return void
+ */
+ public function testSaveAllNotDeepValidateOnly() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
+ $TestModel->Comment->validate['comment'] = 'notEmpty';
+
+ $data = array(
+ 'Article' => array('id' => 2, 'body' => ''),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
+ $this->assertFalse($result);
+ $result = $TestModel->validateAssociated($data, array('deep' => false));
+ $this->assertFalse($result);
+
+ $expected = array('body' => array('This field cannot be left blank'));
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
+ $this->assertTrue($result);
+ $result = $TestModel->validateAssociated($data, array('deep' => false));
+ $this->assertTrue($result);
+
+ $data = array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'deep' => false));
+ $this->assertTrue($result);
+ $result = $TestModel->validateAssociated($data, array('deep' => false));
+ $this->assertTrue($result);
+
+ $data = array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->validateAssociated($data, array('atomic' => false, 'deep' => false));
+ $this->assertSame($expected, $result);
+
+ $expected = array();
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 5,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert ignored',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => '',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
+ $this->assertTrue($result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array();
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => true
+ );
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
+ $this->assertEquals($expected, $result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
+ $this->assertEquals($expected, $result);
+
+ $data['Comment']['Article']['body'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
+ $this->assertTrue($result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('deep' => false));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array();
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => true
+ );
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
+ $this->assertEquals($expected, $result);
+ $result = $TestModel->Comment->Attachment->validateAssociated($data, array('atomic' => false, 'deep' => false));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testValidateAssociated method
+ *
+ * @return void
+ */
+ public function testValidateAssociated() {
+ $this->loadFixtures('Comment', 'Attachment');
+ $TestModel = new Comment();
+ $TestModel->Attachment->validate = array('attachment' => 'notEmpty');
+
+ $data = array(
+ 'Comment' => array(
+ 'comment' => 'This is the comment'
+ ),
+ 'Attachment' => array(
+ 'attachment' => ''
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only'));
+ $this->assertFalse($result);
+ $result = $TestModel->validateAssociated($data);
+ $this->assertFalse($result);
+
+ $TestModel->validate = array('comment' => 'notEmpty');
+ $record = array(
+ 'Comment' => array(
+ 'user_id' => 1,
+ 'article_id' => 1,
+ 'comment' => '',
+ ),
+ 'Attachment' => array(
+ 'attachment' => ''
+ )
+ );
+ $result = $TestModel->saveAll($record, array('validate' => 'only'));
+ $this->assertFalse($result);
+ $result = $TestModel->validateAssociated($record);
+ $this->assertFalse($result);
+
+ $fieldList = array(
+ 'Comment' => array('id', 'article_id', 'user_id'),
+ 'Attachment' => array('comment_id')
+ );
+ $result = $TestModel->saveAll($record, array(
+ 'fieldList' => $fieldList, 'validate' => 'only'
+ ));
+ $this->assertTrue($result);
+ $this->assertEmpty($TestModel->validationErrors);
+ $result = $TestModel->validateAssociated($record, array('fieldList' => $fieldList));
+ $this->assertTrue($result);
+ $this->assertEmpty($TestModel->validationErrors);
+
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->validate = array('comment' => 'notEmpty');
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1,
+ ),
+ array(
+ 'id' => 2,
+ 'comment' =>
+ 'comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ),
+ array(
+ 'id' => 3,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1
+ )));
+ $result = $TestModel->saveAll($data, array('validate' => 'only'));
+ $this->assertFalse($result);
+ $result = $TestModel->validateAssociated($data);
+ $this->assertFalse($result);
+
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(false, true, false)
+ );
+ $result = $TestModel->saveAll($data, array('atomic' => false, 'validate' => 'only'));
+ $this->assertSame($expected, $result);
+ $result = $TestModel->validateAssociated($data, array('atomic' => false));
+ $this->assertSame($expected, $result);
+
+ $expected = array('Comment' => array(
+ 0 => array('comment' => array('This field cannot be left blank')),
+ 2 => array('comment' => array('This field cannot be left blank'))
+ ));
+ $this->assertEquals($expected['Comment'], $TestModel->Comment->validationErrors);
+
+ $model = new Comment();
+ $model->deleteAll(true);
+ $model->validate = array('comment' => 'notEmpty');
+ $model->Attachment->validate = array('attachment' => 'notEmpty');
+ $model->Attachment->bindModel(array('belongsTo' => array('Comment')));
+ $expected = array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Attachment' => array(
+ 'attachment' => array('This field cannot be left blank')
+ )
+ );
+
+ $data = array(
+ 'Comment' => array('comment' => '', 'article_id' => 1, 'user_id' => 1),
+ 'Attachment' => array('attachment' => '')
+ );
+ $result = $model->saveAll($data, array('validate' => 'only'));
+ $this->assertFalse($result);
+ $result = $model->validateAssociated($data);
+ $this->assertFalse($result);
+ $this->assertEquals($expected, $model->validationErrors);
+ $this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
+ }
+
+/**
+ * testValidateMany method
+ *
+ * @return void
+ */
+ public function testValidateMany() {
+ $TestModel = new Article();
+ $TestModel->validate = array('title' => 'notEmpty');
+ $data = array(
+ 0 => array('title' => ''),
+ 1 => array('title' => 'title 1'),
+ 2 => array('title' => 'title 2'),
+ );
+ $expected = array(
+ 0 => array('title' => array('This field cannot be left blank')),
+ );
+
+ $result = $TestModel->saveAll($data, array('validate' => 'only'));
+ $this->assertFalse($result);
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ $result = $TestModel->validateMany($data);
+ $this->assertFalse($result);
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $data = array(
+ 0 => array('title' => 'title 0'),
+ 1 => array('title' => ''),
+ 2 => array('title' => 'title 2'),
+ );
+ $expected = array(
+ 1 => array('title' => array('This field cannot be left blank')),
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'only'));
+ $this->assertFalse($result);
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ $result = $TestModel->validateMany($data);
+ $this->assertFalse($result);
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ }
+
+/**
+ * testGetMethods method
+ *
+ * @return void
+ */
+ public function testGetMethods() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $result = $Validator->getMethods();
+
+ $expected = array_map('strtolower', get_class_methods('Article'));
+ $this->assertEquals($expected, array_keys($result));
+ }
+
+/**
+ * testSetValidationDomain method
+ *
+ * @return void
+ */
+ public function testSetValidationDomain() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $result = $Validator->setValidationDomain('default');
+ $this->assertEquals('default', $TestModel->validationDomain);
+
+ $result = $Validator->setValidationDomain('other');
+ $this->assertEquals('other', $TestModel->validationDomain);
+ }
+
+/**
+ * testGetModel method
+ *
+ * @return void
+ */
+ public function testGetModel() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $result = $Validator->getModel();
+ $this->assertInstanceOf('Article', $result);
+ }
+
+/**
+ * Tests it is possible to get validation sets for a field using an array inteface
+ *
+ * @return void
+ */
+ public function testArrayAccessGet() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $titleValidator = $Validator['title'];
+ $this->assertEquals('title', $titleValidator->field);
+ $this->assertCount(1, $titleValidator->getRules());
+ $rule = current($titleValidator->getRules());
+ $this->assertEquals('notEmpty', $rule->rule);
+
+ $titleValidator = $Validator['body'];
+ $this->assertEquals('body', $titleValidator->field);
+ $this->assertCount(1, $titleValidator->getRules());
+ $rule = current($titleValidator->getRules());
+ $this->assertEquals('notEmpty', $rule->rule);
+
+ $titleValidator = $Validator['user_id'];
+ $this->assertEquals('user_id', $titleValidator->field);
+ $this->assertCount(1, $titleValidator->getRules());
+ $rule = current($titleValidator->getRules());
+ $this->assertEquals('numeric', $rule->rule);
+ }
+
+/**
+ * Tests it is possible to check for validation sets for a field using an array inteface
+ *
+ * @return void
+ */
+ public function testArrayAccessExists() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $this->assertTrue(isset($Validator['title']));
+ $this->assertTrue(isset($Validator['body']));
+ $this->assertTrue(isset($Validator['user_id']));
+ $this->assertFalse(isset($Validator['other']));
+ }
+
+/**
+ * Tests it is possible to set validation rules for a field using an array inteface
+ *
+ * @return void
+ */
+ public function testArrayAccessSet() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $set = array(
+ 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
+ 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
+ );
+ $Validator['other'] = $set;
+ $rules = $Validator['other'];
+ $this->assertEquals('other', $rules->field);
+
+ $validators = $rules->getRules();
+ $this->assertCount(2, $validators);
+ $this->assertEquals('numeric', $validators['numeric']->rule);
+ $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
+
+ $Validator['new'] = new CakeValidationSet('new', $set, array());
+ $rules = $Validator['new'];
+ $this->assertEquals('new', $rules->field);
+
+ $validators = $rules->getRules();
+ $this->assertCount(2, $validators);
+ $this->assertEquals('numeric', $validators['numeric']->rule);
+ $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
+ }
+
+/**
+ * Tests it is possible to unset validation rules
+ *
+ * @return void
+ */
+ public function testArrayAccessUset() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $this->assertTrue(isset($Validator['title']));
+ unset($Validator['title']);
+ $this->assertFalse(isset($Validator['title']));
+ }
+
+/**
+ * Tests it is possible to iterate a validation object
+ *
+ * @return void
+ */
+ public function testIterator() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $i = 0;
+ foreach ($Validator as $field => $rules) {
+ if ($i === 0) {
+ $this->assertEquals('user_id', $field);
+ }
+ if ($i === 1) {
+ $this->assertEquals('title', $field);
+ }
+ if ($i === 2) {
+ $this->assertEquals('body', $field);
+ }
+ $this->assertInstanceOf('CakeValidationSet', $rules);
+ $i++;
+ }
+ $this->assertEquals(3, $i);
+ }
+
+/**
+ * Tests countable interface in ModelValidator
+ *
+ * @return void
+ */
+ public function testCount() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+ $this->assertCount(3, $Validator);
+
+ $set = array(
+ 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
+ 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
+ );
+ $Validator['other'] = $set;
+ $this->assertCount(4, $Validator);
+
+ unset($Validator['title']);
+ $this->assertCount(3, $Validator);
+ unset($Validator['body']);
+ $this->assertCount(2, $Validator);
+ }
+
+/**
+ * Tests it is possible to add validation rules
+ *
+ * @return void
+ */
+ public function testAddRule() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
+ $Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
+ $rules = $Validator['other'];
+ $this->assertEquals('other', $rules->field);
+
+ $validators = $rules->getRules();
+ $this->assertCount(2, $validators);
+ $this->assertEquals('numeric', $validators['numeric']->rule);
+ $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
+ }
+
+/**
+ * Tests it is possible to remove validation rules
+ *
+ * @return void
+ */
+ public function testRemoveRule() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $this->assertTrue(isset($Validator['title']));
+ $Validator->remove('title');
+ $this->assertFalse(isset($Validator['title']));
+
+ $Validator->add('other', 'numeric', array('rule' => 'numeric', 'allowEmpty' => false));
+ $Validator->add('other', 'range', array('rule' => array('between', 1, 5), 'allowEmpty' => false));
+ $this->assertTrue(isset($Validator['other']));
+
+ $Validator->remove('other', 'numeric');
+ $this->assertTrue(isset($Validator['other']));
+ $this->assertFalse(isset($Validator['other']['numeric']));
+ $this->assertTrue(isset($Validator['other']['range']));
+ }
+
+/**
+ * Tests validation callbacks are triggered
+ *
+ * @return void
+ */
+ public function testValidateCallbacks() {
+ $TestModel = $this->getMock('Article', array('beforeValidate', 'afterValidate'));
+ $TestModel->expects($this->once())->method('beforeValidate');
+ $TestModel->expects($this->once())->method('afterValidate');
+
+ $TestModel->set(array('title' => '', 'body' => 'body'));
+ $TestModel->validates();
+ }
+
+/**
+ * Tests that altering data in a beforeValidate callback will lead to saving those
+ * values in database
+ *
+ * @return void
+ */
+ public function testValidateFirstWithBeforeValidate() {
+ $this->loadFixtures('Article', 'User');
+ $model = new CustomArticle();
+ $model->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => true,
+ 'allowEmpty' => false
+ )
+ )
+ );
+ $data = array(
+ 'CustomArticle' => array(
+ 'body' => 'foo0'
+ )
+ );
+ $result = $model->saveAll($data, array('validate' => 'first'));
+ $this->assertTrue($result);
+
+ $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
+
+ $model->findMethods['unPublished'] = true;
+ $data = array(
+ 'CustomArticle' => array(
+ 'body' => 'foo1'
+ )
+ );
+ $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
+ $this->assertTrue($result);
+ $title = $model->field('title', array('body' => 'foo1'));
+ $this->assertEquals('foo', $title);
+ $this->assertFalse($model->findMethods['unPublished'], 'beforeValidate was run twice');
+
+ $data = array(
+ array('body' => 'foo2'),
+ array('body' => 'foo3'),
+ array('body' => 'foo4')
+ );
+
+ $result = $model->saveAll($data, array('validate' => 'first', 'deep' => true));
+ $this->assertTrue($result);
+
+ $this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
+ $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
+ $this->assertEquals('foo', $model->field('title', array('body' => 'foo4')));
+ }
+
+/**
+ * Tests that altering data in a beforeValidate callback will lead to saving those
+ * values in database
+ *
+ * @return void
+ */
+ public function testValidateFirstAssociatedWithBeforeValidate() {
+ $this->loadFixtures('Article', 'User');
+ $model = new CustomArticle();
+ $model->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => true
+ )
+ )
+ );
+ $articles = array(
+ array('body' => 'foo1'),
+ array('body' => 'foo2'),
+ array('body' => 'foo3')
+ );
+ $user = new User();
+ $user->bindModel(array('hasMany' => array('CustomArticle')));
+ $data = array(
+ 'User' => array('user' => 'foo', 'password' => 'bar'),
+ 'CustomArticle' => $articles
+ );
+ $result = $user->saveAll($data, array('validate' => 'first'));
+ $this->assertTrue($result);
+
+ $this->assertEquals('foo', $model->field('title', array('body' => 'foo1')));
+ $this->assertEquals('foo', $model->field('title', array('body' => 'foo2')));
+ $this->assertEquals('foo', $model->field('title', array('body' => 'foo3')));
+ }
+
+/**
+ * testValidateFirstWithDefaults method
+ *
+ * return @void
+ */
+ public function testFirstWithDefaults() {
+ $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
+ $TestModel = new Article();
+
+ $result = $TestModel->find('first', array(
+ 'conditions' => array('Article.id' => 1)
+ ));
+ $expected = array(
+ 'Article' => array(
+ 'id' => 1,
+ 'user_id' => 1,
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23'
+ ),
+ );
+ unset($result['Article']['updated']);
+ $this->assertEquals($expected['Article'], $result['Article']);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => 1,
+ 'title' => 'First Article (modified)'
+ ),
+ 'Comment' => array(
+ array('comment' => 'Article comment', 'user_id' => 1)
+ )
+ );
+ $result = $TestModel->saveAll($data, array('validate' => 'first'));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('first', array(
+ 'conditions' => array('Article.id' => 1)
+ ));
+ $expected['Article']['title'] = 'First Article (modified)';
+ unset($result['Article']['updated']);
+ $this->assertEquals($expected['Article'], $result['Article']);
+ }
+
+ public function testAddMultipleRules() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $set = array(
+ 'numeric' => array('rule' => 'numeric', 'allowEmpty' => false),
+ 'range' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
+ );
+
+ $Validator->add('other', $set);
+ $rules = $Validator['other'];
+ $this->assertEquals('other', $rules->field);
+
+ $validators = $rules->getRules();
+ $this->assertCount(2, $validators);
+ $this->assertEquals('numeric', $validators['numeric']->rule);
+ $this->assertEquals(array('between', 1, 5), $validators['range']->rule);
+
+ $set = new CakeValidationSet('other', array(
+ 'a' => array('rule' => 'numeric', 'allowEmpty' => false),
+ 'b' => array('rule' => array('between', 1, 5), 'allowEmpty' => false),
+ ));
+
+ $Validator->add('other', $set);
+ $this->assertSame($set, $Validator->getField('other'));
+ }
+
+/**
+ * Test that rules are parsed correctly when calling getField()
+ *
+ * @return void
+ */
+ public function testValidator() {
+ $TestModel = new Article();
+ $Validator = $TestModel->validator();
+
+ $result = $Validator->getField();
+ $expected = array('user_id', 'title', 'body');
+ $this->assertEquals($expected, array_keys($result));
+ $this->assertTrue($result['user_id'] instanceof CakeValidationSet);
+
+ $result = $TestModel->validator()->getField('title');
+ $this->assertTrue($result instanceof CakeValidationSet);
+ }
+
+/**
+ * Tests that altering data in a beforeValidate callback will lead to saving those
+ * values in database, this time with belongsTo associations
+ *
+ * @return void
+ */
+ public function testValidateFirstAssociatedWithBeforeValidate2() {
+ $this->loadFixtures('Article', 'User');
+ $model = new CustomArticle();
+ $model->validate = array(
+ 'title' => array(
+ 'notempty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => true
+ )
+ )
+ );
+
+ $data = array(
+ 'User' => array('user' => 'foo', 'password' => 'bar'),
+ 'CustomArticle' => array(
+ 'body' => 'a test'
+ )
+ );
+ $result = $model->saveAll($data, array('validate' => 'first'));
+ $this->assertTrue($result);
+
+ $this->assertEquals('foo', $model->field('title', array('body' => 'a test')));
+ }
+
+/**
+ * Testing you can dynamically add rules to a field, added this to dispel doubts
+ * after a presentation made to show off this new feature
+ *
+ * @return void
+ **/
+ public function testDynamicValidationRuleBuilding() {
+ $model = new Article;
+ $validator = $model->validator();
+ $validator->add('body', 'isSpecial', array('rule' => 'special'));
+ $rules = $validator['body']->getRules();
+ $this->assertCount(2, $rules);
+ $this->assertEquals('special', $rules['isSpecial']->rule);
+ $validator['body']->setRule('isAwesome', array('rule' => 'awesome'));
+ $rules = $validator['body']->getRules();
+ $this->assertCount(3, $rules);
+ $this->assertEquals('awesome', $rules['isAwesome']->rule);
+ }
+
+/**
+ * Test to ensure custom validation methods work with CakeValidationSet
+ *
+ * @return void
+ */
+ public function testCustomMethodsWithCakeValidationSet() {
+ $TestModel = new TestValidate();
+ $Validator = $TestModel->validator();
+
+ $Validator->add('title', 'validateTitle', array(
+ 'rule' => 'validateTitle',
+ 'message' => 'That aint right',
+ ));
+ $data = array('title' => 'notatitle');
+ $result = $Validator->getField('title')->validate($data);
+ $expected = array(0 => 'That aint right');
+ $this->assertEquals($expected, $result);
+
+ $data = array('title' => 'title-is-good');
+ $result = $Validator->getField('title')->validate($data);
+ $expected = array();
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testCustomMethodWithEmptyValue() {
+ $this->loadFixtures('Article');
+
+ $model = $this->getMock('Article', array('isLegit'));
+ $model->validate = array(
+ 'title' => array(
+ 'custom' => array(
+ 'rule' => array('isLegit'),
+ 'message' => 'is no good'
+ )
+ )
+ );
+ $model->expects($this->once())
+ ->method('isLegit')
+ ->will($this->returnValue(false));
+
+ $model->set(array('title' => ''));
+ $this->assertFalse($model->validates());
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelWriteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelWriteTest.php
new file mode 100644
index 0000000..fe8714e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/ModelWriteTest.php
@@ -0,0 +1,6877 @@
+<?php
+/**
+ * ModelWriteTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require_once dirname(__FILE__) . DS . 'ModelTestBase.php';
+/**
+ * ModelWriteTest
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelWriteTest extends BaseModelTest {
+
+/**
+ * testInsertAnotherHabtmRecordWithSameForeignKey method
+ *
+ * @access public
+ * @return void
+ */
+ public function testInsertAnotherHabtmRecordWithSameForeignKey() {
+ $this->loadFixtures('JoinA', 'JoinB', 'JoinAB', 'JoinC', 'JoinAC');
+ $TestModel = new JoinA();
+
+ $result = $TestModel->JoinAsJoinB->findById(1);
+ $expected = array(
+ 'JoinAsJoinB' => array(
+ 'id' => 1,
+ 'join_a_id' => 1,
+ 'join_b_id' => 2,
+ 'other' => 'Data for Join A 1 Join B 2',
+ 'created' => '2008-01-03 10:56:33',
+ 'updated' => '2008-01-03 10:56:33'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->JoinAsJoinB->create();
+ $data = array(
+ 'join_a_id' => 1,
+ 'join_b_id' => 1,
+ 'other' => 'Data for Join A 1 Join B 1',
+ 'created' => '2008-01-03 10:56:44',
+ 'updated' => '2008-01-03 10:56:44'
+ );
+ $result = $TestModel->JoinAsJoinB->save($data);
+ $lastInsertId = $TestModel->JoinAsJoinB->getLastInsertID();
+ $data['id'] = $lastInsertId;
+ $this->assertEquals(array('JoinAsJoinB' => $data), $result);
+ $this->assertTrue($lastInsertId != null);
+
+ $result = $TestModel->JoinAsJoinB->findById(1);
+ $expected = array(
+ 'JoinAsJoinB' => array(
+ 'id' => 1,
+ 'join_a_id' => 1,
+ 'join_b_id' => 2,
+ 'other' => 'Data for Join A 1 Join B 2',
+ 'created' => '2008-01-03 10:56:33',
+ 'updated' => '2008-01-03 10:56:33'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $updatedValue = 'UPDATED Data for Join A 1 Join B 2';
+ $TestModel->JoinAsJoinB->id = 1;
+ $result = $TestModel->JoinAsJoinB->saveField('other', $updatedValue, false);
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->JoinAsJoinB->findById(1);
+ $this->assertEquals($updatedValue, $result['JoinAsJoinB']['other']);
+ }
+
+/**
+ * testSaveDateAsFirstEntry method
+ *
+ * @return void
+ */
+ public function testSaveDateAsFirstEntry() {
+ $this->loadFixtures('Article', 'User', 'Comment', 'Attachment', 'Tag', 'ArticlesTag');
+
+ $Article = new Article();
+
+ $data = array(
+ 'Article' => array(
+ 'created' => array(
+ 'day' => '1',
+ 'month' => '1',
+ 'year' => '2008'
+ ),
+ 'title' => 'Test Title',
+ 'user_id' => 1
+ ));
+ $Article->create();
+ $result = $Article->save($data);
+ $this->assertFalse(empty($result));
+
+ $testResult = $Article->find('first', array('conditions' => array('Article.title' => 'Test Title')));
+
+ $this->assertEquals($data['Article']['title'], $testResult['Article']['title']);
+ $this->assertEquals('2008-01-01 00:00:00', $testResult['Article']['created']);
+ }
+
+/**
+ * testUnderscoreFieldSave method
+ *
+ * @return void
+ */
+ public function testUnderscoreFieldSave() {
+ $this->loadFixtures('UnderscoreField');
+ $UnderscoreField = new UnderscoreField();
+
+ $currentCount = $UnderscoreField->find('count');
+ $this->assertEquals(3, $currentCount);
+ $data = array('UnderscoreField' => array(
+ 'user_id' => '1',
+ 'my_model_has_a_field' => 'Content here',
+ 'body' => 'Body',
+ 'published' => 'Y',
+ 'another_field' => 4
+ ));
+ $ret = $UnderscoreField->save($data);
+ $this->assertFalse(empty($ret));
+
+ $currentCount = $UnderscoreField->find('count');
+ $this->assertEquals(4, $currentCount);
+ }
+
+/**
+ * testAutoSaveUuid method
+ *
+ * @return void
+ */
+ public function testAutoSaveUuid() {
+ // SQLite does not support non-integer primary keys
+ $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with SQLite.');
+
+ $this->loadFixtures('Uuid');
+ $TestModel = new Uuid();
+
+ $TestModel->save(array('title' => 'Test record'));
+ $result = $TestModel->findByTitle('Test record');
+ $this->assertEquals(
+ array('id', 'title', 'count', 'created', 'updated'),
+ array_keys($result['Uuid'])
+ );
+ $this->assertEquals(36, strlen($result['Uuid']['id']));
+ }
+
+/**
+ * Ensure that if the id key is null but present the save doesn't fail (with an
+ * x sql error: "Column id specified twice")
+ *
+ * @return void
+ */
+ public function testSaveUuidNull() {
+ // SQLite does not support non-integer primary keys
+ $this->skipIf($this->db instanceof Sqlite, 'This test is not compatible with SQLite.');
+
+ $this->loadFixtures('Uuid');
+ $TestModel = new Uuid();
+
+ $TestModel->save(array('title' => 'Test record', 'id' => null));
+ $result = $TestModel->findByTitle('Test record');
+ $this->assertEquals(
+ array('id', 'title', 'count', 'created', 'updated'),
+ array_keys($result['Uuid'])
+ );
+ $this->assertEquals(36, strlen($result['Uuid']['id']));
+ }
+
+/**
+ * testZeroDefaultFieldValue method
+ *
+ * @return void
+ */
+ public function testZeroDefaultFieldValue() {
+ $this->skipIf($this->db instanceof Sqlite, 'SQLite uses loose typing, this operation is unsupported.');
+
+ $this->loadFixtures('DataTest');
+ $TestModel = new DataTest();
+
+ $TestModel->create(array());
+ $TestModel->save();
+ $result = $TestModel->findById($TestModel->id);
+ $this->assertEquals(0, $result['DataTest']['count']);
+ $this->assertEquals(0, $result['DataTest']['float']);
+ }
+
+/**
+ * Tests validation parameter order in custom validation methods
+ *
+ * @return void
+ */
+ public function testAllowSimulatedFields() {
+ $TestModel = new ValidationTest1();
+
+ $TestModel->create(array(
+ 'title' => 'foo',
+ 'bar' => 'baz'
+ ));
+ $expected = array(
+ 'ValidationTest1' => array(
+ 'title' => 'foo',
+ 'bar' => 'baz'
+ ));
+ $this->assertEquals($expected, $TestModel->data);
+ }
+
+/**
+ * test that Caches are getting cleared on save().
+ * ensure that both inflections of controller names are getting cleared
+ * as url for controller could be either overallFavorites/index or overall_favorites/index
+ *
+ * @return void
+ */
+ public function testCacheClearOnSave() {
+ $_back = array(
+ 'check' => Configure::read('Cache.check'),
+ 'disable' => Configure::read('Cache.disable'),
+ );
+ Configure::write('Cache.check', true);
+ Configure::write('Cache.disable', false);
+
+ $this->loadFixtures('OverallFavorite');
+ $OverallFavorite = new OverallFavorite();
+
+ touch(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php');
+ touch(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php');
+
+ $data = array(
+ 'OverallFavorite' => array(
+ 'id' => 22,
+ 'model_type' => '8-track',
+ 'model_id' => '3',
+ 'priority' => '1'
+ )
+ );
+ $OverallFavorite->create($data);
+ $OverallFavorite->save();
+
+ $this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overallfavorites_index.php'));
+ $this->assertFalse(file_exists(CACHE . 'views' . DS . 'some_dir_overall_favorites_index.php'));
+
+ Configure::write('Cache.check', $_back['check']);
+ Configure::write('Cache.disable', $_back['disable']);
+ }
+
+/**
+ * testSaveWithCounterCache method
+ *
+ * @return void
+ */
+ public function testSaveWithCounterCache() {
+ $this->loadFixtures('Syfile', 'Item', 'Image', 'Portfolio', 'ItemsPortfolio');
+ $TestModel = new Syfile();
+ $TestModel2 = new Item();
+
+ $result = $TestModel->findById(1);
+ $this->assertSame($result['Syfile']['item_count'], null);
+
+ $TestModel2->save(array(
+ 'name' => 'Item 7',
+ 'syfile_id' => 1,
+ 'published' => false
+ ));
+
+ $result = $TestModel->findById(1);
+ $this->assertEquals(2, $result['Syfile']['item_count']);
+
+ $TestModel2->delete(1);
+ $result = $TestModel->findById(1);
+ $this->assertEquals(1, $result['Syfile']['item_count']);
+
+ $TestModel2->id = 2;
+ $TestModel2->saveField('syfile_id', 1);
+
+ $result = $TestModel->findById(1);
+ $this->assertEquals(2, $result['Syfile']['item_count']);
+
+ $result = $TestModel->findById(2);
+ $this->assertEquals(0, $result['Syfile']['item_count']);
+ }
+
+/**
+ * Tests that counter caches are updated when records are added
+ *
+ * @return void
+ */
+ public function testCounterCacheIncrease() {
+ $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
+ $User = new CounterCacheUser();
+ $Post = new CounterCachePost();
+ $data = array('Post' => array(
+ 'id' => 22,
+ 'title' => 'New Post',
+ 'user_id' => 66
+ ));
+
+ $Post->save($data);
+ $user = $User->find('first', array(
+ 'conditions' => array('id' => 66),
+ 'recursive' => -1
+ ));
+
+ $result = $user[$User->alias]['post_count'];
+ $expected = 3;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests that counter caches are updated when records are deleted
+ *
+ * @return void
+ */
+ public function testCounterCacheDecrease() {
+ $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
+ $User = new CounterCacheUser();
+ $Post = new CounterCachePost();
+
+ $Post->delete(2);
+ $user = $User->find('first', array(
+ 'conditions' => array('id' => 66),
+ 'recursive' => -1
+ ));
+
+ $result = $user[$User->alias]['post_count'];
+ $expected = 1;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests that counter caches are updated when foreign keys of counted records change
+ *
+ * @return void
+ */
+ public function testCounterCacheUpdated() {
+ $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
+ $User = new CounterCacheUser();
+ $Post = new CounterCachePost();
+
+ $data = $Post->find('first', array(
+ 'conditions' => array('id' => 1),
+ 'recursive' => -1
+ ));
+ $data[$Post->alias]['user_id'] = 301;
+ $Post->save($data);
+
+ $users = $User->find('all',array('order' => 'User.id'));
+ $this->assertEquals(1, $users[0]['User']['post_count']);
+ $this->assertEquals(2, $users[1]['User']['post_count']);
+ }
+
+/**
+ * Test counter cache with models that use a non-standard (i.e. not using 'id')
+ * as their primary key.
+ *
+ * @return void
+ */
+ public function testCounterCacheWithNonstandardPrimaryKey() {
+ $this->loadFixtures(
+ 'CounterCacheUserNonstandardPrimaryKey',
+ 'CounterCachePostNonstandardPrimaryKey'
+ );
+
+ $User = new CounterCacheUserNonstandardPrimaryKey();
+ $Post = new CounterCachePostNonstandardPrimaryKey();
+
+ $data = $Post->find('first', array(
+ 'conditions' => array('pid' => 1),
+ 'recursive' => -1
+ ));
+ $data[$Post->alias]['uid'] = 301;
+ $Post->save($data);
+
+ $users = $User->find('all',array('order' => 'User.uid'));
+ $this->assertEquals(1, $users[0]['User']['post_count']);
+ $this->assertEquals(2, $users[1]['User']['post_count']);
+ }
+
+/**
+ * test Counter Cache With Self Joining table
+ *
+ * @return void
+ */
+ public function testCounterCacheWithSelfJoin() {
+ $this->skipIf($this->db instanceof Sqlite, 'SQLite 2.x does not support ALTER TABLE ADD COLUMN');
+
+ $this->loadFixtures('CategoryThread');
+ $column = 'COLUMN ';
+ if ($this->db instanceof Sqlserver) {
+ $column = '';
+ }
+ $column .= $this->db->buildColumn(array('name' => 'child_count', 'type' => 'integer'));
+ $this->db->query('ALTER TABLE ' . $this->db->fullTableName('category_threads') . ' ADD ' . $column);
+ $this->db->flushMethodCache();
+ $Category = new CategoryThread();
+ $result = $Category->updateAll(array('CategoryThread.name' => "'updated'"), array('CategoryThread.parent_id' => 5));
+ $this->assertFalse(empty($result));
+
+ $Category = new CategoryThread();
+ $Category->belongsTo['ParentCategory']['counterCache'] = 'child_count';
+ $Category->updateCounterCache(array('parent_id' => 5));
+ $result = Hash::extract($Category->find('all', array('conditions' => array('CategoryThread.id' => 5))), '{n}.CategoryThread.child_count');
+ $expected = array(1);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveWithCounterCacheScope method
+ *
+ * @return void
+ */
+ public function testSaveWithCounterCacheScope() {
+ $this->loadFixtures('Syfile', 'Item', 'Image', 'ItemsPortfolio', 'Portfolio');
+ $TestModel = new Syfile();
+ $TestModel2 = new Item();
+ $TestModel2->belongsTo['Syfile']['counterCache'] = true;
+ $TestModel2->belongsTo['Syfile']['counterScope'] = array('published' => true);
+
+ $result = $TestModel->findById(1);
+ $this->assertSame($result['Syfile']['item_count'], null);
+
+ $TestModel2->save(array(
+ 'name' => 'Item 7',
+ 'syfile_id' => 1,
+ 'published' => true
+ ));
+
+ $result = $TestModel->findById(1);
+
+ $this->assertEquals(1, $result['Syfile']['item_count']);
+
+ $TestModel2->id = 1;
+ $TestModel2->saveField('published', true);
+ $result = $TestModel->findById(1);
+ $this->assertEquals(2, $result['Syfile']['item_count']);
+
+ $TestModel2->save(array(
+ 'id' => 1,
+ 'syfile_id' => 1,
+ 'published' => false
+ ));
+
+ $result = $TestModel->findById(1);
+ $this->assertEquals(1, $result['Syfile']['item_count']);
+ }
+
+/**
+ * Tests having multiple counter caches for an associated model
+ *
+ * @access public
+ * @return void
+ */
+ public function testCounterCacheMultipleCaches() {
+ $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
+ $User = new CounterCacheUser();
+ $Post = new CounterCachePost();
+ $Post->unbindModel(array('belongsTo' => array('User')), false);
+ $Post->bindModel(array(
+ 'belongsTo' => array(
+ 'User' => array(
+ 'className' => 'CounterCacheUser',
+ 'foreignKey' => 'user_id',
+ 'counterCache' => array(
+ true,
+ 'posts_published' => array('Post.published' => true)
+ )
+ )
+ )
+ ), false);
+
+ // Count Increase
+ $user = $User->find('first', array(
+ 'conditions' => array('id' => 66),
+ 'recursive' => -1
+ ));
+ $data = array('Post' => array(
+ 'id' => 22,
+ 'title' => 'New Post',
+ 'user_id' => 66,
+ 'published' => true
+ ));
+ $Post->save($data);
+ $result = $User->find('first', array(
+ 'conditions' => array('id' => 66),
+ 'recursive' => -1
+ ));
+ $this->assertEquals(3, $result[$User->alias]['post_count']);
+ $this->assertEquals(2, $result[$User->alias]['posts_published']);
+
+ // Count decrease
+ $Post->delete(1);
+ $result = $User->find('first', array(
+ 'conditions' => array('id' => 66),
+ 'recursive' => -1
+ ));
+ $this->assertEquals(2, $result[$User->alias]['post_count']);
+ $this->assertEquals(2, $result[$User->alias]['posts_published']);
+
+ // Count update
+ $data = $Post->find('first', array(
+ 'conditions' => array('id' => 1),
+ 'recursive' => -1
+ ));
+ $data[$Post->alias]['user_id'] = 301;
+ $Post->save($data);
+ $result = $User->find('all',array('order' => 'User.id'));
+ $this->assertEquals(2, $result[0]['User']['post_count']);
+ $this->assertEquals(1, $result[1]['User']['posts_published']);
+ }
+
+/**
+ * test that beforeValidate returning false can abort saves.
+ *
+ * @return void
+ */
+ public function testBeforeValidateSaveAbortion() {
+ $this->loadFixtures('Post');
+ $Model = new CallbackPostTestModel();
+ $Model->beforeValidateReturn = false;
+
+ $data = array(
+ 'title' => 'new article',
+ 'body' => 'this is some text.'
+ );
+ $Model->create();
+ $result = $Model->save($data);
+ $this->assertFalse($result);
+ }
+
+/**
+ * test that beforeSave returning false can abort saves.
+ *
+ * @return void
+ */
+ public function testBeforeSaveSaveAbortion() {
+ $this->loadFixtures('Post');
+ $Model = new CallbackPostTestModel();
+ $Model->beforeSaveReturn = false;
+
+ $data = array(
+ 'title' => 'new article',
+ 'body' => 'this is some text.'
+ );
+ $Model->create();
+ $result = $Model->save($data);
+ $this->assertFalse($result);
+ }
+
+/**
+ * testSaveField method
+ *
+ * @return void
+ */
+ public function testSaveField() {
+ $this->loadFixtures('Article');
+ $TestModel = new Article();
+
+ $TestModel->id = 1;
+ $result = $TestModel->saveField('title', 'New First Article');
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
+ $expected = array('Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'New First Article',
+ 'body' => 'First Article Body'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 1;
+ $result = $TestModel->saveField('title', '');
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
+ $expected = array('Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => '',
+ 'body' => 'First Article Body'
+ ));
+ $result['Article']['title'] = trim($result['Article']['title']);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 1;
+ $TestModel->set('body', 'Messed up data');
+ $result = $TestModel->saveField('title', 'First Article');
+ $this->assertFalse(empty($result));
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
+ $expected = array('Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = -1;
+ $TestModel->read(array('id', 'user_id', 'title', 'body'), 1);
+
+ $TestModel->id = 1;
+ $result = $TestModel->saveField('title', '', true);
+ $this->assertFalse($result);
+
+ $TestModel->recursive = -1;
+ $TestModel->id = 1;
+ $result = $TestModel->saveField('user_id', 9999);
+ $this->assertTrue((bool)$result);
+
+ $result = $TestModel->read(array('id', 'user_id'), 1);
+ $expected = array('Article' => array(
+ 'id' => '1',
+ 'user_id' => '9999',
+ ));
+ $this->assertEquals($expected, $result);
+
+ $this->loadFixtures('Node', 'Dependency');
+ $Node = new Node();
+ $Node->set('id', 1);
+ $result = $Node->read();
+ $this->assertEquals(array('Second'), Hash::extract($result, 'ParentNode.{n}.name'));
+
+ $Node->saveField('state', 10);
+ $result = $Node->read();
+ $this->assertEquals(array('Second'), Hash::extract($result, 'ParentNode.{n}.name'));
+ }
+
+/**
+ * testSaveWithCreate method
+ *
+ * @return void
+ */
+ public function testSaveWithCreate() {
+ $this->loadFixtures(
+ 'User',
+ 'Article',
+ 'User',
+ 'Comment',
+ 'Tag',
+ 'ArticlesTag',
+ 'Attachment'
+ );
+ $TestModel = new User();
+
+ $data = array('User' => array(
+ 'user' => 'user',
+ 'password' => ''
+ ));
+ $result = $TestModel->save($data);
+ $this->assertFalse($result);
+ $this->assertTrue(!empty($TestModel->validationErrors));
+
+ $TestModel = new Article();
+
+ $data = array('Article' => array(
+ 'user_id' => '',
+ 'title' => '',
+ 'body' => ''
+ ));
+ $result = $TestModel->create($data) && $TestModel->save();
+ $this->assertFalse($result);
+ $this->assertTrue(!empty($TestModel->validationErrors));
+
+ $data = array('Article' => array(
+ 'id' => 1,
+ 'user_id' => '1',
+ 'title' => 'New First Article',
+ 'body' => ''
+ ));
+ $result = $TestModel->create($data) && $TestModel->save();
+ $this->assertFalse($result);
+
+ $data = array('Article' => array(
+ 'id' => 1,
+ 'title' => 'New First Article'
+ ));
+ $result = $TestModel->create() && $TestModel->save($data, false);
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 1);
+ $expected = array('Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'New First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'N'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $data = array('Article' => array(
+ 'id' => 1,
+ 'user_id' => '2',
+ 'title' => 'First Article',
+ 'body' => 'New First Article Body',
+ 'published' => 'Y'
+ ));
+ $result = $TestModel->create() && $TestModel->save($data, true, array('id', 'title', 'published'));
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 1);
+ $expected = array('Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body',
+ 'published' => 'Y'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'Article' => array(
+ 'user_id' => '2',
+ 'title' => 'New Article',
+ 'body' => 'New Article Body',
+ 'created' => '2007-03-18 14:55:23',
+ 'updated' => '2007-03-18 14:57:31'
+ ),
+ 'Tag' => array('Tag' => array(1, 3))
+ );
+ $TestModel->create();
+ $result = $TestModel->create() && $TestModel->save($data);
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = 2;
+ $result = $TestModel->read(null, 4);
+ $expected = array(
+ 'Article' => array(
+ 'id' => '4',
+ 'user_id' => '2',
+ 'title' => 'New Article',
+ 'body' => 'New Article Body',
+ 'published' => 'N',
+ 'created' => '2007-03-18 14:55:23',
+ 'updated' => '2007-03-18 14:57:31'
+ ),
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Comment' => array(),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array('Comment' => array(
+ 'article_id' => '4',
+ 'user_id' => '1',
+ 'comment' => 'Comment New Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 14:57:23',
+ 'updated' => '2007-03-18 14:59:31'
+ ));
+ $result = $TestModel->Comment->create() && $TestModel->Comment->save($data);
+ $this->assertFalse(empty($result));
+
+ $data = array('Attachment' => array(
+ 'comment_id' => '7',
+ 'attachment' => 'newattachment.zip',
+ 'created' => '2007-03-18 15:02:23',
+ 'updated' => '2007-03-18 15:04:31'
+ ));
+ $result = $TestModel->Comment->Attachment->save($data);
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = 2;
+ $result = $TestModel->read(null, 4);
+ $expected = array(
+ 'Article' => array(
+ 'id' => '4',
+ 'user_id' => '2',
+ 'title' => 'New Article',
+ 'body' => 'New Article Body',
+ 'published' => 'N',
+ 'created' => '2007-03-18 14:55:23',
+ 'updated' => '2007-03-18 14:57:31'
+ ),
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'nate',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:18:23',
+ 'updated' => '2007-03-17 01:20:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '7',
+ 'article_id' => '4',
+ 'user_id' => '1',
+ 'comment' => 'Comment New Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 14:57:23',
+ 'updated' => '2007-03-18 14:59:31',
+ 'Article' => array(
+ 'id' => '4',
+ 'user_id' => '2',
+ 'title' => 'New Article',
+ 'body' => 'New Article Body',
+ 'published' => 'N',
+ 'created' => '2007-03-18 14:55:23',
+ 'updated' => '2007-03-18 14:57:31'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:16:23',
+ 'updated' => '2007-03-17 01:18:31'
+ ),
+ 'Attachment' => array(
+ 'id' => '2',
+ 'comment_id' => '7',
+ 'attachment' => 'newattachment.zip',
+ 'created' => '2007-03-18 15:02:23',
+ 'updated' => '2007-03-18 15:04:31'
+ ))),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that a null Id doesn't cause errors
+ *
+ * @return void
+ */
+ public function testSaveWithNullId() {
+ $this->loadFixtures('User');
+ $User = new User();
+ $User->read(null, 1);
+ $User->data['User']['id'] = null;
+ $result = $User->save(array('password' => 'test'));
+ $this->assertFalse(empty($result));
+ $this->assertTrue($User->id > 0);
+
+ $User->read(null, 2);
+ $User->data['User']['id'] = null;
+ $result = $User->save(array('password' => 'test'));
+ $this->assertFalse(empty($result));
+ $this->assertTrue($User->id > 0);
+
+ $User->data['User'] = array('password' => 'something');
+ $result = $User->save();
+ $this->assertFalse(empty($result));
+ $result = $User->read();
+ $this->assertEquals('something', $User->data['User']['password']);
+ }
+
+/**
+ * testSaveWithSet method
+ *
+ * @return void
+ */
+ public function testSaveWithSet() {
+ $this->loadFixtures('Article');
+ $TestModel = new Article();
+
+ // Create record we will be updating later
+
+ $data = array('Article' => array(
+ 'user_id' => '1',
+ 'title' => 'Fourth Article',
+ 'body' => 'Fourth Article Body',
+ 'published' => 'Y'
+ ));
+ $result = $TestModel->create() && $TestModel->save($data);
+ $this->assertFalse(empty($result));
+
+ // Check record we created
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
+ $expected = array('Article' => array(
+ 'id' => '4',
+ 'user_id' => '1',
+ 'title' => 'Fourth Article',
+ 'body' => 'Fourth Article Body',
+ 'published' => 'Y'
+ ));
+ $this->assertEquals($expected, $result);
+
+ // Create new record just to overlap Model->id on previously created record
+
+ $data = array('Article' => array(
+ 'user_id' => '4',
+ 'title' => 'Fifth Article',
+ 'body' => 'Fifth Article Body',
+ 'published' => 'Y'
+ ));
+ $result = $TestModel->create() && $TestModel->save($data);
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
+ $expected = array('Article' => array(
+ 'id' => '5',
+ 'user_id' => '4',
+ 'title' => 'Fifth Article',
+ 'body' => 'Fifth Article Body',
+ 'published' => 'Y'
+ ));
+ $this->assertEquals($expected, $result);
+
+ // Go back and edit the first article we created, starting by checking it's still there
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
+ $expected = array('Article' => array(
+ 'id' => '4',
+ 'user_id' => '1',
+ 'title' => 'Fourth Article',
+ 'body' => 'Fourth Article Body',
+ 'published' => 'Y'
+ ));
+ $this->assertEquals($expected, $result);
+
+ // And now do the update with set()
+
+ $data = array('Article' => array(
+ 'id' => '4',
+ 'title' => 'Fourth Article - New Title',
+ 'published' => 'N'
+ ));
+ $result = $TestModel->set($data) && $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
+ $expected = array('Article' => array(
+ 'id' => '4',
+ 'user_id' => '1',
+ 'title' => 'Fourth Article - New Title',
+ 'body' => 'Fourth Article Body',
+ 'published' => 'N'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
+ $expected = array('Article' => array(
+ 'id' => '5',
+ 'user_id' => '4',
+ 'title' => 'Fifth Article',
+ 'body' => 'Fifth Article Body',
+ 'published' => 'Y'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $data = array('Article' => array('id' => '5', 'title' => 'Fifth Article - New Title 5'));
+ $result = ($TestModel->set($data) && $TestModel->save());
+ $this->assertFalse(empty($result));
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
+ $expected = array('Article' => array(
+ 'id' => '5',
+ 'user_id' => '4',
+ 'title' => 'Fifth Article - New Title 5',
+ 'body' => 'Fifth Article Body',
+ 'published' => 'Y'
+ ));
+ $this->assertEquals($expected, $result);
+
+ $TestModel->recursive = -1;
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'title'),
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array('id' => 1, 'title' => 'First Article')),
+ array('Article' => array('id' => 2, 'title' => 'Second Article')),
+ array('Article' => array('id' => 3, 'title' => 'Third Article')),
+ array('Article' => array('id' => 4, 'title' => 'Fourth Article - New Title')),
+ array('Article' => array('id' => 5, 'title' => 'Fifth Article - New Title 5'))
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveWithNonExistentFields method
+ *
+ * @return void
+ */
+ public function testSaveWithNonExistentFields() {
+ $this->loadFixtures('Article');
+ $TestModel = new Article();
+ $TestModel->recursive = -1;
+
+ $data = array(
+ 'non_existent' => 'This field does not exist',
+ 'user_id' => '1',
+ 'title' => 'Fourth Article - New Title',
+ 'body' => 'Fourth Article Body',
+ 'published' => 'N'
+ );
+ $result = $TestModel->create() && $TestModel->save($data);
+ $this->assertFalse(empty($result));
+
+ $expected = array('Article' => array(
+ 'id' => '4',
+ 'user_id' => '1',
+ 'title' => 'Fourth Article - New Title',
+ 'body' => 'Fourth Article Body',
+ 'published' => 'N'
+ ));
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 4);
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'user_id' => '1',
+ 'non_existent' => 'This field does not exist',
+ 'title' => 'Fifth Article - New Title',
+ 'body' => 'Fifth Article Body',
+ 'published' => 'N'
+ );
+ $result = $TestModel->create() && $TestModel->save($data);
+ $this->assertFalse(empty($result));
+
+ $expected = array('Article' => array(
+ 'id' => '5',
+ 'user_id' => '1',
+ 'title' => 'Fifth Article - New Title',
+ 'body' => 'Fifth Article Body',
+ 'published' => 'N'
+ ));
+ $result = $TestModel->read(array('id', 'user_id', 'title', 'body', 'published'), 5);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveFromXml method
+ *
+ * @return void
+ */
+ public function testSaveFromXml() {
+ $this->markTestSkipped('This feature needs to be fixed or dropped');
+ $this->loadFixtures('Article');
+ App::uses('Xml', 'Utility');
+
+ $Article = new Article();
+ $result = $Article->save(Xml::build('<article title="test xml" user_id="5" />'));
+ $this->assertFalse(empty($result));
+ $results = $Article->find('first', array('conditions' => array('Article.title' => 'test xml')));
+ $this->assertFalse(empty($results));
+
+ $result = $Article->save(Xml::build('<article><title>testing</title><user_id>6</user_id></article>'));
+ $this->assertFalse(empty($result));
+ $results = $Article->find('first', array('conditions' => array('Article.title' => 'testing')));
+ $this->assertFalse(empty($results));
+
+ $result = $Article->save(Xml::build('<article><title>testing with DOMDocument</title><user_id>7</user_id></article>', array('return' => 'domdocument')));
+ $this->assertFalse(empty($result));
+ $results = $Article->find('first', array('conditions' => array('Article.title' => 'testing with DOMDocument')));
+ $this->assertFalse(empty($results));
+ }
+
+/**
+ * testSaveHabtm method
+ *
+ * @return void
+ */
+ public function testSaveHabtm() {
+ $this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
+ $TestModel = new Article();
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'larry',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ 'created' => '2007-03-17 01:20:23',
+ 'updated' => '2007-03-17 01:22:31'
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '5',
+ 'article_id' => '2',
+ 'user_id' => '1',
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:53:23',
+ 'updated' => '2007-03-18 10:55:31'
+ ),
+ array(
+ 'id' => '6',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:55:23',
+ 'updated' => '2007-03-18 10:57:31'
+ )),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'title' => 'New Second Article'
+ ),
+ 'Tag' => array('Tag' => array(1, 2))
+ );
+
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'New Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array('Article' => array('id' => '2'), 'Tag' => array('Tag' => array(2, 3)));
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'New Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array('Tag' => array('Tag' => array(1, 2, 3)));
+
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'New Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array('Tag' => array('Tag' => array()));
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $data = array('Tag' => array('Tag' => ''));
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'New Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array()
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array('Tag' => array('Tag' => array(2, 3)));
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'New Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'Tag' => array(
+ 'Tag' => array(1, 2)
+ ),
+ 'Article' => array(
+ 'id' => '2',
+ 'title' => 'New Second Article'
+ ));
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'New Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'Tag' => array(
+ 'Tag' => array(1, 2)
+ ),
+ 'Article' => array(
+ 'id' => '2',
+ 'title' => 'New Second Article Title'
+ ));
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'New Second Article Title',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'Tag' => array(
+ 'Tag' => array(2, 3)
+ ),
+ 'Article' => array(
+ 'id' => '2',
+ 'title' => 'Changed Second Article'
+ ));
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Changed Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'Tag' => array(
+ 'Tag' => array(1, 3)
+ ),
+ 'Article' => array('id' => '2'),
+ );
+
+ $result = $TestModel->set($data);
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->save();
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Changed Second Article',
+ 'body' => 'Second Article Body'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'Article' => array(
+ 'id' => 10,
+ 'user_id' => '2',
+ 'title' => 'New Article With Tags and fieldList',
+ 'body' => 'New Article Body with Tags and fieldList',
+ 'created' => '2007-03-18 14:55:23',
+ 'updated' => '2007-03-18 14:57:31'
+ ),
+ 'Tag' => array(
+ 'Tag' => array(1, 2, 3)
+ )
+ );
+ $result = $TestModel->create()
+ && $TestModel->save($data, true, array('user_id', 'title', 'published'));
+ $this->assertFalse(empty($result));
+
+ $TestModel->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment')
+ ));
+ $result = $TestModel->read();
+ $expected = array(
+ 'Article' => array(
+ 'id' => 4,
+ 'user_id' => 2,
+ 'title' => 'New Article With Tags and fieldList',
+ 'body' => '',
+ 'published' => 'N',
+ 'created' => '',
+ 'updated' => ''
+ ),
+ 'Tag' => array(
+ 0 => array(
+ 'id' => 1,
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ 1 => array(
+ 'id' => 2,
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ),
+ 2 => array(
+ 'id' => 3,
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $this->loadFixtures('JoinA', 'JoinC', 'JoinAC', 'JoinB', 'JoinAB');
+ $TestModel = new JoinA();
+ $TestModel->hasBelongsToMany = array('JoinC' => array('unique' => true));
+ $data = array(
+ 'JoinA' => array(
+ 'id' => 1,
+ 'name' => 'Join A 1',
+ 'body' => 'Join A 1 Body',
+ ),
+ 'JoinC' => array(
+ 'JoinC' => array(
+ array('join_c_id' => 2, 'other' => 'new record'),
+ array('join_c_id' => 3, 'other' => 'new record')
+ )
+ )
+ );
+ $TestModel->save($data);
+ $result = $TestModel->read(null, 1);
+ $expected = array(4, 5);
+ $this->assertEquals($expected, Hash::extract($result, 'JoinC.{n}.JoinAsJoinC.id'));
+ $expected = array('new record', 'new record');
+ $this->assertEquals($expected, Hash::extract($result, 'JoinC.{n}.JoinAsJoinC.other'));
+ }
+
+/**
+ * testSaveHabtmNoPrimaryData method
+ *
+ * @return void
+ */
+ public function testSaveHabtmNoPrimaryData() {
+ $this->loadFixtures('Article', 'User', 'Comment', 'Tag', 'ArticlesTag');
+ $TestModel = new Article();
+
+ $TestModel->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')), false);
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ 'created' => '2007-03-18 12:22:23',
+ 'updated' => '2007-03-18 12:24:31'
+ ),
+ array(
+ 'id' => '3',
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 2;
+ $data = array('Tag' => array('Tag' => array(2)));
+ $TestModel->save($data);
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '3',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => self::date()
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->loadFixtures('Portfolio', 'Item', 'ItemsPortfolio');
+ $TestModel = new Portfolio();
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'Portfolio' => array(
+ 'id' => 2,
+ 'seller_id' => 1,
+ 'name' => 'Portfolio 2'
+ ),
+ 'Item' => array(
+ array(
+ 'id' => 2,
+ 'syfile_id' => 2,
+ 'published' => '',
+ 'name' => 'Item 2',
+ 'ItemsPortfolio' => array(
+ 'id' => 2,
+ 'item_id' => 2,
+ 'portfolio_id' => 2
+ )
+ ),
+ array(
+ 'id' => 6,
+ 'syfile_id' => 6,
+ 'published' => '',
+ 'name' => 'Item 6',
+ 'ItemsPortfolio' => array(
+ 'id' => 6,
+ 'item_id' => 6,
+ 'portfolio_id' => 2
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array('Item' => array('Item' => array(1, 2)));
+ $TestModel->id = 2;
+ $TestModel->save($data);
+ $result = $TestModel->findById(2);
+ $result['Item'] = Hash::sort($result['Item'], '{n}.id', 'asc');
+ $expected = array(
+ 'Portfolio' => array(
+ 'id' => 2,
+ 'seller_id' => 1,
+ 'name' => 'Portfolio 2'
+ ),
+ 'Item' => array(
+ array(
+ 'id' => 1,
+ 'syfile_id' => 1,
+ 'published' => '',
+ 'name' => 'Item 1',
+ 'ItemsPortfolio' => array(
+ 'id' => 7,
+ 'item_id' => 1,
+ 'portfolio_id' => 2
+ )
+ ),
+ array(
+ 'id' => 2,
+ 'syfile_id' => 2,
+ 'published' => '',
+ 'name' => 'Item 2',
+ 'ItemsPortfolio' => array(
+ 'id' => 8,
+ 'item_id' => 2,
+ 'portfolio_id' => 2
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveHabtmCustomKeys method
+ *
+ * @return void
+ */
+ public function testSaveHabtmCustomKeys() {
+ $this->loadFixtures('Story', 'StoriesTag', 'Tag');
+ $Story = new Story();
+
+ $data = array(
+ 'Story' => array('story' => '1'),
+ 'Tag' => array(
+ 'Tag' => array(2, 3)
+ ));
+ $result = $Story->set($data);
+ $this->assertFalse(empty($result));
+
+ $result = $Story->save();
+ $this->assertFalse(empty($result));
+
+ $result = $Story->find('all', array('order' => array('Story.story')));
+ $expected = array(
+ array(
+ 'Story' => array(
+ 'story' => 1,
+ 'title' => 'First Story'
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => 2,
+ 'tag' => 'tag2',
+ 'created' => '2007-03-18 12:24:23',
+ 'updated' => '2007-03-18 12:26:31'
+ ),
+ array(
+ 'id' => 3,
+ 'tag' => 'tag3',
+ 'created' => '2007-03-18 12:26:23',
+ 'updated' => '2007-03-18 12:28:31'
+ ))),
+ array(
+ 'Story' => array(
+ 'story' => 2,
+ 'title' => 'Second Story'
+ ),
+ 'Tag' => array()
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that saving habtm records respects conditions set in the 'conditions' key
+ * for the association.
+ *
+ * @return void
+ */
+ public function testHabtmSaveWithConditionsInAssociation() {
+ $this->loadFixtures('JoinThing', 'Something', 'SomethingElse');
+ $Something = new Something();
+ $Something->unbindModel(array('hasAndBelongsToMany' => array('SomethingElse')), false);
+
+ $Something->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'DoomedSomethingElse' => array(
+ 'className' => 'SomethingElse',
+ 'joinTable' => 'join_things',
+ 'conditions' => array('JoinThing.doomed' => true),
+ 'unique' => true
+ ),
+ 'NotDoomedSomethingElse' => array(
+ 'className' => 'SomethingElse',
+ 'joinTable' => 'join_things',
+ 'conditions' => array('JoinThing.doomed' => 0),
+ 'unique' => true
+ )
+ )
+ ), false);
+ $result = $Something->read(null, 1);
+ $this->assertTrue(empty($result['NotDoomedSomethingElse']));
+ $this->assertEquals(1, count($result['DoomedSomethingElse']));
+
+ $data = array(
+ 'Something' => array('id' => 1),
+ 'NotDoomedSomethingElse' => array(
+ 'NotDoomedSomethingElse' => array(
+ array('something_else_id' => 2, 'doomed' => 0),
+ array('something_else_id' => 3, 'doomed' => 0)
+ )
+ )
+ );
+ $Something->create($data);
+ $result = $Something->save();
+ $this->assertFalse(empty($result));
+
+ $result = $Something->read(null, 1);
+ $this->assertEquals(2, count($result['NotDoomedSomethingElse']));
+ $this->assertEquals(1, count($result['DoomedSomethingElse']));
+ }
+
+/**
+ * testHabtmSaveKeyResolution method
+ *
+ * @return void
+ */
+ public function testHabtmSaveKeyResolution() {
+ $this->loadFixtures('Apple', 'Device', 'ThePaperMonkies');
+ $ThePaper = new ThePaper();
+
+ $ThePaper->id = 1;
+ $ThePaper->save(array('Monkey' => array(2, 3)));
+
+ $result = $ThePaper->findById(1);
+ $expected = array(
+ array(
+ 'id' => '2',
+ 'device_type_id' => '1',
+ 'name' => 'Device 2',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '3',
+ 'device_type_id' => '1',
+ 'name' => 'Device 3',
+ 'typ' => '2'
+ ));
+ $this->assertEquals($expected, $result['Monkey']);
+
+ $ThePaper->id = 2;
+ $ThePaper->save(array('Monkey' => array(1, 2, 3)));
+
+ $result = $ThePaper->findById(2);
+ $expected = array(
+ array(
+ 'id' => '1',
+ 'device_type_id' => '1',
+ 'name' => 'Device 1',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '2',
+ 'device_type_id' => '1',
+ 'name' => 'Device 2',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '3',
+ 'device_type_id' => '1',
+ 'name' => 'Device 3',
+ 'typ' => '2'
+ ));
+ $this->assertEquals($expected, $result['Monkey']);
+
+ $ThePaper->id = 2;
+ $ThePaper->save(array('Monkey' => array(1, 3)));
+
+ $result = $ThePaper->findById(2);
+ $expected = array(
+ array(
+ 'id' => '1',
+ 'device_type_id' => '1',
+ 'name' => 'Device 1',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '3',
+ 'device_type_id' => '1',
+ 'name' => 'Device 3',
+ 'typ' => '2'
+ ));
+ $this->assertEquals($expected, $result['Monkey']);
+
+ $result = $ThePaper->findById(1);
+ $expected = array(
+ array(
+ 'id' => '2',
+ 'device_type_id' => '1',
+ 'name' => 'Device 2',
+ 'typ' => '1'
+ ),
+ array(
+ 'id' => '3',
+ 'device_type_id' => '1',
+ 'name' => 'Device 3',
+ 'typ' => '2'
+ ));
+ $this->assertEquals($expected, $result['Monkey']);
+ }
+
+/**
+ * testCreationOfEmptyRecord method
+ *
+ * @return void
+ */
+ public function testCreationOfEmptyRecord() {
+ $this->loadFixtures('Author');
+ $TestModel = new Author();
+ $this->assertEquals(4, $TestModel->find('count'));
+
+ $TestModel->deleteAll(true, false, false);
+ $this->assertEquals(0, $TestModel->find('count'));
+
+ $result = $TestModel->save();
+ $this->assertTrue(isset($result['Author']['created']));
+ $this->assertTrue(isset($result['Author']['updated']));
+ $this->assertEquals(1, $TestModel->find('count'));
+ }
+
+/**
+ * testCreateWithPKFiltering method
+ *
+ * @return void
+ */
+ public function testCreateWithPKFiltering() {
+ $TestModel = new Article();
+ $data = array(
+ 'id' => 5,
+ 'user_id' => 2,
+ 'title' => 'My article',
+ 'body' => 'Some text'
+ );
+
+ $result = $TestModel->create($data);
+ $expected = array(
+ 'Article' => array(
+ 'published' => 'N',
+ 'id' => 5,
+ 'user_id' => 2,
+ 'title' => 'My article',
+ 'body' => 'Some text'
+ ));
+
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(5, $TestModel->id);
+
+ $result = $TestModel->create($data, true);
+ $expected = array(
+ 'Article' => array(
+ 'published' => 'N',
+ 'id' => false,
+ 'user_id' => 2,
+ 'title' => 'My article',
+ 'body' => 'Some text'
+ ));
+
+ $this->assertEquals($expected, $result);
+ $this->assertFalse($TestModel->id);
+
+ $result = $TestModel->create(array('Article' => $data), true);
+ $expected = array(
+ 'Article' => array(
+ 'published' => 'N',
+ 'id' => false,
+ 'user_id' => 2,
+ 'title' => 'My article',
+ 'body' => 'Some text'
+ ));
+
+ $this->assertEquals($expected, $result);
+ $this->assertFalse($TestModel->id);
+
+ $data = array(
+ 'id' => 6,
+ 'user_id' => 2,
+ 'title' => 'My article',
+ 'body' => 'Some text',
+ 'created' => '1970-01-01 00:00:00',
+ 'updated' => '1970-01-01 12:00:00',
+ 'modified' => '1970-01-01 12:00:00'
+ );
+
+ $result = $TestModel->create($data);
+ $expected = array(
+ 'Article' => array(
+ 'published' => 'N',
+ 'id' => 6,
+ 'user_id' => 2,
+ 'title' => 'My article',
+ 'body' => 'Some text',
+ 'created' => '1970-01-01 00:00:00',
+ 'updated' => '1970-01-01 12:00:00',
+ 'modified' => '1970-01-01 12:00:00'
+ ));
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(6, $TestModel->id);
+
+ $result = $TestModel->create(array(
+ 'Article' => array_diff_key($data, array(
+ 'created' => true,
+ 'updated' => true,
+ 'modified' => true
+ ))), true);
+ $expected = array(
+ 'Article' => array(
+ 'published' => 'N',
+ 'id' => false,
+ 'user_id' => 2,
+ 'title' => 'My article',
+ 'body' => 'Some text'
+ ));
+ $this->assertEquals($expected, $result);
+ $this->assertFalse($TestModel->id);
+ }
+
+/**
+ * testCreationWithMultipleData method
+ *
+ * @return void
+ */
+ public function testCreationWithMultipleData() {
+ $this->loadFixtures('Article', 'Comment');
+ $Article = new Article();
+ $Comment = new Comment();
+
+ $articles = $Article->find('all', array(
+ 'fields' => array('id','title'),
+ 'recursive' => -1,
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'title' => 'First Article'
+ )),
+ array('Article' => array(
+ 'id' => 2,
+ 'title' => 'Second Article'
+ )),
+ array('Article' => array(
+ 'id' => 3,
+ 'title' => 'Third Article'
+ )));
+ $this->assertEquals($expected, $articles);
+
+ $comments = $Comment->find('all', array(
+ 'fields' => array('id','article_id','user_id','comment','published'),
+ 'recursive' => -1,
+ 'order' => array('Comment.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Comment' => array(
+ 'id' => 1,
+ 'article_id' => 1,
+ 'user_id' => 2,
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 2,
+ 'article_id' => 1,
+ 'user_id' => 4,
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 3,
+ 'article_id' => 1,
+ 'user_id' => 1,
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 4,
+ 'article_id' => 1,
+ 'user_id' => 1,
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N'
+ )),
+ array('Comment' => array(
+ 'id' => 5,
+ 'article_id' => 2,
+ 'user_id' => 1,
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 6,
+ 'article_id' => 2,
+ 'user_id' => 2,
+ 'comment' => 'Second Comment for Second Article',
+ 'published' => 'Y'
+ )));
+ $this->assertEquals($expected, $comments);
+
+ $data = array(
+ 'Comment' => array(
+ 'article_id' => 2,
+ 'user_id' => 4,
+ 'comment' => 'Brand New Comment',
+ 'published' => 'N'
+ ),
+ 'Article' => array(
+ 'id' => 2,
+ 'title' => 'Second Article Modified'
+ ));
+ $result = $Comment->create($data);
+ $this->assertFalse(empty($result));
+
+ $result = $Comment->save();
+ $this->assertFalse(empty($result));
+
+ $articles = $Article->find('all', array(
+ 'fields' => array('id','title'),
+ 'recursive' => -1,
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'title' => 'First Article'
+ )),
+ array('Article' => array(
+ 'id' => 2,
+ 'title' => 'Second Article'
+ )),
+ array('Article' => array(
+ 'id' => 3,
+ 'title' => 'Third Article'
+ )));
+ $this->assertEquals($expected, $articles);
+
+ $comments = $Comment->find('all', array(
+ 'fields' => array('id','article_id','user_id','comment','published'),
+ 'recursive' => -1,
+ 'order' => array('Comment.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Comment' => array(
+ 'id' => 1,
+ 'article_id' => 1,
+ 'user_id' => 2,
+ 'comment' => 'First Comment for First Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 2,
+ 'article_id' => 1,
+ 'user_id' => 4,
+ 'comment' => 'Second Comment for First Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 3,
+ 'article_id' => 1,
+ 'user_id' => 1,
+ 'comment' => 'Third Comment for First Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 4,
+ 'article_id' => 1,
+ 'user_id' => 1,
+ 'comment' => 'Fourth Comment for First Article',
+ 'published' => 'N'
+ )),
+ array('Comment' => array(
+ 'id' => 5,
+ 'article_id' => 2,
+ 'user_id' => 1,
+ 'comment' => 'First Comment for Second Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 6,
+ 'article_id' => 2,
+ 'user_id' => 2, 'comment' =>
+ 'Second Comment for Second Article',
+ 'published' => 'Y'
+ )),
+ array('Comment' => array(
+ 'id' => 7,
+ 'article_id' => 2,
+ 'user_id' => 4,
+ 'comment' => 'Brand New Comment',
+ 'published' => 'N'
+ )));
+ $this->assertEquals($expected, $comments);
+ }
+
+/**
+ * testCreationWithMultipleDataSameModel method
+ *
+ * @return void
+ */
+ public function testCreationWithMultipleDataSameModel() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+ $SecondaryArticle = new Article();
+
+ $result = $Article->field('title', array('id' => 1));
+ $this->assertEquals('First Article', $result);
+
+ $data = array(
+ 'Article' => array(
+ 'user_id' => 2,
+ 'title' => 'Brand New Article',
+ 'body' => 'Brand New Article Body',
+ 'published' => 'Y'
+ ),
+ 'SecondaryArticle' => array(
+ 'id' => 1
+ ));
+
+ $Article->create();
+ $result = $Article->save($data);
+ $this->assertFalse(empty($result));
+
+ $result = $Article->getInsertID();
+ $this->assertTrue(!empty($result));
+
+ $result = $Article->field('title', array('id' => 1));
+ $this->assertEquals('First Article', $result);
+
+ $articles = $Article->find('all', array(
+ 'fields' => array('id','title'),
+ 'recursive' => -1,
+ 'order' => array('Article.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Article' => array(
+ 'id' => 1,
+ 'title' => 'First Article'
+ )),
+ array('Article' => array(
+ 'id' => 2,
+ 'title' => 'Second Article'
+ )),
+ array('Article' => array(
+ 'id' => 3,
+ 'title' => 'Third Article'
+ )),
+ array('Article' => array(
+ 'id' => 4,
+ 'title' => 'Brand New Article'
+ )));
+
+ $this->assertEquals($expected, $articles);
+ }
+
+/**
+ * testCreationWithMultipleDataSameModelManualInstances method
+ *
+ * @return void
+ */
+ public function testCreationWithMultipleDataSameModelManualInstances() {
+ $this->loadFixtures('PrimaryModel');
+ $Primary = new PrimaryModel();
+ $Secondary = new PrimaryModel();
+
+ $result = $Primary->field('primary_name', array('id' => 1));
+ $this->assertEquals('Primary Name Existing', $result);
+
+ $data = array(
+ 'PrimaryModel' => array(
+ 'primary_name' => 'Primary Name New'
+ ),
+ 'SecondaryModel' => array(
+ 'id' => array(1)
+ ));
+
+ $Primary->create();
+ $result = $Primary->save($data);
+ $this->assertFalse(empty($result));
+
+ $result = $Primary->field('primary_name', array('id' => 1));
+ $this->assertEquals('Primary Name Existing', $result);
+
+ $result = $Primary->getInsertID();
+ $this->assertTrue(!empty($result));
+
+ $result = $Primary->field('primary_name', array('id' => $result));
+ $this->assertEquals('Primary Name New', $result);
+
+ $result = $Primary->find('count');
+ $this->assertEquals(2, $result);
+ }
+
+/**
+ * testRecordExists method
+ *
+ * @return void
+ */
+ public function testRecordExists() {
+ $this->loadFixtures('User');
+ $TestModel = new User();
+
+ $this->assertFalse($TestModel->exists());
+ $TestModel->read(null, 1);
+ $this->assertTrue($TestModel->exists());
+ $TestModel->create();
+ $this->assertFalse($TestModel->exists());
+ $TestModel->id = 4;
+ $this->assertTrue($TestModel->exists());
+
+ $TestModel = new TheVoid();
+ $this->assertFalse($TestModel->exists());
+ }
+
+/**
+ * testRecordExistsMissingTable method
+ *
+ * @expectedException PDOException
+ * @return void
+ */
+ public function testRecordExistsMissingTable() {
+ $TestModel = new TheVoid();
+ $TestModel->id = 5;
+ $TestModel->exists();
+ }
+
+/**
+ * testUpdateExisting method
+ *
+ * @return void
+ */
+ public function testUpdateExisting() {
+ $this->loadFixtures('User', 'Article', 'Comment');
+ $TestModel = new User();
+ $TestModel->create();
+
+ $TestModel->save(array(
+ 'User' => array(
+ 'user' => 'some user',
+ 'password' => 'some password'
+ )));
+ $this->assertTrue(is_int($TestModel->id) || (intval($TestModel->id) === 5));
+ $id = $TestModel->id;
+
+ $TestModel->save(array(
+ 'User' => array(
+ 'user' => 'updated user'
+ )));
+ $this->assertEquals($id, $TestModel->id);
+
+ $result = $TestModel->findById($id);
+ $this->assertEquals('updated user', $result['User']['user']);
+ $this->assertEquals('some password', $result['User']['password']);
+
+ $Article = new Article();
+ $Comment = new Comment();
+ $data = array(
+ 'Comment' => array(
+ 'id' => 1,
+ 'comment' => 'First Comment for First Article'
+ ),
+ 'Article' => array(
+ 'id' => 2,
+ 'title' => 'Second Article'
+ ));
+
+ $result = $Article->save($data);
+ $this->assertFalse(empty($result));
+
+ $result = $Comment->save($data);
+ $this->assertFalse(empty($result));
+ }
+
+/**
+ * test updating records and saving blank values.
+ *
+ * @return void
+ */
+ public function testUpdateSavingBlankValues() {
+ $this->loadFixtures('Article');
+ $Article = new Article();
+ $Article->validate = array();
+ $Article->create();
+ $result = $Article->save(array(
+ 'id' => 1,
+ 'title' => '',
+ 'body' => ''
+ ));
+ $this->assertTrue((bool)$result);
+ $result = $Article->find('first', array('conditions' => array('Article.id' => 1)));
+ $this->assertEquals('', $result['Article']['title'], 'Title is not blank');
+ $this->assertEquals('', $result['Article']['body'], 'Body is not blank');
+ }
+
+/**
+ * testUpdateMultiple method
+ *
+ * @return void
+ */
+ public function testUpdateMultiple() {
+ $this->loadFixtures('Comment', 'Article', 'User', 'CategoryThread');
+ $TestModel = new Comment();
+ $result = Hash::extract($TestModel->find('all'), '{n}.Comment.user_id');
+ $expected = array('2', '4', '1', '1', '1', '2');
+ $this->assertEquals($expected, $result);
+
+ $TestModel->updateAll(array('Comment.user_id' => 5), array('Comment.user_id' => 2));
+ $result = Hash::combine($TestModel->find('all'), '{n}.Comment.id', '{n}.Comment.user_id');
+ $expected = array(1 => 5, 2 => 4, 3 => 1, 4 => 1, 5 => 1, 6 => 5);
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->updateAll(
+ array('Comment.comment' => "'Updated today'"),
+ array('Comment.user_id' => 5)
+ );
+ $this->assertFalse(empty($result));
+ $result = Hash::extract(
+ $TestModel->find('all', array(
+ 'conditions' => array(
+ 'Comment.user_id' => 5
+ ))),
+ '{n}.Comment.comment'
+ );
+ $expected = array_fill(0, 2, 'Updated today');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testHabtmUuidWithUuidId method
+ *
+ * @return void
+ */
+ public function testHabtmUuidWithUuidId() {
+ $this->loadFixtures('Uuidportfolio', 'Uuiditem', 'UuiditemsUuidportfolio', 'UuiditemsUuidportfolioNumericid');
+ $TestModel = new Uuidportfolio();
+
+ $data = array('Uuidportfolio' => array('name' => 'Portfolio 3'));
+ $data['Uuiditem']['Uuiditem'] = array('483798c8-c7cc-430e-8cf9-4fcc40cf8569');
+ $TestModel->create($data);
+ $TestModel->save();
+ $id = $TestModel->id;
+ $result = $TestModel->read(null, $id);
+ $this->assertEquals(1, count($result['Uuiditem']));
+ $this->assertEquals(36, strlen($result['Uuiditem'][0]['UuiditemsUuidportfolio']['id']));
+ }
+
+/**
+ * test HABTM saving when join table has no primary key and only 2 columns.
+ *
+ * @return void
+ */
+ public function testHabtmSavingWithNoPrimaryKeyUuidJoinTable() {
+ $this->loadFixtures('UuidTag', 'Fruit', 'FruitsUuidTag');
+ $Fruit = new Fruit();
+ $data = array(
+ 'Fruit' => array(
+ 'color' => 'Red',
+ 'shape' => 'Heart-shaped',
+ 'taste' => 'sweet',
+ 'name' => 'Strawberry',
+ ),
+ 'UuidTag' => array(
+ 'UuidTag' => array(
+ '481fc6d0-b920-43e0-e50f-6d1740cf8569'
+ )
+ )
+ );
+ $result = $Fruit->save($data);
+ $this->assertFalse(empty($result));
+ }
+
+/**
+ * test HABTM saving when join table has no primary key and only 2 columns, no with model is used.
+ *
+ * @return void
+ */
+ public function testHabtmSavingWithNoPrimaryKeyUuidJoinTableNoWith() {
+ $this->loadFixtures('UuidTag', 'Fruit', 'FruitsUuidTag');
+ $Fruit = new FruitNoWith();
+ $data = array(
+ 'Fruit' => array(
+ 'color' => 'Red',
+ 'shape' => 'Heart-shaped',
+ 'taste' => 'sweet',
+ 'name' => 'Strawberry',
+ ),
+ 'UuidTag' => array(
+ 'UuidTag' => array(
+ '481fc6d0-b920-43e0-e50f-6d1740cf8569'
+ )
+ )
+ );
+ $result = $Fruit->save($data);
+ $this->assertFalse(empty($result));
+ }
+
+/**
+ * testHabtmUuidWithNumericId method
+ *
+ * @return void
+ */
+ public function testHabtmUuidWithNumericId() {
+ $this->loadFixtures('Uuidportfolio', 'Uuiditem', 'UuiditemsUuidportfolioNumericid');
+ $TestModel = new Uuiditem();
+
+ $data = array('Uuiditem' => array('name' => 'Item 7', 'published' => 0));
+ $data['Uuidportfolio']['Uuidportfolio'] = array('480af662-eb8c-47d3-886b-230540cf8569');
+ $TestModel->create($data);
+ $TestModel->save();
+ $id = $TestModel->id;
+ $result = $TestModel->read(null, $id);
+ $this->assertEquals(1, count($result['Uuidportfolio']));
+ }
+
+/**
+ * testSaveMultipleHabtm method
+ *
+ * @return void
+ */
+ public function testSaveMultipleHabtm() {
+ $this->loadFixtures('JoinA', 'JoinB', 'JoinC', 'JoinAB', 'JoinAC');
+ $TestModel = new JoinA();
+ $result = $TestModel->findById(1);
+
+ $expected = array(
+ 'JoinA' => array(
+ 'id' => 1,
+ 'name' => 'Join A 1',
+ 'body' => 'Join A 1 Body',
+ 'created' => '2008-01-03 10:54:23',
+ 'updated' => '2008-01-03 10:54:23'
+ ),
+ 'JoinB' => array(
+ 0 => array(
+ 'id' => 2,
+ 'name' => 'Join B 2',
+ 'created' => '2008-01-03 10:55:02',
+ 'updated' => '2008-01-03 10:55:02',
+ 'JoinAsJoinB' => array(
+ 'id' => 1,
+ 'join_a_id' => 1,
+ 'join_b_id' => 2,
+ 'other' => 'Data for Join A 1 Join B 2',
+ 'created' => '2008-01-03 10:56:33',
+ 'updated' => '2008-01-03 10:56:33'
+ ))),
+ 'JoinC' => array(
+ 0 => array(
+ 'id' => 2,
+ 'name' => 'Join C 2',
+ 'created' => '2008-01-03 10:56:12',
+ 'updated' => '2008-01-03 10:56:12',
+ 'JoinAsJoinC' => array(
+ 'id' => 1,
+ 'join_a_id' => 1,
+ 'join_c_id' => 2,
+ 'other' => 'Data for Join A 1 Join C 2',
+ 'created' => '2008-01-03 10:57:22',
+ 'updated' => '2008-01-03 10:57:22'
+ ))));
+
+ $this->assertEquals($expected, $result);
+
+ $TestModel->id = 1;
+ $data = array(
+ 'JoinA' => array(
+ 'id' => '1',
+ 'name' => 'New name for Join A 1',
+ 'updated' => self::date()
+ ),
+ 'JoinB' => array(
+ array(
+ 'id' => 1,
+ 'join_b_id' => 2,
+ 'other' => 'New data for Join A 1 Join B 2',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ )),
+ 'JoinC' => array(
+ array(
+ 'id' => 1,
+ 'join_c_id' => 2,
+ 'other' => 'New data for Join A 1 Join C 2',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ )));
+
+ $TestModel->set($data);
+ $TestModel->save();
+
+ $result = $TestModel->findById(1);
+ $expected = array(
+ 'JoinA' => array(
+ 'id' => 1,
+ 'name' => 'New name for Join A 1',
+ 'body' => 'Join A 1 Body',
+ 'created' => '2008-01-03 10:54:23',
+ 'updated' => self::date()
+ ),
+ 'JoinB' => array(
+ 0 => array(
+ 'id' => 2,
+ 'name' => 'Join B 2',
+ 'created' => '2008-01-03 10:55:02',
+ 'updated' => '2008-01-03 10:55:02',
+ 'JoinAsJoinB' => array(
+ 'id' => 1,
+ 'join_a_id' => 1,
+ 'join_b_id' => 2,
+ 'other' => 'New data for Join A 1 Join B 2',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ ))),
+ 'JoinC' => array(
+ 0 => array(
+ 'id' => 2,
+ 'name' => 'Join C 2',
+ 'created' => '2008-01-03 10:56:12',
+ 'updated' => '2008-01-03 10:56:12',
+ 'JoinAsJoinC' => array(
+ 'id' => 1,
+ 'join_a_id' => 1,
+ 'join_c_id' => 2,
+ 'other' => 'New data for Join A 1 Join C 2',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ ))));
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAll method
+ *
+ * @return void
+ */
+ public function testSaveAll() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
+ $TestModel = new Post();
+
+ $result = $TestModel->find('all');
+ $this->assertEquals(3, count($result));
+ $this->assertFalse(isset($result[3]));
+
+ $TestModel->saveAll(array(
+ 'Post' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author'
+ ),
+ 'Author' => array(
+ 'user' => 'bob',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
+ )));
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => '5',
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author',
+ 'published' => 'N'
+ ),
+ 'Author' => array(
+ 'id' => '5',
+ 'user' => 'bob',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf90',
+ 'test' => 'working'
+ ));
+ $this->assertEquals(self::date(), $result[3]['Post']['created']);
+ $this->assertEquals(self::date(), $result[3]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[3]['Author']['created']);
+ $this->assertEquals(self::date(), $result[3]['Author']['updated']);
+ unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
+ unset($result[3]['Author']['created'], $result[3]['Author']['updated']);
+ $this->assertEquals($expected, $result[3]);
+ $this->assertEquals(4, count($result));
+
+ $TestModel->deleteAll(true);
+ $this->assertEquals(array(), $TestModel->find('all'));
+
+ // SQLite seems to reset the PK counter when that happens, so we need this to make the tests pass
+ $this->db->truncate($TestModel);
+
+ $TestModel->saveAll(array(
+ array(
+ 'title' => 'Multi-record post 1',
+ 'body' => 'First multi-record post',
+ 'author_id' => 2
+ ),
+ array(
+ 'title' => 'Multi-record post 2',
+ 'body' => 'Second multi-record post',
+ 'author_id' => 2
+ )));
+
+ $result = $TestModel->find('all', array(
+ 'recursive' => -1,
+ 'order' => 'Post.id ASC'
+ ));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '2',
+ 'title' => 'Multi-record post 1',
+ 'body' => 'First multi-record post',
+ 'published' => 'N'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '2',
+ 'title' => 'Multi-record post 2',
+ 'body' => 'Second multi-record post',
+ 'published' => 'N'
+ )));
+ $this->assertEquals(self::date(), $result[0]['Post']['created']);
+ $this->assertEquals(self::date(), $result[0]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[1]['Post']['created']);
+ $this->assertEquals(self::date(), $result[1]['Post']['updated']);
+ unset($result[0]['Post']['created'], $result[0]['Post']['updated']);
+ unset($result[1]['Post']['created'], $result[1]['Post']['updated']);
+ $this->assertEquals($expected, $result);
+
+ $TestModel = new Comment();
+ $result = $TestModel->saveAll(array(
+ 'Comment' => array(
+ 'article_id' => 2,
+ 'user_id' => 2,
+ 'comment' => 'New comment with attachment',
+ 'published' => 'Y'
+ ),
+ 'Attachment' => array(
+ 'attachment' => 'some_file.tgz'
+ )));
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ 'id' => '7',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'New comment with attachment',
+ 'published' => 'Y'
+ );
+ $this->assertEquals(self::date(), $result[6]['Comment']['created']);
+ $this->assertEquals(self::date(), $result[6]['Comment']['updated']);
+ unset($result[6]['Comment']['created'], $result[6]['Comment']['updated']);
+ $this->assertEquals($expected, $result[6]['Comment']);
+
+ $expected = array(
+ 'id' => '2',
+ 'comment_id' => '7',
+ 'attachment' => 'some_file.tgz'
+ );
+ $this->assertEquals(self::date(), $result[6]['Attachment']['created']);
+ $this->assertEquals(self::date(), $result[6]['Attachment']['updated']);
+ unset($result[6]['Attachment']['created'], $result[6]['Attachment']['updated']);
+ $this->assertEquals($expected, $result[6]['Attachment']);
+ }
+
+/**
+ * Test SaveAll with Habtm relations
+ *
+ * @return void
+ */
+ public function testSaveAllHabtm() {
+ $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
+ $data = array(
+ 'Article' => array(
+ 'user_id' => 1,
+ 'title' => 'Article Has and belongs to Many Tags'
+ ),
+ 'Tag' => array(
+ 'Tag' => array(1, 2)
+ ),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Article comment',
+ 'user_id' => 1
+ )));
+ $Article = new Article();
+ $result = $Article->saveAll($data);
+ $this->assertFalse(empty($result));
+
+ $result = $Article->read();
+ $this->assertEquals(2, count($result['Tag']));
+ $this->assertEquals('tag1', $result['Tag'][0]['tag']);
+ $this->assertEquals(1, count($result['Comment']));
+ $this->assertEquals(1, count($result['Comment'][0]['comment']));
+ }
+
+/**
+ * Test SaveAll with Habtm relations and extra join table fields
+ *
+ * @return void
+ */
+ public function testSaveAllHabtmWithExtraJoinTableFields() {
+ $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
+
+ $data = array(
+ 'Something' => array(
+ 'id' => 4,
+ 'title' => 'Extra Fields',
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ ),
+ 'SomethingElse' => array(
+ array('something_else_id' => 1, 'doomed' => '1'),
+ array('something_else_id' => 2, 'doomed' => '0'),
+ array('something_else_id' => 3, 'doomed' => '1')
+ )
+ );
+
+ $Something = new Something();
+ $result = $Something->saveAll($data);
+ $this->assertFalse(empty($result));
+ $result = $Something->read();
+
+ $this->assertEquals(3, count($result['SomethingElse']));
+ $this->assertTrue(Set::matches('/Something[id=4]', $result));
+
+ $this->assertTrue(Set::matches('/SomethingElse[id=1]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[something_else_id=1]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[doomed=1]', $result));
+
+ $this->assertTrue(Set::matches('/SomethingElse[id=2]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[something_else_id=2]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[doomed=0]', $result));
+
+ $this->assertTrue(Set::matches('/SomethingElse[id=3]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[something_else_id=3]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[doomed=1]', $result));
+ }
+
+/**
+ * testSaveAllHasOne method
+ *
+ * @return void
+ */
+ public function testSaveAllHasOne() {
+ $model = new Comment();
+ $model->deleteAll(true);
+ $this->assertEquals(array(), $model->find('all'));
+
+ $model->Attachment->deleteAll(true);
+ $this->assertEquals(array(), $model->Attachment->find('all'));
+
+ $this->assertTrue($model->saveAll(array(
+ 'Comment' => array(
+ 'comment' => 'Comment with attachment',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Attachment' => array(
+ 'attachment' => 'some_file.zip'
+ ))));
+ $result = $model->find('all', array('fields' => array(
+ 'Comment.id', 'Comment.comment', 'Attachment.id',
+ 'Attachment.comment_id', 'Attachment.attachment'
+ )));
+ $expected = array(array(
+ 'Comment' => array(
+ 'id' => '1',
+ 'comment' => 'Comment with attachment'
+ ),
+ 'Attachment' => array(
+ 'id' => '1',
+ 'comment_id' => '1',
+ 'attachment' => 'some_file.zip'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $model->Attachment->bindModel(array('belongsTo' => array('Comment')), false);
+ $data = array(
+ 'Comment' => array(
+ 'comment' => 'Comment with attachment',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Attachment' => array(
+ 'attachment' => 'some_file.zip'
+ ));
+ $this->assertTrue($model->saveAll($data, array('validate' => 'first')));
+ }
+
+/**
+ * testSaveAllBelongsTo method
+ *
+ * @return void
+ */
+ public function testSaveAllBelongsTo() {
+ $model = new Comment();
+ $model->deleteAll(true);
+ $this->assertEquals(array(), $model->find('all'));
+
+ $model->Article->deleteAll(true);
+ $this->assertEquals(array(), $model->Article->find('all'));
+
+ $this->assertTrue($model->saveAll(array(
+ 'Comment' => array(
+ 'comment' => 'Article comment',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Article' => array(
+ 'title' => 'Model Associations 101',
+ 'user_id' => 1
+ ))));
+ $result = $model->find('all', array('fields' => array(
+ 'Comment.id', 'Comment.comment', 'Comment.article_id', 'Article.id', 'Article.title'
+ )));
+ $expected = array(array(
+ 'Comment' => array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'comment' => 'Article comment'
+ ),
+ 'Article' => array(
+ 'id' => '1',
+ 'title' => 'Model Associations 101'
+ )));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllHasOneValidation method
+ *
+ * @return void
+ */
+ public function testSaveAllHasOneValidation() {
+ $model = new Comment();
+ $model->deleteAll(true);
+ $this->assertEquals(array(), $model->find('all'));
+
+ $model->Attachment->deleteAll(true);
+ $this->assertEquals(array(), $model->Attachment->find('all'));
+
+ $model->validate = array('comment' => 'notEmpty');
+ $model->Attachment->validate = array('attachment' => 'notEmpty');
+ $model->Attachment->bindModel(array('belongsTo' => array('Comment')));
+
+ $result = $model->saveAll(
+ array(
+ 'Comment' => array(
+ 'comment' => '',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Attachment' => array('attachment' => '')
+ ),
+ array('validate' => 'first')
+ );
+ $this->assertEquals(false, $result);
+ $expected = array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Attachment' => array(
+ 'attachment' => array('This field cannot be left blank')
+ )
+ );
+ $this->assertEquals($expected, $model->validationErrors);
+ $this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
+ }
+
+/**
+ * testSaveAllAtomic method
+ *
+ * @return void
+ */
+ public function testSaveAllAtomic() {
+ $this->loadFixtures('Article', 'User', 'Comment');
+ $TestModel = new Article();
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author',
+ 'user_id' => 2
+ ),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'user_id' => 2))
+ ), array('atomic' => false));
+
+ $this->assertSame($result, array('Article' => true, 'Comment' => array(true)));
+
+ $result = $TestModel->saveAll(array(
+ array(
+ 'id' => '1',
+ 'title' => 'Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => 'Just update the title'
+ ),
+ array(
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'user_id' => 2
+ )
+ ), array('atomic' => false));
+ $this->assertSame($result, array(true, true, true));
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => 'First new comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ),
+ array(
+ 'comment' => 'Second new comment',
+ 'published' => 'Y',
+ 'user_id' => 2
+ ))
+ ), array('validate' => true, 'atomic' => false));
+ $this->assertSame($result, array('Article' => true, 'Comment' => array(true, true)));
+
+ $TestModel->validate = array(
+ 'title' => 'notEmpty',
+ 'author_id' => 'numeric'
+ );
+ $result = $TestModel->saveAll(array(
+ array(
+ 'id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ )
+ ), array('validate' => true, 'atomic' => false));
+ $this->assertSame(array(true, false), $result);
+ }
+
+/**
+ * testSaveAllDeepAssociated method
+ *
+ * @return void
+ */
+ public function testSaveAllDeepAssociated() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ), array('deep' => true));
+ $this->assertTrue($result);
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment'
+ );
+ $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
+ $this->assertEquals(5, $result);
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
+ )
+ ), array('deep' => true));
+ $this->assertTrue($result);
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment',
+ 'Third new comment',
+ 'Fourth new comment'
+ );
+ $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
+ $this->assertEquals(2, $result);
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 5,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => '',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+
+ $TestModel->Comment->Attachment->create();
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $expected = array('User' => array('user' => array('This field cannot be left blank')));
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $data['Comment']['Article']['User']['user'] = 'deepsave';
+ $TestModel->Comment->Attachment->create();
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => true));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
+ $expected = array(
+ 'Attachment' => array(
+ 'id' => '3',
+ 'comment_id' => '11',
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'id' => '11',
+ 'article_id' => '4',
+ 'user_id' => '5',
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ )
+ );
+ unset($result['Attachment']['created'], $result['Attachment']['updated']);
+ $this->assertEquals($expected['Attachment'], $result['Attachment']);
+
+ unset($result['Comment']['created'], $result['Comment']['updated']);
+ $this->assertEquals($expected['Comment'], $result['Comment']);
+
+ $result = $TestModel->findById($result['Comment']['article_id']);
+ $expected = array(
+ 'Article' => array(
+ 'id' => '4',
+ 'user_id' => '6',
+ 'title' => 'First Article deepsave insert',
+ 'body' => 'First Article Body deepsave insert',
+ 'published' => 'N',
+ ),
+ 'User' => array(
+ 'id' => '6',
+ 'user' => 'deepsave',
+ 'password' => 'magic',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '11',
+ 'article_id' => '4',
+ 'user_id' => '5',
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ )
+ )
+ );
+ unset(
+ $result['Article']['created'], $result['Article']['updated'],
+ $result['User']['created'], $result['User']['updated'],
+ $result['Comment'][0]['created'], $result['Comment'][0]['updated']
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllDeepMany
+ * tests the validate methods with deeper recursive data
+ *
+ * @return void
+ */
+ public function testSaveAllDeepMany() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+
+ $data = array(
+ array(
+ 'Article' => array('id' => 1),
+ 'Comment' => array(
+ array('comment' => 'First comment deepsaved article 1', 'published' => 'Y', 'User' => array('user' => 'savemany', 'password' => 'manysaved')),
+ array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => 'moresaved')),
+ array('comment' => 'Second comment deepsaved article 2', 'published' => 'Y', 'user_id' => 2)
+ )
+ )
+ );
+ $result = $TestModel->saveAll($data, array('deep' => true));
+ $this->assertTrue($result);
+
+ $data = array(
+ array(
+ 'id' => 1, 'body' => '',
+ 'Comment' => array(
+ array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
+ array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
+ array('comment' => '', 'published' => 'Y', 'user_id' => 2)
+ )
+ )
+ );
+ $TestModel->Comment->validate['comment'] = 'notEmpty';
+ $result = $TestModel->saveAll($data, array('deep' => true));
+ $this->assertFalse($result);
+
+ $expected = array(
+ 0 => array(
+ 'body' => array('This field cannot be left blank'),
+ 'Comment' => array(
+ 0 => array(
+ 'comment' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ ),
+ 1 => array(
+ 'body' => array('This field cannot be left blank'),
+ 'Comment' => array(
+ 0 => array(
+ 'User' => array(
+ 'password' => array('This field cannot be left blank')
+ )
+ ),
+ 1 => array(
+ 'comment' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+ }
+/**
+ * testSaveAllDeepValidateOnly
+ * tests the validate methods with deeper recursive data
+ *
+ * @return void
+ */
+ public function testSaveAllDeepValidateOnly() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
+ $TestModel->Comment->validate['comment'] = 'notEmpty';
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array('validate' => 'only', 'deep' => true)
+ );
+ $this->assertTrue($result);
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array('validate' => 'only', 'deep' => true)
+ );
+ $this->assertFalse($result);
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => 'newuser', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array('validate' => 'only', 'atomic' => false, 'deep' => true)
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array('validate' => 'only', 'atomic' => false, 'deep' => true)
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ false,
+ true
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
+ )
+ ),
+ array('validate' => 'only', 'deep' => true)
+ );
+ $this->assertTrue($result);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ ),
+ array('validate' => 'only', 'deep' => true)
+ );
+ $this->assertFalse($result);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsave'))
+ )
+ ),
+ array('validate' => 'only', 'atomic' => false, 'deep' => true)
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ ),
+ array('validate' => 'only', 'atomic' => false, 'deep' => true)
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ false
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array(
+ 'Comment' => array(
+ 1 => array(
+ 'Attachment' => array(
+ 'attachment' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 5,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => 'deepsave',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => true
+ );
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 5,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => '',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'Comment' => array(
+ 'Article' => array(
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => false
+ );
+ $this->assertEquals($expected, $result);
+
+ $data['Comment']['Article']['body'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'Comment' => array(
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => false
+ );
+ $this->assertEquals($expected, $result);
+
+ $data['Comment']['comment'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'Comment' => array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => false
+ );
+ $this->assertEquals($expected, $result);
+
+ $data['Attachment']['attachment'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array(
+ 'attachment' => array('This field cannot be left blank'),
+ 'Comment' => array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->validationErrors;
+ $expected = array(
+ 'comment' => array('This field cannot be left blank'),
+ 'Article' => array(
+ 'body' => array('This field cannot be left blank'),
+ 'User' => array(
+ 'user' => array('This field cannot be left blank')
+ )
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => true));
+ $expected = array(
+ 'Attachment' => false,
+ 'Comment' => false
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllNotDeepAssociated method
+ * test that only directly associated data gets saved
+ *
+ * @return void
+ */
+ public function testSaveAllNotDeepAssociated() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => 'First new comment', 'published' => 'Y', 'user_id' => 2,
+ 'User' => array('user' => 'newuser', 'password' => 'newuserpass')
+ ),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ), array('deep' => false));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->User->field('id', array('user' => 'newuser', 'password' => 'newuserpass'));
+ $this->assertFalse($result);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 4),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => 'deepsaved'))
+ )
+ ), array('deep' => false));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->Attachment->field('id', array('attachment' => 'deepsaved'));
+ $this->assertFalse($result);
+
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 4,
+ 'article_id' => 1,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => 'deepsave',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+ $expected = $TestModel->User->find('count');
+
+ $TestModel->Comment->Attachment->create();
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('deep' => false));
+ $this->assertTrue($result);
+
+ $result = $TestModel->User->find('count');
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->findById($TestModel->Comment->Attachment->id);
+ $expected = array(
+ 'Attachment' => array(
+ 'id' => '2',
+ 'comment_id' => '11',
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'id' => '11',
+ 'article_id' => 1,
+ 'user_id' => '4',
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ )
+ );
+ unset($result['Attachment']['created'], $result['Attachment']['updated']);
+ $this->assertEquals($expected['Attachment'], $result['Attachment']);
+
+ unset($result['Comment']['created'], $result['Comment']['updated']);
+ $this->assertEquals($expected['Comment'], $result['Comment']);
+ }
+
+/**
+ * testSaveAllNotDeepMany
+ * tests the save methods to not save deeper recursive data
+ *
+ * @return void
+ */
+ public function testSaveAllNotDeepMany() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+
+ $data = array(
+ array(
+ 'id' => 1,
+ 'body' => '',
+ 'Comment' => array(
+ array('comment' => '', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'manysaved')),
+ array('comment' => 'Second comment deepsaved article 1', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First comment deepsaved article 2', 'published' => 'Y', 'User' => array('user' => 'savemore', 'password' => '')),
+ array('comment' => '', 'published' => 'Y', 'user_id' => 2)
+ )
+ )
+ );
+ $TestModel->Comment->validate['comment'] = 'notEmpty';
+ $result = $TestModel->saveAll($data, array('deep' => false));
+ $this->assertFalse($result);
+
+ $expected = array(
+ 0 => array(
+ 'body' => array('This field cannot be left blank')
+ ),
+ 1 => array(
+ 'body' => array('This field cannot be left blank')
+ )
+ );
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ array(
+ 'Article' => array('id' => 1, 'body' => 'Ignore invalid comment'),
+ 'Comment' => array(
+ array('comment' => '', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array(
+ 'Article' => array('id' => 2, 'body' => 'Same here'),
+ 'Comment' => array(
+ array('comment' => '', 'published' => 'Y', 'user_id' => 2)
+ )
+ )
+ );
+ $result = $TestModel->saveAll($data, array('deep' => false));
+ $this->assertTrue($result);
+ }
+/**
+ * testSaveAllNotDeepValidateOnly
+ * tests the validate methods to not validate deeper recursive data
+ *
+ * @return void
+ */
+ public function testSaveAllNotDeepValidateOnly() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->Attachment->validate['attachment'] = 'notEmpty';
+ $TestModel->Comment->validate['comment'] = 'notEmpty';
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2, 'body' => ''),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array('validate' => 'only', 'deep' => false)
+ );
+ $this->assertFalse($result);
+
+ $expected = array('body' => array('This field cannot be left blank'));
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array('validate' => 'only', 'deep' => false)
+ );
+ $this->assertTrue($result);
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid user data'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'User' => array('user' => '', 'password' => 'newuserpass')),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ),
+ array('validate' => 'only', 'atomic' => false, 'deep' => false)
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ ),
+ array('validate' => 'only', 'deep' => false)
+ );
+ $this->assertTrue($result);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2, 'body' => 'Ignore invalid attachment data'),
+ 'Comment' => array(
+ array('comment' => 'Third new comment', 'published' => 'Y', 'user_id' => 5),
+ array('comment' => 'Fourth new comment', 'published' => 'Y', 'user_id' => 2, 'Attachment' => array('attachment' => ''))
+ )
+ ),
+ array('validate' => 'only', 'atomic' => false, 'deep' => false)
+ );
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(
+ true,
+ true
+ )
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array();
+ $result = $TestModel->validationErrors;
+ $this->assertSame($expected, $result);
+
+ $data = array(
+ 'Attachment' => array(
+ 'attachment' => 'deepsave insert',
+ ),
+ 'Comment' => array(
+ 'comment' => 'First comment deepsave insert',
+ 'published' => 'Y',
+ 'user_id' => 5,
+ 'Article' => array(
+ 'title' => 'First Article deepsave insert ignored',
+ 'body' => 'First Article Body deepsave insert',
+ 'User' => array(
+ 'user' => '',
+ 'password' => 'magic'
+ ),
+ ),
+ )
+ );
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array();
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => true
+ );
+ $this->assertEquals($expected, $result);
+
+ $data['Comment']['Article']['body'] = '';
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'deep' => false));
+ $this->assertTrue($result);
+
+ $result = $TestModel->Comment->Attachment->validationErrors;
+ $expected = array();
+ $this->assertSame($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->saveAll($data, array('validate' => 'only', 'atomic' => false, 'deep' => false));
+ $expected = array(
+ 'Attachment' => true,
+ 'Comment' => true
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllHasMany method
+ *
+ * @return void
+ */
+ public function testSaveAllHasMany() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $TestModel->hasMany['Comment']['order'] = array('Comment.created' => 'ASC');
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ));
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment'
+ );
+ $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Third new comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))),
+ array('atomic' => false)
+ );
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment',
+ 'Third new comment'
+ );
+ $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
+ $this->assertEquals($expected, $result);
+
+ $TestModel->beforeSaveReturn = false;
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Fourth new comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))),
+ array('atomic' => false)
+ );
+ $this->assertEquals(array('Article' => false), $result);
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment',
+ 'Third new comment'
+ );
+ $result = Hash::extract(Hash::sort($result['Comment'], '{n}.id', 'ASC'), '{n}.comment');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllHasManyValidation method
+ *
+ * @return void
+ */
+ public function testSaveAllHasManyValidation() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->validate = array('comment' => 'notEmpty');
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => '', 'published' => 'Y', 'user_id' => 1),
+ )
+ ), array('validate' => true));
+ $this->assertFalse($result);
+
+ $expected = array('Comment' => array(
+ array('comment' => array('This field cannot be left blank'))
+ ));
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ $expected = array(
+ array('comment' => array('This field cannot be left blank'))
+ );
+ $this->assertEquals($expected, $TestModel->Comment->validationErrors);
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))
+ ), array('validate' => 'first'));
+ $this->assertFalse($result);
+ }
+
+/**
+ * test saveAll with transactions and ensure there is no missing rollback.
+ *
+ * @return void
+ */
+ public function testSaveAllManyRowsTransactionNoRollback() {
+ $this->loadFixtures('Post');
+
+ $this->getMock('DboSource', array('connect', 'rollback', 'describe'), array(), 'MockTransactionDboSource');
+ $db = ConnectionManager::create('mock_transaction', array(
+ 'datasource' => 'MockTransactionDboSource',
+ ));
+
+ $db->expects($this->once())
+ ->method('describe')
+ ->will($this->returnValue(array()));
+ $db->expects($this->once())->method('rollback');
+
+ $Post = new Post('mock_transaction');
+
+ $Post->validate = array(
+ 'title' => array('rule' => array('notEmpty'))
+ );
+
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => '')
+ );
+ $Post->saveAll($data, array('atomic' => true));
+ }
+
+/**
+ * test saveAll with transactions and ensure there is no missing rollback.
+ *
+ * @return void
+ */
+ public function testSaveAllAssociatedTransactionNoRollback() {
+ $testDb = ConnectionManager::getDataSource('test');
+
+ $mock = $this->getMock(
+ 'DboSource',
+ array('connect', 'rollback', 'describe', 'create', 'update', 'begin'),
+ array(),
+ 'MockTransactionAssociatedDboSource'
+ );
+ $db = ConnectionManager::create('mock_transaction_assoc', array(
+ 'datasource' => 'MockTransactionAssociatedDboSource',
+ ));
+ $this->mockObjects[] = $db;
+ $db->columns = $testDb->columns;
+
+ $db->expects($this->once())->method('rollback');
+ $db->expects($this->any())->method('describe')
+ ->will($this->returnValue(array(
+ 'id' => array('type' => 'integer', 'length' => 11),
+ 'title' => array('type' => 'string'),
+ 'body' => array('type' => 'text'),
+ 'published' => array('type' => 'string')
+ )));
+
+ $Post = new Post();
+ $Post->useDbConfig = 'mock_transaction_assoc';
+ $Post->Author->useDbConfig = 'mock_transaction_assoc';
+
+ $Post->Author->validate = array(
+ 'user' => array('rule' => array('notEmpty'))
+ );
+
+ $data = array(
+ 'Post' => array(
+ 'title' => 'New post',
+ 'body' => 'Content',
+ 'published' => 'Y'
+ ),
+ 'Author' => array(
+ 'user' => '',
+ 'password' => "sekret"
+ )
+ );
+ $Post->saveAll($data, array('validate' => true));
+ }
+
+/**
+ * test saveAll with nested saveAll call.
+ *
+ * @return void
+ */
+ public function testSaveAllNestedSaveAll() {
+ $this->loadFixtures('Sample');
+ $TransactionTestModel = new TransactionTestModel();
+
+ $data = array(
+ array('apple_id' => 1, 'name' => 'sample5'),
+ );
+
+ $this->assertTrue($TransactionTestModel->saveAll($data, array('atomic' => true)));
+ }
+
+/**
+ * testSaveAllTransaction method
+ *
+ * @return void
+ */
+ public function testSaveAllTransaction() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
+ $TestModel = new Post();
+
+ $TestModel->validate = array('title' => 'notEmpty');
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => 'New Fifth Post'),
+ array('author_id' => 1, 'title' => '')
+ );
+ $this->assertFalse($TestModel->saveAll($data));
+
+ $result = $TestModel->find('all', array('recursive' => -1));
+ $expected = array(
+ array('Post' => array(
+ 'id' => '1',
+ 'author_id' => 1,
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array('Post' => array(
+ 'id' => '2',
+ 'author_id' => 3,
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )),
+ array('Post' => array(
+ 'id' => '3',
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )));
+
+ if (count($result) != 3) {
+ // Database doesn't support transactions
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => 1,
+ 'title' => 'New Fourth Post',
+ 'body' => null,
+ 'published' => 'N',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ ));
+
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '5',
+ 'author_id' => 1,
+ 'title' => 'New Fifth Post',
+ 'body' => null,
+ 'published' => 'N',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ ));
+
+ $this->assertEquals($expected, $result);
+ // Skip the rest of the transactional tests
+ return;
+ }
+
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => ''),
+ array('author_id' => 1, 'title' => 'New Sixth Post')
+ );
+ $this->assertFalse($TestModel->saveAll($data));
+
+ $result = $TestModel->find('all', array('recursive' => -1));
+ $expected = array(
+ array('Post' => array(
+ 'id' => '1',
+ 'author_id' => 1,
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array('Post' => array(
+ 'id' => '2',
+ 'author_id' => 3,
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )),
+ array('Post' => array(
+ 'id' => '3',
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )));
+
+ if (count($result) != 3) {
+ // Database doesn't support transactions
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => 1,
+ 'title' => 'New Fourth Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'N',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ ));
+
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '5',
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'N',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ ));
+ }
+ $this->assertEquals($expected, $result);
+
+ $TestModel->validate = array('title' => 'notEmpty');
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => 'New Fifth Post'),
+ array('author_id' => 1, 'title' => 'New Sixth Post')
+ );
+ $this->assertTrue($TestModel->saveAll($data));
+
+ $result = $TestModel->find('all', array(
+ 'recursive' => -1,
+ 'fields' => array('author_id', 'title','body','published'),
+ 'order' => array('Post.created' => 'ASC')
+ ));
+
+ $expected = array(
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y'
+ )),
+ array('Post' => array(
+ 'author_id' => 3,
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'New Fourth Post',
+ 'body' => '',
+ 'published' => 'N'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'New Fifth Post',
+ 'body' => '',
+ 'published' => 'N'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'New Sixth Post',
+ 'body' => '',
+ 'published' => 'N'
+ )));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllValidation method
+ *
+ * @return void
+ */
+ public function testSaveAllValidation() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
+ $TestModel = new Post();
+
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => 'Just update the title'
+ ),
+ array(
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'author_id' => 2
+ ));
+
+ $this->assertTrue($TestModel->saveAll($data));
+
+ $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '1',
+ 'title' => 'Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:39:23'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '3',
+ 'title' => 'Just update the title',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '3',
+ 'author_id' => '1',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => '2',
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'published' => 'N'
+ )));
+ $this->assertEquals(self::date(), $result[0]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[1]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[3]['Post']['created']);
+ $this->assertEquals(self::date(), $result[3]['Post']['updated']);
+ unset($result[0]['Post']['updated'], $result[1]['Post']['updated']);
+ unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ ));
+ $result = $TestModel->saveAll($data);
+ $this->assertFalse($result);
+
+ $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
+ $errors = array(1 => array('title' => array('This field cannot be left blank')));
+ $transactionWorked = Set::matches('/Post[1][title=Baleeted First Post]', $result);
+ if (!$transactionWorked) {
+ $this->assertTrue(Set::matches('/Post[1][title=Un-Baleeted First Post]', $result));
+ $this->assertTrue(Set::matches('/Post[2][title=Just update the title]', $result));
+ }
+
+ $this->assertEquals($errors, $TestModel->validationErrors);
+
+ $TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ ));
+ $result = $TestModel->saveAll($data, array('validate' => true, 'atomic' => false));
+ $this->assertEquals(array(true, false), $result);
+ $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
+ $errors = array(1 => array('title' => array('This field cannot be left blank')));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23'
+ )
+ ),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '3',
+ 'title' => 'Just update the title',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23'
+ )
+ ),
+ array(
+ 'Post' => array(
+ 'id' => '3',
+ 'author_id' => '1',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )
+ ),
+ array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => '2',
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'published' => 'N'
+ )
+ )
+ );
+
+ $this->assertEquals(self::date(), $result[0]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[1]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[3]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[3]['Post']['created']);
+ unset(
+ $result[0]['Post']['updated'], $result[1]['Post']['updated'],
+ $result[3]['Post']['updated'], $result[3]['Post']['created']
+ );
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($errors, $TestModel->validationErrors);
+
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Re-Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ ));
+ $this->assertFalse($TestModel->saveAll($data, array('validate' => 'first')));
+
+ $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
+ unset(
+ $result[0]['Post']['updated'], $result[1]['Post']['updated'],
+ $result[3]['Post']['updated'], $result[3]['Post']['created']
+ );
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($errors, $TestModel->validationErrors);
+ }
+
+/**
+ * testSaveAllValidationOnly method
+ *
+ * @return void
+ */
+ public function testSaveAllValidationOnly() {
+ $this->loadFixtures('Comment', 'Attachment');
+ $TestModel = new Comment();
+ $TestModel->Attachment->validate = array('attachment' => 'notEmpty');
+
+ $data = array(
+ 'Comment' => array(
+ 'comment' => 'This is the comment'
+ ),
+ 'Attachment' => array(
+ 'attachment' => ''
+ )
+ );
+
+ $result = $TestModel->saveAll($data, array('validate' => 'only'));
+ $this->assertFalse($result);
+
+ $TestModel = new Article();
+ $TestModel->validate = array('title' => 'notEmpty');
+ $result = $TestModel->saveAll(
+ array(
+ 0 => array('title' => ''),
+ 1 => array('title' => 'title 1'),
+ 2 => array('title' => 'title 2'),
+ ),
+ array('validate' => 'only')
+ );
+ $this->assertFalse($result);
+ $expected = array(
+ 0 => array('title' => array('This field cannot be left blank')),
+ );
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $result = $TestModel->saveAll(
+ array(
+ 0 => array('title' => 'title 0'),
+ 1 => array('title' => ''),
+ 2 => array('title' => 'title 2'),
+ ),
+ array('validate' => 'only')
+ );
+ $this->assertFalse($result);
+ $expected = array(
+ 1 => array('title' => array('This field cannot be left blank')),
+ );
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ }
+
+/**
+ * testSaveAllValidateFirst method
+ *
+ * @return void
+ */
+ public function testSaveAllValidateFirst() {
+ $this->loadFixtures('Article', 'Comment', 'Attachment', 'User', 'ArticlesTag', 'Tag');
+ $model = new Article();
+ $model->deleteAll(true);
+
+ $model->Comment->validate = array('comment' => 'notEmpty');
+ $result = $model->saveAll(array(
+ 'Article' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved author'
+ ),
+ 'Comment' => array(
+ array('comment' => 'First new comment'),
+ array('comment' => '')
+ )
+ ), array('validate' => 'first'));
+
+ $this->assertFalse($result);
+
+ $result = $model->find('all');
+ $this->assertEquals(array(), $result);
+ $expected = array('Comment' => array(
+ 1 => array('comment' => array('This field cannot be left blank'))
+ ));
+
+ $this->assertEquals($expected['Comment'], $model->Comment->validationErrors);
+
+ $this->assertSame($model->Comment->find('count'), 0);
+
+ $result = $model->saveAll(
+ array(
+ 'Article' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author',
+ 'user_id' => 2
+ ),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Only new comment',
+ 'user_id' => 2
+ ))),
+ array('validate' => 'first')
+ );
+
+ $this->assertSame($result, true);
+
+ $result = $model->Comment->find('all');
+ $this->assertSame(count($result), 1);
+ $result = Hash::extract($result, '{n}.Comment.article_id');
+ $this->assertEquals(4, $result[0]);
+
+ $model->deleteAll(true);
+ $data = array(
+ 'Article' => array(
+ 'title' => 'Post with Author saveAlled from comment',
+ 'body' => 'This post will be saved with an author',
+ 'user_id' => 2
+ ),
+ 'Comment' => array(
+ 'comment' => 'Only new comment', 'user_id' => 2
+ ));
+
+ $result = $model->Comment->saveAll($data, array('validate' => 'first'));
+ $this->assertFalse(empty($result));
+
+ $result = $model->find('all');
+ $this->assertEquals(
+ $result[0]['Article']['title'],
+ 'Post with Author saveAlled from comment'
+ );
+ $this->assertEquals('Only new comment', $result[0]['Comment'][0]['comment']);
+ }
+
+/**
+ * test saveAll()'s return is correct when using atomic = false and validate = first.
+ *
+ * @return void
+ */
+ public function testSaveAllValidateFirstAtomicFalse() {
+ $this->loadFixtures('Something');
+ $Something = new Something();
+ $invalidData = array(
+ array(
+ 'title' => 'foo',
+ 'body' => 'bar',
+ 'published' => 'baz',
+ ),
+ array(
+ 'body' => 3,
+ 'published' => 'sd',
+ ),
+ );
+ $Something->create();
+ $Something->validate = array(
+ 'title' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true,
+ ),
+ 'body' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true,
+ 'allowEmpty' => true,
+ ),
+ );
+ $result = $Something->saveAll($invalidData, array(
+ 'atomic' => false,
+ 'validate' => 'first',
+ ));
+ $expected = array(true, false);
+ $this->assertEquals($expected, $result);
+
+ $Something = new Something();
+ $validData = array(
+ array(
+ 'title' => 'title value',
+ 'body' => 'body value',
+ 'published' => 'baz',
+ ),
+ array(
+ 'title' => 'valid',
+ 'body' => 'this body',
+ 'published' => 'sd',
+ ),
+ );
+ $Something->create();
+ $result = $Something->saveAll($validData, array(
+ 'atomic' => false,
+ 'validate' => 'first',
+ ));
+ $expected = array(true, true);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllHasManyValidationOnly method
+ *
+ * @return void
+ */
+ public function testSaveAllHasManyValidationOnly() {
+ $this->loadFixtures('Article', 'Comment', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->validate = array('comment' => 'notEmpty');
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1),
+ array(
+ 'id' => 2,
+ 'comment' =>
+ 'comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))),
+ array('validate' => 'only')
+ );
+ $this->assertFalse($result);
+
+ $result = $TestModel->saveAll(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ),
+ array(
+ 'id' => 2,
+ 'comment' => 'comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ),
+ array(
+ 'id' => 3,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))),
+ array(
+ 'validate' => 'only',
+ 'atomic' => false
+ ));
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(false, true, false)
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array('Comment' => array(
+ 0 => array('comment' => array('This field cannot be left blank')),
+ 2 => array('comment' => array('This field cannot be left blank'))
+ ));
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $expected = array(
+ 0 => array('comment' => array('This field cannot be left blank')),
+ 2 => array('comment' => array('This field cannot be left blank'))
+ );
+ $this->assertEquals($expected, $TestModel->Comment->validationErrors);
+ }
+
+/**
+ * test that saveAll behaves like plain save() when supplied empty data
+ *
+ * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
+ * @return void
+ */
+ public function testSaveAllEmptyData() {
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
+ $model = new Article();
+ $result = $model->saveAll(array(), array('validate' => 'first'));
+ $this->assertFalse(empty($result));
+
+ $model = new ProductUpdateAll();
+ $result = $model->saveAll(array());
+ $this->assertFalse($result);
+ }
+
+/**
+ * testSaveAssociated method
+ *
+ * @return void
+ */
+ public function testSaveAssociated() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
+ $TestModel = new Post();
+
+ $result = $TestModel->find('all');
+ $this->assertEquals(3, count($result));
+ $this->assertFalse(isset($result[3]));
+
+ $TestModel->saveAssociated(array(
+ 'Post' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author'
+ ),
+ 'Author' => array(
+ 'user' => 'bob',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf90'
+ )));
+
+ $result = $TestModel->find('all', array('order' => array('Post.id ' => 'ASC')));
+ $expected = array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => '5',
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author',
+ 'published' => 'N'
+ ),
+ 'Author' => array(
+ 'id' => '5',
+ 'user' => 'bob',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf90',
+ 'test' => 'working'
+ ));
+ $this->assertEquals(self::date(), $result[3]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[3]['Post']['created']);
+ $this->assertEquals(self::date(), $result[3]['Author']['created']);
+ $this->assertEquals(self::date(), $result[3]['Author']['updated']);
+ unset(
+ $result[3]['Post']['updated'], $result[3]['Post']['created'],
+ $result[3]['Author']['updated'], $result[3]['Author']['created']
+ );
+ $this->assertEquals($expected, $result[3]);
+ $this->assertEquals(4, count($result));
+
+ $TestModel = new Comment();
+ $result = $TestModel->saveAssociated(array(
+ 'Comment' => array(
+ 'article_id' => 2,
+ 'user_id' => 2,
+ 'comment' => 'New comment with attachment',
+ 'published' => 'Y'
+ ),
+ 'Attachment' => array(
+ 'attachment' => 'some_file.tgz'
+ )));
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ 'id' => '7',
+ 'article_id' => '2',
+ 'user_id' => '2',
+ 'comment' => 'New comment with attachment',
+ 'published' => 'Y'
+ );
+ $this->assertEquals(self::date(), $result[6]['Comment']['updated']);
+ $this->assertEquals(self::date(), $result[6]['Comment']['created']);
+ unset($result[6]['Comment']['updated'], $result[6]['Comment']['created']);
+ $this->assertEquals($expected, $result[6]['Comment']);
+
+ $expected = array(
+ 'id' => '2',
+ 'comment_id' => '7',
+ 'attachment' => 'some_file.tgz'
+ );
+ $this->assertEquals(self::date(), $result[6]['Attachment']['updated']);
+ $this->assertEquals(self::date(), $result[6]['Attachment']['created']);
+ unset($result[6]['Attachment']['updated'], $result[6]['Attachment']['created']);
+ $this->assertEquals($expected, $result[6]['Attachment']);
+ }
+
+/**
+ * testSaveMany method
+ *
+ * @return void
+ */
+ public function testSaveMany() {
+ $this->loadFixtures('Post');
+ $TestModel = new Post();
+ $TestModel->deleteAll(true);
+ $this->assertEquals(array(), $TestModel->find('all'));
+
+ // SQLite seems to reset the PK counter when that happens, so we need this to make the tests pass
+ $this->db->truncate($TestModel);
+
+ $TestModel->saveMany(array(
+ array(
+ 'title' => 'Multi-record post 1',
+ 'body' => 'First multi-record post',
+ 'author_id' => 2
+ ),
+ array(
+ 'title' => 'Multi-record post 2',
+ 'body' => 'Second multi-record post',
+ 'author_id' => 2
+ )));
+
+ $result = $TestModel->find('all', array(
+ 'recursive' => -1,
+ 'order' => 'Post.id ASC'
+ ));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '2',
+ 'title' => 'Multi-record post 1',
+ 'body' => 'First multi-record post',
+ 'published' => 'N'
+ )
+ ),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '2',
+ 'title' => 'Multi-record post 2',
+ 'body' => 'Second multi-record post',
+ 'published' => 'N'
+ )
+ )
+ );
+ $this->assertEquals(self::date(), $result[0]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[0]['Post']['created']);
+ $this->assertEquals(self::date(), $result[1]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[1]['Post']['created']);
+ unset($result[0]['Post']['updated'], $result[0]['Post']['created']);
+ unset($result[1]['Post']['updated'], $result[1]['Post']['created']);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test SaveAssociated with Habtm relations
+ *
+ * @return void
+ */
+ public function testSaveAssociatedHabtm() {
+ $this->loadFixtures('Article', 'Tag', 'Comment', 'User', 'ArticlesTag');
+ $data = array(
+ 'Article' => array(
+ 'user_id' => 1,
+ 'title' => 'Article Has and belongs to Many Tags'
+ ),
+ 'Tag' => array(
+ 'Tag' => array(1, 2)
+ ),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Article comment',
+ 'user_id' => 1
+ )));
+ $Article = new Article();
+ $result = $Article->saveAssociated($data);
+ $this->assertFalse(empty($result));
+
+ $result = $Article->read();
+ $this->assertEquals(2, count($result['Tag']));
+ $this->assertEquals('tag1', $result['Tag'][0]['tag']);
+ $this->assertEquals(1, count($result['Comment']));
+ $this->assertEquals(1, count($result['Comment'][0]['comment']));
+ }
+
+/**
+ * Test SaveAssociated with Habtm relations and extra join table fields
+ *
+ * @return void
+ */
+ public function testSaveAssociatedHabtmWithExtraJoinTableFields() {
+ $this->loadFixtures('Something', 'SomethingElse', 'JoinThing');
+
+ $data = array(
+ 'Something' => array(
+ 'id' => 4,
+ 'title' => 'Extra Fields',
+ 'body' => 'Extra Fields Body',
+ 'published' => '1'
+ ),
+ 'SomethingElse' => array(
+ array('something_else_id' => 1, 'doomed' => '1'),
+ array('something_else_id' => 2, 'doomed' => '0'),
+ array('something_else_id' => 3, 'doomed' => '1')
+ )
+ );
+
+ $Something = new Something();
+ $result = $Something->saveAssociated($data);
+ $this->assertFalse(empty($result));
+ $result = $Something->read();
+
+ $this->assertEquals(3, count($result['SomethingElse']));
+ $this->assertTrue(Set::matches('/Something[id=4]', $result));
+
+ $this->assertTrue(Set::matches('/SomethingElse[id=1]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[something_else_id=1]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=1]/JoinThing[doomed=1]', $result));
+
+ $this->assertTrue(Set::matches('/SomethingElse[id=2]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[something_else_id=2]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=2]/JoinThing[doomed=0]', $result));
+
+ $this->assertTrue(Set::matches('/SomethingElse[id=3]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[something_else_id=3]', $result));
+ $this->assertTrue(Set::matches('/SomethingElse[id=3]/JoinThing[doomed=1]', $result));
+ }
+
+/**
+ * testSaveAssociatedHasOne method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedHasOne() {
+ $model = new Comment();
+ $model->deleteAll(true);
+ $this->assertEquals(array(), $model->find('all'));
+
+ $model->Attachment->deleteAll(true);
+ $this->assertEquals(array(), $model->Attachment->find('all'));
+
+ $this->assertTrue($model->saveAssociated(array(
+ 'Comment' => array(
+ 'comment' => 'Comment with attachment',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Attachment' => array(
+ 'attachment' => 'some_file.zip'
+ ))));
+ $result = $model->find('all', array('fields' => array(
+ 'Comment.id', 'Comment.comment', 'Attachment.id',
+ 'Attachment.comment_id', 'Attachment.attachment'
+ )));
+ $expected = array(array(
+ 'Comment' => array(
+ 'id' => '1',
+ 'comment' => 'Comment with attachment'
+ ),
+ 'Attachment' => array(
+ 'id' => '1',
+ 'comment_id' => '1',
+ 'attachment' => 'some_file.zip'
+ )));
+ $this->assertEquals($expected, $result);
+
+ $model->Attachment->bindModel(array('belongsTo' => array('Comment')), false);
+ $data = array(
+ 'Comment' => array(
+ 'comment' => 'Comment with attachment',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Attachment' => array(
+ 'attachment' => 'some_file.zip'
+ ));
+ $this->assertTrue($model->saveAssociated($data, array('validate' => 'first')));
+ }
+
+/**
+ * testSaveAssociatedBelongsTo method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedBelongsTo() {
+ $model = new Comment();
+ $model->deleteAll(true);
+ $this->assertEquals(array(), $model->find('all'));
+
+ $model->Article->deleteAll(true);
+ $this->assertEquals(array(), $model->Article->find('all'));
+
+ $this->assertTrue($model->saveAssociated(array(
+ 'Comment' => array(
+ 'comment' => 'Article comment',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Article' => array(
+ 'title' => 'Model Associations 101',
+ 'user_id' => 1
+ ))));
+ $result = $model->find('all', array('fields' => array(
+ 'Comment.id', 'Comment.comment', 'Comment.article_id', 'Article.id', 'Article.title'
+ )));
+ $expected = array(array(
+ 'Comment' => array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'comment' => 'Article comment'
+ ),
+ 'Article' => array(
+ 'id' => '1',
+ 'title' => 'Model Associations 101'
+ )));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAssociatedHasOneValidation method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedHasOneValidation() {
+ $model = new Comment();
+ $model->deleteAll(true);
+ $this->assertEquals(array(), $model->find('all'));
+
+ $model->Attachment->deleteAll(true);
+ $this->assertEquals(array(), $model->Attachment->find('all'));
+
+ $model->validate = array('comment' => 'notEmpty');
+ $model->Attachment->validate = array('attachment' => 'notEmpty');
+ $model->Attachment->bindModel(array('belongsTo' => array('Comment')));
+
+ $result = $model->saveAssociated(
+ array(
+ 'Comment' => array(
+ 'comment' => '',
+ 'article_id' => 1,
+ 'user_id' => 1
+ ),
+ 'Attachment' => array('attachment' => '')
+ )
+ );
+ $this->assertFalse($result);
+ $expected = array(
+ 'comment' => array(
+ 'This field cannot be left blank'
+ ),
+ 'Attachment' => array(
+ 'attachment' => array(
+ 'This field cannot be left blank'
+ )
+ )
+ );
+ $this->assertEquals($expected, $model->validationErrors);
+ $this->assertEquals($expected['Attachment'], $model->Attachment->validationErrors);
+ }
+
+/**
+ * testSaveAssociatedAtomic method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedAtomic() {
+ $this->loadFixtures('Article', 'User');
+ $TestModel = new Article();
+
+ $result = $TestModel->saveAssociated(array(
+ 'Article' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author',
+ 'user_id' => 2
+ ),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'user_id' => 2))
+ ), array('atomic' => false));
+
+ $this->assertSame($result, array('Article' => true, 'Comment' => array(true)));
+
+ $result = $TestModel->saveAssociated(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => 'First new comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ),
+ array(
+ 'comment' => 'Second new comment',
+ 'published' => 'Y',
+ 'user_id' => 2
+ ))
+ ), array('validate' => true, 'atomic' => false));
+ $this->assertSame($result, array('Article' => true, 'Comment' => array(true, true)));
+ }
+
+/**
+ * testSaveManyAtomic method
+ *
+ * @return void
+ */
+ public function testSaveManyAtomic() {
+ $this->loadFixtures('Article', 'User');
+ $TestModel = new Article();
+
+ $result = $TestModel->saveMany(array(
+ array(
+ 'id' => '1',
+ 'title' => 'Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => 'Just update the title'
+ ),
+ array(
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'user_id' => 2
+ )
+ ), array('atomic' => false));
+ $this->assertSame($result, array(true, true, true));
+
+ $TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
+ $result = $TestModel->saveMany(array(
+ array(
+ 'id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ )
+ ), array('validate' => true, 'atomic' => false));
+
+ $this->assertSame(array(true, false), $result);
+ }
+
+/**
+ * testSaveAssociatedHasMany method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedHasMany() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+
+ $result = $TestModel->saveAssociated(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ));
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment'
+ );
+ $this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
+
+ $result = $TestModel->saveAssociated(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Third new comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))),
+ array('atomic' => false)
+ );
+ $this->assertFalse(empty($result));
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment',
+ 'Third new comment'
+ );
+ $this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
+
+ $TestModel->beforeSaveReturn = false;
+ $result = $TestModel->saveAssociated(
+ array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Fourth new comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))),
+ array('atomic' => false)
+ );
+ $this->assertEquals(array('Article' => false), $result);
+
+ $result = $TestModel->findById(2);
+ $expected = array(
+ 'First Comment for Second Article',
+ 'Second Comment for Second Article',
+ 'First new comment',
+ 'Second new comment',
+ 'Third new comment'
+ );
+ $this->assertEquals($expected, Hash::extract($result['Comment'], '{n}.comment'));
+ }
+
+/**
+ * testSaveAssociatedHasManyEmpty method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedHasManyEmpty() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+ $TestModel->validate = $TestModel->Comment->validate = array('user_id' => array('notEmpty' => array('rule' => 'notEmpty', 'required' => true)));
+
+ //empty hasMany data is ignored in save
+ $result = $TestModel->saveAssociated(array(
+ 'Article' => array('title' => 'title', 'user_id' => 1),
+ 'Comment' => array()
+ ), array('validate' => true));
+ $this->assertTrue($result);
+
+ $result = $TestModel->saveAssociated(array(
+ 'Article' => array('title' => 'title', 'user_id' => 1),
+ 'Comment' => array()
+ ), array('validate' => true, 'atomic' => false));
+ $this->assertEquals(array('Article' => true), $result);
+
+ //empty primary data is not ignored
+ $result = $TestModel->saveAssociated(array('Article' => array()), array('validate' => true));
+ $this->assertFalse($result);
+
+ $result = $TestModel->saveAssociated(array('Article' => array()), array('validate' => true, 'atomic' => false));
+ $this->assertEquals(array('Article' => false), $result);
+ }
+
+/**
+ * testSaveAssociatedHasManyValidation method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedHasManyValidation() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->validate = array('comment' => 'notEmpty');
+
+ $result = $TestModel->saveAssociated(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array('comment' => '', 'published' => 'Y', 'user_id' => 1),
+ )
+ ), array('validate' => true));
+ $this->assertFalse($result);
+
+ $expected = array('Comment' => array(
+ array('comment' => array('This field cannot be left blank'))
+ ));
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ $expected = array(
+ array('comment' => array('This field cannot be left blank'))
+ );
+ $this->assertEquals($expected, $TestModel->Comment->validationErrors);
+
+ $result = $TestModel->saveAssociated(array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ))
+ ), array('validate' => 'first'));
+ $this->assertFalse($result);
+ }
+
+/**
+ * test saveMany with transactions and ensure there is no missing rollback.
+ *
+ * @return void
+ */
+ public function testSaveManyTransactionNoRollback() {
+ $this->loadFixtures('Post');
+
+ $this->getMock('DboSource', array('connect', 'rollback', 'describe'), array(), 'MockManyTransactionDboSource');
+ $db = ConnectionManager::create('mock_many_transaction', array(
+ 'datasource' => 'MockManyTransactionDboSource',
+ ));
+
+ $db->expects($this->once())
+ ->method('describe')
+ ->will($this->returnValue(array()));
+ $db->expects($this->once())->method('rollback');
+
+ $Post = new Post('mock_many_transaction');
+
+ $Post->validate = array(
+ 'title' => array('rule' => array('notEmpty'))
+ );
+
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => '')
+ );
+ $Post->saveMany($data);
+ }
+
+/**
+ * test saveAssociated with transactions and ensure there is no missing rollback.
+ *
+ * @return void
+ */
+ public function testSaveAssociatedTransactionNoRollback() {
+ $testDb = ConnectionManager::getDataSource('test');
+
+ $mock = $this->getMock(
+ 'DboSource',
+ array('connect', 'rollback', 'describe', 'create', 'begin'),
+ array(),
+ 'MockAssociatedTransactionDboSource',
+ false
+ );
+ $db = ConnectionManager::create('mock_assoc_transaction', array(
+ 'datasource' => 'MockAssociatedTransactionDboSource',
+ ));
+ $this->mockObjects[] = $db;
+ $db->columns = $testDb->columns;
+
+ $db->expects($this->once())->method('rollback');
+ $db->expects($this->any())->method('describe')
+ ->will($this->returnValue(array(
+ 'id' => array('type' => 'integer', 'length' => 11),
+ 'title' => array('type' => 'string'),
+ 'body' => array('type' => 'text'),
+ 'published' => array('type' => 'string')
+ )));
+
+ $Post = new Post();
+ $Post->useDbConfig = 'mock_assoc_transaction';
+ $Post->Author->useDbConfig = 'mock_assoc_transaction';
+
+ $Post->Author->validate = array(
+ 'user' => array('rule' => array('notEmpty'))
+ );
+
+ $data = array(
+ 'Post' => array(
+ 'title' => 'New post',
+ 'body' => 'Content',
+ 'published' => 'Y'
+ ),
+ 'Author' => array(
+ 'user' => '',
+ 'password' => "sekret"
+ )
+ );
+ $Post->saveAssociated($data, array('validate' => true, 'atomic' => true));
+ }
+
+/**
+ * test saveMany with nested saveMany call.
+ *
+ * @return void
+ */
+ public function testSaveManyNestedSaveMany() {
+ $this->loadFixtures('Sample');
+ $TransactionManyTestModel = new TransactionManyTestModel();
+
+ $data = array(
+ array('apple_id' => 1, 'name' => 'sample5'),
+ );
+
+ $this->assertTrue($TransactionManyTestModel->saveMany($data, array('atomic' => true)));
+ }
+
+/**
+ * testSaveManyTransaction method
+ *
+ * @return void
+ */
+ public function testSaveManyTransaction() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
+ $TestModel = new Post();
+
+ $TestModel->validate = array('title' => 'notEmpty');
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => 'New Fifth Post'),
+ array('author_id' => 1, 'title' => '')
+ );
+ $this->assertFalse($TestModel->saveMany($data));
+
+ $result = $TestModel->find('all', array('recursive' => -1));
+ $expected = array(
+ array('Post' => array(
+ 'id' => '1',
+ 'author_id' => 1,
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array('Post' => array(
+ 'id' => '2',
+ 'author_id' => 3,
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )),
+ array('Post' => array(
+ 'id' => '3',
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )));
+
+ if (count($result) != 3) {
+ // Database doesn't support transactions
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => 1,
+ 'title' => 'New Fourth Post',
+ 'body' => null,
+ 'published' => 'N'
+ ));
+
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '5',
+ 'author_id' => 1,
+ 'title' => 'New Fifth Post',
+ 'body' => null,
+ 'published' => 'N',
+ ));
+
+ $this->assertEquals(self::date(), $result[3]['Post']['created']);
+ $this->assertEquals(self::date(), $result[3]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[4]['Post']['created']);
+ $this->assertEquals(self::date(), $result[4]['Post']['updated']);
+ unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
+ unset($result[4]['Post']['created'], $result[4]['Post']['updated']);
+ $this->assertEquals($expected, $result);
+ // Skip the rest of the transactional tests
+ return;
+ }
+
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => ''),
+ array('author_id' => 1, 'title' => 'New Sixth Post')
+ );
+ $this->assertFalse($TestModel->saveMany($data));
+
+ $result = $TestModel->find('all', array('recursive' => -1));
+ $expected = array(
+ array('Post' => array(
+ 'id' => '1',
+ 'author_id' => 1,
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:39:23',
+ 'updated' => '2007-03-18 10:41:31'
+ )),
+ array('Post' => array(
+ 'id' => '2',
+ 'author_id' => 3,
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23',
+ 'updated' => '2007-03-18 10:43:31'
+ )),
+ array('Post' => array(
+ 'id' => '3',
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )));
+
+ if (count($result) != 3) {
+ // Database doesn't support transactions
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => 1,
+ 'title' => 'New Fourth Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'N'
+ ));
+
+ $expected[] = array(
+ 'Post' => array(
+ 'id' => '5',
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'N'
+ ));
+ $this->assertEquals(self::date(), $result[3]['Post']['created']);
+ $this->assertEquals(self::date(), $result[3]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[4]['Post']['created']);
+ $this->assertEquals(self::date(), $result[4]['Post']['updated']);
+ unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
+ unset($result[4]['Post']['created'], $result[4]['Post']['updated']);
+ }
+ $this->assertEquals($expected, $result);
+
+ $TestModel->validate = array('title' => 'notEmpty');
+ $data = array(
+ array('author_id' => 1, 'title' => 'New Fourth Post'),
+ array('author_id' => 1, 'title' => 'New Fifth Post'),
+ array('author_id' => 1, 'title' => 'New Sixth Post')
+ );
+ $this->assertTrue($TestModel->saveMany($data));
+
+ $result = $TestModel->find('all', array(
+ 'recursive' => -1,
+ 'fields' => array('author_id', 'title','body','published'),
+ 'order' => array('Post.created' => 'ASC')
+ ));
+
+ $expected = array(
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'First Post',
+ 'body' => 'First Post Body',
+ 'published' => 'Y'
+ )),
+ array('Post' => array(
+ 'author_id' => 3,
+ 'title' => 'Second Post',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'New Fourth Post',
+ 'body' => '',
+ 'published' => 'N'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'New Fifth Post',
+ 'body' => '',
+ 'published' => 'N'
+ )),
+ array('Post' => array(
+ 'author_id' => 1,
+ 'title' => 'New Sixth Post',
+ 'body' => '',
+ 'published' => 'N'
+ )));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveManyValidation method
+ *
+ * @return void
+ */
+ public function testSaveManyValidation() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
+ $TestModel = new Post();
+
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => 'Just update the title'
+ ),
+ array(
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'author_id' => 2
+ ));
+
+ $this->assertTrue($TestModel->saveMany($data));
+
+ $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '1',
+ 'title' => 'Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N',
+ 'created' => '2007-03-18 10:39:23'
+ )
+ ),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '3',
+ 'title' => 'Just update the title',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:41:23'
+ )
+ ),
+ array(
+ 'Post' => array(
+ 'id' => '3',
+ 'author_id' => '1',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ 'created' => '2007-03-18 10:43:23',
+ 'updated' => '2007-03-18 10:45:31'
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => '2',
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'published' => 'N'
+ )
+ )
+ );
+
+ $this->assertEquals(self::date(), $result[0]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[1]['Post']['updated']);
+ $this->assertEquals(self::date(), $result[3]['Post']['created']);
+ $this->assertEquals(self::date(), $result[3]['Post']['updated']);
+ unset($result[0]['Post']['updated'], $result[1]['Post']['updated']);
+ unset($result[3]['Post']['created'], $result[3]['Post']['updated']);
+ $this->assertEquals($expected, $result);
+
+ $TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ ));
+ $result = $TestModel->saveMany($data);
+ $this->assertFalse($result);
+
+ $result = $TestModel->find('all', array('recursive' => -1, 'order' => 'Post.id ASC'));
+ $errors = array(1 => array('title' => array('This field cannot be left blank')));
+ $transactionWorked = Set::matches('/Post[1][title=Baleeted First Post]', $result);
+ if (!$transactionWorked) {
+ $this->assertTrue(Set::matches('/Post[1][title=Un-Baleeted First Post]', $result));
+ $this->assertTrue(Set::matches('/Post[2][title=Just update the title]', $result));
+ }
+
+ $this->assertEquals($errors, $TestModel->validationErrors);
+
+ $TestModel->validate = array('title' => 'notEmpty', 'author_id' => 'numeric');
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ ));
+ $result = $TestModel->saveMany($data, array('validate' => true, 'atomic' => false));
+ $this->assertEquals(array(true, false), $result);
+
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'author_id', 'title', 'body', 'published'),
+ 'recursive' => -1,
+ 'order' => 'Post.id ASC'
+ ));
+ $errors = array(1 => array('title' => array('This field cannot be left blank')));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '1',
+ 'title' => 'Un-Baleeted First Post',
+ 'body' => 'Not Baleeted!',
+ 'published' => 'Y',
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '3',
+ 'title' => 'Just update the title',
+ 'body' => 'Second Post Body',
+ 'published' => 'Y',
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '3',
+ 'author_id' => '1',
+ 'title' => 'Third Post',
+ 'body' => 'Third Post Body',
+ 'published' => 'Y',
+ )),
+ array(
+ 'Post' => array(
+ 'id' => '4',
+ 'author_id' => '2',
+ 'title' => 'Creating a fourth post',
+ 'body' => 'Fourth post body',
+ 'published' => 'N',
+ )));
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($errors, $TestModel->validationErrors);
+
+ $data = array(
+ array(
+ 'id' => '1',
+ 'title' => 'Re-Baleeted First Post',
+ 'body' => 'Baleeted!',
+ 'published' => 'N'
+ ),
+ array(
+ 'id' => '2',
+ 'title' => '',
+ 'body' => 'Trying to get away with an empty title'
+ ));
+ $this->assertFalse($TestModel->saveMany($data, array('validate' => 'first')));
+
+ $result = $TestModel->find('all', array(
+ 'fields' => array('id', 'author_id', 'title', 'body', 'published'),
+ 'recursive' => -1,
+ 'order' => 'Post.id ASC'
+ ));
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($errors, $TestModel->validationErrors);
+ }
+
+/**
+ * testValidateMany method
+ *
+ * @return void
+ */
+ public function testValidateMany() {
+ $TestModel = new Article();
+ $TestModel->validate = array('title' => 'notEmpty');
+ $data = array(
+ 0 => array('title' => ''),
+ 1 => array('title' => 'title 1'),
+ 2 => array('title' => 'title 2'),
+ );
+ $result = $TestModel->validateMany($data);
+ $this->assertFalse($result);
+ $expected = array(
+ 0 => array('title' => array('This field cannot be left blank')),
+ );
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $data = array(
+ 0 => array('title' => 'title 0'),
+ 1 => array('title' => ''),
+ 2 => array('title' => 'title 2'),
+ );
+ $result = $TestModel->validateMany($data);
+ $this->assertFalse($result);
+ $expected = array(
+ 1 => array('title' => array('This field cannot be left blank')),
+ );
+ $this->assertEquals($expected, $TestModel->validationErrors);
+ }
+
+/**
+ * testSaveAssociatedValidateFirst method
+ *
+ * @return void
+ */
+ public function testSaveAssociatedValidateFirst() {
+ $this->loadFixtures('Article', 'Comment', 'Attachment');
+ $model = new Article();
+ $model->deleteAll(true);
+
+ $model->Comment->validate = array('comment' => 'notEmpty');
+ $result = $model->saveAssociated(array(
+ 'Article' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved author'
+ ),
+ 'Comment' => array(
+ array('comment' => 'First new comment'),
+ array('comment' => '')
+ )
+ ), array('validate' => 'first'));
+
+ $this->assertFalse($result);
+
+ $result = $model->find('all');
+ $this->assertEquals(array(), $result);
+ $expected = array('Comment' => array(
+ 1 => array('comment' => array('This field cannot be left blank'))
+ ));
+
+ $this->assertEquals($expected['Comment'], $model->Comment->validationErrors);
+
+ $this->assertSame($model->Comment->find('count'), 0);
+
+ $result = $model->saveAssociated(
+ array(
+ 'Article' => array(
+ 'title' => 'Post with Author',
+ 'body' => 'This post will be saved with an author',
+ 'user_id' => 2
+ ),
+ 'Comment' => array(
+ array(
+ 'comment' => 'Only new comment',
+ 'user_id' => 2
+ ))),
+ array('validate' => 'first')
+ );
+
+ $this->assertSame($result, true);
+
+ $result = $model->Comment->find('all');
+ $this->assertSame(count($result), 1);
+ $result = Hash::extract($result, '{n}.Comment.article_id');
+ $this->assertEquals(4, $result[0]);
+
+ $model->deleteAll(true);
+ $data = array(
+ 'Article' => array(
+ 'title' => 'Post with Author saveAlled from comment',
+ 'body' => 'This post will be saved with an author',
+ 'user_id' => 2
+ ),
+ 'Comment' => array(
+ 'comment' => 'Only new comment', 'user_id' => 2
+ ));
+
+ $result = $model->Comment->saveAssociated($data, array('validate' => 'first'));
+ $this->assertFalse(empty($result));
+
+ $result = $model->find('all');
+ $this->assertEquals(
+ 'Post with Author saveAlled from comment',
+ $result[0]['Article']['title']
+ );
+ $this->assertEquals('Only new comment', $result[0]['Comment'][0]['comment']);
+ }
+
+/**
+ * test saveMany()'s return is correct when using atomic = false and validate = first.
+ *
+ * @return void
+ */
+ public function testSaveManyValidateFirstAtomicFalse() {
+ $Something = new Something();
+ $invalidData = array(
+ array(
+ 'title' => 'foo',
+ 'body' => 'bar',
+ 'published' => 'baz',
+ ),
+ array(
+ 'body' => 3,
+ 'published' => 'sd',
+ ),
+ );
+ $Something->create();
+ $Something->validate = array(
+ 'title' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true,
+ ),
+ 'body' => array(
+ 'rule' => 'alphaNumeric',
+ 'required' => true,
+ 'allowEmpty' => true,
+ ),
+ );
+ $result = $Something->saveMany($invalidData, array(
+ 'atomic' => false,
+ 'validate' => 'first',
+ ));
+ $expected = array(true, false);
+ $this->assertEquals($expected, $result);
+
+ $Something = new Something();
+ $validData = array(
+ array(
+ 'title' => 'title value',
+ 'body' => 'body value',
+ 'published' => 'baz',
+ ),
+ array(
+ 'title' => 'valid',
+ 'body' => 'this body',
+ 'published' => 'sd',
+ ),
+ );
+ $Something->create();
+ $result = $Something->saveMany($validData, array(
+ 'atomic' => false,
+ 'validate' => 'first',
+ ));
+ $expected = array(true, true);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testValidateAssociated method
+ *
+ * @return void
+ */
+ public function testValidateAssociated() {
+ $this->loadFixtures('Attachment', 'Article', 'Comment');
+ $TestModel = new Comment();
+ $TestModel->Attachment->validate = array('attachment' => 'notEmpty');
+
+ $data = array(
+ 'Comment' => array(
+ 'comment' => 'This is the comment'
+ ),
+ 'Attachment' => array(
+ 'attachment' => ''
+ )
+ );
+
+ $result = $TestModel->validateAssociated($data);
+ $this->assertFalse($result);
+
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+ $TestModel->Comment->validate = array('comment' => 'notEmpty');
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1),
+ array(
+ 'id' => 2,
+ 'comment' =>
+ 'comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ )));
+ $result = $TestModel->validateAssociated($data);
+ $this->assertFalse($result);
+
+ $data = array(
+ 'Article' => array('id' => 2),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ),
+ array(
+ 'id' => 2,
+ 'comment' => 'comment',
+ 'published' => 'Y',
+ 'user_id' => 1
+ ),
+ array(
+ 'id' => 3,
+ 'comment' => '',
+ 'published' => 'Y',
+ 'user_id' => 1
+ )));
+ $result = $TestModel->validateAssociated($data, array(
+ 'atomic' => false
+ ));
+ $expected = array(
+ 'Article' => true,
+ 'Comment' => array(false, true, false)
+ );
+ $this->assertSame($expected, $result);
+
+ $expected = array('Comment' => array(
+ 0 => array('comment' => array('This field cannot be left blank')),
+ 2 => array('comment' => array('This field cannot be left blank'))
+ ));
+ $this->assertEquals($expected, $TestModel->validationErrors);
+
+ $expected = array(
+ 0 => array('comment' => array('This field cannot be left blank')),
+ 2 => array('comment' => array('This field cannot be left blank'))
+ );
+ $this->assertEquals($expected, $TestModel->Comment->validationErrors);
+ }
+
+/**
+ * test that saveMany behaves like plain save() when suplied empty data
+ *
+ * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
+ * @return void
+ */
+ public function testSaveManyEmptyData() {
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
+ $model = new Article();
+ $result = $model->saveMany(array(), array('validate' => true));
+ $this->assertFalse(empty($result));
+
+ $model = new ProductUpdateAll();
+ $result = $model->saveMany(array());
+ $this->assertFalse($result);
+ }
+
+/**
+ * test that saveAssociated behaves like plain save() when supplied empty data
+ *
+ * @link http://cakephp.lighthouseapp.com/projects/42648/tickets/277-test-saveall-with-validation-returns-incorrect-boolean-when-saving-empty-data
+ * @return void
+ */
+ public function testSaveAssociatedEmptyData() {
+ $this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
+
+ $this->loadFixtures('Article', 'ProductUpdateAll', 'Comment', 'Attachment');
+ $model = new Article();
+ $result = $model->saveAssociated(array(), array('validate' => true));
+ $this->assertFalse(empty($result));
+
+ $model = new ProductUpdateAll();
+ $result = $model->saveAssociated(array());
+ $this->assertFalse($result);
+ }
+
+/**
+ * testUpdateWithCalculation method
+ *
+ * @return void
+ */
+ public function testUpdateWithCalculation() {
+ $this->loadFixtures('DataTest');
+ $model = new DataTest();
+ $model->deleteAll(true);
+ $result = $model->saveMany(array(
+ array('count' => 5, 'float' => 1.1),
+ array('count' => 3, 'float' => 1.2),
+ array('count' => 4, 'float' => 1.3),
+ array('count' => 1, 'float' => 2.0),
+ ));
+ $this->assertFalse(empty($result));
+
+ $result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
+ $this->assertEquals(array(5, 3, 4, 1), $result);
+
+ $this->assertTrue($model->updateAll(array('count' => 'count + 2')));
+ $result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
+ $this->assertEquals(array(7, 5, 6, 3), $result);
+
+ $this->assertTrue($model->updateAll(array('DataTest.count' => 'DataTest.count - 1')));
+ $result = Hash::extract($model->find('all', array('fields' => 'count')), '{n}.DataTest.count');
+ $this->assertEquals(array(6, 4, 5, 2), $result);
+ }
+
+ public function testToggleBoolFields() {
+ $this->loadFixtures('CounterCacheUser', 'CounterCachePost');
+ $Post = new CounterCachePost();
+ $Post->unbindModel(array('belongsTo' => array('User')), true);
+
+ $true = array('Post' => array('published' => true, 'id' => 2));
+ $false = array('Post' => array('published' => false, 'id' => 2));
+ $fields = array('Post.published', 'Post.id');
+ $updateConditions = array('Post.id' => 2);
+
+ // check its true
+ $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
+ $this->assertEquals($true, $result);
+
+ // Testing without the alias
+ $this->assertTrue($Post->updateAll(array('published' => 'NOT published'), $updateConditions));
+ $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
+ $this->assertEquals($false, $result);
+
+ $this->assertTrue($Post->updateAll(array('published' => 'NOT published'), $updateConditions));
+ $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
+ $this->assertEquals($true, $result);
+
+ $db = ConnectionManager::getDataSource('test');
+ $alias = $db->name('Post.published');
+
+ // Testing with the alias
+ $this->assertTrue($Post->updateAll(array('Post.published' => "NOT $alias"), $updateConditions));
+ $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
+ $this->assertEquals($false, $result);
+
+ $this->assertTrue($Post->updateAll(array('Post.published' => "NOT $alias"), $updateConditions));
+ $result = $Post->find('first', array('conditions' => $updateConditions, 'fields' => $fields));
+ $this->assertEquals($true, $result);
+ }
+
+/**
+ * TestFindAllWithoutForeignKey
+ *
+ * @return void
+ */
+ public function testFindAllForeignKey() {
+ $this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
+ $ProductUpdateAll = new ProductUpdateAll();
+
+ $conditions = array('Group.name' => 'group one');
+
+ $ProductUpdateAll->bindModel(array(
+ 'belongsTo' => array(
+ 'Group' => array('className' => 'GroupUpdateAll')
+ )
+ ));
+
+ $ProductUpdateAll->belongsTo = array(
+ 'Group' => array('className' => 'GroupUpdateAll', 'foreignKey' => 'group_id')
+ );
+
+ $results = $ProductUpdateAll->find('all', compact('conditions'));
+ $this->assertTrue(!empty($results));
+
+ $ProductUpdateAll->bindModel(array('belongsTo' => array('Group')));
+ $ProductUpdateAll->belongsTo = array(
+ 'Group' => array(
+ 'className' => 'GroupUpdateAll',
+ 'foreignKey' => false,
+ 'conditions' => 'ProductUpdateAll.groupcode = Group.code'
+ ));
+
+ $resultsFkFalse = $ProductUpdateAll->find('all', compact('conditions'));
+ $this->assertTrue(!empty($resultsFkFalse));
+ $expected = array(
+ '0' => array(
+ 'ProductUpdateAll' => array(
+ 'id' => 1,
+ 'name' => 'product one',
+ 'groupcode' => 120,
+ 'group_id' => 1),
+ 'Group' => array(
+ 'id' => 1,
+ 'name' => 'group one',
+ 'code' => 120)
+ ),
+ '1' => array(
+ 'ProductUpdateAll' => array(
+ 'id' => 2,
+ 'name' => 'product two',
+ 'groupcode' => 120,
+ 'group_id' => 1),
+ 'Group' => array(
+ 'id' => 1,
+ 'name' => 'group one',
+ 'code' => 120)
+ )
+
+ );
+ $this->assertEquals($expected, $results);
+ $this->assertEquals($expected, $resultsFkFalse);
+ }
+
+/**
+ * test updateAll with empty values.
+ *
+ * @return void
+ */
+ public function testUpdateAllEmptyValues() {
+ $this->skipIf($this->db instanceof Sqlserver || $this->db instanceof Postgres, 'This test is not compatible with Postgres or SQL Server.');
+
+ $this->loadFixtures('Author', 'Post');
+ $model = new Author();
+ $result = $model->updateAll(array('user' => '""'));
+ $this->assertTrue($result);
+ }
+
+/**
+ * testUpdateAllWithJoins
+ *
+ * @return void
+ */
+ public function testUpdateAllWithJoins() {
+ $this->skipIf(!$this->db instanceof Mysql, 'Currently, there is no way of doing joins in an update statement in postgresql or sqlite');
+
+ $this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
+ $ProductUpdateAll = new ProductUpdateAll();
+
+ $conditions = array('Group.name' => 'group one');
+
+ $ProductUpdateAll->bindModel(array('belongsTo' => array(
+ 'Group' => array('className' => 'GroupUpdateAll')))
+ );
+
+ $ProductUpdateAll->updateAll(array('name' => "'new product'"), $conditions);
+ $results = $ProductUpdateAll->find('all', array(
+ 'conditions' => array('ProductUpdateAll.name' => 'new product')
+ ));
+ $expected = array(
+ '0' => array(
+ 'ProductUpdateAll' => array(
+ 'id' => 1,
+ 'name' => 'new product',
+ 'groupcode' => 120,
+ 'group_id' => 1),
+ 'Group' => array(
+ 'id' => 1,
+ 'name' => 'group one',
+ 'code' => 120)
+ ),
+ '1' => array(
+ 'ProductUpdateAll' => array(
+ 'id' => 2,
+ 'name' => 'new product',
+ 'groupcode' => 120,
+ 'group_id' => 1),
+ 'Group' => array(
+ 'id' => 1,
+ 'name' => 'group one',
+ 'code' => 120)));
+
+ $this->assertEquals($expected, $results);
+ }
+
+/**
+ * testUpdateAllWithoutForeignKey
+ *
+ * @return void
+ */
+ public function testUpdateAllWithoutForeignKey() {
+ $this->skipIf(!$this->db instanceof Mysql, 'Currently, there is no way of doing joins in an update statement in postgresql');
+
+ $this->loadFixtures('ProductUpdateAll', 'GroupUpdateAll');
+ $ProductUpdateAll = new ProductUpdateAll();
+
+ $conditions = array('Group.name' => 'group one');
+
+ $ProductUpdateAll->bindModel(array('belongsTo' => array(
+ 'Group' => array('className' => 'GroupUpdateAll')
+ )));
+
+ $ProductUpdateAll->belongsTo = array(
+ 'Group' => array(
+ 'className' => 'GroupUpdateAll',
+ 'foreignKey' => false,
+ 'conditions' => 'ProductUpdateAll.groupcode = Group.code'
+ )
+ );
+
+ $ProductUpdateAll->updateAll(array('name' => "'new product'"), $conditions);
+ $resultsFkFalse = $ProductUpdateAll->find('all', array('conditions' => array('ProductUpdateAll.name' => 'new product')));
+ $expected = array(
+ '0' => array(
+ 'ProductUpdateAll' => array(
+ 'id' => 1,
+ 'name' => 'new product',
+ 'groupcode' => 120,
+ 'group_id' => 1),
+ 'Group' => array(
+ 'id' => 1,
+ 'name' => 'group one',
+ 'code' => 120)
+ ),
+ '1' => array(
+ 'ProductUpdateAll' => array(
+ 'id' => 2,
+ 'name' => 'new product',
+ 'groupcode' => 120,
+ 'group_id' => 1),
+ 'Group' => array(
+ 'id' => 1,
+ 'name' => 'group one',
+ 'code' => 120)));
+ $this->assertEquals($expected, $resultsFkFalse);
+ }
+
+/**
+ * test writing floats in german locale.
+ *
+ * @return void
+ */
+ public function testWriteFloatAsGerman() {
+ $restore = setlocale(LC_NUMERIC, 0);
+ setlocale(LC_NUMERIC, 'de_DE');
+
+ $model = new DataTest();
+ $result = $model->save(array(
+ 'count' => 1,
+ 'float' => 3.14593
+ ));
+ $this->assertTrue((bool)$result);
+ setlocale(LC_NUMERIC, $restore);
+ }
+
+/**
+ * Test returned array contains primary key when save creates a new record
+ *
+ * @return void
+ */
+ public function testPkInReturnArrayForCreate() {
+ $this->loadFixtures('Article');
+ $TestModel = new Article();
+
+ $data = array('Article' => array(
+ 'user_id' => '1',
+ 'title' => 'Fourth Article',
+ 'body' => 'Fourth Article Body',
+ 'published' => 'Y'
+ ));
+ $result = $TestModel->save($data);
+ $this->assertSame($result['Article']['id'], $TestModel->id);
+ }
+
+/**
+ * testSaveAllFieldListValidateBelongsTo
+ *
+ * @return void
+ */
+ public function testSaveAllFieldListValidateBelongsTo() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment');
+ $TestModel = new Post();
+
+ $result = $TestModel->find('all');
+ $this->assertEquals(3, count($result));
+ $this->assertFalse(isset($result[3]));
+
+ // test belongsTo
+ $fieldList = array(
+ 'Post' => array('title', 'author_id'),
+ 'Author' => array('user')
+ );
+ $TestModel->saveAll(array(
+ 'Post' => array(
+ 'title' => 'Post without body',
+ 'body' => 'This will not be saved',
+ ),
+ 'Author' => array(
+ 'user' => 'bob',
+ 'test' => 'This will not be saved',
+
+ )), array('fieldList' => $fieldList));
+
+ $result = $TestModel->find('all');
+ $expected = array(
+ 'Post' => array (
+ 'id' => '4',
+ 'author_id' => '5',
+ 'title' => 'Post without body',
+ 'body' => null,
+ 'published' => 'N',
+ 'created' => self::date(),
+ 'updated' => self::date(),
+ ),
+ 'Author' => array (
+ 'id' => '5',
+ 'user' => 'bob',
+ 'password' => null,
+ 'created' => self::date(),
+ 'updated' => self::date(),
+ 'test' => 'working',
+ ),
+ );
+ $this->assertEquals($expected, $result[3]);
+ $this->assertEquals(4, count($result));
+ $this->assertEquals('', $result[3]['Post']['body']);
+ $this->assertEquals('working', $result[3]['Author']['test']);
+
+ // test multirecord
+ $this->db->truncate($TestModel);
+
+ $fieldList = array('title', 'author_id');
+ $TestModel->saveAll(array(
+ array(
+ 'title' => 'Multi-record post 1',
+ 'body' => 'First multi-record post',
+ 'author_id' => 2
+ ),
+ array(
+ 'title' => 'Multi-record post 2',
+ 'body' => 'Second multi-record post',
+ 'author_id' => 2
+ )), array('fieldList' => $fieldList));
+
+ $result = $TestModel->find('all', array(
+ 'recursive' => -1,
+ 'order' => 'Post.id ASC'
+ ));
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => '1',
+ 'author_id' => '2',
+ 'title' => 'Multi-record post 1',
+ 'body' => '',
+ 'published' => 'N',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ )
+ ),
+ array(
+ 'Post' => array(
+ 'id' => '2',
+ 'author_id' => '2',
+ 'title' => 'Multi-record post 2',
+ 'body' => '',
+ 'published' => 'N',
+ 'created' => self::date(),
+ 'updated' => self::date()
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllFieldListHasMany method
+ *
+ * return @void
+ */
+ public function testSaveAllFieldListHasMany() {
+ $this->loadFixtures('Article', 'Comment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+
+ $this->db->truncate($TestModel);
+ $this->db->truncate(new Comment());
+
+ $fieldList = array(
+ 'Article' => array('id'),
+ 'Comment' => array('article_id', 'user_id')
+ );
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2, 'title' => 'I will not save'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
+ array('comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2)
+ )
+ ), array('fieldList' => $fieldList));
+
+ $result = $TestModel->find('all');
+ $this->assertEquals('', $result[0]['Article']['title']);
+ $this->assertEquals('', $result[0]['Comment'][0]['comment']);
+ $this->assertEquals('', $result[0]['Comment'][1]['comment']);
+ }
+
+/**
+ * testSaveAllFieldListHasOne method
+ *
+ * @return void
+ */
+ public function testSaveAllFieldListHasOne() {
+ $this->loadFixtures('Attachment', 'Comment', 'Article', 'User');
+ $TestModel = new Comment();
+
+ $TestModel->validate = array('comment' => 'notEmpty');
+ $TestModel->Attachment->validate = array('attachment' => 'notEmpty');
+
+ $record = array(
+ 'Comment' => array(
+ 'user_id' => 1,
+ 'article_id' => 1,
+ 'comment' => '',
+ ),
+ 'Attachment' => array(
+ 'attachment' => ''
+ )
+ );
+ $result = $TestModel->saveAll($record, array('validate' => 'only'));
+ $this->assertFalse($result);
+
+ $fieldList = array(
+ 'Comment' => array('id', 'article_id', 'user_id'),
+ 'Attachment' => array('comment_id')
+ );
+ $result = $TestModel->saveAll($record, array(
+ 'fieldList' => $fieldList, 'validate' => 'only'
+ ));
+ $this->assertTrue($result);
+ $this->assertEmpty($TestModel->validationErrors);
+ }
+
+/**
+ * testSaveAllDeepFieldListValidateBelongsTo
+ *
+ * @return void
+ */
+ public function testSaveAllDeepFieldListValidateBelongsTo() {
+ $this->loadFixtures('Post', 'Author', 'Comment', 'Attachment', 'Article', 'User');
+ $TestModel = new Post();
+ $TestModel->Author->bindModel(array('hasMany' => array('Comment' => array('foreignKey' => 'user_id'))), false);
+ $TestModel->recursive = 2;
+
+ $result = $TestModel->find('all');
+ $this->assertEquals(3, count($result));
+ $this->assertFalse(isset($result[3]));
+
+ // test belongsTo
+ $fieldList = array(
+ 'Post' => array('title', 'author_id'),
+ 'Author' => array('user'),
+ 'Comment' => array('comment')
+ );
+ $TestModel->saveAll(array(
+ 'Post' => array(
+ 'title' => 'Post without body',
+ 'body' => 'This will not be saved',
+ ),
+ 'Author' => array(
+ 'user' => 'bob',
+ 'test' => 'This will not be saved',
+ 'Comment' => array(
+ array('id' => 5, 'comment' => 'I am still published', 'published' => 'N'))
+
+ )), array('fieldList' => $fieldList, 'deep' => true));
+
+ $result = $TestModel->Author->Comment->find('first', array(
+ 'conditions' => array('Comment.id' => 5),
+ 'fields' => array('comment', 'published')
+ ));
+ $expected = array(
+ 'Comment' => array(
+ 'comment' => 'I am still published',
+ 'published' => 'Y'
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllDeepFieldListHasMany method
+ *
+ * return @void
+ */
+ public function testSaveAllDeepFieldListHasMany() {
+ $this->loadFixtures('Article', 'Comment', 'User');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+
+ $this->db->truncate($TestModel);
+ $this->db->truncate(new Comment());
+
+ $fieldList = array(
+ 'Article' => array('id'),
+ 'Comment' => array('article_id', 'user_id'),
+ 'User' => array('user')
+ );
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2, 'title' => 'I will not save'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
+ array(
+ 'comment' => 'Second new comment', 'published' => 'Y', 'user_id' => 2,
+ 'User' => array('user' => 'nopassword', 'password' => 'not saved')
+ )
+ )
+ ), array('fieldList' => $fieldList, 'deep' => true));
+
+ $result = $TestModel->Comment->User->find('first', array(
+ 'conditions' => array('User.user' => 'nopassword'),
+ 'fields' => array('user', 'password')
+ ));
+ $expected = array(
+ 'User' => array(
+ 'user' => 'nopassword',
+ 'password' => ''
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllDeepHasManyBelongsTo method
+ *
+ * return @void
+ */
+ public function testSaveAllDeepHasManyBelongsTo() {
+ $this->loadFixtures('Article', 'Comment', 'User');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = array();
+
+ $this->db->truncate($TestModel);
+ $this->db->truncate(new Comment());
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2, 'title' => 'The title'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
+ array(
+ 'comment' => 'belongsto', 'published' => 'Y',
+ 'User' => array('user' => 'findme', 'password' => 'somepass')
+ )
+ )
+ ), array('deep' => true));
+
+ $result = $TestModel->Comment->User->find('first', array(
+ 'conditions' => array('User.user' => 'findme'),
+ 'fields' => array('id', 'user', 'password')
+ ));
+ $expected = array(
+ 'User' => array(
+ 'id' => 5,
+ 'user' => 'findme',
+ 'password' => 'somepass',
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Comment->find('first', array(
+ 'conditions' => array('Comment.user_id' => 5),
+ 'fields' => array('id', 'comment', 'published', 'user_id')
+ ));
+ $expected = array(
+ 'Comment' => array(
+ 'id' => 2,
+ 'comment' => 'belongsto',
+ 'published' => 'Y',
+ 'user_id' => 5
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllDeepHasManyhasMany method
+ *
+ * return @void
+ */
+ public function testSaveAllDeepHasManyHasMany() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
+ $TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
+ $TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
+
+ $this->db->truncate($TestModel);
+ $this->db->truncate(new Comment());
+ $this->db->truncate(new Attachment());
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2, 'title' => 'The title'),
+ 'Comment' => array(
+ array('comment' => 'First new comment', 'published' => 'Y', 'user_id' => 1),
+ array(
+ 'comment' => 'hasmany', 'published' => 'Y', 'user_id' => 5,
+ 'Attachment' => array(
+ array('attachment' => 'first deep attachment'),
+ array('attachment' => 'second deep attachment'),
+ )
+ )
+ )
+ ), array('deep' => true));
+
+ $result = $TestModel->Comment->find('first', array(
+ 'conditions' => array('Comment.comment' => 'hasmany'),
+ 'fields' => array('id', 'comment', 'published', 'user_id'),
+ 'recursive' => -1
+ ));
+ $expected = array(
+ 'Comment' => array(
+ 'id' => 2,
+ 'comment' => 'hasmany',
+ 'published' => 'Y',
+ 'user_id' => 5
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $TestModel->Comment->Attachment->find('all', array(
+ 'fields' => array('attachment', 'comment_id'),
+ 'order' => array('Attachment.id' => 'ASC')
+ ));
+ $expected = array(
+ array('Attachment' => array('attachment' => 'first deep attachment', 'comment_id' => 2)),
+ array('Attachment' => array('attachment' => 'second deep attachment', 'comment_id' => 2)),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testSaveAllDeepOrderHasManyHasMany method
+ *
+ * return @void
+ */
+ public function testSaveAllDeepOrderHasManyHasMany() {
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
+ $TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
+ $TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
+
+ $this->db->truncate($TestModel);
+ $this->db->truncate(new Comment());
+ $this->db->truncate(new Attachment());
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 2, 'title' => 'Comment has its data after Attachment'),
+ 'Comment' => array(
+ array(
+ 'Attachment' => array(
+ array('attachment' => 'attachment should be created with comment_id'),
+ array('attachment' => 'comment should be created with article_id'),
+ ),
+ 'comment' => 'after associated data',
+ 'user_id' => 1
+ )
+ )
+ ), array('deep' => true));
+ $result = $TestModel->Comment->find('first', array(
+ 'conditions' => array('Comment.article_id' => 2),
+ ));
+
+ $this->assertEquals(2, $result['Comment']['article_id']);
+ $this->assertEquals(2, count($result['Attachment']));
+ }
+
+/**
+ * testSaveAllDeepEmptyHasManyHasMany method
+ *
+ * return @void
+ */
+ public function testSaveAllDeepEmptyHasManyHasMany() {
+ $this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.');
+ $this->loadFixtures('Article', 'Comment', 'User', 'Attachment');
+ $TestModel = new Article();
+ $TestModel->belongsTo = $TestModel->hasAndBelongsToMany = $TestModel->Comment->belongsTo = array();
+ $TestModel->Comment->unbindModel(array('hasOne' => array('Attachment')), false);
+ $TestModel->Comment->bindModel(array('hasMany' => array('Attachment')), false);
+
+ $this->db->truncate($TestModel);
+ $this->db->truncate(new Comment());
+ $this->db->truncate(new Attachment());
+
+ $result = $TestModel->saveAll(array(
+ 'Article' => array('id' => 3, 'title' => 'Comment has no data'),
+ 'Comment' => array(
+ array(
+ 'Attachment' => array(
+ array('attachment' => 'attachment should be created with comment_id'),
+ array('attachment' => 'comment should be created with article_id'),
+ ),
+ )
+ )
+ ), array('deep' => true));
+ $result = $TestModel->Comment->find('first', array(
+ 'conditions' => array('Comment.article_id' => 3),
+ ));
+
+ $this->assertEquals(3, $result['Comment']['article_id']);
+ $this->assertEquals(2, count($result['Attachment']));
+ }
+
+/**
+ * testUpdateAllBoolean
+ *
+ * return @void
+ */
+ public function testUpdateAllBoolean() {
+ $this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
+ $TestModel = new Item();
+ $result = $TestModel->updateAll(array('published' => true));
+ $this->assertTrue($result);
+
+ $result = $TestModel->find('first', array('fields' => array('id', 'published')));
+ $this->assertEquals(true, $result['Item']['published']);
+ }
+
+/**
+ * testUpdateAllBooleanConditions
+ *
+ * return @void
+ */
+ public function testUpdateAllBooleanConditions() {
+ $this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
+ $TestModel = new Item();
+
+ $result = $TestModel->updateAll(array('published' => true), array('Item.id' => 1));
+ $this->assertTrue($result);
+ $result = $TestModel->find('first', array(
+ 'fields' => array('id', 'published'),
+ 'conditions' => array('Item.id' => 1)));
+ $this->assertEquals(true, $result['Item']['published']);
+ }
+
+/**
+ * testUpdateBoolean
+ *
+ * return @void
+ */
+ public function testUpdateBoolean() {
+ $this->loadFixtures('Item', 'Syfile', 'Portfolio', 'Image', 'ItemsPortfolio');
+ $TestModel = new Item();
+
+ $result = $TestModel->save(array('published' => true, 'id' => 1));
+ $this->assertTrue((boolean)$result);
+ $result = $TestModel->find('first', array(
+ 'fields' => array('id', 'published'),
+ 'conditions' => array('Item.id' => 1)));
+ $this->assertEquals(true, $result['Item']['published']);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php
new file mode 100644
index 0000000..31caf5f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationRuleTest.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ * CakeValidationRuleTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Validator
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeValidationRule', 'Model/Validator');
+
+/**
+ * CakeValidationRuleTest
+ *
+ * @package Cake.Test.Case.Model.Validator
+ */
+class CakeValidationRuleTest extends CakeTestCase {
+
+/**
+ * Auxiliary method to test custom validators
+ *
+ * @return boolean
+ **/
+ public function myTestRule() {
+ return false;
+ }
+
+/**
+ * Auxiliary method to test custom validators
+ *
+ * @return boolean
+ **/
+ public function myTestRule2() {
+ return true;
+ }
+
+/**
+ * Auxiliary method to test custom validators
+ *
+ * @return string
+ **/
+ public function myTestRule3() {
+ return 'string';
+ }
+
+/**
+ * Test isValid method
+ *
+ * @return void
+ */
+ public function testIsValid() {
+ $def = array('rule' => 'notEmpty', 'message' => 'Can not be empty');
+ $data = array(
+ 'fieldName' => ''
+ );
+ $methods = array();
+
+ $Rule = new CakeValidationRule($def);
+ $Rule->process('fieldName', $data, $methods);
+ $this->assertFalse($Rule->isValid());
+
+ $data = array('fieldName' => 'not empty');
+ $Rule->process('fieldName', $data, $methods);
+ $this->assertTrue($Rule->isValid());
+ }
+/**
+ * tests that passing custom validation methods work
+ *
+ * @return void
+ */
+ public function testCustomMethods() {
+ $def = array('rule' => 'myTestRule');
+ $data = array(
+ 'fieldName' => 'some data'
+ );
+ $methods = array('mytestrule' => array($this, 'myTestRule'));
+
+ $Rule = new CakeValidationRule($def);
+ $Rule->process('fieldName', $data, $methods);
+ $this->assertFalse($Rule->isValid());
+
+ $methods = array('mytestrule' => array($this, 'myTestRule2'));
+ $Rule->process('fieldName', $data, $methods);
+ $this->assertTrue($Rule->isValid());
+
+ $methods = array('mytestrule' => array($this, 'myTestRule3'));
+ $Rule->process('fieldName', $data, $methods);
+ $this->assertFalse($Rule->isValid());
+ }
+
+/**
+ * Test isRequired method
+ *
+ * @return void
+ */
+ public function testIsRequired() {
+ $def = array('rule' => 'notEmpty', 'required' => true);
+ $Rule = new CakeValidationRule($def);
+ $this->assertTrue($Rule->isRequired());
+
+ $def = array('rule' => 'notEmpty', 'required' => false);
+ $Rule = new CakeValidationRule($def);
+ $this->assertFalse($Rule->isRequired());
+
+ $def = array('rule' => 'notEmpty', 'required' => 'create');
+ $Rule = new CakeValidationRule($def);
+ $this->assertTrue($Rule->isRequired());
+
+ $def = array('rule' => 'notEmpty', 'required' => 'update');
+ $Rule = new CakeValidationRule($def);
+ $this->assertFalse($Rule->isRequired());
+
+ $Rule->isUpdate(true);
+ $this->assertTrue($Rule->isRequired());
+ }
+
+/**
+ * Test isEmptyAllowed method
+ *
+ * @return void
+ */
+ public function testIsEmptyAllowed() {
+ $def = array('rule' => 'aRule', 'allowEmpty' => true);
+ $Rule = new CakeValidationRule($def);
+ $this->assertTrue($Rule->isEmptyAllowed());
+
+ $def = array('rule' => 'aRule', 'allowEmpty' => false);
+ $Rule = new CakeValidationRule($def);
+ $this->assertFalse($Rule->isEmptyAllowed());
+
+ $def = array('rule' => 'notEmpty', 'allowEmpty' => false, 'on' => 'update');
+ $Rule = new CakeValidationRule($def);
+ $this->assertTrue($Rule->isEmptyAllowed());
+
+ $Rule->isUpdate(true);
+ $this->assertFalse($Rule->isEmptyAllowed());
+
+ $def = array('rule' => 'notEmpty', 'allowEmpty' => false, 'on' => 'create');
+ $Rule = new CakeValidationRule($def);
+ $this->assertFalse($Rule->isEmptyAllowed());
+
+ $Rule->isUpdate(true);
+ $this->assertTrue($Rule->isEmptyAllowed());
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php
new file mode 100644
index 0000000..10fa6fd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/Validator/CakeValidationSetTest.php
@@ -0,0 +1,321 @@
+<?php
+/**
+ * CakeValidationSetTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model.Validator
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeValidationSet', 'Model/Validator');
+
+/**
+ * CakeValidationSetTest
+ *
+ * @package Cake.Test.Case.Model.Validator
+ */
+class CakeValidationSetTest extends CakeTestCase {
+
+/**
+ * testValidate method
+ *
+ * @return void
+ */
+ public function testValidate() {
+ $Field = new CakeValidationSet('title', 'notEmpty');
+ $data = array(
+ 'title' => '',
+ 'body' => 'a body'
+ );
+
+ $result = $Field->validate($data);
+ $expected = array('This field cannot be left blank');
+ $this->assertEquals($expected, $result);
+
+ $Field = new CakeValidationSet('body', 'notEmpty');
+
+ $result = $Field->validate($data);
+ $this->assertEmpty($result);
+
+ $Field = new CakeValidationSet('nothere', array(
+ 'notEmpty' => array(
+ 'rule' => 'notEmpty',
+ 'required' => true
+ )
+ ));
+
+ $result = $Field->validate($data);
+ $expected = array('notEmpty');
+ $this->assertEquals($expected, $result);
+
+ $Field = new CakeValidationSet('body', array(
+ 'inList' => array(
+ 'rule' => array('inList', array('test'))
+ )
+ ));
+ $result = $Field->validate($data);
+ $expected = array('inList');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testGetRule method
+ *
+ * @return void
+ */
+ public function testGetRule() {
+ $rules = array('notEmpty' => array('rule' => 'notEmpty', 'message' => 'Can not be empty'));
+ $Field = new CakeValidationSet('title', $rules);
+ $data = array(
+ 'title' => '',
+ 'body' => 'a body'
+ );
+
+ $result = $Field->getRule('notEmpty');
+ $this->assertInstanceOf('CakeValidationRule', $result);
+ $this->assertEquals('notEmpty', $result->rule);
+ $this->assertEquals(null, $result->required);
+ $this->assertEquals(false, $result->allowEmpty);
+ $this->assertEquals(null, $result->on);
+ $this->assertEquals(true, $result->last);
+ $this->assertEquals('Can not be empty', $result->message);
+ }
+
+/**
+ * testGetRules method
+ *
+ * @return void
+ */
+ public function testGetRules() {
+ $rules = array('notEmpty' => array('rule' => 'notEmpty', 'message' => 'Can not be empty'));
+ $Field = new CakeValidationSet('title', $rules);
+
+ $result = $Field->getRules();
+ $this->assertEquals(array('notEmpty'), array_keys($result));
+ $this->assertInstanceOf('CakeValidationRule', $result['notEmpty']);
+ }
+
+/**
+ * testSetRule method
+ *
+ * @return void
+ */
+ public function testSetRule() {
+ $rules = array('notEmpty' => array('rule' => 'notEmpty', 'message' => 'Can not be empty'));
+ $Field = new CakeValidationSet('title', $rules);
+ $Rule = new CakeValidationRule($rules['notEmpty']);
+
+ $this->assertEquals($Rule, $Field->getRule('notEmpty'));
+
+ $rules = array('validEmail' => array('rule' => 'email', 'message' => 'Invalid email'));
+ $Rule = new CakeValidationRule($rules['validEmail']);
+ $Field->setRule('validEmail', $Rule);
+ $result = $Field->getRules();
+ $this->assertEquals(array('notEmpty', 'validEmail'), array_keys($result));
+
+ $rules = array('validEmail' => array('rule' => 'email', 'message' => 'Other message'));
+ $Rule = new CakeValidationRule($rules['validEmail']);
+ $Field->setRule('validEmail', $Rule);
+ $result = $Field->getRules();
+ $this->assertEquals(array('notEmpty', 'validEmail'), array_keys($result));
+ $result = $Field->getRule('validEmail');
+ $this->assertInstanceOf('CakeValidationRule', $result);
+ $this->assertEquals('email', $result->rule);
+ $this->assertEquals(null, $result->required);
+ $this->assertEquals(false, $result->allowEmpty);
+ $this->assertEquals(null, $result->on);
+ $this->assertEquals(true, $result->last);
+ $this->assertEquals('Other message', $result->message);
+ }
+
+/**
+ * testSetRules method
+ *
+ * @return void
+ */
+ public function testSetRules() {
+ $rule = array('notEmpty' => array('rule' => 'notEmpty', 'message' => 'Can not be empty'));
+ $Field = new CakeValidationSet('title', $rule);
+ $RuleEmpty = new CakeValidationRule($rule['notEmpty']);
+
+ $rule = array('validEmail' => array('rule' => 'email', 'message' => 'Invalid email'));
+ $RuleEmail = new CakeValidationRule($rule['validEmail']);
+
+ $rules = array('validEmail' => $RuleEmail);
+ $Field->setRules($rules, false);
+ $result = $Field->getRules();
+ $this->assertEquals(array('validEmail'), array_keys($result));
+
+ $rules = array('notEmpty' => $RuleEmpty);
+ $Field->setRules($rules, true);
+ $result = $Field->getRules();
+ $this->assertEquals(array('validEmail', 'notEmpty'), array_keys($result));
+ }
+
+/**
+ * Tests getting a rule from the set using array access
+ *
+ * @return void
+ */
+ public function testArrayAccessGet() {
+ $Set = new CakeValidationSet('title', array(
+ 'notEmpty' => array('rule' => 'notEmpty', 'required' => true),
+ 'numeric' => array('rule' => 'numeric'),
+ 'other' => array('rule' => array('other', 1)),
+ ));
+
+ $rule = $Set['notEmpty'];
+ $this->assertInstanceOf('CakeValidationRule', $rule);
+ $this->assertEquals('notEmpty', $rule->rule);
+
+ $rule = $Set['numeric'];
+ $this->assertInstanceOf('CakeValidationRule', $rule);
+ $this->assertEquals('numeric', $rule->rule);
+
+ $rule = $Set['other'];
+ $this->assertInstanceOf('CakeValidationRule', $rule);
+ $this->assertEquals(array('other', 1), $rule->rule);
+ }
+
+/**
+ * Tests checking a rule from the set using array access
+ *
+ * @return void
+ */
+ public function testArrayAccessExists() {
+ $Set = new CakeValidationSet('title', array(
+ 'notEmpty' => array('rule' => 'notEmpty', 'required' => true),
+ 'numeric' => array('rule' => 'numeric'),
+ 'other' => array('rule' => array('other', 1)),
+ ));
+
+ $this->assertTrue(isset($Set['notEmpty']));
+ $this->assertTrue(isset($Set['numeric']));
+ $this->assertTrue(isset($Set['other']));
+ $this->assertFalse(isset($Set['fail']));
+ }
+
+/**
+ * Tests setting a rule in the set using array access
+ *
+ * @return void
+ */
+ public function testArrayAccessSet() {
+ $Set = new CakeValidationSet('title', array(
+ 'notEmpty' => array('rule' => 'notEmpty', 'required' => true),
+ ));
+
+ $this->assertFalse(isset($Set['other']));
+ $Set['other'] = array('rule' => array('other', 1));
+ $rule = $Set['other'];
+ $this->assertInstanceOf('CakeValidationRule', $rule);
+ $this->assertEquals(array('other', 1), $rule->rule);
+
+ $this->assertFalse(isset($Set['numeric']));
+ $Set['numeric'] = new CakeValidationRule(array('rule' => 'numeric'));
+ $rule = $Set['numeric'];
+ $this->assertInstanceOf('CakeValidationRule', $rule);
+ $this->assertEquals('numeric', $rule->rule);
+ }
+
+/**
+ * Tests unseting a rule from the set using array access
+ *
+ * @return void
+ */
+ public function testArrayAccessUnset() {
+ $Set = new CakeValidationSet('title', array(
+ 'notEmpty' => array('rule' => 'notEmpty', 'required' => true),
+ 'numeric' => array('rule' => 'numeric'),
+ 'other' => array('rule' => array('other', 1)),
+ ));
+
+ unset($Set['notEmpty']);
+ $this->assertFalse(isset($Set['notEmpty']));
+
+ unset($Set['numeric']);
+ $this->assertFalse(isset($Set['notEmpty']));
+
+ unset($Set['other']);
+ $this->assertFalse(isset($Set['notEmpty']));
+ }
+
+/**
+ * Tests it is possible to iterate a validation set object
+ *
+ * @return void
+ */
+ public function testIterator() {
+ $Set = new CakeValidationSet('title', array(
+ 'notEmpty' => array('rule' => 'notEmpty', 'required' => true),
+ 'numeric' => array('rule' => 'numeric'),
+ 'other' => array('rule' => array('other', 1)),
+ ));
+
+ $i = 0;
+ foreach ($Set as $name => $rule) {
+ if ($i === 0) {
+ $this->assertEquals('notEmpty', $name);
+ }
+ if ($i === 1) {
+ $this->assertEquals('numeric', $name);
+ }
+ if ($i === 2) {
+ $this->assertEquals('other', $name);
+ }
+ $this->assertInstanceOf('CakeValidationRule', $rule);
+ $i++;
+ }
+ $this->assertEquals(3, $i);
+ }
+
+/**
+ * Tests countable interface
+ *
+ * @return void
+ */
+ public function testCount() {
+ $Set = new CakeValidationSet('title', array(
+ 'notEmpty' => array('rule' => 'notEmpty', 'required' => true),
+ 'numeric' => array('rule' => 'numeric'),
+ 'other' => array('rule' => array('other', 1)),
+ ));
+ $this->assertCount(3, $Set);
+
+ unset($Set['other']);
+ $this->assertCount(2, $Set);
+ }
+
+/**
+ * Test removeRule method
+ *
+ * @return void
+ */
+ public function testRemoveRule() {
+ $Set = new CakeValidationSet('title', array(
+ 'notEmpty' => array('rule' => 'notEmpty', 'required' => true),
+ 'numeric' => array('rule' => 'numeric'),
+ 'other' => array('rule' => array('other', 1)),
+ ));
+
+ $Set->removeRule('notEmpty');
+ $this->assertFalse(isset($Set['notEmpty']));
+
+ $Set->removeRule('numeric');
+ $this->assertFalse(isset($Set['numeric']));
+
+ $Set->removeRule('other');
+ $this->assertFalse(isset($Set['other']));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/models.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/models.php
new file mode 100644
index 0000000..b550a0a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Model/models.php
@@ -0,0 +1,4989 @@
+<?php
+/**
+ * Mock models file
+ *
+ * Mock classes for use in Model and related test cases
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Model
+ * @since CakePHP(tm) v 1.2.0.6464
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Model', 'Model');
+/**
+ * AppModel class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class AppModel extends Model {
+
+/**
+ * findMethods property
+ *
+ * @var array
+ */
+ public $findMethods = array('published' => true);
+
+/**
+ * useDbConfig property
+ *
+ * @var array
+ */
+ public $useDbConfig = 'test';
+
+/**
+ * _findPublished custom find
+ *
+ * @return array
+ */
+ protected function _findPublished($state, $query, $results = array()) {
+ if ($state === 'before') {
+ $query['conditions']['published'] = 'Y';
+ return $query;
+ }
+ return $results;
+ }
+
+}
+
+/**
+ * Test class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Test extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'Test'
+ */
+ public $name = 'Test';
+
+/**
+ * schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '1', 'length' => '8', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'notes' => array('type' => 'text', 'null' => '1', 'default' => 'write some notes here', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+
+}
+
+/**
+ * TestAlias class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestAlias extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'TestAlias'
+ */
+ public $name = 'TestAlias';
+
+/**
+ * alias property
+ *
+ * @var string 'TestAlias'
+ */
+ public $alias = 'TestAlias';
+
+/**
+ * schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '1', 'length' => '8', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'notes' => array('type' => 'text', 'null' => '1', 'default' => 'write some notes here', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+}
+
+/**
+ * TestValidate class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestValidate extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'TestValidate'
+ */
+ public $name = 'TestValidate';
+
+/**
+ * schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'title' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'body' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => ''),
+ 'number' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'modified' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+
+/**
+ * validateNumber method
+ *
+ * @param mixed $value
+ * @param mixed $options
+ * @return void
+ */
+ public function validateNumber($value, $options) {
+ $options = array_merge(array('min' => 0, 'max' => 100), $options);
+ $valid = ($value['number'] >= $options['min'] && $value['number'] <= $options['max']);
+ return $valid;
+ }
+
+/**
+ * validateTitle method
+ *
+ * @param mixed $value
+ * @return void
+ */
+ public function validateTitle($value) {
+ return (!empty($value) && strpos(strtolower($value['title']), 'title-') === 0);
+ }
+
+}
+
+/**
+ * User class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class User extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'User'
+ */
+ public $name = 'User';
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array('user' => 'notEmpty', 'password' => 'notEmpty');
+
+/**
+ * beforeFind() callback used to run ContainableBehaviorTest::testLazyLoad()
+ *
+ * @return bool
+ * @throws Exception
+ */
+ public function beforeFind($queryData) {
+ if (!empty($queryData['lazyLoad'])) {
+ if (!isset($this->Article, $this->Comment, $this->ArticleFeatured)) {
+ throw new Exception('Unavailable associations');
+ }
+ }
+ return true;
+ }
+
+}
+
+/**
+ * Article class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Article extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Article'
+ */
+ public $name = 'Article';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('User');
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Comment' => array('dependent' => true));
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Tag');
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array(
+ 'user_id' => 'numeric',
+ 'title' => array('required' => false, 'rule' => 'notEmpty'),
+ 'body' => 'notEmpty',
+ );
+
+/**
+ * beforeSaveReturn property
+ *
+ * @var bool true
+ */
+ public $beforeSaveReturn = true;
+
+/**
+ * beforeSave method
+ *
+ * @return void
+ */
+ public function beforeSave($options = array()) {
+ return $this->beforeSaveReturn;
+ }
+
+/**
+ * titleDuplicate method
+ *
+ * @param string $title
+ * @return void
+ */
+ public static function titleDuplicate($title) {
+ if ($title === 'My Article Title') {
+ return false;
+ }
+ return true;
+ }
+
+}
+
+/**
+ * Model stub for beforeDelete testing
+ *
+ * @see #250
+ * @package Cake.Test.Case.Model
+ */
+class BeforeDeleteComment extends CakeTestModel {
+
+ public $name = 'BeforeDeleteComment';
+
+ public $useTable = 'comments';
+
+ public function beforeDelete($cascade = true) {
+ $db = $this->getDataSource();
+ $db->delete($this, array($this->alias . '.' . $this->primaryKey => array(1, 3)));
+ return true;
+ }
+
+}
+
+/**
+ * NumericArticle class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class NumericArticle extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'NumericArticle'
+ */
+ public $name = 'NumericArticle';
+
+/**
+ * useTable property
+ *
+ * @var string 'numeric_articles'
+ */
+ public $useTable = 'numeric_articles';
+
+}
+
+/**
+ * Article10 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Article10 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Article10'
+ */
+ public $name = 'Article10';
+
+/**
+ * useTable property
+ *
+ * @var string 'articles'
+ */
+ public $useTable = 'articles';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Comment' => array('dependent' => true, 'exclusive' => true));
+
+}
+
+/**
+ * ArticleFeatured class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ArticleFeatured extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ArticleFeatured'
+ */
+ public $name = 'ArticleFeatured';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('User', 'Category');
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('Featured');
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Comment' => array('className' => 'Comment', 'dependent' => true));
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Tag');
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array('user_id' => 'numeric', 'title' => 'notEmpty', 'body' => 'notEmpty');
+
+}
+
+/**
+ * Featured class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Featured extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Featured'
+ */
+ public $name = 'Featured';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('ArticleFeatured', 'Category');
+}
+
+/**
+ * Tag class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Tag extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Tag'
+ */
+ public $name = 'Tag';
+}
+
+/**
+ * ArticlesTag class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ArticlesTag extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ArticlesTag'
+ */
+ public $name = 'ArticlesTag';
+}
+
+/**
+ * ArticleFeaturedsTag class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ArticleFeaturedsTag extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ArticleFeaturedsTag'
+ */
+ public $name = 'ArticleFeaturedsTag';
+}
+
+/**
+ * Comment class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Comment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Comment'
+ */
+ public $name = 'Comment';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Article', 'User');
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('Attachment' => array('dependent' => true));
+}
+
+/**
+ * Modified Comment Class has afterFind Callback
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModifiedComment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Comment'
+ */
+ public $name = 'Comment';
+
+/**
+ * useTable property
+ *
+ * @var string 'comments'
+ */
+ public $useTable = 'comments';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Article');
+
+/**
+ * afterFind callback
+ *
+ * @return void
+ */
+ public function afterFind($results, $primary = false) {
+ if (isset($results[0])) {
+ $results[0]['Comment']['callback'] = 'Fire';
+ }
+ return $results;
+ }
+
+}
+
+/**
+ * Modified Comment Class has afterFind Callback
+ *
+ * @package Cake.Test.Case.Model
+ */
+class AgainModifiedComment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Comment'
+ */
+ public $name = 'Comment';
+
+/**
+ * useTable property
+ *
+ * @var string 'comments'
+ */
+ public $useTable = 'comments';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Article');
+
+/**
+ * afterFind callback
+ *
+ * @return void
+ */
+ public function afterFind($results, $primary = false) {
+ if (isset($results[0])) {
+ $results[0]['Comment']['querytype'] = $this->findQueryType;
+ }
+ return $results;
+ }
+
+}
+
+/**
+ * MergeVarPluginAppModel class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MergeVarPluginAppModel extends AppModel {
+
+/**
+ * actsAs parameter
+ *
+ * @var array
+ */
+ public $actsAs = array(
+ 'Containable'
+ );
+}
+
+/**
+ * MergeVarPluginPost class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MergeVarPluginPost extends MergeVarPluginAppModel {
+
+/**
+ * actsAs parameter
+ *
+ * @var array
+ */
+ public $actsAs = array(
+ 'Tree'
+ );
+
+/**
+ * useTable parameter
+ *
+ * @var string
+ */
+ public $useTable = 'posts';
+}
+
+/**
+ * MergeVarPluginComment class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MergeVarPluginComment extends MergeVarPluginAppModel {
+
+/**
+ * actsAs parameter
+ *
+ * @var array
+ */
+ public $actsAs = array(
+ 'Containable' => array('some_settings')
+ );
+
+/**
+ * useTable parameter
+ *
+ * @var string
+ */
+ public $useTable = 'comments';
+}
+
+/**
+ * Attachment class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Attachment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Attachment'
+ */
+ public $name = 'Attachment';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Comment');
+}
+
+/**
+ * ModifiedAttachment class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModifiedAttachment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ModifiedAttachment'
+ */
+ public $name = 'ModifiedAttachment';
+
+/**
+ * useTable property
+ *
+ * @var string 'attachments'
+ */
+ public $useTable = 'attachments';
+
+/**
+ * afterFind callback
+ *
+ * @return void
+ */
+ public function afterFind($results, $primary = false) {
+ if (isset($results['id'])) {
+ $results['callback'] = 'Fired';
+ }
+ return $results;
+ }
+
+}
+
+/**
+ * Category class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Category extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Category'
+ */
+ public $name = 'Category';
+}
+
+/**
+ * CategoryThread class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class CategoryThread extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'CategoryThread'
+ */
+ public $name = 'CategoryThread';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('ParentCategory' => array('className' => 'CategoryThread', 'foreignKey' => 'parent_id'));
+}
+
+/**
+ * Apple class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Apple extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Apple'
+ */
+ public $name = 'Apple';
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array('name' => 'notEmpty');
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('Sample');
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Child' => array('className' => 'Apple', 'dependent' => true));
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Parent' => array('className' => 'Apple', 'foreignKey' => 'apple_id'));
+}
+
+/**
+ * Sample class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Sample extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Sample'
+ */
+ public $name = 'Sample';
+
+/**
+ * belongsTo property
+ *
+ * @var string 'Apple'
+ */
+ public $belongsTo = 'Apple';
+}
+
+/**
+ * AnotherArticle class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class AnotherArticle extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'AnotherArticle'
+ */
+ public $name = 'AnotherArticle';
+
+/**
+ * hasMany property
+ *
+ * @var string 'Home'
+ */
+ public $hasMany = 'Home';
+}
+
+/**
+ * Advertisement class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Advertisement extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Advertisement'
+ */
+ public $name = 'Advertisement';
+
+/**
+ * hasMany property
+ *
+ * @var string 'Home'
+ */
+ public $hasMany = 'Home';
+}
+
+/**
+ * Home class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Home extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Home'
+ */
+ public $name = 'Home';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('AnotherArticle', 'Advertisement');
+}
+
+/**
+ * Post class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Post extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Post'
+ */
+ public $name = 'Post';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Author');
+
+ public function beforeFind($queryData) {
+ if (isset($queryData['connection'])) {
+ $this->useDbConfig = $queryData['connection'];
+ }
+ return true;
+ }
+
+ public function afterFind($results, $primary = false) {
+ $this->useDbConfig = 'test';
+ return $results;
+ }
+
+}
+
+/**
+ * Author class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Author extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Author'
+ */
+ public $name = 'Author';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Post');
+
+/**
+ * afterFind method
+ *
+ * @param array $results
+ * @return void
+ */
+ public function afterFind($results, $primary = false) {
+ $results[0]['Author']['test'] = 'working';
+ return $results;
+ }
+
+}
+
+/**
+ * ModifiedAuthor class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModifiedAuthor extends Author {
+
+/**
+ * name property
+ *
+ * @var string 'Author'
+ */
+ public $name = 'Author';
+
+/**
+ * afterFind method
+ *
+ * @param array $results
+ * @return void
+ */
+ public function afterFind($results, $primary = false) {
+ foreach ($results as $index => $result) {
+ $results[$index]['Author']['user'] .= ' (CakePHP)';
+ }
+ return $results;
+ }
+
+}
+
+/**
+ * Project class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Project extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Project'
+ */
+ public $name = 'Project';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Thread');
+}
+
+/**
+ * Thread class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Thread extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Thread'
+ */
+ public $name = 'Thread';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Project');
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Message');
+}
+
+/**
+ * Message class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Message extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Message'
+ */
+ public $name = 'Message';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('Bid');
+}
+
+/**
+ * Bid class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Bid extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Bid'
+ */
+ public $name = 'Bid';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Message');
+}
+
+/**
+ * BiddingMessage class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class BiddingMessage extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'BiddingMessage'
+ */
+ public $name = 'BiddingMessage';
+
+/**
+ * primaryKey property
+ *
+ * @var string 'bidding'
+ */
+ public $primaryKey = 'bidding';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Bidding' => array(
+ 'foreignKey' => false,
+ 'conditions' => array('BiddingMessage.bidding = Bidding.bid')
+ )
+ );
+}
+
+/**
+ * Bidding class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Bidding extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Bidding'
+ */
+ public $name = 'Bidding';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array(
+ 'BiddingMessage' => array(
+ 'foreignKey' => false,
+ 'conditions' => array('BiddingMessage.bidding = Bidding.bid'),
+ 'dependent' => true
+ )
+ );
+}
+
+/**
+ * NodeAfterFind class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class NodeAfterFind extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'NodeAfterFind'
+ */
+ public $name = 'NodeAfterFind';
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array('name' => 'notEmpty');
+
+/**
+ * useTable property
+ *
+ * @var string 'apples'
+ */
+ public $useTable = 'apples';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('Sample' => array('className' => 'NodeAfterFindSample'));
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Child' => array('className' => 'NodeAfterFind', 'dependent' => true));
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Parent' => array('className' => 'NodeAfterFind', 'foreignKey' => 'apple_id'));
+
+/**
+ * afterFind method
+ *
+ * @param mixed $results
+ * @return array
+ */
+ public function afterFind($results, $primary = false) {
+ return $results;
+ }
+
+}
+
+/**
+ * NodeAfterFindSample class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class NodeAfterFindSample extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'NodeAfterFindSample'
+ */
+ public $name = 'NodeAfterFindSample';
+
+/**
+ * useTable property
+ *
+ * @var string 'samples'
+ */
+ public $useTable = 'samples';
+
+/**
+ * belongsTo property
+ *
+ * @var string 'NodeAfterFind'
+ */
+ public $belongsTo = 'NodeAfterFind';
+}
+
+/**
+ * NodeNoAfterFind class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class NodeNoAfterFind extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'NodeAfterFind'
+ */
+ public $name = 'NodeAfterFind';
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array('name' => 'notEmpty');
+
+/**
+ * useTable property
+ *
+ * @var string 'apples'
+ */
+ public $useTable = 'apples';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('Sample' => array('className' => 'NodeAfterFindSample'));
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Child' => array('className' => 'NodeAfterFind', 'dependent' => true));
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Parent' => array('className' => 'NodeAfterFind', 'foreignKey' => 'apple_id'));
+}
+
+/**
+ * Node class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Node extends CakeTestModel{
+
+/**
+ * name property
+ *
+ * @var string 'Node'
+ */
+ public $name = 'Node';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array(
+ 'ParentNode' => array(
+ 'className' => 'Node',
+ 'joinTable' => 'dependency',
+ 'with' => 'Dependency',
+ 'foreignKey' => 'child_id',
+ 'associationForeignKey' => 'parent_id',
+ )
+ );
+}
+
+/**
+ * Dependency class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Dependency extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Dependency'
+ */
+ public $name = 'Dependency';
+}
+
+/**
+ * ModelA class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelA extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ModelA'
+ */
+ public $name = 'ModelA';
+
+/**
+ * useTable property
+ *
+ * @var string 'apples'
+ */
+ public $useTable = 'apples';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('ModelB', 'ModelC');
+}
+
+/**
+ * ModelB class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelB extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ModelB'
+ */
+ public $name = 'ModelB';
+
+/**
+ * useTable property
+ *
+ * @var string 'messages'
+ */
+ public $useTable = 'messages';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('ModelD');
+}
+
+/**
+ * ModelC class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelC extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ModelC'
+ */
+ public $name = 'ModelC';
+
+/**
+ * useTable property
+ *
+ * @var string 'bids'
+ */
+ public $useTable = 'bids';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('ModelD');
+}
+
+/**
+ * ModelD class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ModelD extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ModelD'
+ */
+ public $name = 'ModelD';
+
+/**
+ * useTable property
+ *
+ * @var string 'threads'
+ */
+ public $useTable = 'threads';
+}
+
+/**
+ * Something class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Something extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Something'
+ */
+ public $name = 'Something';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('SomethingElse' => array('with' => array('JoinThing' => array('doomed'))));
+}
+
+/**
+ * SomethingElse class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SomethingElse extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SomethingElse'
+ */
+ public $name = 'SomethingElse';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Something' => array('with' => 'JoinThing'));
+}
+
+/**
+ * JoinThing class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class JoinThing extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'JoinThing'
+ */
+ public $name = 'JoinThing';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Something', 'SomethingElse');
+}
+
+/**
+ * Portfolio class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Portfolio extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Portfolio'
+ */
+ public $name = 'Portfolio';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Item');
+}
+
+/**
+ * Item class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Item extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Item'
+ */
+ public $name = 'Item';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Syfile' => array('counterCache' => true));
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Portfolio' => array('unique' => false));
+}
+
+/**
+ * ItemsPortfolio class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ItemsPortfolio extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ItemsPortfolio'
+ */
+ public $name = 'ItemsPortfolio';
+}
+
+/**
+ * Syfile class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Syfile extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Syfile'
+ */
+ public $name = 'Syfile';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Image');
+}
+
+/**
+ * Image class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Image extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Image'
+ */
+ public $name = 'Image';
+}
+
+/**
+ * DeviceType class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DeviceType extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'DeviceType'
+ */
+ public $name = 'DeviceType';
+
+/**
+ * order property
+ *
+ * @var array
+ */
+ public $order = array('DeviceType.order' => 'ASC');
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'DeviceTypeCategory', 'FeatureSet', 'ExteriorTypeCategory',
+ 'Image' => array('className' => 'Document'),
+ 'Extra1' => array('className' => 'Document'),
+ 'Extra2' => array('className' => 'Document'));
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Device' => array('order' => array('Device.id' => 'ASC')));
+}
+
+/**
+ * DeviceTypeCategory class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DeviceTypeCategory extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'DeviceTypeCategory'
+ */
+ public $name = 'DeviceTypeCategory';
+}
+
+/**
+ * FeatureSet class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class FeatureSet extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'FeatureSet'
+ */
+ public $name = 'FeatureSet';
+}
+
+/**
+ * ExteriorTypeCategory class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ExteriorTypeCategory extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ExteriorTypeCategory'
+ */
+ public $name = 'ExteriorTypeCategory';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Image' => array('className' => 'Device'));
+}
+
+/**
+ * Document class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Document extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Document'
+ */
+ public $name = 'Document';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('DocumentDirectory');
+}
+
+/**
+ * Device class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Device extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Device'
+ */
+ public $name = 'Device';
+}
+
+/**
+ * DocumentDirectory class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DocumentDirectory extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'DocumentDirectory'
+ */
+ public $name = 'DocumentDirectory';
+}
+
+/**
+ * PrimaryModel class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class PrimaryModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'PrimaryModel'
+ */
+ public $name = 'PrimaryModel';
+}
+
+/**
+ * SecondaryModel class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class SecondaryModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SecondaryModel'
+ */
+ public $name = 'SecondaryModel';
+}
+
+/**
+ * JoinA class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class JoinA extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'JoinA'
+ */
+ public $name = 'JoinA';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('JoinB', 'JoinC');
+}
+
+/**
+ * JoinB class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class JoinB extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'JoinB'
+ */
+ public $name = 'JoinB';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('JoinA');
+}
+
+/**
+ * JoinC class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class JoinC extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'JoinC'
+ */
+ public $name = 'JoinC';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('JoinA');
+}
+
+/**
+ * ThePaper class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ThePaper extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ThePaper'
+ */
+ public $name = 'ThePaper';
+
+/**
+ * useTable property
+ *
+ * @var string 'apples'
+ */
+ public $useTable = 'apples';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('Itself' => array('className' => 'ThePaper', 'foreignKey' => 'apple_id'));
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Monkey' => array('joinTable' => 'the_paper_monkies', 'order' => 'id'));
+}
+
+/**
+ * Monkey class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Monkey extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Monkey'
+ */
+ public $name = 'Monkey';
+
+/**
+ * useTable property
+ *
+ * @var string 'devices'
+ */
+ public $useTable = 'devices';
+}
+
+/**
+ * AssociationTest1 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class AssociationTest1 extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var string 'join_as'
+ */
+ public $useTable = 'join_as';
+
+/**
+ * name property
+ *
+ * @var string 'AssociationTest1'
+ */
+ public $name = 'AssociationTest1';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('AssociationTest2' => array(
+ 'unique' => false, 'joinTable' => 'join_as_join_bs', 'foreignKey' => false
+ ));
+}
+
+/**
+ * AssociationTest2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class AssociationTest2 extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var string 'join_bs'
+ */
+ public $useTable = 'join_bs';
+
+/**
+ * name property
+ *
+ * @var string 'AssociationTest2'
+ */
+ public $name = 'AssociationTest2';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('AssociationTest1' => array(
+ 'unique' => false, 'joinTable' => 'join_as_join_bs'
+ ));
+}
+
+/**
+ * Callback class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Callback extends CakeTestModel {
+
+}
+
+/**
+ * CallbackPostTestModel class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class CallbackPostTestModel extends CakeTestModel {
+
+ public $useTable = 'posts';
+
+/**
+ * variable to control return of beforeValidate
+ *
+ * @var string
+ */
+ public $beforeValidateReturn = true;
+
+/**
+ * variable to control return of beforeSave
+ *
+ * @var string
+ */
+ public $beforeSaveReturn = true;
+
+/**
+ * variable to control return of beforeDelete
+ *
+ * @var string
+ */
+ public $beforeDeleteReturn = true;
+
+/**
+ * beforeSave callback
+ *
+ * @return void
+ */
+ public function beforeSave($options = array()) {
+ return $this->beforeSaveReturn;
+ }
+
+/**
+ * beforeValidate callback
+ *
+ * @return void
+ */
+ public function beforeValidate($options = array()) {
+ return $this->beforeValidateReturn;
+ }
+
+/**
+ * beforeDelete callback
+ *
+ * @return void
+ */
+ public function beforeDelete($cascade = true) {
+ return $this->beforeDeleteReturn;
+ }
+
+}
+
+/**
+ * Uuid class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Uuid extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Uuid'
+ */
+ public $name = 'Uuid';
+}
+
+/**
+ * DataTest class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class DataTest extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'DataTest'
+ */
+ public $name = 'DataTest';
+}
+
+/**
+ * TheVoid class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TheVoid extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TheVoid'
+ */
+ public $name = 'TheVoid';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+}
+
+/**
+ * ValidationTest1 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ValidationTest1 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ValidationTest'
+ */
+ public $name = 'ValidationTest1';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema property
+ *
+ * @var array
+ */
+ protected $_schema = array();
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array(
+ 'title' => 'notEmpty',
+ 'published' => 'customValidationMethod',
+ 'body' => array(
+ 'notEmpty',
+ '/^.{5,}$/s' => 'no matchy',
+ '/^[0-9A-Za-z \\.]{1,}$/s'
+ )
+ );
+
+/**
+ * customValidationMethod method
+ *
+ * @param mixed $data
+ * @return void
+ */
+ public function customValidationMethod($data) {
+ return $data === 1;
+ }
+
+/**
+ * Custom validator with parameters + default values
+ *
+ * @return array
+ */
+ public function customValidatorWithParams($data, $validator, $or = true, $ignoreOnSame = 'id') {
+ $this->validatorParams = get_defined_vars();
+ unset($this->validatorParams['this']);
+ return true;
+ }
+
+/**
+ * Custom validator with message
+ *
+ * @return array
+ */
+ public function customValidatorWithMessage($data) {
+ return 'This field will *never* validate! Muhahaha!';
+ }
+
+/**
+ * Test validation with many parameters
+ *
+ * @return void
+ */
+ public function customValidatorWithSixParams($data, $one = 1, $two = 2, $three = 3, $four = 4, $five = 5, $six = 6) {
+ $this->validatorParams = get_defined_vars();
+ unset($this->validatorParams['this']);
+ return true;
+ }
+
+}
+
+/**
+ * ValidationTest2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ValidationTest2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ValidationTest2'
+ */
+ public $name = 'ValidationTest2';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array(
+ 'title' => 'notEmpty',
+ 'published' => 'customValidationMethod',
+ 'body' => array(
+ 'notEmpty',
+ '/^.{5,}$/s' => 'no matchy',
+ '/^[0-9A-Za-z \\.]{1,}$/s'
+ )
+ );
+
+/**
+ * customValidationMethod method
+ *
+ * @param mixed $data
+ * @return void
+ */
+ public function customValidationMethod($data) {
+ return $data === 1;
+ }
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ return array();
+ }
+
+}
+
+/**
+ * Person class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Person extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Person'
+ */
+ public $name = 'Person';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Mother' => array(
+ 'className' => 'Person',
+ 'foreignKey' => 'mother_id'
+ ),
+ 'Father' => array(
+ 'className' => 'Person',
+ 'foreignKey' => 'father_id'
+ )
+ );
+}
+
+/**
+ * UnderscoreField class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class UnderscoreField extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'UnderscoreField'
+ */
+ public $name = 'UnderscoreField';
+}
+
+/**
+ * Product class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Product extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Product'
+ */
+ public $name = 'Product';
+}
+
+/**
+ * Story class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Story extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Story'
+ */
+ public $name = 'Story';
+
+/**
+ * primaryKey property
+ *
+ * @var string 'story'
+ */
+ public $primaryKey = 'story';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Tag' => array('foreignKey' => 'story'));
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array('title' => 'notEmpty');
+}
+
+/**
+ * Cd class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Cd extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Cd'
+ */
+ public $name = 'Cd';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array(
+ 'OverallFavorite' => array(
+ 'foreignKey' => 'model_id',
+ 'dependent' => true,
+ 'conditions' => array('model_type' => 'Cd')
+ )
+ );
+
+}
+
+/**
+ * Book class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Book extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Book'
+ */
+ public $name = 'Book';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array(
+ 'OverallFavorite' => array(
+ 'foreignKey' => 'model_id',
+ 'dependent' => true,
+ 'conditions' => 'OverallFavorite.model_type = \'Book\''
+ )
+ );
+
+}
+
+/**
+ * OverallFavorite class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class OverallFavorite extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'OverallFavorite'
+ */
+ public $name = 'OverallFavorite';
+}
+
+/**
+ * MyUser class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MyUser extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'MyUser'
+ */
+ public $name = 'MyUser';
+
+/**
+ * undocumented variable
+ *
+ * @var string
+ */
+ public $hasAndBelongsToMany = array('MyCategory');
+}
+
+/**
+ * MyCategory class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MyCategory extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'MyCategory'
+ */
+ public $name = 'MyCategory';
+
+/**
+ * undocumented variable
+ *
+ * @var string
+ */
+ public $hasAndBelongsToMany = array('MyProduct', 'MyUser');
+}
+
+/**
+ * MyProduct class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MyProduct extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'MyProduct'
+ */
+ public $name = 'MyProduct';
+
+/**
+ * undocumented variable
+ *
+ * @var string
+ */
+ public $hasAndBelongsToMany = array('MyCategory');
+}
+
+/**
+ * MyCategoriesMyUser class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MyCategoriesMyUser extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'MyCategoriesMyUser'
+ */
+ public $name = 'MyCategoriesMyUser';
+}
+
+/**
+ * MyCategoriesMyProduct class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MyCategoriesMyProduct extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'MyCategoriesMyProduct'
+ */
+ public $name = 'MyCategoriesMyProduct';
+}
+
+
+/**
+ * NumberTree class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class NumberTree extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'NumberTree'
+ */
+ public $name = 'NumberTree';
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Tree');
+
+/**
+ * initialize method
+ *
+ * @param integer $levelLimit
+ * @param integer $childLimit
+ * @param mixed $currentLevel
+ * @param mixed $parent_id
+ * @param string $prefix
+ * @param bool $hierarchal
+ * @return void
+ */
+ public function initialize($levelLimit = 3, $childLimit = 3, $currentLevel = null, $parentId = null, $prefix = '1', $hierarchal = true) {
+ if (!$parentId) {
+ $db = ConnectionManager::getDataSource($this->useDbConfig);
+ $db->truncate($this->table);
+ $this->save(array($this->name => array('name' => '1. Root')));
+ $this->initialize($levelLimit, $childLimit, 1, $this->id, '1', $hierarchal);
+ $this->create(array());
+ }
+
+ if (!$currentLevel || $currentLevel > $levelLimit) {
+ return;
+ }
+
+ for ($i = 1; $i <= $childLimit; $i++) {
+ $name = $prefix . '.' . $i;
+ $data = array($this->name => array('name' => $name));
+ $this->create($data);
+
+ if ($hierarchal) {
+ if ($this->name == 'UnconventionalTree') {
+ $data[$this->name]['join'] = $parentId;
+ } else {
+ $data[$this->name]['parent_id'] = $parentId;
+ }
+ }
+ $this->save($data);
+ $this->initialize($levelLimit, $childLimit, $currentLevel + 1, $this->id, $name, $hierarchal);
+ }
+ }
+
+}
+
+/**
+ * NumberTreeTwo class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class NumberTreeTwo extends NumberTree {
+
+/**
+ * name property
+ *
+ * @var string 'NumberTree'
+ */
+ public $name = 'NumberTreeTwo';
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array();
+}
+
+/**
+ * FlagTree class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class FlagTree extends NumberTree {
+
+/**
+ * name property
+ *
+ * @var string 'FlagTree'
+ */
+ public $name = 'FlagTree';
+}
+
+/**
+ * UnconventionalTree class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class UnconventionalTree extends NumberTree {
+
+/**
+ * name property
+ *
+ * @var string 'FlagTree'
+ */
+ public $name = 'UnconventionalTree';
+
+ public $actsAs = array(
+ 'Tree' => array(
+ 'parent' => 'join',
+ 'left' => 'left',
+ 'right' => 'right'
+ )
+ );
+
+}
+
+/**
+ * UuidTree class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class UuidTree extends NumberTree {
+
+/**
+ * name property
+ *
+ * @var string 'FlagTree'
+ */
+ public $name = 'UuidTree';
+}
+
+/**
+ * Campaign class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Campaign extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Campaign'
+ */
+ public $name = 'Campaign';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Ad' => array('fields' => array('id', 'campaign_id', 'name')));
+}
+
+/**
+ * Ad class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Ad extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Ad'
+ */
+ public $name = 'Ad';
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Tree');
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Campaign');
+}
+
+/**
+ * AfterTree class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class AfterTree extends NumberTree {
+
+/**
+ * name property
+ *
+ * @var string 'AfterTree'
+ */
+ public $name = 'AfterTree';
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Tree');
+
+ public function afterSave($created) {
+ if ($created && isset($this->data['AfterTree'])) {
+ $this->data['AfterTree']['name'] = 'Six and One Half Changed in AfterTree::afterSave() but not in database';
+ }
+ }
+
+}
+
+/**
+ * Nonconformant Content class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Content extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Content'
+ */
+ public $name = 'Content';
+
+/**
+ * useTable property
+ *
+ * @var string 'Content'
+ */
+ public $useTable = 'Content';
+
+/**
+ * primaryKey property
+ *
+ * @var string 'iContentId'
+ */
+ public $primaryKey = 'iContentId';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Account' => array('className' => 'Account', 'with' => 'ContentAccount', 'joinTable' => 'ContentAccounts', 'foreignKey' => 'iContentId', 'associationForeignKey', 'iAccountId'));
+}
+
+/**
+ * Nonconformant Account class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Account extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Account'
+ */
+ public $name = 'Account';
+
+/**
+ * useTable property
+ *
+ * @var string 'Account'
+ */
+ public $useTable = 'Accounts';
+
+/**
+ * primaryKey property
+ *
+ * @var string 'iAccountId'
+ */
+ public $primaryKey = 'iAccountId';
+}
+
+/**
+ * Nonconformant ContentAccount class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ContentAccount extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Account'
+ */
+ public $name = 'ContentAccount';
+
+/**
+ * useTable property
+ *
+ * @var string 'Account'
+ */
+ public $useTable = 'ContentAccounts';
+
+/**
+ * primaryKey property
+ *
+ * @var string 'iAccountId'
+ */
+ public $primaryKey = 'iContentAccountsId';
+}
+
+/**
+ * FilmFile class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class FilmFile extends CakeTestModel {
+
+ public $name = 'FilmFile';
+
+}
+
+/**
+ * Basket test model
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Basket extends CakeTestModel {
+
+ public $name = 'Basket';
+
+ public $belongsTo = array(
+ 'FilmFile' => array(
+ 'className' => 'FilmFile',
+ 'foreignKey' => 'object_id',
+ 'conditions' => "Basket.type = 'file'",
+ 'fields' => '',
+ 'order' => ''
+ )
+ );
+
+}
+
+/**
+ * TestPluginArticle class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestPluginArticle extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestPluginArticle'
+ */
+ public $name = 'TestPluginArticle';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('User');
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'TestPluginComment' => array(
+ 'className' => 'TestPlugin.TestPluginComment',
+ 'foreignKey' => 'article_id',
+ 'dependent' => true
+ )
+ );
+}
+
+/**
+ * TestPluginComment class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestPluginComment extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestPluginComment'
+ */
+ public $name = 'TestPluginComment';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'TestPluginArticle' => array(
+ 'className' => 'TestPlugin.TestPluginArticle',
+ 'foreignKey' => 'article_id',
+ ),
+ 'TestPlugin.User'
+ );
+}
+
+/**
+ * Uuidportfolio class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Uuidportfolio extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Uuidportfolio'
+ */
+ public $name = 'Uuidportfolio';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Uuiditem');
+}
+
+/**
+ * Uuiditem class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Uuiditem extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Item'
+ */
+ public $name = 'Uuiditem';
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('Uuidportfolio' => array('with' => 'UuiditemsUuidportfolioNumericid'));
+
+}
+
+/**
+ * UuiditemsPortfolio class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class UuiditemsUuidportfolio extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ItemsPortfolio'
+ */
+ public $name = 'UuiditemsUuidportfolio';
+}
+
+/**
+ * UuiditemsPortfolioNumericid class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class UuiditemsUuidportfolioNumericid extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string
+ */
+ public $name = 'UuiditemsUuidportfolioNumericid';
+}
+
+/**
+ * TranslateTestModel class.
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TranslateTestModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TranslateTestModel'
+ */
+ public $name = 'TranslateTestModel';
+
+/**
+ * useTable property
+ *
+ * @var string 'i18n'
+ */
+ public $useTable = 'i18n';
+
+/**
+ * displayField property
+ *
+ * @var string 'field'
+ */
+ public $displayField = 'field';
+}
+
+/**
+ * TranslateTestModel class.
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TranslateWithPrefix extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TranslateTestModel'
+ */
+ public $name = 'TranslateWithPrefix';
+
+/**
+ * tablePrefix property
+ *
+ * @var string 'i18n'
+ */
+ public $tablePrefix = 'i18n_';
+
+/**
+ * displayField property
+ *
+ * @var string 'field'
+ */
+ public $displayField = 'field';
+
+}
+
+/**
+ * TranslatedItem class.
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TranslatedItem extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TranslatedItem'
+ */
+ public $name = 'TranslatedItem';
+
+/**
+ * cacheQueries property
+ *
+ * @var bool false
+ */
+ public $cacheQueries = false;
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Translate' => array('content', 'title'));
+
+/**
+ * translateModel property
+ *
+ * @var string 'TranslateTestModel'
+ */
+ public $translateModel = 'TranslateTestModel';
+
+}
+
+/**
+ * TranslatedItem class.
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TranslatedItem2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TranslatedItem'
+ */
+ public $name = 'TranslatedItem';
+
+/**
+ * cacheQueries property
+ *
+ * @var bool false
+ */
+ public $cacheQueries = false;
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Translate' => array('content', 'title'));
+
+/**
+ * translateModel property
+ *
+ * @var string
+ */
+ public $translateModel = 'TranslateWithPrefix';
+
+}
+
+/**
+ * TranslatedItemWithTable class.
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TranslatedItemWithTable extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TranslatedItemWithTable'
+ */
+ public $name = 'TranslatedItemWithTable';
+
+/**
+ * useTable property
+ *
+ * @var string 'translated_items'
+ */
+ public $useTable = 'translated_items';
+
+/**
+ * cacheQueries property
+ *
+ * @var bool false
+ */
+ public $cacheQueries = false;
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Translate' => array('content', 'title'));
+
+/**
+ * translateModel property
+ *
+ * @var string
+ */
+ public $translateModel = 'TranslateTestModel';
+
+/**
+ * translateTable property
+ *
+ * @var string 'another_i18n'
+ */
+ public $translateTable = 'another_i18n';
+
+}
+
+/**
+ * TranslateArticleModel class.
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TranslateArticleModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TranslateArticleModel'
+ */
+ public $name = 'TranslateArticleModel';
+
+/**
+ * useTable property
+ *
+ * @var string 'article_i18n'
+ */
+ public $useTable = 'article_i18n';
+
+/**
+ * displayField property
+ *
+ * @var string 'field'
+ */
+ public $displayField = 'field';
+
+}
+
+/**
+ * TranslatedArticle class.
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TranslatedArticle extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TranslatedArticle'
+ */
+ public $name = 'TranslatedArticle';
+
+/**
+ * cacheQueries property
+ *
+ * @var bool false
+ */
+ public $cacheQueries = false;
+
+/**
+ * actsAs property
+ *
+ * @var array
+ */
+ public $actsAs = array('Translate' => array('title', 'body'));
+
+/**
+ * translateModel property
+ *
+ * @var string 'TranslateArticleModel'
+ */
+ public $translateModel = 'TranslateArticleModel';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('User');
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $hasMany = array('TranslatedItem');
+
+}
+
+class CounterCacheUser extends CakeTestModel {
+
+ public $name = 'CounterCacheUser';
+
+ public $alias = 'User';
+
+ public $hasMany = array(
+ 'Post' => array(
+ 'className' => 'CounterCachePost',
+ 'foreignKey' => 'user_id'
+ )
+ );
+}
+
+class CounterCachePost extends CakeTestModel {
+
+ public $name = 'CounterCachePost';
+
+ public $alias = 'Post';
+
+ public $belongsTo = array(
+ 'User' => array(
+ 'className' => 'CounterCacheUser',
+ 'foreignKey' => 'user_id',
+ 'counterCache' => true
+ )
+ );
+}
+
+class CounterCacheUserNonstandardPrimaryKey extends CakeTestModel {
+
+ public $name = 'CounterCacheUserNonstandardPrimaryKey';
+
+ public $alias = 'User';
+
+ public $primaryKey = 'uid';
+
+ public $hasMany = array(
+ 'Post' => array(
+ 'className' => 'CounterCachePostNonstandardPrimaryKey',
+ 'foreignKey' => 'uid'
+ )
+ );
+
+}
+
+class CounterCachePostNonstandardPrimaryKey extends CakeTestModel {
+
+ public $name = 'CounterCachePostNonstandardPrimaryKey';
+
+ public $alias = 'Post';
+
+ public $primaryKey = 'pid';
+
+ public $belongsTo = array(
+ 'User' => array(
+ 'className' => 'CounterCacheUserNonstandardPrimaryKey',
+ 'foreignKey' => 'uid',
+ 'counterCache' => true
+ )
+ );
+
+}
+
+class ArticleB extends CakeTestModel {
+
+ public $name = 'ArticleB';
+
+ public $useTable = 'articles';
+
+ public $hasAndBelongsToMany = array(
+ 'TagB' => array(
+ 'className' => 'TagB',
+ 'joinTable' => 'articles_tags',
+ 'foreignKey' => 'article_id',
+ 'associationForeignKey' => 'tag_id'
+ )
+ );
+
+}
+
+class TagB extends CakeTestModel {
+
+ public $name = 'TagB';
+
+ public $useTable = 'tags';
+
+ public $hasAndBelongsToMany = array(
+ 'ArticleB' => array(
+ 'className' => 'ArticleB',
+ 'joinTable' => 'articles_tags',
+ 'foreignKey' => 'tag_id',
+ 'associationForeignKey' => 'article_id'
+ )
+ );
+
+}
+
+class Fruit extends CakeTestModel {
+
+ public $name = 'Fruit';
+
+ public $hasAndBelongsToMany = array(
+ 'UuidTag' => array(
+ 'className' => 'UuidTag',
+ 'joinTable' => 'fruits_uuid_tags',
+ 'foreignKey' => 'fruit_id',
+ 'associationForeignKey' => 'uuid_tag_id',
+ 'with' => 'FruitsUuidTag'
+ )
+ );
+
+}
+
+class FruitsUuidTag extends CakeTestModel {
+
+ public $name = 'FruitsUuidTag';
+
+ public $primaryKey = false;
+
+ public $belongsTo = array(
+ 'UuidTag' => array(
+ 'className' => 'UuidTag',
+ 'foreignKey' => 'uuid_tag_id',
+ ),
+ 'Fruit' => array(
+ 'className' => 'Fruit',
+ 'foreignKey' => 'fruit_id',
+ )
+ );
+
+}
+
+class UuidTag extends CakeTestModel {
+
+ public $name = 'UuidTag';
+
+ public $hasAndBelongsToMany = array(
+ 'Fruit' => array(
+ 'className' => 'Fruit',
+ 'joinTable' => 'fruits_uuid_tags',
+ 'foreign_key' => 'uuid_tag_id',
+ 'associationForeignKey' => 'fruit_id',
+ 'with' => 'FruitsUuidTag'
+ )
+ );
+
+}
+
+class FruitNoWith extends CakeTestModel {
+
+ public $name = 'Fruit';
+
+ public $useTable = 'fruits';
+
+ public $hasAndBelongsToMany = array(
+ 'UuidTag' => array(
+ 'className' => 'UuidTagNoWith',
+ 'joinTable' => 'fruits_uuid_tags',
+ 'foreignKey' => 'fruit_id',
+ 'associationForeignKey' => 'uuid_tag_id',
+ )
+ );
+
+}
+
+class UuidTagNoWith extends CakeTestModel {
+
+ public $name = 'UuidTag';
+
+ public $useTable = 'uuid_tags';
+
+ public $hasAndBelongsToMany = array(
+ 'Fruit' => array(
+ 'className' => 'FruitNoWith',
+ 'joinTable' => 'fruits_uuid_tags',
+ 'foreign_key' => 'uuid_tag_id',
+ 'associationForeignKey' => 'fruit_id',
+ )
+ );
+
+}
+
+class ProductUpdateAll extends CakeTestModel {
+
+ public $name = 'ProductUpdateAll';
+
+ public $useTable = 'product_update_all';
+
+}
+
+class GroupUpdateAll extends CakeTestModel {
+
+ public $name = 'GroupUpdateAll';
+
+ public $useTable = 'group_update_all';
+
+}
+
+class TransactionTestModel extends CakeTestModel {
+
+ public $name = 'TransactionTestModel';
+
+ public $useTable = 'samples';
+
+ public function afterSave($created) {
+ $data = array(
+ array('apple_id' => 1, 'name' => 'sample6'),
+ );
+ $this->saveAll($data, array('atomic' => true, 'callbacks' => false));
+ }
+
+}
+
+class TransactionManyTestModel extends CakeTestModel {
+
+ public $name = 'TransactionManyTestModel';
+
+ public $useTable = 'samples';
+
+ public function afterSave($created) {
+ $data = array(
+ array('apple_id' => 1, 'name' => 'sample6'),
+ );
+ $this->saveMany($data, array('atomic' => true, 'callbacks' => false));
+ }
+
+}
+
+class Site extends CakeTestModel {
+
+ public $name = 'Site';
+
+ public $useTable = 'sites';
+
+ public $hasAndBelongsToMany = array(
+ 'Domain' => array('unique' => 'keepExisting'),
+ );
+}
+
+class Domain extends CakeTestModel {
+
+ public $name = 'Domain';
+
+ public $useTable = 'domains';
+
+ public $hasAndBelongsToMany = array(
+ 'Site' => array('unique' => 'keepExisting'),
+ );
+}
+
+/**
+ * TestModel class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel'
+ */
+ public $name = 'TestModel';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'client_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '11'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
+ 'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'last_login' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+
+/**
+ * find method
+ *
+ * @param mixed $conditions
+ * @param mixed $fields
+ * @param mixed $order
+ * @param mixed $recursive
+ * @return void
+ */
+ public function find($conditions = null, $fields = null, $order = null, $recursive = null) {
+ return array($conditions, $fields);
+ }
+
+/**
+ * findAll method
+ *
+ * @param mixed $conditions
+ * @param mixed $fields
+ * @param mixed $order
+ * @param mixed $recursive
+ * @return void
+ */
+ public function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
+ return $conditions;
+ }
+
+}
+
+/**
+ * TestModel2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel2'
+ */
+ public $name = 'TestModel2';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+}
+
+/**
+ * TestModel4 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel3 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel3'
+ */
+ public $name = 'TestModel3';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+}
+
+/**
+ * TestModel4 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel4 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel4'
+ */
+ public $name = 'TestModel4';
+
+/**
+ * table property
+ *
+ * @var string 'test_model4'
+ */
+ public $table = 'test_model4';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'TestModel4Parent' => array(
+ 'className' => 'TestModel4',
+ 'foreignKey' => 'parent_id'
+ )
+ );
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array(
+ 'TestModel5' => array(
+ 'className' => 'TestModel5',
+ 'foreignKey' => 'test_model4_id'
+ )
+ );
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('TestModel7' => array(
+ 'className' => 'TestModel7',
+ 'joinTable' => 'test_model4_test_model7',
+ 'foreignKey' => 'test_model4_id',
+ 'associationForeignKey' => 'test_model7_id',
+ 'with' => 'TestModel4TestModel7'
+ ));
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * TestModel4TestModel7 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel4TestModel7 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel4TestModel7'
+ */
+ public $name = 'TestModel4TestModel7';
+
+/**
+ * table property
+ *
+ * @var string 'test_model4_test_model7'
+ */
+ public $table = 'test_model4_test_model7';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'test_model4_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'test_model7_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8')
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * TestModel5 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel5 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel5'
+ */
+ public $name = 'TestModel5';
+
+/**
+ * table property
+ *
+ * @var string 'test_model5'
+ */
+ public $table = 'test_model5';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('TestModel4' => array(
+ 'className' => 'TestModel4',
+ 'foreignKey' => 'test_model4_id'
+ ));
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('TestModel6' => array(
+ 'className' => 'TestModel6',
+ 'foreignKey' => 'test_model5_id'
+ ));
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'test_model4_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * TestModel6 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel6 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel6'
+ */
+ public $name = 'TestModel6';
+
+/**
+ * table property
+ *
+ * @var string 'test_model6'
+ */
+ public $table = 'test_model6';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'TestModel5' => array(
+ 'className' => 'TestModel5',
+ 'foreignKey' => 'test_model5_id'
+ )
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'test_model5_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * TestModel7 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel7 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel7'
+ */
+ public $name = 'TestModel7';
+
+/**
+ * table property
+ *
+ * @var string 'test_model7'
+ */
+ public $table = 'test_model7';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * TestModel8 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel8 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel8'
+ */
+ public $name = 'TestModel8';
+
+/**
+ * table property
+ *
+ * @var string 'test_model8'
+ */
+ public $table = 'test_model8';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array(
+ 'TestModel9' => array(
+ 'className' => 'TestModel9',
+ 'foreignKey' => 'test_model8_id',
+ 'conditions' => 'TestModel9.name != \'mariano\''
+ )
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'test_model9_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * TestModel9 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class TestModel9 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestModel9'
+ */
+ public $name = 'TestModel9';
+
+/**
+ * table property
+ *
+ * @var string 'test_model9'
+ */
+ public $table = 'test_model9';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'TestModel8' => array(
+ 'className' => 'TestModel8',
+ 'foreignKey' => 'test_model8_id',
+ 'conditions' => 'TestModel8.name != \'larry\''
+ )
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'test_model8_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '11'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * Level class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Level extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Level'
+ */
+ public $name = 'Level';
+
+/**
+ * table property
+ *
+ * @var string 'level'
+ */
+ public $table = 'level';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Group' => array(
+ 'className' => 'Group'
+ ),
+ 'User2' => array(
+ 'className' => 'User2'
+ )
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'name' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => '20'),
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * Group class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Group extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Group'
+ */
+ public $name = 'Group';
+
+/**
+ * table property
+ *
+ * @var string 'group'
+ */
+ public $table = 'group';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('Level');
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array('Category2', 'User2');
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'level_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'name' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => '20'),
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * User2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class User2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'User2'
+ */
+ public $name = 'User2';
+
+/**
+ * table property
+ *
+ * @var string 'user'
+ */
+ public $table = 'user';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Group' => array(
+ 'className' => 'Group'
+ ),
+ 'Level' => array(
+ 'className' => 'Level'
+ )
+ );
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Article2' => array(
+ 'className' => 'Article2'
+ ),
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'group_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'level_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'name' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => '20'),
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * Category2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Category2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Category2'
+ */
+ public $name = 'Category2';
+
+/**
+ * table property
+ *
+ * @var string 'category'
+ */
+ public $table = 'category';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Group' => array(
+ 'className' => 'Group',
+ 'foreignKey' => 'group_id'
+ ),
+ 'ParentCat' => array(
+ 'className' => 'Category2',
+ 'foreignKey' => 'parent_id'
+ )
+ );
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'ChildCat' => array(
+ 'className' => 'Category2',
+ 'foreignKey' => 'parent_id'
+ ),
+ 'Article2' => array(
+ 'className' => 'Article2',
+ 'order' => 'Article2.published_date DESC',
+ 'foreignKey' => 'category_id',
+ 'limit' => '3')
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '10'),
+ 'group_id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '10'),
+ 'parent_id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '10'),
+ 'name' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'icon' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'description' => array('type' => 'text', 'null' => false, 'default' => '', 'length' => null),
+
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * Article2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Article2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Article2'
+ */
+ public $name = 'Article2';
+
+/**
+ * table property
+ *
+ * @var string 'article'
+ */
+ public $table = 'articles';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Category2' => array('className' => 'Category2'),
+ 'User2' => array('className' => 'User2')
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '10'),
+ 'category_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'user_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'rate_count' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'rate_sum' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'viewed' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'version' => array('type' => 'string', 'null' => true, 'default' => '', 'length' => '45'),
+ 'title' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '200'),
+ 'intro' => array('text' => 'string', 'null' => true, 'default' => '', 'length' => null),
+ 'comments' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '4'),
+ 'body' => array('text' => 'string', 'null' => true, 'default' => '', 'length' => null),
+ 'isdraft' => array('type' => 'boolean', 'null' => false, 'default' => '0', 'length' => '1'),
+ 'allow_comments' => array('type' => 'boolean', 'null' => false, 'default' => '1', 'length' => '1'),
+ 'moderate_comments' => array('type' => 'boolean', 'null' => false, 'default' => '1', 'length' => '1'),
+ 'published' => array('type' => 'boolean', 'null' => false, 'default' => '0', 'length' => '1'),
+ 'multipage' => array('type' => 'boolean', 'null' => false, 'default' => '0', 'length' => '1'),
+ 'published_date' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null),
+ 'created' => array('type' => 'datetime', 'null' => false, 'default' => '0000-00-00 00:00:00', 'length' => null),
+ 'modified' => array('type' => 'datetime', 'null' => false, 'default' => '0000-00-00 00:00:00', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * CategoryFeatured2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class CategoryFeatured2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'CategoryFeatured2'
+ */
+ public $name = 'CategoryFeatured2';
+
+/**
+ * table property
+ *
+ * @var string 'category_featured'
+ */
+ public $table = 'category_featured';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '10'),
+ 'parent_id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '10'),
+ 'name' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'icon' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'description' => array('text' => 'string', 'null' => false, 'default' => '', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * Featured2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Featured2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Featured2'
+ */
+ public $name = 'Featured2';
+
+/**
+ * table property
+ *
+ * @var string 'featured2'
+ */
+ public $table = 'featured2';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'CategoryFeatured2' => array(
+ 'className' => 'CategoryFeatured2'
+ )
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'article_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'category_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'name' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => '20')
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * Comment2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Comment2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Comment2'
+ */
+ public $name = 'Comment2';
+
+/**
+ * table property
+ *
+ * @var string 'comment'
+ */
+ public $table = 'comment';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('ArticleFeatured2', 'User2');
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'article_featured_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'user_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'name' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => '20')
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * ArticleFeatured2 class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ArticleFeatured2 extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'ArticleFeatured2'
+ */
+ public $name = 'ArticleFeatured2';
+
+/**
+ * table property
+ *
+ * @var string 'article_featured'
+ */
+ public $table = 'article_featured';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'CategoryFeatured2' => array('className' => 'CategoryFeatured2'),
+ 'User2' => array('className' => 'User2')
+ );
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array(
+ 'Featured2' => array('className' => 'Featured2')
+ );
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Comment2' => array('className' => 'Comment2', 'dependent' => true)
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ if (!isset($this->_schema)) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => '10'),
+ 'category_featured_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'user_id' => array('type' => 'integer', 'null' => false, 'default' => '0', 'length' => '10'),
+ 'title' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => '20'),
+ 'body' => array('text' => 'string', 'null' => true, 'default' => '', 'length' => null),
+ 'published' => array('type' => 'boolean', 'null' => false, 'default' => '0', 'length' => '1'),
+ 'published_date' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null),
+ 'created' => array('type' => 'datetime', 'null' => false, 'default' => '0000-00-00 00:00:00', 'length' => null),
+ 'modified' => array('type' => 'datetime', 'null' => false, 'default' => '0000-00-00 00:00:00', 'length' => null)
+ );
+ }
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * MysqlTestModel class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class MysqlTestModel extends Model {
+
+/**
+ * name property
+ *
+ * @var string 'MysqlTestModel'
+ */
+ public $name = 'MysqlTestModel';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * find method
+ *
+ * @param mixed $conditions
+ * @param mixed $fields
+ * @param mixed $order
+ * @param mixed $recursive
+ * @return void
+ */
+ public function find($conditions = null, $fields = null, $order = null, $recursive = null) {
+ return $conditions;
+ }
+
+/**
+ * findAll method
+ *
+ * @param mixed $conditions
+ * @param mixed $fields
+ * @param mixed $order
+ * @param mixed $recursive
+ * @return void
+ */
+ public function findAll($conditions = null, $fields = null, $order = null, $recursive = null) {
+ return $conditions;
+ }
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ return array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'client_id' => array('type' => 'integer', 'null' => '', 'default' => '0', 'length' => '11'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'login' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'passwd' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_1' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'addr_2' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '25'),
+ 'zip_code' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'city' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'country' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'phone' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'fax' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'url' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '1', 'default' => '', 'length' => '155'),
+ 'comments' => array('type' => 'text', 'null' => '1', 'default' => '', 'length' => ''),
+ 'last_login' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+ }
+
+}
+
+/**
+ * Test model for datasource prefixes
+ *
+ */
+class PrefixTestModel extends CakeTestModel {
+}
+
+class PrefixTestUseTableModel extends CakeTestModel {
+
+ public $name = 'PrefixTest';
+
+ public $useTable = 'prefix_tests';
+
+}
+
+/**
+ * ScaffoldMock class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldMock extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'articles';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'User' => array(
+ 'className' => 'ScaffoldUser',
+ 'foreignKey' => 'user_id',
+ )
+ );
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Comment' => array(
+ 'className' => 'ScaffoldComment',
+ 'foreignKey' => 'article_id',
+ )
+ );
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var string
+ */
+ public $hasAndBelongsToMany = array(
+ 'ScaffoldTag' => array(
+ 'className' => 'ScaffoldTag',
+ 'foreignKey' => 'something_id',
+ 'associationForeignKey' => 'something_else_id',
+ 'joinTable' => 'join_things'
+ )
+ );
+
+}
+
+/**
+ * ScaffoldUser class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldUser extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'users';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Article' => array(
+ 'className' => 'ScaffoldMock',
+ 'foreignKey' => 'article_id',
+ )
+ );
+}
+
+/**
+ * ScaffoldComment class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldComment extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'comments';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'Article' => array(
+ 'className' => 'ScaffoldMock',
+ 'foreignKey' => 'article_id',
+ )
+ );
+}
+
+/**
+ * ScaffoldTag class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldTag extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var string 'posts'
+ */
+ public $useTable = 'tags';
+
+}
+
+/**
+ * Player class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Player extends CakeTestModel {
+
+ public $hasAndBelongsToMany = array(
+ 'Guild' => array(
+ 'with' => 'GuildsPlayer',
+ 'unique' => true,
+ ),
+ );
+
+}
+
+/**
+ * Guild class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Guild extends CakeTestModel {
+
+ public $hasAndBelongsToMany = array(
+ 'Player' => array(
+ 'with' => 'GuildsPlayer',
+ 'unique' => true,
+ ),
+ );
+
+}
+
+/**
+ * GuildsPlayer class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class GuildsPlayer extends CakeTestModel {
+
+ public $useDbConfig = 'test2';
+
+ public $belongsTo = array(
+ 'Player',
+ 'Guild',
+ );
+}
+
+/**
+ * Armor class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class Armor extends CakeTestModel {
+
+ public $useDbConfig = 'test2';
+
+ public $hasAndBelongsToMany = array(
+ 'Player' => array('with' => 'ArmorsPlayer'),
+ );
+}
+
+/**
+ * ArmorsPlayer class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class ArmorsPlayer extends CakeTestModel {
+
+ public $useDbConfig = 'test_database_three';
+
+}
+
+/**
+ * CustomArticle class
+ *
+ * @package Cake.Test.Case.Model
+ */
+class CustomArticle extends AppModel {
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = 'articles';
+
+/**
+ * findMethods property
+ *
+ * @var array
+ */
+ public $findMethods = array('unPublished' => true);
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('User');
+
+/**
+ * _findUnPublished custom find
+ *
+ * @return array
+ */
+ protected function _findUnPublished($state, $query, $results = array()) {
+ if ($state === 'before') {
+ $query['conditions']['published'] = 'N';
+ return $query;
+ }
+ return $results;
+ }
+
+/**
+ * Alters title data
+ *
+ * @return void
+ **/
+ public function beforeValidate($options = array()) {
+ $this->data[$this->alias]['title'] = 'foo';
+ if ($this->findMethods['unPublished'] === true) {
+ $this->findMethods['unPublished'] = false;
+ } else {
+ $this->findMethods['unPublished'] = 'true again';
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeRequestTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeRequestTest.php
new file mode 100644
index 0000000..8ef0e18
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeRequestTest.php
@@ -0,0 +1,1890 @@
+<?php
+/**
+ * CakeRequest Test case file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Network
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Dispatcher', 'Routing');
+App::uses('Xml', 'Utility');
+App::uses('CakeRequest', 'Network');
+
+class TestCakeRequest extends CakeRequest {
+
+ public function reConstruct($url = 'some/path', $parseEnvironment = true) {
+ $this->_base();
+ if (empty($url)) {
+ $url = $this->_url();
+ }
+ if ($url[0] == '/') {
+ $url = substr($url, 1);
+ }
+ $this->url = $url;
+
+ if ($parseEnvironment) {
+ $this->_processPost();
+ $this->_processGet();
+ $this->_processFiles();
+ }
+ $this->here = $this->base . '/' . $this->url;
+ }
+
+}
+
+class CakeRequestTest extends CakeTestCase {
+
+/**
+ * setup callback
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->_app = Configure::read('App');
+ $this->_case = null;
+ if (isset($_GET['case'])) {
+ $this->_case = $_GET['case'];
+ unset($_GET['case']);
+ }
+
+ Configure::write('App.baseUrl', false);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ if (!empty($this->_case)) {
+ $_GET['case'] = $this->_case;
+ }
+ Configure::write('App', $this->_app);
+ }
+
+/**
+ * test that the autoparse = false constructor works.
+ *
+ * @return void
+ */
+ public function testNoAutoParseConstruction() {
+ $_GET = array(
+ 'one' => 'param'
+ );
+ $request = new CakeRequest(null, false);
+ $this->assertFalse(isset($request->query['one']));
+ }
+
+/**
+ * test construction
+ *
+ * @return void
+ */
+ public function testConstructionGetParsing() {
+ $_GET = array(
+ 'one' => 'param',
+ 'two' => 'banana'
+ );
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($request->query, $_GET);
+
+ $_GET = array(
+ 'one' => 'param',
+ 'two' => 'banana',
+ );
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($request->query, $_GET);
+ $this->assertEquals('some/path', $request->url);
+ }
+
+/**
+ * Test that querystring args provided in the url string are parsed.
+ *
+ * @return void
+ */
+ public function testQueryStringParsingFromInputUrl() {
+ $_GET = array();
+ $request = new CakeRequest('some/path?one=something&two=else');
+ $expected = array('one' => 'something', 'two' => 'else');
+ $this->assertEquals($expected, $request->query);
+ $this->assertEquals('some/path?one=something&two=else', $request->url);
+ }
+
+/**
+ * Test that named arguments + querystrings are handled correctly.
+ *
+ * @return void
+ */
+ public function testQueryStringAndNamedParams() {
+ $_SERVER['REQUEST_URI'] = '/tasks/index/page:1?ts=123456';
+ $request = new CakeRequest();
+ $this->assertEquals('tasks/index/page:1', $request->url);
+
+ $_SERVER['REQUEST_URI'] = '/tasks/index/page:1/?ts=123456';
+ $request = new CakeRequest();
+ $this->assertEquals('tasks/index/page:1/', $request->url);
+ }
+
+/**
+ * test addParams() method
+ *
+ * @return void
+ */
+ public function testAddParams() {
+ $request = new CakeRequest('some/path');
+ $request->params = array('controller' => 'posts', 'action' => 'view');
+ $result = $request->addParams(array('plugin' => null, 'action' => 'index'));
+
+ $this->assertSame($result, $request, 'Method did not return itself. %s');
+
+ $this->assertEquals('posts', $request->controller);
+ $this->assertEquals('index', $request->action);
+ $this->assertEquals(null, $request->plugin);
+ }
+
+/**
+ * test splicing in paths.
+ *
+ * @return void
+ */
+ public function testAddPaths() {
+ $request = new CakeRequest('some/path');
+ $request->webroot = '/some/path/going/here/';
+ $result = $request->addPaths(array(
+ 'random' => '/something', 'webroot' => '/', 'here' => '/', 'base' => '/base_dir'
+ ));
+
+ $this->assertSame($result, $request, 'Method did not return itself. %s');
+
+ $this->assertEquals('/', $request->webroot);
+ $this->assertEquals('/base_dir', $request->base);
+ $this->assertEquals('/', $request->here);
+ $this->assertFalse(isset($request->random));
+ }
+
+/**
+ * test parsing POST data into the object.
+ *
+ * @return void
+ */
+ public function testPostParsing() {
+ $_POST = array('data' => array(
+ 'Article' => array('title')
+ ));
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($_POST['data'], $request->data);
+
+ $_POST = array('one' => 1, 'two' => 'three');
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($_POST, $request->data);
+
+ $_POST = array(
+ 'data' => array(
+ 'Article' => array('title' => 'Testing'),
+ ),
+ 'action' => 'update'
+ );
+ $request = new CakeRequest('some/path');
+ $expected = array(
+ 'Article' => array('title' => 'Testing'),
+ 'action' => 'update'
+ );
+ $this->assertEquals($expected, $request->data);
+
+ $_POST = array('data' => array(
+ 'Article' => array('title'),
+ 'Tag' => array('Tag' => array(1, 2))
+ ));
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($_POST['data'], $request->data);
+
+ $_POST = array('data' => array(
+ 'Article' => array('title' => 'some title'),
+ 'Tag' => array('Tag' => array(1, 2))
+ ));
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($_POST['data'], $request->data);
+
+ $_POST = array(
+ 'a' => array(1, 2),
+ 'b' => array(1, 2)
+ );
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($_POST, $request->data);
+ }
+
+/**
+ * test parsing PUT data into the object.
+ *
+ * @return void
+ */
+ public function testPutParsing() {
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+
+ $data = array('data' => array(
+ 'Article' => array('title')
+ ));
+
+ $request = $this->getMock('TestCakeRequest', array('_readInput'));
+ $request->expects($this->at(0))->method('_readInput')
+ ->will($this->returnValue('data[Article][]=title'));
+ $request->reConstruct();
+ $this->assertEquals($data['data'], $request->data);
+
+ $data = array('one' => 1, 'two' => 'three');
+ $request = $this->getMock('TestCakeRequest', array('_readInput'));
+ $request->expects($this->at(0))->method('_readInput')
+ ->will($this->returnValue('one=1&two=three'));
+ $request->reConstruct();
+ $this->assertEquals($data, $request->data);
+
+ $data = array(
+ 'data' => array(
+ 'Article' => array('title' => 'Testing'),
+ ),
+ 'action' => 'update'
+ );
+ $request = $this->getMock('TestCakeRequest', array('_readInput'));
+ $request->expects($this->at(0))->method('_readInput')
+ ->will($this->returnValue('data[Article][title]=Testing&action=update'));
+ $request->reConstruct();
+ $expected = array(
+ 'Article' => array('title' => 'Testing'),
+ 'action' => 'update'
+ );
+ $this->assertEquals($expected, $request->data);
+
+ $_SERVER['REQUEST_METHOD'] = 'DELETE';
+ $data = array('data' => array(
+ 'Article' => array('title'),
+ 'Tag' => array('Tag' => array(1, 2))
+ ));
+ $request = $this->getMock('TestCakeRequest', array('_readInput'));
+ $request->expects($this->at(0))->method('_readInput')
+ ->will($this->returnValue('data[Article][]=title&Tag[Tag][]=1&Tag[Tag][]=2'));
+ $request->reConstruct();
+ $this->assertEquals($data['data'], $request->data);
+
+ $data = array('data' => array(
+ 'Article' => array('title' => 'some title'),
+ 'Tag' => array('Tag' => array(1, 2))
+ ));
+ $request = $this->getMock('TestCakeRequest', array('_readInput'));
+ $request->expects($this->at(0))->method('_readInput')
+ ->will($this->returnValue('data[Article][title]=some%20title&Tag[Tag][]=1&Tag[Tag][]=2'));
+ $request->reConstruct();
+ $this->assertEquals($data['data'], $request->data);
+
+ $data = array(
+ 'a' => array(1, 2),
+ 'b' => array(1, 2)
+ );
+ $request = $this->getMock('TestCakeRequest', array('_readInput'));
+ $request->expects($this->at(0))->method('_readInput')
+ ->will($this->returnValue('a[]=1&a[]=2&b[]=1&b[]=2'));
+ $request->reConstruct();
+ $this->assertEquals($data, $request->data);
+ }
+
+/**
+ * test parsing json PUT data into the object.
+ *
+ * @return void
+ */
+ public function testPutParsingJSON() {
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $_SERVER['CONTENT_TYPE'] = 'application/json';
+
+ $request = $this->getMock('TestCakeRequest', array('_readInput'));
+ $request->expects($this->at(0))->method('_readInput')
+ ->will($this->returnValue('{Article":["title"]}'));
+ $request->reConstruct();
+ $this->assertEquals('{Article":["title"]}', $request->data);
+ }
+
+/**
+ * test parsing of FILES array
+ *
+ * @return void
+ */
+ public function testFilesParsing() {
+ $_FILES = array(
+ 'data' => array(
+ 'name' => array(
+ 'File' => array(
+ array('data' => 'cake_sqlserver_patch.patch'),
+ array('data' => 'controller.diff'),
+ array('data' => ''),
+ array('data' => ''),
+ ),
+ 'Post' => array('attachment' => 'jquery-1.2.1.js'),
+ ),
+ 'type' => array(
+ 'File' => array(
+ array('data' => ''),
+ array('data' => ''),
+ array('data' => ''),
+ array('data' => ''),
+ ),
+ 'Post' => array('attachment' => 'application/x-javascript'),
+ ),
+ 'tmp_name' => array(
+ 'File' => array(
+ array('data' => '/private/var/tmp/phpy05Ywj'),
+ array('data' => '/private/var/tmp/php7MBztY'),
+ array('data' => ''),
+ array('data' => ''),
+ ),
+ 'Post' => array('attachment' => '/private/var/tmp/phpEwlrIo'),
+ ),
+ 'error' => array(
+ 'File' => array(
+ array('data' => 0),
+ array('data' => 0),
+ array('data' => 4),
+ array('data' => 4)
+ ),
+ 'Post' => array('attachment' => 0)
+ ),
+ 'size' => array(
+ 'File' => array(
+ array('data' => 6271),
+ array('data' => 350),
+ array('data' => 0),
+ array('data' => 0),
+ ),
+ 'Post' => array('attachment' => 80469)
+ ),
+ )
+ );
+
+ $request = new CakeRequest('some/path');
+ $expected = array(
+ 'File' => array(
+ array(
+ 'data' => array(
+ 'name' => 'cake_sqlserver_patch.patch',
+ 'type' => '',
+ 'tmp_name' => '/private/var/tmp/phpy05Ywj',
+ 'error' => 0,
+ 'size' => 6271,
+ )
+ ),
+ array(
+ 'data' => array(
+ 'name' => 'controller.diff',
+ 'type' => '',
+ 'tmp_name' => '/private/var/tmp/php7MBztY',
+ 'error' => 0,
+ 'size' => 350,
+ )
+ ),
+ array(
+ 'data' => array(
+ 'name' => '',
+ 'type' => '',
+ 'tmp_name' => '',
+ 'error' => 4,
+ 'size' => 0,
+ )
+ ),
+ array(
+ 'data' => array(
+ 'name' => '',
+ 'type' => '',
+ 'tmp_name' => '',
+ 'error' => 4,
+ 'size' => 0,
+ )
+ ),
+ ),
+ 'Post' => array(
+ 'attachment' => array(
+ 'name' => 'jquery-1.2.1.js',
+ 'type' => 'application/x-javascript',
+ 'tmp_name' => '/private/var/tmp/phpEwlrIo',
+ 'error' => 0,
+ 'size' => 80469,
+ )
+ )
+ );
+ $this->assertEquals($expected, $request->data);
+
+ $_FILES = array(
+ 'data' => array(
+ 'name' => array(
+ 'Document' => array(
+ 1 => array(
+ 'birth_cert' => 'born on.txt',
+ 'passport' => 'passport.txt',
+ 'drivers_license' => 'ugly pic.jpg'
+ ),
+ 2 => array(
+ 'birth_cert' => 'aunt betty.txt',
+ 'passport' => 'betty-passport.txt',
+ 'drivers_license' => 'betty-photo.jpg'
+ ),
+ ),
+ ),
+ 'type' => array(
+ 'Document' => array(
+ 1 => array(
+ 'birth_cert' => 'application/octet-stream',
+ 'passport' => 'application/octet-stream',
+ 'drivers_license' => 'application/octet-stream',
+ ),
+ 2 => array(
+ 'birth_cert' => 'application/octet-stream',
+ 'passport' => 'application/octet-stream',
+ 'drivers_license' => 'application/octet-stream',
+ )
+ )
+ ),
+ 'tmp_name' => array(
+ 'Document' => array(
+ 1 => array(
+ 'birth_cert' => '/private/var/tmp/phpbsUWfH',
+ 'passport' => '/private/var/tmp/php7f5zLt',
+ 'drivers_license' => '/private/var/tmp/phpMXpZgT',
+ ),
+ 2 => array(
+ 'birth_cert' => '/private/var/tmp/php5kHZt0',
+ 'passport' => '/private/var/tmp/phpnYkOuM',
+ 'drivers_license' => '/private/var/tmp/php9Rq0P3',
+ )
+ )
+ ),
+ 'error' => array(
+ 'Document' => array(
+ 1 => array(
+ 'birth_cert' => 0,
+ 'passport' => 0,
+ 'drivers_license' => 0,
+ ),
+ 2 => array(
+ 'birth_cert' => 0,
+ 'passport' => 0,
+ 'drivers_license' => 0,
+ )
+ )
+ ),
+ 'size' => array(
+ 'Document' => array(
+ 1 => array(
+ 'birth_cert' => 123,
+ 'passport' => 458,
+ 'drivers_license' => 875,
+ ),
+ 2 => array(
+ 'birth_cert' => 876,
+ 'passport' => 976,
+ 'drivers_license' => 9783,
+ )
+ )
+ )
+ )
+ );
+
+ $request = new CakeRequest('some/path');
+ $expected = array(
+ 'Document' => array(
+ 1 => array(
+ 'birth_cert' => array(
+ 'name' => 'born on.txt',
+ 'tmp_name' => '/private/var/tmp/phpbsUWfH',
+ 'error' => 0,
+ 'size' => 123,
+ 'type' => 'application/octet-stream',
+ ),
+ 'passport' => array(
+ 'name' => 'passport.txt',
+ 'tmp_name' => '/private/var/tmp/php7f5zLt',
+ 'error' => 0,
+ 'size' => 458,
+ 'type' => 'application/octet-stream',
+ ),
+ 'drivers_license' => array(
+ 'name' => 'ugly pic.jpg',
+ 'tmp_name' => '/private/var/tmp/phpMXpZgT',
+ 'error' => 0,
+ 'size' => 875,
+ 'type' => 'application/octet-stream',
+ ),
+ ),
+ 2 => array(
+ 'birth_cert' => array(
+ 'name' => 'aunt betty.txt',
+ 'tmp_name' => '/private/var/tmp/php5kHZt0',
+ 'error' => 0,
+ 'size' => 876,
+ 'type' => 'application/octet-stream',
+ ),
+ 'passport' => array(
+ 'name' => 'betty-passport.txt',
+ 'tmp_name' => '/private/var/tmp/phpnYkOuM',
+ 'error' => 0,
+ 'size' => 976,
+ 'type' => 'application/octet-stream',
+ ),
+ 'drivers_license' => array(
+ 'name' => 'betty-photo.jpg',
+ 'tmp_name' => '/private/var/tmp/php9Rq0P3',
+ 'error' => 0,
+ 'size' => 9783,
+ 'type' => 'application/octet-stream',
+ ),
+ ),
+ )
+ );
+ $this->assertEquals($expected, $request->data);
+
+ $_FILES = array(
+ 'data' => array(
+ 'name' => array('birth_cert' => 'born on.txt'),
+ 'type' => array('birth_cert' => 'application/octet-stream'),
+ 'tmp_name' => array('birth_cert' => '/private/var/tmp/phpbsUWfH'),
+ 'error' => array('birth_cert' => 0),
+ 'size' => array('birth_cert' => 123)
+ )
+ );
+
+ $request = new CakeRequest('some/path');
+ $expected = array(
+ 'birth_cert' => array(
+ 'name' => 'born on.txt',
+ 'type' => 'application/octet-stream',
+ 'tmp_name' => '/private/var/tmp/phpbsUWfH',
+ 'error' => 0,
+ 'size' => 123
+ )
+ );
+ $this->assertEquals($expected, $request->data);
+
+ $_FILES = array(
+ 'something' => array(
+ 'name' => 'something.txt',
+ 'type' => 'text/plain',
+ 'tmp_name' => '/some/file',
+ 'error' => 0,
+ 'size' => 123
+ )
+ );
+ $request = new CakeRequest('some/path');
+ $this->assertEquals($request->params['form'], $_FILES);
+ }
+
+/**
+ * test method overrides coming in from POST data.
+ *
+ * @return void
+ */
+ public function testMethodOverrides() {
+ $_POST = array('_method' => 'POST');
+ $request = new CakeRequest('some/path');
+ $this->assertEquals(env('REQUEST_METHOD'), 'POST');
+
+ $_POST = array('_method' => 'DELETE');
+ $request = new CakeRequest('some/path');
+ $this->assertEquals(env('REQUEST_METHOD'), 'DELETE');
+
+ $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
+ $request = new CakeRequest('some/path');
+ $this->assertEquals(env('REQUEST_METHOD'), 'PUT');
+ }
+
+/**
+ * test the clientIp method.
+ *
+ * @return void
+ */
+ public function testclientIp() {
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '192.168.1.5, 10.0.1.1, proxy.com';
+ $_SERVER['HTTP_CLIENT_IP'] = '192.168.1.2';
+ $_SERVER['REMOTE_ADDR'] = '192.168.1.3';
+ $request = new CakeRequest('some/path');
+ $this->assertEquals('192.168.1.5', $request->clientIp(false));
+ $this->assertEquals('192.168.1.2', $request->clientIp());
+
+ unset($_SERVER['HTTP_X_FORWARDED_FOR']);
+ $this->assertEquals('192.168.1.2', $request->clientIp());
+
+ unset($_SERVER['HTTP_CLIENT_IP']);
+ $this->assertEquals('192.168.1.3', $request->clientIp());
+
+ $_SERVER['HTTP_CLIENTADDRESS'] = '10.0.1.2, 10.0.1.1';
+ $this->assertEquals('10.0.1.2', $request->clientIp());
+ }
+
+/**
+ * test the referer function.
+ *
+ * @return void
+ */
+ public function testReferer() {
+ $request = new CakeRequest('some/path');
+ $request->webroot = '/';
+
+ $_SERVER['HTTP_REFERER'] = 'http://cakephp.org';
+ $result = $request->referer();
+ $this->assertSame($result, 'http://cakephp.org');
+
+ $_SERVER['HTTP_REFERER'] = '';
+ $result = $request->referer();
+ $this->assertSame($result, '/');
+
+ $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/some/path';
+ $result = $request->referer(true);
+ $this->assertSame($result, '/some/path');
+
+ $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/some/path';
+ $result = $request->referer(false);
+ $this->assertSame($result, FULL_BASE_URL . '/some/path');
+
+ $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/some/path';
+ $result = $request->referer(true);
+ $this->assertSame($result, '/some/path');
+
+ $_SERVER['HTTP_REFERER'] = FULL_BASE_URL . '/recipes/add';
+ $result = $request->referer(true);
+ $this->assertSame($result, '/recipes/add');
+
+ $_SERVER['HTTP_X_FORWARDED_HOST'] = 'cakephp.org';
+ $result = $request->referer();
+ $this->assertSame($result, 'cakephp.org');
+ }
+
+/**
+ * test the simple uses of is()
+ *
+ * @return void
+ */
+ public function testIsHttpMethods() {
+ $request = new CakeRequest('some/path');
+
+ $this->assertFalse($request->is('undefined-behavior'));
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $this->assertTrue($request->is('get'));
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $this->assertTrue($request->is('POST'));
+
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $this->assertTrue($request->is('put'));
+ $this->assertFalse($request->is('get'));
+
+ $_SERVER['REQUEST_METHOD'] = 'DELETE';
+ $this->assertTrue($request->is('delete'));
+ $this->assertTrue($request->isDelete());
+
+ $_SERVER['REQUEST_METHOD'] = 'delete';
+ $this->assertFalse($request->is('delete'));
+ }
+
+/**
+ * test the method() method.
+ *
+ * @return void
+ */
+ public function testMethod() {
+ $_SERVER['REQUEST_METHOD'] = 'delete';
+ $request = new CakeRequest('some/path');
+
+ $this->assertEquals('delete', $request->method());
+ }
+
+/**
+ * test host retrieval.
+ *
+ * @return void
+ */
+ public function testHost() {
+ $_SERVER['HTTP_HOST'] = 'localhost';
+ $request = new CakeRequest('some/path');
+
+ $this->assertEquals('localhost', $request->host());
+ }
+
+/**
+ * test domain retrieval.
+ *
+ * @return void
+ */
+ public function testDomain() {
+ $_SERVER['HTTP_HOST'] = 'something.example.com';
+ $request = new CakeRequest('some/path');
+
+ $this->assertEquals('example.com', $request->domain());
+
+ $_SERVER['HTTP_HOST'] = 'something.example.co.uk';
+ $this->assertEquals('example.co.uk', $request->domain(2));
+ }
+
+/**
+ * test getting subdomains for a host.
+ *
+ * @return void
+ */
+ public function testSubdomain() {
+ $_SERVER['HTTP_HOST'] = 'something.example.com';
+ $request = new CakeRequest('some/path');
+
+ $this->assertEquals(array('something'), $request->subdomains());
+
+ $_SERVER['HTTP_HOST'] = 'www.something.example.com';
+ $this->assertEquals(array('www', 'something'), $request->subdomains());
+
+ $_SERVER['HTTP_HOST'] = 'www.something.example.co.uk';
+ $this->assertEquals(array('www', 'something'), $request->subdomains(2));
+
+ $_SERVER['HTTP_HOST'] = 'example.co.uk';
+ $this->assertEquals(array(), $request->subdomains(2));
+ }
+
+/**
+ * test ajax, flash and friends
+ *
+ * @return void
+ */
+ public function testisAjaxFlashAndFriends() {
+ $request = new CakeRequest('some/path');
+
+ $_SERVER['HTTP_USER_AGENT'] = 'Shockwave Flash';
+ $this->assertTrue($request->is('flash'));
+
+ $_SERVER['HTTP_USER_AGENT'] = 'Adobe Flash';
+ $this->assertTrue($request->is('flash'));
+
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
+ $this->assertTrue($request->is('ajax'));
+
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHTTPREQUEST';
+ $this->assertFalse($request->is('ajax'));
+ $this->assertFalse($request->isAjax());
+
+ $_SERVER['HTTP_USER_AGENT'] = 'Android 2.0';
+ $this->assertTrue($request->is('mobile'));
+ $this->assertTrue($request->isMobile());
+
+ $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 5.1; rv:2.0b6pre) Gecko/20100902 Firefox/4.0b6pre Fennec/2.0b1pre';
+ $this->assertTrue($request->is('mobile'));
+ $this->assertTrue($request->isMobile());
+
+ $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; OMNIA7)';
+ $this->assertTrue($request->is('mobile'));
+ $this->assertTrue($request->isMobile());
+ }
+
+/**
+ * test __call expcetions
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testMagicCallExceptionOnUnknownMethod() {
+ $request = new CakeRequest('some/path');
+ $request->IamABanana();
+ }
+
+/**
+ * test is(ssl)
+ *
+ * @return void
+ */
+ public function testIsSsl() {
+ $request = new CakeRequest('some/path');
+
+ $_SERVER['HTTPS'] = 1;
+ $this->assertTrue($request->is('ssl'));
+
+ $_SERVER['HTTPS'] = 'on';
+ $this->assertTrue($request->is('ssl'));
+
+ $_SERVER['HTTPS'] = '1';
+ $this->assertTrue($request->is('ssl'));
+
+ $_SERVER['HTTPS'] = 'I am not empty';
+ $this->assertTrue($request->is('ssl'));
+
+ $_SERVER['HTTPS'] = 1;
+ $this->assertTrue($request->is('ssl'));
+
+ $_SERVER['HTTPS'] = 'off';
+ $this->assertFalse($request->is('ssl'));
+
+ $_SERVER['HTTPS'] = false;
+ $this->assertFalse($request->is('ssl'));
+
+ $_SERVER['HTTPS'] = '';
+ $this->assertFalse($request->is('ssl'));
+ }
+
+/**
+ * test getting request params with object properties.
+ *
+ * @return void
+ */
+ public function testMagicget() {
+ $request = new CakeRequest('some/path');
+ $request->params = array('controller' => 'posts', 'action' => 'view', 'plugin' => 'blogs');
+
+ $this->assertEquals('posts', $request->controller);
+ $this->assertEquals('view', $request->action);
+ $this->assertEquals('blogs', $request->plugin);
+ $this->assertSame($request->banana, null);
+ }
+
+/**
+ * Test isset()/empty() with overloaded properties.
+ *
+ * @return void
+ */
+ public function testMagicisset() {
+ $request = new CakeRequest('some/path');
+ $request->params = array(
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'plugin' => 'blogs',
+ 'named' => array()
+ );
+
+ $this->assertTrue(isset($request->controller));
+ $this->assertFalse(isset($request->notthere));
+ $this->assertFalse(empty($request->controller));
+ $this->assertTrue(empty($request->named));
+ }
+
+/**
+ * test the array access implementation
+ *
+ * @return void
+ */
+ public function testArrayAccess() {
+ $request = new CakeRequest('some/path');
+ $request->params = array('controller' => 'posts', 'action' => 'view', 'plugin' => 'blogs');
+
+ $this->assertEquals('posts', $request['controller']);
+
+ $request['slug'] = 'speedy-slug';
+ $this->assertEquals('speedy-slug', $request->slug);
+ $this->assertEquals('speedy-slug', $request['slug']);
+
+ $this->assertTrue(isset($request['action']));
+ $this->assertFalse(isset($request['wrong-param']));
+
+ $this->assertTrue(isset($request['plugin']));
+ unset($request['plugin']);
+ $this->assertFalse(isset($request['plugin']));
+ $this->assertNull($request['plugin']);
+ $this->assertNull($request->plugin);
+
+ $request = new CakeRequest('some/path?one=something&two=else');
+ $this->assertTrue(isset($request['url']['one']));
+
+ $request->data = array('Post' => array('title' => 'something'));
+ $this->assertEquals('something', $request['data']['Post']['title']);
+ }
+
+/**
+ * test adding detectors and having them work.
+ *
+ * @return void
+ */
+ public function testAddDetector() {
+ $request = new CakeRequest('some/path');
+ $request->addDetector('compare', array('env' => 'TEST_VAR', 'value' => 'something'));
+
+ $_SERVER['TEST_VAR'] = 'something';
+ $this->assertTrue($request->is('compare'), 'Value match failed.');
+
+ $_SERVER['TEST_VAR'] = 'wrong';
+ $this->assertFalse($request->is('compare'), 'Value mis-match failed.');
+
+ $request->addDetector('compareCamelCase', array('env' => 'TEST_VAR', 'value' => 'foo'));
+
+ $_SERVER['TEST_VAR'] = 'foo';
+ $this->assertTrue($request->is('compareCamelCase'), 'Value match failed.');
+
+ $request->addDetector('banana', array('env' => 'TEST_VAR', 'pattern' => '/^ban.*$/'));
+ $_SERVER['TEST_VAR'] = 'banana';
+ $this->assertTrue($request->isBanana());
+
+ $_SERVER['TEST_VAR'] = 'wrong value';
+ $this->assertFalse($request->isBanana());
+
+ $request->addDetector('mobile', array('options' => array('Imagination')));
+ $_SERVER['HTTP_USER_AGENT'] = 'Imagination land';
+ $this->assertTrue($request->isMobile());
+
+ $_SERVER['HTTP_USER_AGENT'] = 'iPhone 3.0';
+ $this->assertTrue($request->isMobile());
+
+ $request->addDetector('callme', array('env' => 'TEST_VAR', 'callback' => array($this, 'detectCallback')));
+
+ $request->addDetector('index', array('param' => 'action', 'value' => 'index'));
+ $request->params['action'] = 'index';
+ $this->assertTrue($request->isIndex());
+
+ $request->params['action'] = 'add';
+ $this->assertFalse($request->isIndex());
+
+ $request->return = true;
+ $this->assertTrue($request->isCallMe());
+
+ $request->return = false;
+ $this->assertFalse($request->isCallMe());
+ }
+
+/**
+ * helper function for testing callbacks.
+ *
+ * @return void
+ */
+ public function detectCallback($request) {
+ return $request->return == true;
+ }
+
+/**
+ * test getting headers
+ *
+ * @return void
+ */
+ public function testHeader() {
+ $_SERVER['HTTP_HOST'] = 'localhost';
+ $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-ca) AppleWebKit/534.8+ (KHTML, like Gecko) Version/5.0 Safari/533.16';
+ $request = new CakeRequest('/', false);
+
+ $this->assertEquals($_SERVER['HTTP_HOST'], $request->header('host'));
+ $this->assertEquals($_SERVER['HTTP_USER_AGENT'], $request->header('User-Agent'));
+ }
+
+/**
+ * test accepts() with and without parameters
+ *
+ * @return void
+ */
+ public function testAccepts() {
+ $_SERVER['HTTP_ACCEPT'] = 'text/xml,application/xml;q=0.9,application/xhtml+xml,text/html,text/plain,image/png';
+ $request = new CakeRequest('/', false);
+
+ $result = $request->accepts();
+ $expected = array(
+ 'text/xml', 'application/xhtml+xml', 'text/html', 'text/plain', 'image/png', 'application/xml'
+ );
+ $this->assertEquals($expected, $result, 'Content types differ.');
+
+ $result = $request->accepts('text/html');
+ $this->assertTrue($result);
+
+ $result = $request->accepts('image/gif');
+ $this->assertFalse($result);
+ }
+
+/**
+ * Test that accept header types are trimmed for comparisons.
+ *
+ * @return void
+ */
+ public function testAcceptWithWhitespace() {
+ $_SERVER['HTTP_ACCEPT'] = 'text/xml , text/html , text/plain,image/png';
+ $request = new CakeRequest('/', false);
+ $result = $request->accepts();
+ $expected = array(
+ 'text/xml', 'text/html', 'text/plain', 'image/png'
+ );
+ $this->assertEquals($expected, $result, 'Content types differ.');
+
+ $this->assertTrue($request->accepts('text/html'));
+ }
+
+/**
+ * Content types from accepts() should respect the client's q preference values.
+ *
+ * @return void
+ */
+ public function testAcceptWithQvalueSorting() {
+ $_SERVER['HTTP_ACCEPT'] = 'text/html;q=0.8,application/json;q=0.7,application/xml;q=1.0';
+ $request = new CakeRequest('/', false);
+ $result = $request->accepts();
+ $expected = array('application/xml', 'text/html', 'application/json');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the raw parsing of accept headers into the q value formatting.
+ *
+ * @return void
+ */
+ public function testParseAcceptWithQValue() {
+ $_SERVER['HTTP_ACCEPT'] = 'text/html;q=0.8,application/json;q=0.7,application/xml;q=1.0,image/png';
+ $request = new CakeRequest('/', false);
+ $result = $request->parseAccept();
+ $expected = array(
+ '1.0' => array('application/xml', 'image/png'),
+ '0.8' => array('text/html'),
+ '0.7' => array('application/json'),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test parsing accept with a confusing accept value.
+ *
+ * @return void
+ */
+ public function testParseAcceptNoQValues() {
+ $_SERVER['HTTP_ACCEPT'] = 'application/json, text/plain, */*';
+
+ $request = new CakeRequest('/', false);
+ $result = $request->parseAccept();
+ $expected = array(
+ '1.0' => array('application/json', 'text/plain', '*/*'),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testBaseUrlAndWebrootWithModRewrite method
+ *
+ * @return void
+ */
+ public function testBaseUrlAndWebrootWithModRewrite() {
+ Configure::write('App.baseUrl', false);
+
+ $_SERVER['DOCUMENT_ROOT'] = '/cake/repo/branches';
+ $_SERVER['PHP_SELF'] = '/1.2.x.x/app/webroot/index.php';
+ $_SERVER['PATH_INFO'] = '/posts/view/1';
+
+ $request = new CakeRequest();
+ $this->assertEquals('/1.2.x.x', $request->base);
+ $this->assertEquals('/1.2.x.x/', $request->webroot);
+ $this->assertEquals('posts/view/1', $request->url);
+
+ $_SERVER['DOCUMENT_ROOT'] = '/cake/repo/branches/1.2.x.x/app/webroot';
+ $_SERVER['PHP_SELF'] = '/index.php';
+ $_SERVER['PATH_INFO'] = '/posts/add';
+ $request = new CakeRequest();
+
+ $this->assertEquals('', $request->base);
+ $this->assertEquals('/', $request->webroot);
+ $this->assertEquals('posts/add', $request->url);
+
+ $_SERVER['DOCUMENT_ROOT'] = '/cake/repo/branches/1.2.x.x/test/';
+ $_SERVER['PHP_SELF'] = '/webroot/index.php';
+ $request = new CakeRequest();
+
+ $this->assertEquals('', $request->base);
+ $this->assertEquals('/', $request->webroot);
+
+ $_SERVER['DOCUMENT_ROOT'] = '/some/apps/where';
+ $_SERVER['PHP_SELF'] = '/app/webroot/index.php';
+ $request = new CakeRequest();
+
+ $this->assertEquals('', $request->base);
+ $this->assertEquals('/', $request->webroot);
+
+ Configure::write('App.dir', 'auth');
+
+ $_SERVER['DOCUMENT_ROOT'] = '/cake/repo/branches';
+ $_SERVER['PHP_SELF'] = '/demos/auth/webroot/index.php';
+
+ $request = new CakeRequest();
+
+ $this->assertEquals('/demos/auth', $request->base);
+ $this->assertEquals('/demos/auth/', $request->webroot);
+
+ Configure::write('App.dir', 'code');
+
+ $_SERVER['DOCUMENT_ROOT'] = '/Library/WebServer/Documents';
+ $_SERVER['PHP_SELF'] = '/clients/PewterReport/code/webroot/index.php';
+ $request = new CakeRequest();
+
+ $this->assertEquals('/clients/PewterReport/code', $request->base);
+ $this->assertEquals('/clients/PewterReport/code/', $request->webroot);
+ }
+
+/**
+ * testBaseUrlwithModRewriteAlias method
+ *
+ * @return void
+ */
+ public function testBaseUrlwithModRewriteAlias() {
+ $_SERVER['DOCUMENT_ROOT'] = '/home/aplusnur/public_html';
+ $_SERVER['PHP_SELF'] = '/control/index.php';
+
+ Configure::write('App.base', '/control');
+
+ $request = new CakeRequest();
+
+ $this->assertEquals('/control', $request->base);
+ $this->assertEquals('/control/', $request->webroot);
+
+ Configure::write('App.base', false);
+ Configure::write('App.dir', 'affiliate');
+ Configure::write('App.webroot', 'newaffiliate');
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/abtravaff/html';
+ $_SERVER['PHP_SELF'] = '/newaffiliate/index.php';
+ $request = new CakeRequest();
+
+ $this->assertEquals('/newaffiliate', $request->base);
+ $this->assertEquals('/newaffiliate/', $request->webroot);
+ }
+
+/**
+ * test base, webroot, and url parsing when there is no url rewriting
+ *
+ * @return void
+ */
+ public function testBaseUrlWithNoModRewrite() {
+ $_SERVER['DOCUMENT_ROOT'] = '/Users/markstory/Sites';
+ $_SERVER['SCRIPT_FILENAME'] = '/Users/markstory/Sites/cake/index.php';
+ $_SERVER['PHP_SELF'] = '/cake/index.php/posts/index';
+ $_SERVER['REQUEST_URI'] = '/cake/index.php/posts/index';
+
+ Configure::write('App', array(
+ 'dir' => APP_DIR,
+ 'webroot' => WEBROOT_DIR,
+ 'base' => false,
+ 'baseUrl' => '/cake/index.php'
+ ));
+
+ $request = new CakeRequest();
+ $this->assertEquals('/cake/index.php', $request->base);
+ $this->assertEquals('/cake/app/webroot/', $request->webroot);
+ $this->assertEquals('posts/index', $request->url);
+ }
+
+/**
+ * testBaseUrlAndWebrootWithBaseUrl method
+ *
+ * @return void
+ */
+ public function testBaseUrlAndWebrootWithBaseUrl() {
+ Configure::write('App.dir', 'app');
+ Configure::write('App.baseUrl', '/app/webroot/index.php');
+
+ $request = new CakeRequest();
+ $this->assertEquals('/app/webroot/index.php', $request->base);
+ $this->assertEquals('/app/webroot/', $request->webroot);
+
+ Configure::write('App.baseUrl', '/app/webroot/test.php');
+ $request = new CakeRequest();
+ $this->assertEquals('/app/webroot/test.php', $request->base);
+ $this->assertEquals('/app/webroot/', $request->webroot);
+
+ Configure::write('App.baseUrl', '/app/index.php');
+ $request = new CakeRequest();
+ $this->assertEquals('/app/index.php', $request->base);
+ $this->assertEquals('/app/webroot/', $request->webroot);
+
+ Configure::write('App.baseUrl', '/CakeBB/app/webroot/index.php');
+ $request = new CakeRequest();
+ $this->assertEquals('/CakeBB/app/webroot/index.php', $request->base);
+ $this->assertEquals('/CakeBB/app/webroot/', $request->webroot);
+
+ Configure::write('App.baseUrl', '/CakeBB/app/index.php');
+ $request = new CakeRequest();
+
+ $this->assertEquals('/CakeBB/app/index.php', $request->base);
+ $this->assertEquals('/CakeBB/app/webroot/', $request->webroot);
+
+ Configure::write('App.baseUrl', '/CakeBB/index.php');
+ $request = new CakeRequest();
+
+ $this->assertEquals('/CakeBB/index.php', $request->base);
+ $this->assertEquals('/CakeBB/app/webroot/', $request->webroot);
+
+ Configure::write('App.baseUrl', '/dbhauser/index.php');
+ $_SERVER['DOCUMENT_ROOT'] = '/kunden/homepages/4/d181710652/htdocs/joomla';
+ $_SERVER['SCRIPT_FILENAME'] = '/kunden/homepages/4/d181710652/htdocs/joomla/dbhauser/index.php';
+ $request = new CakeRequest();
+
+ $this->assertEquals('/dbhauser/index.php', $request->base);
+ $this->assertEquals('/dbhauser/app/webroot/', $request->webroot);
+ }
+
+/**
+ * test baseUrl with no rewrite and using the top level index.php.
+ *
+ * @return void
+ */
+ public function testBaseUrlNoRewriteTopLevelIndex() {
+ Configure::write('App.baseUrl', '/index.php');
+ $_SERVER['DOCUMENT_ROOT'] = '/Users/markstory/Sites/cake_dev';
+ $_SERVER['SCRIPT_FILENAME'] = '/Users/markstory/Sites/cake_dev/index.php';
+
+ $request = new CakeRequest();
+ $this->assertEquals('/index.php', $request->base);
+ $this->assertEquals('/app/webroot/', $request->webroot);
+ }
+
+/**
+ * Check that a sub-directory containing app|webroot doesn't get mishandled when re-writing is off.
+ *
+ * @return void
+ */
+ public function testBaseUrlWithAppAndWebrootInDirname() {
+ Configure::write('App.baseUrl', '/approval/index.php');
+ $_SERVER['DOCUMENT_ROOT'] = '/Users/markstory/Sites/';
+ $_SERVER['SCRIPT_FILENAME'] = '/Users/markstory/Sites/approval/index.php';
+
+ $request = new CakeRequest();
+ $this->assertEquals('/approval/index.php', $request->base);
+ $this->assertEquals('/approval/app/webroot/', $request->webroot);
+
+ Configure::write('App.baseUrl', '/webrootable/index.php');
+ $_SERVER['DOCUMENT_ROOT'] = '/Users/markstory/Sites/';
+ $_SERVER['SCRIPT_FILENAME'] = '/Users/markstory/Sites/webrootable/index.php';
+
+ $request = new CakeRequest();
+ $this->assertEquals('/webrootable/index.php', $request->base);
+ $this->assertEquals('/webrootable/app/webroot/', $request->webroot);
+ }
+
+/**
+ * test baseUrl with no rewrite, and using the app/webroot/index.php file as is normal with virtual hosts.
+ *
+ * @return void
+ */
+ public function testBaseUrlNoRewriteWebrootIndex() {
+ Configure::write('App.baseUrl', '/index.php');
+ $_SERVER['DOCUMENT_ROOT'] = '/Users/markstory/Sites/cake_dev/app/webroot';
+ $_SERVER['SCRIPT_FILENAME'] = '/Users/markstory/Sites/cake_dev/app/webroot/index.php';
+
+ $request = new CakeRequest();
+ $this->assertEquals('/index.php', $request->base);
+ $this->assertEquals('/', $request->webroot);
+ }
+
+/**
+ * Test that a request with a . in the main GET parameter is filtered out.
+ * PHP changes GET parameter keys containing dots to _.
+ *
+ * @return void
+ */
+ public function testGetParamsWithDot() {
+ $_GET = array();
+ $_GET['/posts/index/add_add'] = '';
+ $_SERVER['PHP_SELF'] = '/cake_dev/app/webroot/index.php';
+ $_SERVER['REQUEST_URI'] = '/cake_dev/posts/index/add.add';
+
+ $request = new CakeRequest();
+ $this->assertEquals(array(), $request->query);
+ }
+
+/**
+ * Test that a request with urlencoded bits in the main GET parameter are filtered out.
+ *
+ * @return void
+ */
+ public function testGetParamWithUrlencodedElement() {
+ $_GET = array();
+ $_GET['/posts/add/∂∂'] = '';
+ $_SERVER['PHP_SELF'] = '/cake_dev/app/webroot/index.php';
+ $_SERVER['REQUEST_URI'] = '/cake_dev/posts/add/%E2%88%82%E2%88%82';
+
+ $request = new CakeRequest();
+ $this->assertEquals(array(), $request->query);
+ }
+
+/**
+ * generator for environment configurations
+ *
+ * @return void
+ */
+ public static function environmentGenerator() {
+ return array(
+ array(
+ 'IIS - No rewrite base path',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'SCRIPT_NAME' => '/index.php',
+ 'PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot',
+ 'QUERY_STRING' => '',
+ 'REQUEST_URI' => '/index.php',
+ 'URL' => '/index.php',
+ 'SCRIPT_FILENAME' => 'C:\\Inetpub\\wwwroot\\index.php',
+ 'ORIG_PATH_INFO' => '/index.php',
+ 'PATH_INFO' => '',
+ 'ORIG_PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot\\index.php',
+ 'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot',
+ 'PHP_SELF' => '/index.php',
+ ),
+ ),
+ array(
+ 'base' => '/index.php',
+ 'webroot' => '/app/webroot/',
+ 'url' => ''
+ ),
+ ),
+ array(
+ 'IIS - No rewrite with path, no PHP_SELF',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/index.php?',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'QUERY_STRING' => '/posts/add',
+ 'REQUEST_URI' => '/index.php?/posts/add',
+ 'PHP_SELF' => '',
+ 'URL' => '/index.php?/posts/add',
+ 'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot',
+ 'argv' => array('/posts/add'),
+ 'argc' => 1
+ ),
+ ),
+ array(
+ 'url' => 'posts/add',
+ 'base' => '/index.php?',
+ 'webroot' => '/app/webroot/'
+ )
+ ),
+ array(
+ 'IIS - No rewrite sub dir 2',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/site/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot',
+ ),
+ 'SERVER' => array(
+ 'SCRIPT_NAME' => '/site/index.php',
+ 'PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot',
+ 'QUERY_STRING' => '',
+ 'REQUEST_URI' => '/site/index.php',
+ 'URL' => '/site/index.php',
+ 'SCRIPT_FILENAME' => 'C:\\Inetpub\\wwwroot\\site\\index.php',
+ 'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot',
+ 'PHP_SELF' => '/site/index.php',
+ 'argv' => array(),
+ 'argc' => 0
+ ),
+ ),
+ array(
+ 'url' => '',
+ 'base' => '/site/index.php',
+ 'webroot' => '/site/app/webroot/'
+ ),
+ ),
+ array(
+ 'IIS - No rewrite sub dir 2 with path',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/site/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'GET' => array('/posts/add' => ''),
+ 'SERVER' => array(
+ 'SCRIPT_NAME' => '/site/index.php',
+ 'PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot',
+ 'QUERY_STRING' => '/posts/add',
+ 'REQUEST_URI' => '/site/index.php/posts/add',
+ 'URL' => '/site/index.php/posts/add',
+ 'ORIG_PATH_TRANSLATED' => 'C:\\Inetpub\\wwwroot\\site\\index.php',
+ 'DOCUMENT_ROOT' => 'C:\\Inetpub\\wwwroot',
+ 'PHP_SELF' => '/site/index.php/posts/add',
+ 'argv' => array('/posts/add'),
+ 'argc' => 1
+ ),
+ ),
+ array(
+ 'url' => 'posts/add',
+ 'base' => '/site/index.php',
+ 'webroot' => '/site/app/webroot/'
+ )
+ ),
+ array(
+ 'Apache - No rewrite, document root set to webroot, requesting path',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents/site/app/webroot',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/app/webroot/index.php',
+ 'QUERY_STRING' => '',
+ 'REQUEST_URI' => '/index.php/posts/index',
+ 'SCRIPT_NAME' => '/index.php',
+ 'PATH_INFO' => '/posts/index',
+ 'PHP_SELF' => '/index.php/posts/index',
+ ),
+ ),
+ array(
+ 'url' => 'posts/index',
+ 'base' => '/index.php',
+ 'webroot' => '/'
+ ),
+ ),
+ array(
+ 'Apache - No rewrite, document root set to webroot, requesting root',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents/site/app/webroot',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/app/webroot/index.php',
+ 'QUERY_STRING' => '',
+ 'REQUEST_URI' => '/index.php',
+ 'SCRIPT_NAME' => '/index.php',
+ 'PATH_INFO' => '',
+ 'PHP_SELF' => '/index.php',
+ ),
+ ),
+ array(
+ 'url' => '',
+ 'base' => '/index.php',
+ 'webroot' => '/'
+ ),
+ ),
+ array(
+ 'Apache - No rewrite, document root set above top level cake dir, requesting path',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/site/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'SERVER_NAME' => 'localhost',
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php',
+ 'REQUEST_URI' => '/site/index.php/posts/index',
+ 'SCRIPT_NAME' => '/site/index.php',
+ 'PATH_INFO' => '/posts/index',
+ 'PHP_SELF' => '/site/index.php/posts/index',
+ ),
+ ),
+ array(
+ 'url' => 'posts/index',
+ 'base' => '/site/index.php',
+ 'webroot' => '/site/app/webroot/',
+ ),
+ ),
+ array(
+ 'Apache - No rewrite, document root set above top level cake dir, request root, no PATH_INFO',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/site/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'SERVER_NAME' => 'localhost',
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php',
+ 'REQUEST_URI' => '/site/index.php/',
+ 'SCRIPT_NAME' => '/site/index.php',
+ 'PHP_SELF' => '/site/index.php/',
+ ),
+ ),
+ array(
+ 'url' => '',
+ 'base' => '/site/index.php',
+ 'webroot' => '/site/app/webroot/',
+ ),
+ ),
+ array(
+ 'Apache - No rewrite, document root set above top level cake dir, request path, with GET',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => '/site/index.php',
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'GET' => array('a' => 'b', 'c' => 'd'),
+ 'SERVER' => array(
+ 'SERVER_NAME' => 'localhost',
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php',
+ 'REQUEST_URI' => '/site/index.php/posts/index?a=b&c=d',
+ 'SCRIPT_NAME' => '/site/index.php',
+ 'PATH_INFO' => '/posts/index',
+ 'PHP_SELF' => '/site/index.php/posts/index',
+ 'QUERY_STRING' => 'a=b&c=d'
+ ),
+ ),
+ array(
+ 'urlParams' => array('a' => 'b', 'c' => 'd'),
+ 'url' => 'posts/index',
+ 'base' => '/site/index.php',
+ 'webroot' => '/site/app/webroot/',
+ ),
+ ),
+ array(
+ 'Apache - w/rewrite, document root set above top level cake dir, request root, no PATH_INFO',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => false,
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'SERVER_NAME' => 'localhost',
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php',
+ 'REQUEST_URI' => '/site/',
+ 'SCRIPT_NAME' => '/site/app/webroot/index.php',
+ 'PHP_SELF' => '/site/app/webroot/index.php',
+ ),
+ ),
+ array(
+ 'url' => '',
+ 'base' => '/site',
+ 'webroot' => '/site/',
+ ),
+ ),
+ array(
+ 'Apache - w/rewrite, document root above top level cake dir, request root, no PATH_INFO/REQUEST_URI',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => false,
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'SERVER_NAME' => 'localhost',
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php',
+ 'SCRIPT_NAME' => '/site/app/webroot/index.php',
+ 'PHP_SELF' => '/site/app/webroot/index.php',
+ 'PATH_INFO' => null,
+ 'REQUEST_URI' => null,
+ ),
+ ),
+ array(
+ 'url' => '',
+ 'base' => '/site',
+ 'webroot' => '/site/',
+ ),
+ ),
+ array(
+ 'Apache - w/rewrite, document root set to webroot, request root, no PATH_INFO/REQUEST_URI',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => false,
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'SERVER' => array(
+ 'SERVER_NAME' => 'localhost',
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents/site/app/webroot',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/app/webroot/index.php',
+ 'SCRIPT_NAME' => '/index.php',
+ 'PHP_SELF' => '/index.php',
+ 'PATH_INFO' => null,
+ 'REQUEST_URI' => null,
+ ),
+ ),
+ array(
+ 'url' => '',
+ 'base' => '',
+ 'webroot' => '/',
+ ),
+ ),
+ array(
+ 'Nginx - w/rewrite, document root set to webroot, request root, no PATH_INFO',
+ array(
+ 'App' => array(
+ 'base' => false,
+ 'baseUrl' => false,
+ 'dir' => 'app',
+ 'webroot' => 'webroot'
+ ),
+ 'GET' => array('/posts/add' => ''),
+ 'SERVER' => array(
+ 'SERVER_NAME' => 'localhost',
+ 'DOCUMENT_ROOT' => '/Library/WebServer/Documents/site/app/webroot',
+ 'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/app/webroot/index.php',
+ 'SCRIPT_NAME' => '/index.php',
+ 'QUERY_STRING' => '/posts/add&',
+ 'PHP_SELF' => '/index.php',
+ 'PATH_INFO' => null,
+ 'REQUEST_URI' => '/posts/add',
+ ),
+ ),
+ array(
+ 'url' => 'posts/add',
+ 'base' => '',
+ 'webroot' => '/',
+ 'urlParams' => array()
+ ),
+ ),
+ );
+ }
+
+/**
+ * testEnvironmentDetection method
+ *
+ * @dataProvider environmentGenerator
+ * @return void
+ */
+ public function testEnvironmentDetection($name, $env, $expected) {
+ $_GET = array();
+ $this->__loadEnvironment($env);
+
+ $request = new CakeRequest();
+ $this->assertEquals($expected['url'], $request->url, "url error");
+ $this->assertEquals($expected['base'], $request->base, "base error");
+ $this->assertEquals($expected['webroot'], $request->webroot, "webroot error");
+ if (isset($expected['urlParams'])) {
+ $this->assertEquals($expected['urlParams'], $request->query, "GET param mismatch");
+ }
+ }
+
+/**
+ * test the data() method reading
+ *
+ * @return void
+ */
+ public function testDataReading() {
+ $_POST['data'] = array(
+ 'Model' => array(
+ 'field' => 'value'
+ )
+ );
+ $request = new CakeRequest('posts/index');
+ $result = $request->data('Model');
+ $this->assertEquals($_POST['data']['Model'], $result);
+
+ $result = $request->data('Model.imaginary');
+ $this->assertNull($result);
+ }
+
+/**
+ * test writing with data()
+ *
+ * @return void
+ */
+ public function testDataWriting() {
+ $_POST['data'] = array(
+ 'Model' => array(
+ 'field' => 'value'
+ )
+ );
+ $request = new CakeRequest('posts/index');
+ $result = $request->data('Model.new_value', 'new value');
+ $this->assertSame($result, $request, 'Return was not $this');
+
+ $this->assertEquals('new value', $request->data['Model']['new_value']);
+
+ $request->data('Post.title', 'New post')->data('Comment.1.author', 'Mark');
+ $this->assertEquals('New post', $request->data['Post']['title']);
+ $this->assertEquals('Mark', $request->data['Comment']['1']['author']);
+ }
+
+/**
+ * test writing falsey values.
+ *
+ * @return void
+ */
+ public function testDataWritingFalsey() {
+ $request = new CakeRequest('posts/index');
+
+ $request->data('Post.null', null);
+ $this->assertNull($request->data['Post']['null']);
+
+ $request->data('Post.false', false);
+ $this->assertFalse($request->data['Post']['false']);
+
+ $request->data('Post.zero', 0);
+ $this->assertSame(0, $request->data['Post']['zero']);
+
+ $request->data('Post.empty', '');
+ $this->assertSame('', $request->data['Post']['empty']);
+ }
+
+/**
+ * test accept language
+ *
+ * @return void
+ */
+ public function testAcceptLanguage() {
+ $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'inexistent,en-ca';
+ $result = CakeRequest::acceptLanguage();
+ $this->assertEquals(array('inexistent', 'en-ca'), $result, 'Languages do not match');
+
+ $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'es_mx;en_ca';
+ $result = CakeRequest::acceptLanguage();
+ $this->assertEquals(array('es-mx', 'en-ca'), $result, 'Languages do not match');
+
+ $result = CakeRequest::acceptLanguage('en-ca');
+ $this->assertTrue($result);
+
+ $result = CakeRequest::acceptLanguage('en-us');
+ $this->assertFalse($result);
+ }
+
+/**
+ * test the here() method
+ *
+ * @return void
+ */
+ public function testHere() {
+ Configure::write('App.base', '/base_path');
+ $_GET = array('test' => 'value');
+ $request = new CakeRequest('/posts/add/1/name:value');
+
+ $result = $request->here();
+ $this->assertEquals('/base_path/posts/add/1/name:value?test=value', $result);
+
+ $result = $request->here(false);
+ $this->assertEquals('/posts/add/1/name:value?test=value', $result);
+
+ $request = new CakeRequest('/posts/base_path/1/name:value');
+ $result = $request->here();
+ $this->assertEquals('/base_path/posts/base_path/1/name:value?test=value', $result);
+
+ $result = $request->here(false);
+ $this->assertEquals('/posts/base_path/1/name:value?test=value', $result);
+ }
+
+/**
+ * Test the input() method.
+ *
+ * @return void
+ */
+ public function testInput() {
+ $request = $this->getMock('CakeRequest', array('_readInput'));
+ $request->expects($this->once())->method('_readInput')
+ ->will($this->returnValue('I came from stdin'));
+
+ $result = $request->input();
+ $this->assertEquals('I came from stdin', $result);
+ }
+
+/**
+ * Test input() decoding.
+ *
+ * @return void
+ */
+ public function testInputDecode() {
+ $request = $this->getMock('CakeRequest', array('_readInput'));
+ $request->expects($this->once())->method('_readInput')
+ ->will($this->returnValue('{"name":"value"}'));
+
+ $result = $request->input('json_decode');
+ $this->assertEquals(array('name' => 'value'), (array)$result);
+ }
+
+/**
+ * Test input() decoding with additional arguments.
+ *
+ * @return void
+ */
+ public function testInputDecodeExtraParams() {
+ $xml = <<<XML
+<?xml version="1.0" encoding="utf-8"?>
+<post>
+ <title id="title">Test</title>
+</post>
+XML;
+
+ $request = $this->getMock('CakeRequest', array('_readInput'));
+ $request->expects($this->once())->method('_readInput')
+ ->will($this->returnValue($xml));
+
+ $result = $request->input('Xml::build', array('return' => 'domdocument'));
+ $this->assertInstanceOf('DOMDocument', $result);
+ $this->assertEquals(
+ 'Test',
+ $result->getElementsByTagName('title')->item(0)->childNodes->item(0)->wholeText
+ );
+ }
+
+/**
+ * Test is('requested') and isRequested()
+ *
+ * @return void
+ */
+ public function testIsRequested() {
+ $request = new CakeRequest('/posts/index');
+ $request->addParams(array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'plugin' => null,
+ 'requested' => 1
+ ));
+ $this->assertTrue($request->is('requested'));
+ $this->assertTrue($request->isRequested());
+
+ $request = new CakeRequest('/posts/index');
+ $request->addParams(array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'plugin' => null,
+ ));
+ $this->assertFalse($request->is('requested'));
+ $this->assertFalse($request->isRequested());
+ }
+
+/**
+ * loadEnvironment method
+ *
+ * @param array $env
+ * @return void
+ */
+ protected function __loadEnvironment($env) {
+ if (isset($env['App'])) {
+ Configure::write('App', $env['App']);
+ }
+
+ if (isset($env['GET'])) {
+ foreach ($env['GET'] as $key => $val) {
+ $_GET[$key] = $val;
+ }
+ }
+
+ if (isset($env['POST'])) {
+ foreach ($env['POST'] as $key => $val) {
+ $_POST[$key] = $val;
+ }
+ }
+
+ if (isset($env['SERVER'])) {
+ foreach ($env['SERVER'] as $key => $val) {
+ $_SERVER[$key] = $val;
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeResponseTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeResponseTest.php
new file mode 100644
index 0000000..9f601b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeResponseTest.php
@@ -0,0 +1,1009 @@
+<?php
+/**
+ * CakeResponse Test case file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Network
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeResponse', 'Network');
+App::uses('CakeRequest', 'Network');
+
+class CakeResponseTest extends CakeTestCase {
+
+/**
+ * Setup for tests
+ *
+ * @return void
+ */
+ public function setUp() {
+ ob_start();
+ }
+
+/**
+ * Cleanup after tests
+ *
+ * @return void
+ */
+ public function tearDown() {
+ ob_end_clean();
+ }
+
+/**
+ * Tests the request object constructor
+ *
+ */
+ public function testConstruct() {
+ $response = new CakeResponse();
+ $this->assertNull($response->body());
+ $this->assertEquals('UTF-8', $response->charset());
+ $this->assertEquals('text/html', $response->type());
+ $this->assertEquals(200, $response->statusCode());
+
+ $options = array(
+ 'body' => 'This is the body',
+ 'charset' => 'my-custom-charset',
+ 'type' => 'mp3',
+ 'status' => '203'
+ );
+ $response = new CakeResponse($options);
+ $this->assertEquals('This is the body', $response->body());
+ $this->assertEquals('my-custom-charset', $response->charset());
+ $this->assertEquals('audio/mpeg', $response->type());
+ $this->assertEquals(203, $response->statusCode());
+ }
+
+/**
+ * Tests the body method
+ *
+ */
+ public function testBody() {
+ $response = new CakeResponse();
+ $this->assertNull($response->body());
+ $response->body('Response body');
+ $this->assertEquals('Response body', $response->body());
+ $this->assertEquals('Changed Body', $response->body('Changed Body'));
+ }
+
+/**
+ * Tests the charset method
+ *
+ */
+ public function testCharset() {
+ $response = new CakeResponse();
+ $this->assertEquals('UTF-8', $response->charset());
+ $response->charset('iso-8859-1');
+ $this->assertEquals('iso-8859-1', $response->charset());
+ $this->assertEquals('UTF-16', $response->charset('UTF-16'));
+ }
+
+/**
+ * Tests the statusCode method
+ *
+ * @expectedException CakeException
+ */
+ public function testStatusCode() {
+ $response = new CakeResponse();
+ $this->assertEquals(200, $response->statusCode());
+ $response->statusCode(404);
+ $this->assertEquals(404, $response->statusCode());
+ $this->assertEquals(500, $response->statusCode(500));
+
+ //Throws exception
+ $response->statusCode(1001);
+ }
+
+/**
+ * Tests the type method
+ *
+ */
+ public function testType() {
+ $response = new CakeResponse();
+ $this->assertEquals('text/html', $response->type());
+ $response->type('pdf');
+ $this->assertEquals('application/pdf', $response->type());
+ $this->assertEquals('application/crazy-mime', $response->type('application/crazy-mime'));
+ $this->assertEquals('application/json', $response->type('json'));
+ $this->assertEquals('text/vnd.wap.wml', $response->type('wap'));
+ $this->assertEquals('application/vnd.wap.xhtml+xml', $response->type('xhtml-mobile'));
+ $this->assertEquals('text/csv', $response->type('csv'));
+
+ $response->type(array('keynote' => 'application/keynote', 'bat' => 'application/bat'));
+ $this->assertEquals('application/keynote', $response->type('keynote'));
+ $this->assertEquals('application/bat', $response->type('bat'));
+
+ $this->assertFalse($response->type('wackytype'));
+ }
+
+/**
+ * Tests the header method
+ *
+ */
+ public function testHeader() {
+ $response = new CakeResponse();
+ $headers = array();
+ $this->assertEquals($response->header(), $headers);
+
+ $response->header('Location', 'http://example.com');
+ $headers += array('Location' => 'http://example.com');
+ $this->assertEquals($response->header(), $headers);
+
+ //Headers with the same name are overwritten
+ $response->header('Location', 'http://example2.com');
+ $headers = array('Location' => 'http://example2.com');
+ $this->assertEquals($response->header(), $headers);
+
+ $response->header(array('WWW-Authenticate' => 'Negotiate'));
+ $headers += array('WWW-Authenticate' => 'Negotiate');
+ $this->assertEquals($response->header(), $headers);
+
+ $response->header(array('WWW-Authenticate' => 'Not-Negotiate'));
+ $headers['WWW-Authenticate'] = 'Not-Negotiate';
+ $this->assertEquals($response->header(), $headers);
+
+ $response->header(array('Age' => 12, 'Allow' => 'GET, HEAD'));
+ $headers += array('Age' => 12, 'Allow' => 'GET, HEAD');
+ $this->assertEquals($response->header(), $headers);
+
+ // String headers are allowed
+ $response->header('Content-Language: da');
+ $headers += array('Content-Language' => 'da');
+ $this->assertEquals($response->header(), $headers);
+
+ $response->header('Content-Language: da');
+ $headers += array('Content-Language' => 'da');
+ $this->assertEquals($response->header(), $headers);
+
+ $response->header(array('Content-Encoding: gzip', 'Vary: *', 'Pragma' => 'no-cache'));
+ $headers += array('Content-Encoding' => 'gzip', 'Vary' => '*', 'Pragma' => 'no-cache');
+ $this->assertEquals($response->header(), $headers);
+ }
+
+/**
+ * Tests the send method
+ *
+ */
+ public function testSend() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
+ $response->header(array(
+ 'Content-Language' => 'es',
+ 'WWW-Authenticate' => 'Negotiate'
+ ));
+ $response->body('the response body');
+ $response->expects($this->once())->method('_sendContent')->with('the response body');
+ $response->expects($this->at(0))->method('_setCookies');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Language', 'es');
+ $response->expects($this->at(3))
+ ->method('_sendHeader')->with('WWW-Authenticate', 'Negotiate');
+ $response->expects($this->at(4))
+ ->method('_sendHeader')->with('Content-Length', 17);
+ $response->expects($this->at(5))
+ ->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
+ $response->send();
+ }
+
+/**
+ * Tests the send method and changing the content type
+ *
+ */
+ public function testSendChangingContentYype() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
+ $response->type('mp3');
+ $response->body('the response body');
+ $response->expects($this->once())->method('_sendContent')->with('the response body');
+ $response->expects($this->at(0))->method('_setCookies');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Length', 17);
+ $response->expects($this->at(3))
+ ->method('_sendHeader')->with('Content-Type', 'audio/mpeg');
+ $response->send();
+ }
+
+/**
+ * Tests the send method and changing the content type
+ *
+ */
+ public function testSendChangingContentType() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
+ $response->type('mp3');
+ $response->body('the response body');
+ $response->expects($this->once())->method('_sendContent')->with('the response body');
+ $response->expects($this->at(0))->method('_setCookies');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Length', 17);
+ $response->expects($this->at(3))
+ ->method('_sendHeader')->with('Content-Type', 'audio/mpeg');
+ $response->send();
+ }
+
+/**
+ * Tests the send method and changing the content type
+ *
+ */
+ public function testSendWithLocation() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', '_setCookies'));
+ $response->header('Location', 'http://www.example.com');
+ $response->expects($this->at(0))->method('_setCookies');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('HTTP/1.1 302 Found');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Location', 'http://www.example.com');
+ $response->expects($this->at(3))
+ ->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
+ $response->send();
+ }
+
+/**
+ * Tests the disableCache method
+ *
+ */
+ public function testDisableCache() {
+ $response = new CakeResponse();
+ $expected = array(
+ 'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
+ 'Last-Modified' => gmdate("D, d M Y H:i:s") . " GMT",
+ 'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
+ );
+ $response->disableCache();
+ $this->assertEquals($expected, $response->header());
+ }
+
+/**
+ * Tests the cache method
+ *
+ */
+ public function testCache() {
+ $response = new CakeResponse();
+ $since = time();
+ $time = new DateTime('+1 day', new DateTimeZone('UTC'));
+ $response->expires('+1 day');
+ $expected = array(
+ 'Date' => gmdate("D, j M Y G:i:s ", $since) . 'GMT',
+ 'Last-Modified' => gmdate("D, j M Y H:i:s ", $since) . 'GMT',
+ 'Expires' => $time->format('D, j M Y H:i:s') . ' GMT',
+ 'Cache-Control' => 'public, max-age=' . ($time->format('U') - time())
+ );
+ $response->cache($since);
+ $this->assertEquals($expected, $response->header());
+
+ $response = new CakeResponse();
+ $since = time();
+ $time = '+5 day';
+ $expected = array(
+ 'Date' => gmdate("D, j M Y G:i:s ", $since) . 'GMT',
+ 'Last-Modified' => gmdate("D, j M Y H:i:s ", $since) . 'GMT',
+ 'Expires' => gmdate("D, j M Y H:i:s", strtotime($time)) . " GMT",
+ 'Cache-Control' => 'public, max-age=' . (strtotime($time) - time())
+ );
+ $response->cache($since, $time);
+ $this->assertEquals($expected, $response->header());
+
+ $response = new CakeResponse();
+ $since = time();
+ $time = time();
+ $expected = array(
+ 'Date' => gmdate("D, j M Y G:i:s ", $since) . 'GMT',
+ 'Last-Modified' => gmdate("D, j M Y H:i:s ", $since) . 'GMT',
+ 'Expires' => gmdate("D, j M Y H:i:s", $time) . " GMT",
+ 'Cache-Control' => 'public, max-age=0'
+ );
+ $response->cache($since, $time);
+ $this->assertEquals($expected, $response->header());
+ }
+
+/**
+ * Tests the compress method
+ *
+ * @return void
+ */
+ public function testCompress() {
+ if (php_sapi_name() !== 'cli') {
+ $this->markTestSkipped('The response compression can only be tested in cli.');
+ }
+
+ $response = new CakeResponse();
+ if (ini_get("zlib.output_compression") === '1' || !extension_loaded("zlib")) {
+ $this->assertFalse($response->compress());
+ $this->markTestSkipped('Is not possible to test output compression');
+ }
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = '';
+ $result = $response->compress();
+ $this->assertFalse($result);
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
+ $result = $response->compress();
+ $this->assertTrue($result);
+ $this->assertTrue(in_array('ob_gzhandler', ob_list_handlers()));
+
+ ob_get_clean();
+ }
+
+/**
+ * Tests the httpCodes method
+ *
+ */
+ public function testHttpCodes() {
+ $response = new CakeResponse();
+ $result = $response->httpCodes();
+ $this->assertEquals(39, count($result));
+
+ $result = $response->httpCodes(100);
+ $expected = array(100 => 'Continue');
+ $this->assertEquals($expected, $result);
+
+ $codes = array(
+ 1337 => 'Undefined Unicorn',
+ 1729 => 'Hardy-Ramanujan Located'
+ );
+
+ $result = $response->httpCodes($codes);
+ $this->assertTrue($result);
+ $this->assertEquals(41, count($response->httpCodes()));
+
+ $result = $response->httpCodes(1337);
+ $expected = array(1337 => 'Undefined Unicorn');
+ $this->assertEquals($expected, $result);
+
+ $codes = array(404 => 'Sorry Bro');
+ $result = $response->httpCodes($codes);
+ $this->assertTrue($result);
+ $this->assertEquals(41, count($response->httpCodes()));
+
+ $result = $response->httpCodes(404);
+ $expected = array(404 => 'Sorry Bro');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests the download method
+ *
+ */
+ public function testDownload() {
+ $response = new CakeResponse();
+ $expected = array(
+ 'Content-Disposition' => 'attachment; filename="myfile.mp3"'
+ );
+ $response->download('myfile.mp3');
+ $this->assertEquals($expected, $response->header());
+ }
+
+/**
+ * Tests the mapType method
+ *
+ */
+ public function testMapType() {
+ $response = new CakeResponse();
+ $this->assertEquals('wav', $response->mapType('audio/x-wav'));
+ $this->assertEquals('pdf', $response->mapType('application/pdf'));
+ $this->assertEquals('xml', $response->mapType('text/xml'));
+ $this->assertEquals('html', $response->mapType('*/*'));
+ $this->assertEquals('csv', $response->mapType('application/vnd.ms-excel'));
+ $expected = array('json', 'xhtml', 'css');
+ $result = $response->mapType(array('application/json', 'application/xhtml+xml', 'text/css'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests the outputCompressed method
+ *
+ */
+ public function testOutputCompressed() {
+ $response = new CakeResponse();
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
+ $result = $response->outputCompressed();
+ $this->assertFalse($result);
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = '';
+ $result = $response->outputCompressed();
+ $this->assertFalse($result);
+
+ if (!extension_loaded("zlib")) {
+ $this->markTestSkipped('Skipping further tests for outputCompressed as zlib extension is not loaded');
+ }
+ if (php_sapi_name() !== 'cli') {
+ $this->markTestSkipped('Testing outputCompressed method with compression enabled done only in cli');
+ }
+
+ if (ini_get("zlib.output_compression") !== '1') {
+ ob_start('ob_gzhandler');
+ }
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = 'gzip';
+ $result = $response->outputCompressed();
+ $this->assertTrue($result);
+
+ $_SERVER['HTTP_ACCEPT_ENCODING'] = '';
+ $result = $response->outputCompressed();
+ $this->assertFalse($result);
+ if (ini_get("zlib.output_compression") !== '1') {
+ ob_get_clean();
+ }
+ }
+
+/**
+ * Tests the send and setting of Content-Length
+ *
+ */
+ public function testSendContentLength() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->body('the response body');
+ $response->expects($this->once())->method('_sendContent')->with('the response body');
+ $response->expects($this->at(0))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Content-Length', strlen('the response body'));
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
+ $response->body($body);
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->at(0))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Content-Length', 116);
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
+ $body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
+ $response->body($body);
+ $response->expects($this->once())->method('outputCompressed')->will($this->returnValue(true));
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->exactly(2))->method('_sendHeader');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent', 'outputCompressed'));
+ $body = 'hwy';
+ $response->body($body);
+ $response->header('Content-Length', 1);
+ $response->expects($this->never())->method('outputCompressed');
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Content-Length', 1);
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $body = 'content';
+ $response->statusCode(301);
+ $response->body($body);
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->exactly(2))->method('_sendHeader');
+ $response->send();
+
+ ob_start();
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $goofyOutput = 'I am goofily sending output in the controller';
+ echo $goofyOutput;
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $body = '長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?';
+ $response->body($body);
+ $response->expects($this->once())->method('_sendContent')->with($body);
+ $response->expects($this->at(0))
+ ->method('_sendHeader')->with('HTTP/1.1 200 OK');
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Content-Length', strlen($goofyOutput) + 116);
+ $response->expects($this->at(2))
+ ->method('_sendHeader')->with('Content-Type', 'text/html; charset=UTF-8');
+ $response->send();
+ ob_end_clean();
+ }
+
+/**
+ * Tests getting/setting the protocol
+ *
+ * @return void
+ */
+ public function testProtocol() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->protocol('HTTP/1.0');
+ $this->assertEquals('HTTP/1.0', $response->protocol());
+ $response->expects($this->at(0))
+ ->method('_sendHeader')->with('HTTP/1.0 200 OK');
+ $response->send();
+ }
+
+/**
+ * Tests getting/setting the Content-Length
+ *
+ * @return void
+ */
+ public function testLength() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->length(100);
+ $this->assertEquals(100, $response->length());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Content-Length', 100);
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->length(false);
+ $this->assertFalse($response->length());
+ $response->expects($this->exactly(2))
+ ->method('_sendHeader');
+ $response->send();
+ }
+
+/**
+ * Tests that the response body is unset if the status code is 304 or 204
+ *
+ * @return void
+ */
+ public function testUnmodifiedContent() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->body('This is a body');
+ $response->statusCode(204);
+ $response->expects($this->once())
+ ->method('_sendContent')->with('');
+ $response->send();
+ $this->assertFalse(array_key_exists('Content-Type', $response->header()));
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->body('This is a body');
+ $response->statusCode(304);
+ $response->expects($this->once())
+ ->method('_sendContent')->with('');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->body('This is a body');
+ $response->statusCode(200);
+ $response->expects($this->once())
+ ->method('_sendContent')->with('This is a body');
+ $response->send();
+ }
+
+/**
+ * Tests setting the expiration date
+ *
+ * @return void
+ */
+ public function testExpires() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $now = new DateTime('now', new DateTimeZone('America/Los_Angeles'));
+ $response->expires($now);
+ $now->setTimeZone(new DateTimeZone('UTC'));
+ $this->assertEquals($now->format('D, j M Y H:i:s') . ' GMT', $response->expires());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Expires', $now->format('D, j M Y H:i:s') . ' GMT');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $now = time();
+ $response->expires($now);
+ $this->assertEquals(gmdate('D, j M Y H:i:s', $now) . ' GMT', $response->expires());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Expires', gmdate('D, j M Y H:i:s', $now) . ' GMT');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $time = new DateTime('+1 day', new DateTimeZone('UTC'));
+ $response->expires('+1 day');
+ $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->expires());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Expires', $time->format('D, j M Y H:i:s') . ' GMT');
+ $response->send();
+ }
+
+/**
+ * Tests setting the modification date
+ *
+ * @return void
+ */
+ public function testModified() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $now = new DateTime('now', new DateTimeZone('America/Los_Angeles'));
+ $response->modified($now);
+ $now->setTimeZone(new DateTimeZone('UTC'));
+ $this->assertEquals($now->format('D, j M Y H:i:s') . ' GMT', $response->modified());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Last-Modified', $now->format('D, j M Y H:i:s') . ' GMT');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $now = time();
+ $response->modified($now);
+ $this->assertEquals(gmdate('D, j M Y H:i:s', $now) . ' GMT', $response->modified());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Last-Modified', gmdate('D, j M Y H:i:s', $now) . ' GMT');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $time = new DateTime('+1 day', new DateTimeZone('UTC'));
+ $response->modified('+1 day');
+ $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Last-Modified', $time->format('D, j M Y H:i:s') . ' GMT');
+ $response->send();
+ }
+
+/**
+ * Tests setting of public/private Cache-Control directives
+ *
+ * @return void
+ */
+ public function testSharable() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $this->assertNull($response->sharable());
+ $response->sharable(true);
+ $headers = $response->header();
+ $this->assertEquals('public', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 'public');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->sharable(false);
+ $headers = $response->header();
+ $this->assertEquals('private', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 'private');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->sharable(true);
+ $headers = $response->header();
+ $this->assertEquals('public', $headers['Cache-Control']);
+ $response->sharable(false);
+ $headers = $response->header();
+ $this->assertEquals('private', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 'private');
+ $response->send();
+ $this->assertFalse($response->sharable());
+ $response->sharable(true);
+ $this->assertTrue($response->sharable());
+
+ $response = new CakeResponse;
+ $response->sharable(true, 3600);
+ $headers = $response->header();
+ $this->assertEquals('public, s-maxage=3600', $headers['Cache-Control']);
+
+ $response = new CakeResponse;
+ $response->sharable(false, 3600);
+ $headers = $response->header();
+ $this->assertEquals('private, max-age=3600', $headers['Cache-Control']);
+ $response->send();
+ }
+
+/**
+ * Tests setting of max-age Cache-Control directive
+ *
+ * @return void
+ */
+ public function testMaxAge() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $this->assertNull($response->maxAge());
+ $response->maxAge(3600);
+ $this->assertEquals(3600, $response->maxAge());
+ $headers = $response->header();
+ $this->assertEquals('max-age=3600', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 'max-age=3600');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->maxAge(3600);
+ $response->sharable(false);
+ $headers = $response->header();
+ $this->assertEquals('max-age=3600, private', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 'max-age=3600, private');
+ $response->send();
+ }
+
+/**
+ * Tests setting of s-maxage Cache-Control directive
+ *
+ * @return void
+ */
+ public function testSharedMaxAge() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $this->assertNull($response->maxAge());
+ $response->sharedMaxAge(3600);
+ $this->assertEquals(3600, $response->sharedMaxAge());
+ $headers = $response->header();
+ $this->assertEquals('s-maxage=3600', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 's-maxage=3600');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->sharedMaxAge(3600);
+ $response->sharable(true);
+ $headers = $response->header();
+ $this->assertEquals('s-maxage=3600, public', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 's-maxage=3600, public');
+ $response->send();
+ }
+
+/**
+ * Tests setting of must-revalidate Cache-Control directive
+ *
+ * @return void
+ */
+ public function testMustRevalidate() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $this->assertFalse($response->mustRevalidate());
+ $response->mustRevalidate(true);
+ $this->assertTrue($response->mustRevalidate());
+ $headers = $response->header();
+ $this->assertEquals('must-revalidate', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 'must-revalidate');
+ $response->send();
+ $response->mustRevalidate(false);
+ $this->assertFalse($response->mustRevalidate());
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->sharedMaxAge(3600);
+ $response->mustRevalidate(true);
+ $headers = $response->header();
+ $this->assertEquals('s-maxage=3600, must-revalidate', $headers['Cache-Control']);
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Cache-Control', 's-maxage=3600, must-revalidate');
+ $response->send();
+ }
+
+/**
+ * Tests getting/setting the Vary header
+ *
+ * @return void
+ */
+ public function testVary() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->vary('Accept-encoding');
+ $this->assertEquals(array('Accept-encoding'), $response->vary());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Vary', 'Accept-encoding');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->vary(array('Accept-language', 'Accept-encoding'));
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Vary', 'Accept-language, Accept-encoding');
+ $response->send();
+ $this->assertEquals(array('Accept-language', 'Accept-encoding'), $response->vary());
+ }
+
+/**
+ * Tests getting/setting the Etag header
+ *
+ * @return void
+ */
+ public function testEtag() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->etag('something');
+ $this->assertEquals('"something"', $response->etag());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Etag', '"something"');
+ $response->send();
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->etag('something', true);
+ $this->assertEquals('W/"something"', $response->etag());
+ $response->expects($this->at(1))
+ ->method('_sendHeader')->with('Etag', 'W/"something"');
+ $response->send();
+ }
+
+/**
+ * Tests that the response is able to be marked as not modified
+ *
+ * @return void
+ */
+ public function testNotModified() {
+ $response = $this->getMock('CakeResponse', array('_sendHeader', '_sendContent'));
+ $response->body('something');
+ $response->statusCode(200);
+ $response->length(100);
+ $response->modified('now');
+ $response->notModified();
+
+ $this->assertEmpty($response->header());
+ $this->assertEmpty($response->body());
+ $this->assertEquals(304, $response->statusCode());
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagStar() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = '*';
+ $response = $this->getMock('CakeResponse', array('notModified'));
+ $response->etag('something');
+ $response->expects($this->once())->method('notModified');
+ $response->checkNotModified(new CakeRequest);
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagExact() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
+ $response = $this->getMock('CakeResponse', array('notModified'));
+ $response->etag('something', true);
+ $response->expects($this->once())->method('notModified');
+ $this->assertTrue($response->checkNotModified(new CakeRequest));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagAndTime() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
+ $response = $this->getMock('CakeResponse', array('notModified'));
+ $response->etag('something', true);
+ $response->modified('2012-01-01 00:00:00');
+ $response->expects($this->once())->method('notModified');
+ $this->assertTrue($response->checkNotModified(new CakeRequest));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagAndTimeMismatch() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
+ $response = $this->getMock('CakeResponse', array('notModified'));
+ $response->etag('something', true);
+ $response->modified('2012-01-01 00:00:01');
+ $response->expects($this->never())->method('notModified');
+ $this->assertFalse($response->checkNotModified(new CakeRequest));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByEtagMismatch() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something-else", "other"';
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
+ $response = $this->getMock('CakeResponse', array('notModified'));
+ $response->etag('something', true);
+ $response->modified('2012-01-01 00:00:00');
+ $response->expects($this->never())->method('notModified');
+ $this->assertFalse($response->checkNotModified(new CakeRequest));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedByTime() {
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
+ $response = $this->getMock('CakeResponse', array('notModified'));
+ $response->modified('2012-01-01 00:00:00');
+ $response->expects($this->once())->method('notModified');
+ $this->assertTrue($response->checkNotModified(new CakeRequest));
+ }
+
+/**
+ * Test checkNotModified method
+ *
+ * @return void
+ **/
+ public function testCheckNotModifiedNoHints() {
+ $_SERVER['HTTP_IF_NONE_MATCH'] = 'W/"something", "other"';
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = '2012-01-01 00:00:00';
+ $response = $this->getMock('CakeResponse', array('notModified'));
+ $response->expects($this->never())->method('notModified');
+ $this->assertFalse($response->checkNotModified(new CakeRequest));
+ }
+
+/**
+ * Test cookie setting
+ *
+ * @return void
+ */
+ public function testCookieSettings() {
+ $response = new CakeResponse();
+ $cookie = array(
+ 'name' => 'CakeTestCookie[Testing]'
+ );
+ $response->cookie($cookie);
+ $expected = array(
+ 'name' => 'CakeTestCookie[Testing]',
+ 'value' => '',
+ 'expire' => 0,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => false,
+ 'httpOnly' => false);
+ $result = $response->cookie('CakeTestCookie[Testing]');
+ $this->assertEquals($expected, $result);
+
+ $cookie = array(
+ 'name' => 'CakeTestCookie[Testing2]',
+ 'value' => '[a,b,c]',
+ 'expire' => 1000,
+ 'path' => '/test',
+ 'secure' => true
+ );
+ $response->cookie($cookie);
+ $expected = array(
+ 'CakeTestCookie[Testing]' => array(
+ 'name' => 'CakeTestCookie[Testing]',
+ 'value' => '',
+ 'expire' => 0,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => false,
+ 'httpOnly' => false
+ ),
+ 'CakeTestCookie[Testing2]' => array(
+ 'name' => 'CakeTestCookie[Testing2]',
+ 'value' => '[a,b,c]',
+ 'expire' => 1000,
+ 'path' => '/test',
+ 'domain' => '',
+ 'secure' => true,
+ 'httpOnly' => false
+ )
+ );
+
+ $result = $response->cookie();
+ $this->assertEquals($expected, $result);
+
+ $cookie = $expected['CakeTestCookie[Testing]'];
+ $cookie['value'] = 'test';
+ $response->cookie($cookie);
+ $expected = array(
+ 'CakeTestCookie[Testing]' => array(
+ 'name' => 'CakeTestCookie[Testing]',
+ 'value' => 'test',
+ 'expire' => 0,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => false,
+ 'httpOnly' => false
+ ),
+ 'CakeTestCookie[Testing2]' => array(
+ 'name' => 'CakeTestCookie[Testing2]',
+ 'value' => '[a,b,c]',
+ 'expire' => 1000,
+ 'path' => '/test',
+ 'domain' => '',
+ 'secure' => true,
+ 'httpOnly' => false
+ )
+ );
+
+ $result = $response->cookie();
+ $this->assertEquals($expected, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeSocketTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeSocketTest.php
new file mode 100644
index 0000000..abe6fca
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/CakeSocketTest.php
@@ -0,0 +1,217 @@
+<?php
+/**
+ * SocketTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeSocket', 'Network');
+
+/**
+ * SocketTest class
+ *
+ * @package Cake.Test.Case.Network
+ */
+class CakeSocketTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Socket = new CakeSocket(array('timeout' => 1));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Socket);
+ }
+
+/**
+ * testConstruct method
+ *
+ * @return void
+ */
+ public function testConstruct() {
+ $this->Socket = new CakeSocket();
+ $config = $this->Socket->config;
+ $this->assertSame($config, array(
+ 'persistent' => false,
+ 'host' => 'localhost',
+ 'protocol' => getprotobyname('tcp'),
+ 'port' => 80,
+ 'timeout' => 30
+ ));
+
+ $this->Socket->reset();
+ $this->Socket->__construct(array('host' => 'foo-bar'));
+ $config['host'] = 'foo-bar';
+ $this->assertSame($this->Socket->config, $config);
+
+ $this->Socket = new CakeSocket(array('host' => 'www.cakephp.org', 'port' => 23, 'protocol' => 'udp'));
+ $config = $this->Socket->config;
+
+ $config['host'] = 'www.cakephp.org';
+ $config['port'] = 23;
+ $config['protocol'] = 17;
+
+ $this->assertSame($this->Socket->config, $config);
+ }
+
+/**
+ * testSocketConnection method
+ *
+ * @return void
+ */
+ public function testSocketConnection() {
+ $this->assertFalse($this->Socket->connected);
+ $this->Socket->disconnect();
+ $this->assertFalse($this->Socket->connected);
+ $this->Socket->connect();
+ $this->assertTrue($this->Socket->connected);
+ $this->Socket->connect();
+ $this->assertTrue($this->Socket->connected);
+
+ $this->Socket->disconnect();
+ $config = array('persistent' => true);
+ $this->Socket = new CakeSocket($config);
+ $this->Socket->connect();
+ $this->assertTrue($this->Socket->connected);
+ }
+
+/**
+ * data provider function for testInvalidConnection
+ *
+ * @return array
+ */
+ public static function invalidConnections() {
+ return array(
+ array(array('host' => 'invalid.host', 'port' => 9999, 'timeout' => 1)),
+ array(array('host' => '127.0.0.1', 'port' => '70000', 'timeout' => 1))
+ );
+ }
+
+/**
+ * testInvalidConnection method
+ *
+ * @dataProvider invalidConnections
+ * @expectedException SocketException
+ * return void
+ */
+ public function testInvalidConnection($data) {
+ $this->Socket->config = array_merge($this->Socket->config, $data);
+ $this->Socket->connect();
+ }
+
+/**
+ * testSocketHost method
+ *
+ * @return void
+ */
+ public function testSocketHost() {
+ $this->Socket = new CakeSocket();
+ $this->Socket->connect();
+ $this->assertEquals('127.0.0.1', $this->Socket->address());
+ $this->assertEquals(gethostbyaddr('127.0.0.1'), $this->Socket->host());
+ $this->assertEquals(null, $this->Socket->lastError());
+ $this->assertTrue(in_array('127.0.0.1', $this->Socket->addresses()));
+
+ $this->Socket = new CakeSocket(array('host' => '127.0.0.1'));
+ $this->Socket->connect();
+ $this->assertEquals('127.0.0.1', $this->Socket->address());
+ $this->assertEquals(gethostbyaddr('127.0.0.1'), $this->Socket->host());
+ $this->assertEquals(null, $this->Socket->lastError());
+ $this->assertTrue(in_array('127.0.0.1', $this->Socket->addresses()));
+ }
+
+/**
+ * testSocketWriting method
+ *
+ * @return void
+ */
+ public function testSocketWriting() {
+ $request = "GET / HTTP/1.1\r\nConnection: close\r\n\r\n";
+ $this->assertTrue((bool)$this->Socket->write($request));
+ }
+
+/**
+ * testSocketReading method
+ *
+ * @return void
+ */
+ public function testSocketReading() {
+ $this->Socket = new CakeSocket(array('timeout' => 5));
+ $this->Socket->connect();
+ $this->assertEquals(null, $this->Socket->read(26));
+
+ $config = array('host' => 'google.com', 'port' => 80, 'timeout' => 1);
+ $this->Socket = new CakeSocket($config);
+ $this->assertTrue($this->Socket->connect());
+ $this->assertEquals(null, $this->Socket->read(26));
+ $this->assertEquals('2: ' . __d('cake_dev', 'Connection timed out'), $this->Socket->lastError());
+ }
+
+/**
+ * testTimeOutConnection method
+ *
+ * @return void
+ */
+ public function testTimeOutConnection() {
+ $config = array('host' => '127.0.0.1', 'timeout' => 0.5);
+ $this->Socket = new CakeSocket($config);
+ $this->assertTrue($this->Socket->connect());
+
+ $config = array('host' => '127.0.0.1', 'timeout' => 0.00001);
+ $this->Socket = new CakeSocket($config);
+ $this->assertFalse($this->Socket->read(1024 * 1024));
+ $this->assertEquals('2: ' . __d('cake_dev', 'Connection timed out'), $this->Socket->lastError());
+ }
+
+/**
+ * testLastError method
+ *
+ * @return void
+ */
+ public function testLastError() {
+ $this->Socket = new CakeSocket();
+ $this->Socket->setLastError(4, 'some error here');
+ $this->assertEquals('4: some error here', $this->Socket->lastError());
+ }
+
+/**
+ * testReset method
+ *
+ * @return void
+ */
+ public function testReset() {
+ $config = array(
+ 'persistent' => true,
+ 'host' => '127.0.0.1',
+ 'protocol' => 'udp',
+ 'port' => 80,
+ 'timeout' => 20
+ );
+ $anotherSocket = new CakeSocket($config);
+ $anotherSocket->reset();
+ $this->assertEquals(array(), $anotherSocket->config);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php
new file mode 100644
index 0000000..cde6495
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/CakeEmailTest.php
@@ -0,0 +1,1793 @@
+<?php
+/**
+ * CakeEmailTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeEmail', 'Network/Email');
+
+/**
+ * Help to test CakeEmail
+ *
+ */
+class TestCakeEmail extends CakeEmail {
+
+/**
+ * Config
+ *
+ */
+ protected $_config = array();
+
+/**
+ * Wrap to protected method
+ *
+ */
+ public function formatAddress($address) {
+ return parent::_formatAddress($address);
+ }
+
+/**
+ * Wrap to protected method
+ *
+ */
+ public function wrap($text) {
+ return parent::_wrap($text);
+ }
+
+/**
+ * Get the boundary attribute
+ *
+ * @return string
+ */
+ public function getBoundary() {
+ return $this->_boundary;
+ }
+
+/**
+ * Encode to protected method
+ *
+ */
+ public function encode($text) {
+ return $this->_encode($text);
+ }
+
+}
+
+/*
+ * EmailConfig class
+ *
+ */
+class EmailConfig {
+
+/**
+ * test config
+ *
+ * @var string
+ */
+ public $test = array(
+ 'from' => array('some@example.com' => 'My website'),
+ 'to' => array('test@example.com' => 'Testname'),
+ 'subject' => 'Test mail subject',
+ 'transport' => 'Debug',
+ 'theme' => 'TestTheme',
+ 'helpers' => array('Html', 'Form'),
+ );
+
+}
+
+/*
+ * ExtendTransport class
+ * test class to ensure the class has send() method
+ *
+ */
+class ExtendTransport {
+
+}
+
+/**
+ * CakeEmailTest class
+ *
+ * @package Cake.Test.Case.Network.Email
+ */
+class CakeEmailTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->CakeEmail = new TestCakeEmail();
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ App::build();
+ }
+
+/**
+ * testFrom method
+ *
+ * @return void
+ */
+ public function testFrom() {
+ $this->assertSame($this->CakeEmail->from(), array());
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $expected = array('cake@cakephp.org' => 'cake@cakephp.org');
+ $this->assertSame($this->CakeEmail->from(), $expected);
+
+ $this->CakeEmail->from(array('cake@cakephp.org'));
+ $this->assertSame($this->CakeEmail->from(), $expected);
+
+ $this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
+ $expected = array('cake@cakephp.org' => 'CakePHP');
+ $this->assertSame($this->CakeEmail->from(), $expected);
+
+ $result = $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP'));
+ $this->assertSame($this->CakeEmail->from(), $expected);
+ $this->assertSame($this->CakeEmail, $result);
+
+ $this->setExpectedException('SocketException');
+ $result = $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP', 'fail@cakephp.org' => 'From can only be one address'));
+ }
+
+/**
+ * testSender method
+ *
+ * @return void
+ */
+ public function testSender() {
+ $this->CakeEmail->reset();
+ $this->assertSame($this->CakeEmail->sender(), array());
+
+ $this->CakeEmail->sender('cake@cakephp.org', 'Name');
+ $expected = array('cake@cakephp.org' => 'Name');
+ $this->assertSame($this->CakeEmail->sender(), $expected);
+
+ $headers = $this->CakeEmail->getHeaders(array('from' => true, 'sender' => true));
+ $this->assertSame($headers['From'], false);
+ $this->assertSame($headers['Sender'], 'Name <cake@cakephp.org>');
+
+ $this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
+ $headers = $this->CakeEmail->getHeaders(array('from' => true, 'sender' => true));
+ $this->assertSame($headers['From'], 'CakePHP <cake@cakephp.org>');
+ $this->assertSame($headers['Sender'], '');
+ }
+
+/**
+ * testTo method
+ *
+ * @return void
+ */
+ public function testTo() {
+ $this->assertSame($this->CakeEmail->to(), array());
+
+ $result = $this->CakeEmail->to('cake@cakephp.org');
+ $expected = array('cake@cakephp.org' => 'cake@cakephp.org');
+ $this->assertSame($this->CakeEmail->to(), $expected);
+ $this->assertSame($this->CakeEmail, $result);
+
+ $this->CakeEmail->to('cake@cakephp.org', 'CakePHP');
+ $expected = array('cake@cakephp.org' => 'CakePHP');
+ $this->assertSame($this->CakeEmail->to(), $expected);
+
+ $list = array(
+ 'cake@cakephp.org' => 'Cake PHP',
+ 'cake-php@googlegroups.com' => 'Cake Groups',
+ 'root@cakephp.org'
+ );
+ $this->CakeEmail->to($list);
+ $expected = array(
+ 'cake@cakephp.org' => 'Cake PHP',
+ 'cake-php@googlegroups.com' => 'Cake Groups',
+ 'root@cakephp.org' => 'root@cakephp.org'
+ );
+ $this->assertSame($this->CakeEmail->to(), $expected);
+
+ $this->CakeEmail->addTo('jrbasso@cakephp.org');
+ $this->CakeEmail->addTo('mark_story@cakephp.org', 'Mark Story');
+ $result = $this->CakeEmail->addTo(array('phpnut@cakephp.org' => 'PhpNut', 'jose_zap@cakephp.org'));
+ $expected = array(
+ 'cake@cakephp.org' => 'Cake PHP',
+ 'cake-php@googlegroups.com' => 'Cake Groups',
+ 'root@cakephp.org' => 'root@cakephp.org',
+ 'jrbasso@cakephp.org' => 'jrbasso@cakephp.org',
+ 'mark_story@cakephp.org' => 'Mark Story',
+ 'phpnut@cakephp.org' => 'PhpNut',
+ 'jose_zap@cakephp.org' => 'jose_zap@cakephp.org'
+ );
+ $this->assertSame($this->CakeEmail->to(), $expected);
+ $this->assertSame($this->CakeEmail, $result);
+ }
+
+/**
+ * Data provider function for testBuildInvalidData
+ *
+ * @return array
+ */
+ public static function invalidEmails() {
+ return array(
+ array(1.0),
+ array(''),
+ array('string'),
+ array('<tag>'),
+ array('some@one.whereis'),
+ array('wrong@key' => 'Name'),
+ array(array('ok@cakephp.org', 1.0, '', 'string'))
+ );
+ }
+
+/**
+ * testBuildInvalidData
+ *
+ * @dataProvider invalidEmails
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testInvalidEmail($value) {
+ $this->CakeEmail->to($value);
+ }
+
+/**
+ * testBuildInvalidData
+ *
+ * @dataProvider invalidEmails
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testInvalidEmailAdd($value) {
+ $this->CakeEmail->addTo($value);
+ }
+
+/**
+ * testFormatAddress method
+ *
+ * @return void
+ */
+ public function testFormatAddress() {
+ $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'cake@cakephp.org'));
+ $expected = array('cake@cakephp.org');
+ $this->assertSame($expected, $result);
+
+ $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'cake@cakephp.org', 'php@cakephp.org' => 'php@cakephp.org'));
+ $expected = array('cake@cakephp.org', 'php@cakephp.org');
+ $this->assertSame($expected, $result);
+
+ $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'CakePHP', 'php@cakephp.org' => 'Cake'));
+ $expected = array('CakePHP <cake@cakephp.org>', 'Cake <php@cakephp.org>');
+ $this->assertSame($expected, $result);
+
+ $result = $this->CakeEmail->formatAddress(array('me@example.com' => 'Last, First'));
+ $expected = array('"Last, First" <me@example.com>');
+ $this->assertSame($expected, $result);
+
+ $result = $this->CakeEmail->formatAddress(array('me@example.com' => 'Last First'));
+ $expected = array('Last First <me@example.com>');
+ $this->assertSame($expected, $result);
+
+ $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'ÄÖÜTest'));
+ $expected = array('=?UTF-8?B?w4TDlsOcVGVzdA==?= <cake@cakephp.org>');
+ $this->assertSame($expected, $result);
+
+ $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => '日本語Test'));
+ $expected = array('=?UTF-8?B?5pel5pys6KqeVGVzdA==?= <cake@cakephp.org>');
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testFormatAddressJapanese
+ *
+ * @return void
+ */
+ public function testFormatAddressJapanese() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+
+ $this->CakeEmail->headerCharset = 'ISO-2022-JP';
+ $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => '日本語Test'));
+ $expected = array('=?ISO-2022-JP?B?GyRCRnxLXDhsGyhCVGVzdA==?= <cake@cakephp.org>');
+ $this->assertSame($expected, $result);
+
+ $result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => '寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処やぶら小路の藪柑子パイポパイポパイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助'));
+ $expected = array("=?ISO-2022-JP?B?GyRCPHc4Qkw1PHc4Qkw1OF45ZSROOyQkakBaJGwzJDo9TXg/ZTV7GyhC?=\r\n" .
+ " =?ISO-2022-JP?B?GyRCJE4/ZTlUS3YxQE1oS3ZJd01oS3Y/KSQmPzIkaz1oJEs9OyRgGyhC?=\r\n" .
+ " =?ISO-2022-JP?B?GyRCPWgkZCRWJGk+Lk8pJE5pLjQ7O1IlUSUkJV0lUSUkJV0lUSUkGyhC?=\r\n" .
+ " =?ISO-2022-JP?B?GyRCJV0kTiU3JWUhPCVqJXMlLCVzJTclZSE8JWolcyUsJXMkTiUwGyhC?=\r\n" .
+ " =?ISO-2022-JP?B?GyRCITwlaiVzJUAlJCUwITwlaiVzJUAlJCROJV0lcyVdJTMlVCE8GyhC?=\r\n" .
+ " =?ISO-2022-JP?B?GyRCJE4lXSVzJV0lMyVKITwkTkQ5NVdMPyRORDk9dRsoQg==?= <cake@cakephp.org>");
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testAddresses method
+ *
+ * @return void
+ */
+ public function testAddresses() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
+ $this->CakeEmail->replyTo('replyto@cakephp.org', 'ReplyTo CakePHP');
+ $this->CakeEmail->readReceipt('readreceipt@cakephp.org', 'ReadReceipt CakePHP');
+ $this->CakeEmail->returnPath('returnpath@cakephp.org', 'ReturnPath CakePHP');
+ $this->CakeEmail->to('to@cakephp.org', 'To CakePHP');
+ $this->CakeEmail->cc('cc@cakephp.org', 'Cc CakePHP');
+ $this->CakeEmail->bcc('bcc@cakephp.org', 'Bcc CakePHP');
+ $this->CakeEmail->addTo('to2@cakephp.org', 'To2 CakePHP');
+ $this->CakeEmail->addCc('cc2@cakephp.org', 'Cc2 CakePHP');
+ $this->CakeEmail->addBcc('bcc2@cakephp.org', 'Bcc2 CakePHP');
+
+ $this->assertSame($this->CakeEmail->from(), array('cake@cakephp.org' => 'CakePHP'));
+ $this->assertSame($this->CakeEmail->replyTo(), array('replyto@cakephp.org' => 'ReplyTo CakePHP'));
+ $this->assertSame($this->CakeEmail->readReceipt(), array('readreceipt@cakephp.org' => 'ReadReceipt CakePHP'));
+ $this->assertSame($this->CakeEmail->returnPath(), array('returnpath@cakephp.org' => 'ReturnPath CakePHP'));
+ $this->assertSame($this->CakeEmail->to(), array('to@cakephp.org' => 'To CakePHP', 'to2@cakephp.org' => 'To2 CakePHP'));
+ $this->assertSame($this->CakeEmail->cc(), array('cc@cakephp.org' => 'Cc CakePHP', 'cc2@cakephp.org' => 'Cc2 CakePHP'));
+ $this->assertSame($this->CakeEmail->bcc(), array('bcc@cakephp.org' => 'Bcc CakePHP', 'bcc2@cakephp.org' => 'Bcc2 CakePHP'));
+
+ $headers = $this->CakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true));
+ $this->assertSame($headers['From'], 'CakePHP <cake@cakephp.org>');
+ $this->assertSame($headers['Reply-To'], 'ReplyTo CakePHP <replyto@cakephp.org>');
+ $this->assertSame($headers['Disposition-Notification-To'], 'ReadReceipt CakePHP <readreceipt@cakephp.org>');
+ $this->assertSame($headers['Return-Path'], 'ReturnPath CakePHP <returnpath@cakephp.org>');
+ $this->assertSame($headers['To'], 'To CakePHP <to@cakephp.org>, To2 CakePHP <to2@cakephp.org>');
+ $this->assertSame($headers['Cc'], 'Cc CakePHP <cc@cakephp.org>, Cc2 CakePHP <cc2@cakephp.org>');
+ $this->assertSame($headers['Bcc'], 'Bcc CakePHP <bcc@cakephp.org>, Bcc2 CakePHP <bcc2@cakephp.org>');
+ }
+
+/**
+ * testMessageId method
+ *
+ * @return void
+ */
+ public function testMessageId() {
+ $this->CakeEmail->messageId(true);
+ $result = $this->CakeEmail->getHeaders();
+ $this->assertTrue(isset($result['Message-ID']));
+
+ $this->CakeEmail->messageId(false);
+ $result = $this->CakeEmail->getHeaders();
+ $this->assertFalse(isset($result['Message-ID']));
+
+ $result = $this->CakeEmail->messageId('<my-email@localhost>');
+ $this->assertSame($this->CakeEmail, $result);
+ $result = $this->CakeEmail->getHeaders();
+ $this->assertSame($result['Message-ID'], '<my-email@localhost>');
+
+ $result = $this->CakeEmail->messageId();
+ $this->assertSame($result, '<my-email@localhost>');
+ }
+
+/**
+ * testMessageIdInvalid method
+ *
+ * @return void
+ * @expectedException SocketException
+ */
+ public function testMessageIdInvalid() {
+ $this->CakeEmail->messageId('my-email@localhost');
+ }
+
+/**
+ * testDomain method
+ *
+ * @return void
+ */
+ public function testDomain() {
+ $result = $this->CakeEmail->domain();
+ $expected = env('HTTP_HOST') ? env('HTTP_HOST') : php_uname('n');
+ $this->assertSame($expected, $result);
+
+ $this->CakeEmail->domain('example.org');
+ $result = $this->CakeEmail->domain();
+ $expected = 'example.org';
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testMessageIdWithDomain method
+ *
+ * @return void
+ */
+ public function testMessageIdWithDomain() {
+ $result = $this->CakeEmail->getHeaders();
+ $expected = '@' . (env('HTTP_HOST') ? env('HTTP_HOST') : php_uname('n')) . '>';
+ $this->assertTextContains($expected, $result['Message-ID']);
+
+ $this->CakeEmail->domain('example.org');
+ $result = $this->CakeEmail->getHeaders();
+ $expected = '@example.org>';
+ $this->assertTextContains($expected, $result['Message-ID']);
+ }
+
+/**
+ * testSubject method
+ *
+ * @return void
+ */
+ public function testSubject() {
+ $this->CakeEmail->subject('You have a new message.');
+ $this->assertSame($this->CakeEmail->subject(), 'You have a new message.');
+
+ $this->CakeEmail->subject('You have a new message, I think.');
+ $this->assertSame($this->CakeEmail->subject(), 'You have a new message, I think.');
+ $this->CakeEmail->subject(1);
+ $this->assertSame($this->CakeEmail->subject(), '1');
+
+ $this->CakeEmail->subject('هذه رسالة بعنوان طويل مرسل للمستلم');
+ $expected = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?=';
+ $this->assertSame($this->CakeEmail->subject(), $expected);
+ }
+
+/**
+ * testSubjectJapanese
+ *
+ * @return void
+ */
+ public function testSubjectJapanese() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+ mb_internal_encoding('UTF-8');
+
+ $this->CakeEmail->headerCharset = 'ISO-2022-JP';
+ $this->CakeEmail->subject('日本語のSubjectにも対応するよ');
+ $expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsJE4bKEJTdWJqZWN0GyRCJEskYkJQMX4kOSRrJGgbKEI=?=';
+ $this->assertSame($this->CakeEmail->subject(), $expected);
+
+ $this->CakeEmail->subject('長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?');
+ $expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
+ " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
+ " =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=";
+ $this->assertSame($this->CakeEmail->subject(), $expected);
+ }
+
+/**
+ * testHeaders method
+ *
+ * @return void
+ */
+ public function testHeaders() {
+ $this->CakeEmail->messageId(false);
+ $this->CakeEmail->setHeaders(array('X-Something' => 'nice'));
+ $expected = array(
+ 'X-Something' => 'nice',
+ 'X-Mailer' => 'CakePHP Email',
+ 'Date' => date(DATE_RFC2822),
+ 'MIME-Version' => '1.0',
+ 'Content-Type' => 'text/plain; charset=UTF-8',
+ 'Content-Transfer-Encoding' => '8bit'
+ );
+ $this->assertSame($this->CakeEmail->getHeaders(), $expected);
+
+ $this->CakeEmail->addHeaders(array('X-Something' => 'very nice', 'X-Other' => 'cool'));
+ $expected = array(
+ 'X-Something' => 'very nice',
+ 'X-Other' => 'cool',
+ 'X-Mailer' => 'CakePHP Email',
+ 'Date' => date(DATE_RFC2822),
+ 'MIME-Version' => '1.0',
+ 'Content-Type' => 'text/plain; charset=UTF-8',
+ 'Content-Transfer-Encoding' => '8bit'
+ );
+ $this->assertSame($this->CakeEmail->getHeaders(), $expected);
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->assertSame($this->CakeEmail->getHeaders(), $expected);
+
+ $expected = array(
+ 'From' => 'cake@cakephp.org',
+ 'X-Something' => 'very nice',
+ 'X-Other' => 'cool',
+ 'X-Mailer' => 'CakePHP Email',
+ 'Date' => date(DATE_RFC2822),
+ 'MIME-Version' => '1.0',
+ 'Content-Type' => 'text/plain; charset=UTF-8',
+ 'Content-Transfer-Encoding' => '8bit'
+ );
+ $this->assertSame($this->CakeEmail->getHeaders(array('from' => true)), $expected);
+
+ $this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
+ $expected['From'] = 'CakePHP <cake@cakephp.org>';
+ $this->assertSame($this->CakeEmail->getHeaders(array('from' => true)), $expected);
+
+ $this->CakeEmail->to(array('cake@cakephp.org', 'php@cakephp.org' => 'CakePHP'));
+ $expected = array(
+ 'From' => 'CakePHP <cake@cakephp.org>',
+ 'To' => 'cake@cakephp.org, CakePHP <php@cakephp.org>',
+ 'X-Something' => 'very nice',
+ 'X-Other' => 'cool',
+ 'X-Mailer' => 'CakePHP Email',
+ 'Date' => date(DATE_RFC2822),
+ 'MIME-Version' => '1.0',
+ 'Content-Type' => 'text/plain; charset=UTF-8',
+ 'Content-Transfer-Encoding' => '8bit'
+ );
+ $this->assertSame($this->CakeEmail->getHeaders(array('from' => true, 'to' => true)), $expected);
+
+ $this->CakeEmail->charset = 'ISO-2022-JP';
+ $expected = array(
+ 'From' => 'CakePHP <cake@cakephp.org>',
+ 'To' => 'cake@cakephp.org, CakePHP <php@cakephp.org>',
+ 'X-Something' => 'very nice',
+ 'X-Other' => 'cool',
+ 'X-Mailer' => 'CakePHP Email',
+ 'Date' => date(DATE_RFC2822),
+ 'MIME-Version' => '1.0',
+ 'Content-Type' => 'text/plain; charset=ISO-2022-JP',
+ 'Content-Transfer-Encoding' => '7bit'
+ );
+ $this->assertSame($this->CakeEmail->getHeaders(array('from' => true, 'to' => true)), $expected);
+
+ $result = $this->CakeEmail->setHeaders(array());
+ $this->assertInstanceOf('CakeEmail', $result);
+ }
+
+/**
+ * Data provider function for testInvalidHeaders
+ *
+ * @return array
+ */
+ public static function invalidHeaders() {
+ return array(
+ array(10),
+ array(''),
+ array('string'),
+ array(false),
+ array(null)
+ );
+ }
+
+/**
+ * testInvalidHeaders
+ *
+ * @dataProvider invalidHeaders
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testInvalidHeaders($value) {
+ $this->CakeEmail->setHeaders($value);
+ }
+
+/**
+ * testInvalidAddHeaders
+ *
+ * @dataProvider invalidHeaders
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testInvalidAddHeaders($value) {
+ $this->CakeEmail->addHeaders($value);
+ }
+
+/**
+ * testTemplate method
+ *
+ * @return void
+ */
+ public function testTemplate() {
+ $this->CakeEmail->template('template', 'layout');
+ $expected = array('template' => 'template', 'layout' => 'layout');
+ $this->assertSame($this->CakeEmail->template(), $expected);
+
+ $this->CakeEmail->template('new_template');
+ $expected = array('template' => 'new_template', 'layout' => 'layout');
+ $this->assertSame($this->CakeEmail->template(), $expected);
+
+ $this->CakeEmail->template('template', null);
+ $expected = array('template' => 'template', 'layout' => null);
+ $this->assertSame($this->CakeEmail->template(), $expected);
+
+ $this->CakeEmail->template(null, null);
+ $expected = array('template' => null, 'layout' => null);
+ $this->assertSame($this->CakeEmail->template(), $expected);
+ }
+
+/**
+ * testTheme method
+ *
+ * @return void
+ */
+ public function testTheme() {
+ $this->assertSame(null, $this->CakeEmail->theme());
+
+ $this->CakeEmail->theme('default');
+ $expected = 'default';
+ $this->assertSame($expected, $this->CakeEmail->theme());
+ }
+
+/**
+ * testViewVars method
+ *
+ * @return void
+ */
+ public function testViewVars() {
+ $this->assertSame($this->CakeEmail->viewVars(), array());
+
+ $this->CakeEmail->viewVars(array('value' => 12345));
+ $this->assertSame($this->CakeEmail->viewVars(), array('value' => 12345));
+
+ $this->CakeEmail->viewVars(array('name' => 'CakePHP'));
+ $this->assertSame($this->CakeEmail->viewVars(), array('value' => 12345, 'name' => 'CakePHP'));
+
+ $this->CakeEmail->viewVars(array('value' => 4567));
+ $this->assertSame($this->CakeEmail->viewVars(), array('value' => 4567, 'name' => 'CakePHP'));
+ }
+
+/**
+ * testAttachments method
+ *
+ * @return void
+ */
+ public function testAttachments() {
+ $this->CakeEmail->attachments(CAKE . 'basics.php');
+ $expected = array('basics.php' => array('file' => CAKE . 'basics.php', 'mimetype' => 'application/octet-stream'));
+ $this->assertSame($this->CakeEmail->attachments(), $expected);
+
+ $this->CakeEmail->attachments(array());
+ $this->assertSame($this->CakeEmail->attachments(), array());
+
+ $this->CakeEmail->attachments(array(array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain')));
+ $this->CakeEmail->addAttachments(CAKE . 'bootstrap.php');
+ $this->CakeEmail->addAttachments(array(CAKE . 'bootstrap.php'));
+ $this->CakeEmail->addAttachments(array('other.txt' => CAKE . 'bootstrap.php', 'license' => CAKE . 'LICENSE.txt'));
+ $expected = array(
+ 'basics.php' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain'),
+ 'bootstrap.php' => array('file' => CAKE . 'bootstrap.php', 'mimetype' => 'application/octet-stream'),
+ 'other.txt' => array('file' => CAKE . 'bootstrap.php', 'mimetype' => 'application/octet-stream'),
+ 'license' => array('file' => CAKE . 'LICENSE.txt', 'mimetype' => 'application/octet-stream')
+ );
+ $this->assertSame($this->CakeEmail->attachments(), $expected);
+
+ $this->setExpectedException('SocketException');
+ $this->CakeEmail->attachments(array(array('nofile' => CAKE . 'basics.php', 'mimetype' => 'text/plain')));
+ }
+
+/**
+ * testTransport method
+ *
+ * @return void
+ */
+ public function testTransport() {
+ $result = $this->CakeEmail->transport('Debug');
+ $this->assertSame($this->CakeEmail, $result);
+ $this->assertSame($this->CakeEmail->transport(), 'Debug');
+
+ $result = $this->CakeEmail->transportClass();
+ $this->assertInstanceOf('DebugTransport', $result);
+
+ $this->setExpectedException('SocketException');
+ $this->CakeEmail->transport('Invalid');
+ $result = $this->CakeEmail->transportClass();
+ }
+
+/**
+ * testExtendTransport method
+ *
+ * @return void
+ */
+ public function testExtendTransport() {
+ $this->setExpectedException('SocketException');
+ $this->CakeEmail->transport('Extend');
+ $result = $this->CakeEmail->transportClass();
+ }
+
+/**
+ * testConfig method
+ *
+ * @return void
+ */
+ public function testConfig() {
+ $transportClass = $this->CakeEmail->transport('debug')->transportClass();
+
+ $config = array('test' => 'ok', 'test2' => true);
+ $this->CakeEmail->config($config);
+ $this->assertSame($transportClass->config(), $config);
+ $this->assertSame($this->CakeEmail->config(), $config);
+
+ $this->CakeEmail->config(array());
+ $this->assertSame($transportClass->config(), array());
+ }
+
+/**
+ * testConfigString method
+ *
+ * @return void
+ */
+ public function testConfigString() {
+ $configs = new EmailConfig();
+ $this->CakeEmail->config('test');
+
+ $result = $this->CakeEmail->to();
+ $this->assertEquals($configs->test['to'], $result);
+
+ $result = $this->CakeEmail->from();
+ $this->assertEquals($configs->test['from'], $result);
+
+ $result = $this->CakeEmail->subject();
+ $this->assertEquals($configs->test['subject'], $result);
+
+ $result = $this->CakeEmail->theme();
+ $this->assertEquals($configs->test['theme'], $result);
+
+ $result = $this->CakeEmail->transport();
+ $this->assertEquals($configs->test['transport'], $result);
+
+ $result = $this->CakeEmail->transportClass();
+ $this->assertInstanceOf('DebugTransport', $result);
+
+ $result = $this->CakeEmail->helpers();
+ $this->assertEquals($configs->test['helpers'], $result);
+ }
+
+/**
+ * testSendWithContent method
+ *
+ * @return void
+ */
+ public function testSendWithContent() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('Debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+
+ $result = $this->CakeEmail->send("Here is my body, with multi lines.\nThis is the second line.\r\n\r\nAnd the last.");
+ $expected = array('headers', 'message');
+ $this->assertEquals($expected, array_keys($result));
+ $expected = "Here is my body, with multi lines.\r\nThis is the second line.\r\n\r\nAnd the last.\r\n\r\n";
+
+ $this->assertEquals($expected, $result['message']);
+ $this->assertTrue((bool)strpos($result['headers'], 'Date: '));
+ $this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
+ $this->assertTrue((bool)strpos($result['headers'], 'To: '));
+
+ $result = $this->CakeEmail->send("Other body");
+ $expected = "Other body\r\n\r\n";
+ $this->assertSame($result['message'], $expected);
+ $this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
+ $this->assertTrue((bool)strpos($result['headers'], 'To: '));
+
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('Debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $result = $this->CakeEmail->send(array('Sending content', 'As array'));
+ $expected = "Sending content\r\nAs array\r\n\r\n\r\n";
+ $this->assertSame($result['message'], $expected);
+ }
+
+/**
+ * testSendWithoutFrom method
+ *
+ * @return void
+ */
+ public function testSendWithoutFrom() {
+ $this->CakeEmail->transport('Debug');
+ $this->CakeEmail->to('cake@cakephp.org');
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->setExpectedException('SocketException');
+ $this->CakeEmail->send("Forgot to set From");
+ }
+
+/**
+ * testSendWithoutTo method
+ *
+ * @return void
+ */
+ public function testSendWithoutTo() {
+ $this->CakeEmail->transport('Debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->setExpectedException('SocketException');
+ $this->CakeEmail->send("Forgot to set To");
+ }
+
+/**
+ * Test send() with no template.
+ *
+ * @return void
+ */
+ public function testSendNoTemplateWithAttachments() {
+ $this->CakeEmail->transport('debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to('cake@cakephp.org');
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->emailFormat('text');
+ $this->CakeEmail->attachments(array(CAKE . 'basics.php'));
+ $result = $this->CakeEmail->send('Hello');
+
+ $boundary = $this->CakeEmail->getBoundary();
+ $this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
+ $expected = "--$boundary\r\n" .
+ "Content-Type: text/plain; charset=UTF-8\r\n" .
+ "Content-Transfer-Encoding: 8bit\r\n" .
+ "\r\n" .
+ "Hello" .
+ "\r\n" .
+ "\r\n" .
+ "\r\n" .
+ "--$boundary\r\n" .
+ "Content-Type: application/octet-stream\r\n" .
+ "Content-Transfer-Encoding: base64\r\n" .
+ "Content-Disposition: attachment; filename=\"basics.php\"\r\n\r\n";
+ $this->assertContains($expected, $result['message']);
+ }
+
+/**
+ * Test send() with no template as both
+ *
+ * @return void
+ */
+ public function testSendNoTemplateWithAttachmentsAsBoth() {
+ $this->CakeEmail->transport('debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to('cake@cakephp.org');
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->emailFormat('both');
+ $this->CakeEmail->attachments(array(CAKE . 'VERSION.txt'));
+ $result = $this->CakeEmail->send('Hello');
+
+ $boundary = $this->CakeEmail->getBoundary();
+ $this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
+ $expected = "--$boundary\r\n" .
+ "Content-Type: multipart/alternative; boundary=\"alt-$boundary\"\r\n" .
+ "\r\n" .
+ "--alt-$boundary\r\n" .
+ "Content-Type: text/plain; charset=UTF-8\r\n" .
+ "Content-Transfer-Encoding: 8bit\r\n" .
+ "\r\n" .
+ "Hello" .
+ "\r\n" .
+ "\r\n" .
+ "\r\n" .
+ "--alt-$boundary\r\n" .
+ "Content-Type: text/html; charset=UTF-8\r\n" .
+ "Content-Transfer-Encoding: 8bit\r\n" .
+ "\r\n" .
+ "Hello" .
+ "\r\n" .
+ "\r\n" .
+ "\r\n" .
+ "--alt-{$boundary}--\r\n" .
+ "\r\n" .
+ "--$boundary\r\n" .
+ "Content-Type: application/octet-stream\r\n" .
+ "Content-Transfer-Encoding: base64\r\n" .
+ "Content-Disposition: attachment; filename=\"VERSION.txt\"\r\n\r\n";
+ $this->assertContains($expected, $result['message']);
+ }
+
+/**
+ * Test setting inline attachments and messages.
+ *
+ * @return void
+ */
+ public function testSendWithInlineAttachments() {
+ $this->CakeEmail->transport('debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to('cake@cakephp.org');
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->emailFormat('both');
+ $this->CakeEmail->attachments(array(
+ 'cake.png' => array(
+ 'file' => CAKE . 'VERSION.txt',
+ 'contentId' => 'abc123'
+ )
+ ));
+ $result = $this->CakeEmail->send('Hello');
+
+ $boundary = $this->CakeEmail->getBoundary();
+ $this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
+ $expected = "--$boundary\r\n" .
+ "Content-Type: multipart/related; boundary=\"rel-$boundary\"\r\n" .
+ "\r\n" .
+ "--rel-$boundary\r\n" .
+ "Content-Type: multipart/alternative; boundary=\"alt-$boundary\"\r\n" .
+ "\r\n" .
+ "--alt-$boundary\r\n" .
+ "Content-Type: text/plain; charset=UTF-8\r\n" .
+ "Content-Transfer-Encoding: 8bit\r\n" .
+ "\r\n" .
+ "Hello" .
+ "\r\n" .
+ "\r\n" .
+ "\r\n" .
+ "--alt-$boundary\r\n" .
+ "Content-Type: text/html; charset=UTF-8\r\n" .
+ "Content-Transfer-Encoding: 8bit\r\n" .
+ "\r\n" .
+ "Hello" .
+ "\r\n" .
+ "\r\n" .
+ "\r\n" .
+ "--alt-{$boundary}--\r\n" .
+ "\r\n" .
+ "--rel-$boundary\r\n" .
+ "Content-Type: application/octet-stream\r\n" .
+ "Content-Transfer-Encoding: base64\r\n" .
+ "Content-ID: <abc123>\r\n" .
+ "Content-Disposition: inline; filename=\"cake.png\"\r\n\r\n";
+ $this->assertContains($expected, $result['message']);
+ $this->assertContains('--rel-' . $boundary . '--', $result['message']);
+ $this->assertContains('--' . $boundary . '--', $result['message']);
+ }
+
+/**
+ * testSendWithLog method
+ *
+ * @return void
+ */
+ public function testSendWithLog() {
+ $path = CAKE . 'Test' . DS . 'test_app' . DS . 'tmp' . DS;
+ CakeLog::config('email', array(
+ 'engine' => 'FileLog',
+ 'path' => TMP
+ ));
+ CakeLog::drop('default');
+ $this->CakeEmail->transport('Debug');
+ $this->CakeEmail->to('me@cakephp.org');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('log' => 'cake_test_emails'));
+ $result = $this->CakeEmail->send("Logging This");
+
+ App::uses('File', 'Utility');
+ $File = new File(TMP . 'cake_test_emails.log');
+ $log = $File->read();
+ $this->assertTrue(strpos($log, $result['headers']) !== false);
+ $this->assertTrue(strpos($log, $result['message']) !== false);
+ $File->delete();
+ CakeLog::drop('email');
+ }
+
+/**
+ * testSendRender method
+ *
+ * @return void
+ */
+ public function testSendRender() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->template('default', 'default');
+ $result = $this->CakeEmail->send();
+
+ $this->assertContains('This email was sent using the CakePHP Framework', $result['message']);
+ $this->assertContains('Message-ID: ', $result['headers']);
+ $this->assertContains('To: ', $result['headers']);
+ }
+
+/**
+ * testSendRender method for ISO-2022-JP
+ *
+ * @return void
+ */
+ public function testSendRenderJapanese() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->template('default', 'japanese');
+ $this->CakeEmail->charset = 'ISO-2022-JP';
+ $result = $this->CakeEmail->send();
+
+ $expected = mb_convert_encoding('CakePHP Framework を使って送信したメールです。 http://cakephp.org.', 'ISO-2022-JP');
+ $this->assertContains($expected, $result['message']);
+ $this->assertContains('Message-ID: ', $result['headers']);
+ $this->assertContains('To: ', $result['headers']);
+ }
+
+/**
+ * testSendRenderThemed method
+ *
+ * @return void
+ */
+ public function testSendRenderThemed() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->theme('TestTheme');
+ $this->CakeEmail->template('themed', 'default');
+ $result = $this->CakeEmail->send();
+
+ $this->assertContains('In TestTheme', $result['message']);
+ $this->assertContains('Message-ID: ', $result['headers']);
+ $this->assertContains('To: ', $result['headers']);
+ }
+
+/**
+ * testSendRenderWithVars method
+ *
+ * @return void
+ */
+ public function testSendRenderWithVars() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->template('custom', 'default');
+ $this->CakeEmail->viewVars(array('value' => 12345));
+ $result = $this->CakeEmail->send();
+
+ $this->assertContains('Here is your value: 12345', $result['message']);
+ }
+
+/**
+ * testSendRenderWithVars method for ISO-2022-JP
+ *
+ * @return void
+ */
+ public function testSendRenderWithVarsJapanese() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->template('japanese', 'default');
+ $this->CakeEmail->viewVars(array('value' => '日本語の差し込み123'));
+ $this->CakeEmail->charset = 'ISO-2022-JP';
+ $result = $this->CakeEmail->send();
+
+ $expected = mb_convert_encoding('ここにあなたの設定した値が入ります: 日本語の差し込み123', 'ISO-2022-JP');
+ $this->assertTrue((bool)strpos($result['message'], $expected));
+ }
+
+/**
+ * testSendRenderWithHelpers method
+ *
+ * @return void
+ */
+ public function testSendRenderWithHelpers() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+
+ $timestamp = time();
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->template('custom_helper', 'default');
+ $this->CakeEmail->viewVars(array('time' => $timestamp));
+
+ $result = $this->CakeEmail->helpers(array('Time'));
+ $this->assertInstanceOf('CakeEmail', $result);
+
+ $result = $this->CakeEmail->send();
+ $this->assertTrue((bool)strpos($result['message'], 'Right now: ' . date('Y-m-d\TH:i:s\Z', $timestamp)));
+
+ $result = $this->CakeEmail->helpers();
+ $this->assertEquals(array('Time'), $result);
+ }
+
+/**
+ * testSendRenderWithImage method
+ *
+ * @return void
+ */
+ public function testSendRenderWithImage() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('Debug');
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->template('image');
+ $this->CakeEmail->emailFormat('html');
+
+ $server = env('SERVER_NAME') ? env('SERVER_NAME') : 'localhost';
+ $expected = '<img src="http://' . $server . '/img/image.gif" alt="cool image" width="100" height="100" />';
+ $result = $this->CakeEmail->send();
+ $this->assertContains($expected, $result['message']);
+ }
+
+/**
+ * testSendRenderPlugin method
+ *
+ * @return void
+ */
+ public function testSendRenderPlugin() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+
+ $result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'default')->send();
+ $this->assertContains('Into TestPlugin.', $result['message']);
+ $this->assertContains('This email was sent using the CakePHP Framework', $result['message']);
+
+ $result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'TestPlugin.plug_default')->send();
+ $this->assertContains('Into TestPlugin.', $result['message']);
+ $this->assertContains('This email was sent using the TestPlugin.', $result['message']);
+
+ $result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'plug_default')->send();
+ $this->assertContains('Into TestPlugin.', $result['message']);
+ $this->assertContains('This email was sent using the TestPlugin.', $result['message']);
+
+ // test plugin template overridden by theme
+ $this->CakeEmail->theme('TestTheme');
+ $result = $this->CakeEmail->send();
+
+ $this->assertContains('Into TestPlugin. (themed)', $result['message']);
+
+ $this->CakeEmail->viewVars(array('value' => 12345));
+ $result = $this->CakeEmail->template('custom', 'TestPlugin.plug_default')->send();
+ $this->assertContains('Here is your value: 12345', $result['message']);
+ $this->assertContains('This email was sent using the TestPlugin.', $result['message']);
+
+ $this->setExpectedException('MissingViewException');
+ $this->CakeEmail->template('test_plugin_tpl', 'plug_default')->send();
+ }
+
+/**
+ * testSendMultipleMIME method
+ *
+ * @return void
+ */
+ public function testSendMultipleMIME() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->template('custom', 'default');
+ $this->CakeEmail->config(array());
+ $this->CakeEmail->viewVars(array('value' => 12345));
+ $this->CakeEmail->emailFormat('both');
+ $result = $this->CakeEmail->send();
+
+ $message = $this->CakeEmail->message();
+ $boundary = $this->CakeEmail->getBoundary();
+ $this->assertFalse(empty($boundary));
+ $this->assertContains('--' . $boundary, $message);
+ $this->assertContains('--' . $boundary . '--', $message);
+ $this->assertContains('--alt-' . $boundary, $message);
+ $this->assertContains('--alt-' . $boundary . '--', $message);
+
+ $this->CakeEmail->attachments(array('fake.php' => __FILE__));
+ $this->CakeEmail->send();
+
+ $message = $this->CakeEmail->message();
+ $boundary = $this->CakeEmail->getBoundary();
+ $this->assertFalse(empty($boundary));
+ $this->assertContains('--' . $boundary, $message);
+ $this->assertContains('--' . $boundary . '--', $message);
+ $this->assertContains('--alt-' . $boundary, $message);
+ $this->assertContains('--alt-' . $boundary . '--', $message);
+ }
+
+/**
+ * testSendAttachment method
+ *
+ * @return void
+ */
+ public function testSendAttachment() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array());
+ $this->CakeEmail->attachments(array(CAKE . 'basics.php'));
+ $result = $this->CakeEmail->send('body');
+ $this->assertContains("Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"basics.php\"", $result['message']);
+
+ $this->CakeEmail->attachments(array('my.file.txt' => CAKE . 'basics.php'));
+ $result = $this->CakeEmail->send('body');
+ $this->assertContains("Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"my.file.txt\"", $result['message']);
+
+ $this->CakeEmail->attachments(array('file.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain')));
+ $result = $this->CakeEmail->send('body');
+ $this->assertContains("Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"file.txt\"", $result['message']);
+
+ $this->CakeEmail->attachments(array('file2.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1')));
+ $result = $this->CakeEmail->send('body');
+ $this->assertContains("Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-ID: <a1b1c1>\r\nContent-Disposition: inline; filename=\"file2.txt\"", $result['message']);
+ }
+
+/**
+ * testDeliver method
+ *
+ * @return void
+ */
+ public function testDeliver() {
+ $instance = CakeEmail::deliver('all@cakephp.org', 'About', 'Everything ok', array('from' => 'root@cakephp.org'), false);
+ $this->assertInstanceOf('CakeEmail', $instance);
+ $this->assertSame($instance->to(), array('all@cakephp.org' => 'all@cakephp.org'));
+ $this->assertSame($instance->subject(), 'About');
+ $this->assertSame($instance->from(), array('root@cakephp.org' => 'root@cakephp.org'));
+
+ $config = array(
+ 'from' => 'cake@cakephp.org',
+ 'to' => 'debug@cakephp.org',
+ 'subject' => 'Update ok',
+ 'template' => 'custom',
+ 'layout' => 'custom_layout',
+ 'viewVars' => array('value' => 123),
+ 'cc' => array('cake@cakephp.org' => 'Myself')
+ );
+ $instance = CakeEmail::deliver(null, null, array('name' => 'CakePHP'), $config, false);
+ $this->assertSame($instance->from(), array('cake@cakephp.org' => 'cake@cakephp.org'));
+ $this->assertSame($instance->to(), array('debug@cakephp.org' => 'debug@cakephp.org'));
+ $this->assertSame($instance->subject(), 'Update ok');
+ $this->assertSame($instance->template(), array('template' => 'custom', 'layout' => 'custom_layout'));
+ $this->assertSame($instance->viewVars(), array('value' => 123, 'name' => 'CakePHP'));
+ $this->assertSame($instance->cc(), array('cake@cakephp.org' => 'Myself'));
+
+ $configs = array('from' => 'root@cakephp.org', 'message' => 'Message from configs', 'transport' => 'Debug');
+ $instance = CakeEmail::deliver('all@cakephp.org', 'About', null, $configs, true);
+ $message = $instance->message();
+ $this->assertEquals($configs['message'], $message[0]);
+ }
+
+/**
+ * testMessage method
+ *
+ * @return void
+ */
+ public function testMessage() {
+ $this->CakeEmail->reset();
+ $this->CakeEmail->transport('debug');
+ $this->CakeEmail->from('cake@cakephp.org');
+ $this->CakeEmail->to(array('you@cakephp.org' => 'You'));
+ $this->CakeEmail->subject('My title');
+ $this->CakeEmail->config(array('empty'));
+ $this->CakeEmail->template('default', 'default');
+ $this->CakeEmail->emailFormat('both');
+ $result = $this->CakeEmail->send();
+
+ $expected = '<p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>';
+ $this->assertContains($expected, $this->CakeEmail->message(CakeEmail::MESSAGE_HTML));
+
+ $expected = 'This email was sent using the CakePHP Framework, http://cakephp.org.';
+ $this->assertContains($expected, $this->CakeEmail->message(CakeEmail::MESSAGE_TEXT));
+
+ $message = $this->CakeEmail->message();
+ $this->assertContains('Content-Type: text/plain; charset=UTF-8', $message);
+ $this->assertContains('Content-Type: text/html; charset=UTF-8', $message);
+
+ // UTF-8 is 8bit
+ $this->assertTrue($this->_checkContentTransferEncoding($message, '8bit'));
+
+ $this->CakeEmail->charset = 'ISO-2022-JP';
+ $this->CakeEmail->send();
+ $message = $this->CakeEmail->message();
+ $this->assertContains('Content-Type: text/plain; charset=ISO-2022-JP', $message);
+ $this->assertContains('Content-Type: text/html; charset=ISO-2022-JP', $message);
+
+ // ISO-2022-JP is 7bit
+ $this->assertTrue($this->_checkContentTransferEncoding($message, '7bit'));
+ }
+
+/**
+ * testReset method
+ *
+ * @return void
+ */
+ public function testReset() {
+ $this->CakeEmail->to('cake@cakephp.org');
+ $this->CakeEmail->theme('TestTheme');
+ $this->assertSame($this->CakeEmail->to(), array('cake@cakephp.org' => 'cake@cakephp.org'));
+
+ $this->CakeEmail->reset();
+ $this->assertSame($this->CakeEmail->to(), array());
+ $this->assertSame(null, $this->CakeEmail->theme());
+ }
+
+/**
+ * testReset with charset
+ *
+ * @return void
+ */
+ public function testResetWithCharset() {
+ $this->CakeEmail->charset = 'ISO-2022-JP';
+ $this->CakeEmail->reset();
+
+ $this->assertSame($this->CakeEmail->charset, 'utf-8', $this->CakeEmail->charset);
+ $this->assertSame($this->CakeEmail->headerCharset, null, $this->CakeEmail->headerCharset);
+ }
+
+/**
+ * testWrap method
+ *
+ * @return void
+ */
+ public function testWrap() {
+ $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
+ $result = $this->CakeEmail->wrap($text);
+ $expected = array(
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci,',
+ 'non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.',
+ ''
+ );
+ $this->assertSame($expected, $result);
+
+ $text = 'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan amet.';
+ $result = $this->CakeEmail->wrap($text);
+ $expected = array(
+ 'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis',
+ 'orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan',
+ 'amet.',
+ ''
+ );
+ $this->assertSame($expected, $result);
+
+ $text = '<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula pellentesque accumsan amet.<hr></p>';
+ $result = $this->CakeEmail->wrap($text);
+ $expected = array(
+ '<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac',
+ 'turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula',
+ 'pellentesque accumsan amet.<hr></p>',
+ ''
+ );
+ $this->assertSame($expected, $result);
+
+ $text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac <a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
+ $result = $this->CakeEmail->wrap($text);
+ $expected = array(
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac',
+ '<a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh',
+ 'nisi, vehicula pellentesque accumsan amet.',
+ ''
+ );
+ $this->assertSame($expected, $result);
+
+ $text = 'Lorem ipsum <a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">ok</a>';
+ $result = $this->CakeEmail->wrap($text);
+ $expected = array(
+ 'Lorem ipsum',
+ '<a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">',
+ 'ok</a>',
+ ''
+ );
+ $this->assertSame($expected, $result);
+
+ $text = 'Lorem ipsum withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite ok.';
+ $result = $this->CakeEmail->wrap($text);
+ $expected = array(
+ 'Lorem ipsum',
+ 'withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite',
+ 'ok.',
+ ''
+ );
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testConstructWithConfigArray method
+ *
+ * @return void
+ */
+ public function testConstructWithConfigArray() {
+ $configs = array(
+ 'from' => array('some@example.com' => 'My website'),
+ 'to' => 'test@example.com',
+ 'subject' => 'Test mail subject',
+ 'transport' => 'Debug',
+ );
+ $this->CakeEmail = new CakeEmail($configs);
+
+ $result = $this->CakeEmail->to();
+ $this->assertEquals(array($configs['to'] => $configs['to']), $result);
+
+ $result = $this->CakeEmail->from();
+ $this->assertEquals($configs['from'], $result);
+
+ $result = $this->CakeEmail->subject();
+ $this->assertEquals($configs['subject'], $result);
+
+ $result = $this->CakeEmail->transport();
+ $this->assertEquals($configs['transport'], $result);
+
+ $result = $this->CakeEmail->transportClass();
+ $this->assertTrue($result instanceof DebugTransport);
+
+ $result = $this->CakeEmail->send('This is the message');
+
+ $this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
+ $this->assertTrue((bool)strpos($result['headers'], 'To: '));
+ }
+
+/**
+ * testConstructWithConfigString method
+ *
+ * @return void
+ */
+ public function testConstructWithConfigString() {
+ $configs = new EmailConfig();
+ $this->CakeEmail = new CakeEmail('test');
+
+ $result = $this->CakeEmail->to();
+ $this->assertEquals($configs->test['to'], $result);
+
+ $result = $this->CakeEmail->from();
+ $this->assertEquals($configs->test['from'], $result);
+
+ $result = $this->CakeEmail->subject();
+ $this->assertEquals($configs->test['subject'], $result);
+
+ $result = $this->CakeEmail->transport();
+ $this->assertEquals($configs->test['transport'], $result);
+
+ $result = $this->CakeEmail->transportClass();
+ $this->assertTrue($result instanceof DebugTransport);
+
+ $result = $this->CakeEmail->send('This is the message');
+
+ $this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
+ $this->assertTrue((bool)strpos($result['headers'], 'To: '));
+ }
+
+/**
+ * testViewRender method
+ *
+ * @return void
+ */
+ public function testViewRender() {
+ $result = $this->CakeEmail->viewRender();
+ $this->assertEquals('View', $result);
+
+ $result = $this->CakeEmail->viewRender('Theme');
+ $this->assertInstanceOf('CakeEmail', $result);
+
+ $result = $this->CakeEmail->viewRender();
+ $this->assertEquals('Theme', $result);
+ }
+
+/**
+ * testEmailFormat method
+ *
+ * @return void
+ */
+ public function testEmailFormat() {
+ $result = $this->CakeEmail->emailFormat();
+ $this->assertEquals('text', $result);
+
+ $result = $this->CakeEmail->emailFormat('html');
+ $this->assertInstanceOf('CakeEmail', $result);
+
+ $result = $this->CakeEmail->emailFormat();
+ $this->assertEquals('html', $result);
+
+ $this->setExpectedException('SocketException');
+ $result = $this->CakeEmail->emailFormat('invalid');
+ }
+
+/**
+ * Tests that it is possible to add charset configuration to a CakeEmail object
+ *
+ * @return void
+ */
+ public function testConfigCharset() {
+ $email = new CakeEmail();
+ $this->assertEquals(Configure::read('App.encoding'), $email->charset);
+ $this->assertEquals(Configure::read('App.encoding'), $email->headerCharset);
+
+ $email = new CakeEmail(array('charset' => 'iso-2022-jp', 'headerCharset' => 'iso-2022-jp-ms'));
+ $this->assertEquals('iso-2022-jp', $email->charset);
+ $this->assertEquals('iso-2022-jp-ms', $email->headerCharset);
+
+ $email = new CakeEmail(array('charset' => 'iso-2022-jp'));
+ $this->assertEquals('iso-2022-jp', $email->charset);
+ $this->assertEquals('iso-2022-jp', $email->headerCharset);
+
+ $email = new CakeEmail(array('headerCharset' => 'iso-2022-jp-ms'));
+ $this->assertEquals(Configure::read('App.encoding'), $email->charset);
+ $this->assertEquals('iso-2022-jp-ms', $email->headerCharset);
+ }
+
+/**
+ * Tests that the header is encoded using the configured headerCharset
+ *
+ * @return void
+ */
+ public function testHeaderEncoding() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+ $email = new CakeEmail(array('headerCharset' => 'iso-2022-jp-ms', 'transport' => 'Debug'));
+ $email->subject('あれ?もしかしての前と');
+ $headers = $email->getHeaders(array('subject'));
+ $expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
+ $this->assertContains($expected, $headers['Subject']);
+
+ $email->to('someone@example.com')->from('someone@example.com');
+ $result = $email->send('ってテーブルを作ってやってたらう');
+ $this->assertContains('ってテーブルを作ってやってたらう', $result['message']);
+ }
+
+/**
+ * Tests that the body is encoded using the configured charset
+ *
+ * @return void
+ */
+ public function testBodyEncoding() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+ $email = new CakeEmail(array(
+ 'charset' => 'iso-2022-jp',
+ 'headerCharset' => 'iso-2022-jp-ms',
+ 'transport' => 'Debug'
+ ));
+ $email->subject('あれ?もしかしての前と');
+ $headers = $email->getHeaders(array('subject'));
+ $expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
+ $this->assertContains($expected, $headers['Subject']);
+
+ $email->to('someone@example.com')->from('someone@example.com');
+ $result = $email->send('ってテーブルを作ってやってたらう');
+ $this->assertContains('Content-Type: text/plain; charset=ISO-2022-JP', $result['headers']);
+ $this->assertContains(mb_convert_encoding('ってテーブルを作ってやってたらう','ISO-2022-JP'), $result['message']);
+ }
+
+/**
+ * Tests that the body is encoded using the configured charset (Japanese standard encoding)
+ *
+ * @return void
+ */
+ public function testBodyEncodingIso2022Jp() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+ $email = new CakeEmail(array(
+ 'charset' => 'iso-2022-jp',
+ 'headerCharset' => 'iso-2022-jp',
+ 'transport' => 'Debug'
+ ));
+ $email->subject('あれ?もしかしての前と');
+ $headers = $email->getHeaders(array('subject'));
+ $expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
+ $this->assertContains($expected, $headers['Subject']);
+
+ $email->to('someone@example.com')->from('someone@example.com');
+ $result = $email->send('①㈱');
+ $this->assertTextContains("Content-Type: text/plain; charset=ISO-2022-JP", $result['headers']);
+ $this->assertTextNotContains("Content-Type: text/plain; charset=ISO-2022-JP-MS", $result['headers']); // not charset=iso-2022-jp-ms
+ $this->assertTextNotContains(mb_convert_encoding('①㈱','ISO-2022-JP-MS'), $result['message']);
+ }
+
+/**
+ * Tests that the body is encoded using the configured charset (Japanese irregular encoding, but sometime use this)
+ *
+ * @return void
+ */
+ public function testBodyEncodingIso2022JpMs() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+ $email = new CakeEmail(array(
+ 'charset' => 'iso-2022-jp-ms',
+ 'headerCharset' => 'iso-2022-jp-ms',
+ 'transport' => 'Debug'
+ ));
+ $email->subject('あれ?もしかしての前と');
+ $headers = $email->getHeaders(array('subject'));
+ $expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
+ $this->assertContains($expected, $headers['Subject']);
+
+ $email->to('someone@example.com')->from('someone@example.com');
+ $result = $email->send('①㈱');
+ $this->assertTextContains("Content-Type: text/plain; charset=ISO-2022-JP", $result['headers']);
+ $this->assertTextNotContains("Content-Type: text/plain; charset=iso-2022-jp-ms", $result['headers']); // not charset=iso-2022-jp-ms
+ $this->assertContains(mb_convert_encoding('①㈱','ISO-2022-JP-MS'), $result['message']);
+ }
+
+ protected function _checkContentTransferEncoding($message, $charset) {
+ $boundary = '--alt-' . $this->CakeEmail->getBoundary();
+ $result['text'] = false;
+ $result['html'] = false;
+ $length = count($message);
+ for ($i = 0; $i < $length; ++$i) {
+ if ($message[$i] == $boundary) {
+ $flag = false;
+ $type = '';
+ while (!preg_match('/^$/', $message[$i])) {
+ if (preg_match('/^Content-Type: text\/plain/', $message[$i])) {
+ $type = 'text';
+ }
+ if (preg_match('/^Content-Type: text\/html/', $message[$i])) {
+ $type = 'html';
+ }
+ if ($message[$i] === 'Content-Transfer-Encoding: ' . $charset) {
+ $flag = true;
+ }
+ ++$i;
+ }
+ $result[$type] = $flag;
+ }
+ }
+ return $result['text'] && $result['html'];
+ }
+
+/**
+ * Test CakeEmail::_encode function
+ *
+ * @return void
+ */
+ public function testEncode() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+
+ $this->CakeEmail->headerCharset = 'ISO-2022-JP';
+ $result = $this->CakeEmail->encode('日本語');
+ $expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=';
+ $this->assertSame($expected, $result);
+
+ $this->CakeEmail->headerCharset = 'ISO-2022-JP';
+ $result = $this->CakeEmail->encode('長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?');
+ $expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
+ " =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
+ " =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=";
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * Tests charset setter/getter
+ *
+ * @return void
+ */
+ public function testCharset() {
+ $this->CakeEmail->charset('UTF-8');
+ $this->assertSame($this->CakeEmail->charset(), 'UTF-8');
+
+ $this->CakeEmail->charset('ISO-2022-JP');
+ $this->assertSame($this->CakeEmail->charset(), 'ISO-2022-JP');
+
+ $charset = $this->CakeEmail->charset('Shift_JIS');
+ $this->assertSame($charset, 'Shift_JIS');
+ }
+
+/**
+ * Tests headerCharset setter/getter
+ *
+ * @return void
+ */
+ public function testHeaderCharset() {
+ $this->CakeEmail->headerCharset('UTF-8');
+ $this->assertSame($this->CakeEmail->headerCharset(), 'UTF-8');
+
+ $this->CakeEmail->headerCharset('ISO-2022-JP');
+ $this->assertSame($this->CakeEmail->headerCharset(), 'ISO-2022-JP');
+
+ $charset = $this->CakeEmail->headerCharset('Shift_JIS');
+ $this->assertSame($charset, 'Shift_JIS');
+ }
+
+/**
+ * Tests for compatible check.
+ * charset property and charset() method.
+ * headerCharset property and headerCharset() method.
+ */
+ public function testCharsetsCompatible() {
+ $this->skipIf(!function_exists('mb_convert_encoding'));
+
+ $checkHeaders = array(
+ 'from' => true,
+ 'to' => true,
+ 'cc' => true,
+ 'subject' => true,
+ );
+
+ // Header Charset : null (used by default UTF-8)
+ // Body Charset : ISO-2022-JP
+ $oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', null);
+ $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);
+
+ $newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', null);
+ $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);
+
+ $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
+ $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
+ $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
+ $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
+
+ // Header Charset : UTF-8
+ // Boby Charset : ISO-2022-JP
+ $oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', 'utf-8');
+ $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);
+
+ $newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', 'utf-8');
+ $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);
+
+ $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
+ $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
+ $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
+ $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
+
+ // Header Charset : ISO-2022-JP
+ // Boby Charset : UTF-8
+ $oldStyleEmail = $this->_getEmailByOldStyleCharset('utf-8', 'iso-2022-jp');
+ $oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);
+
+ $newStyleEmail = $this->_getEmailByNewStyleCharset('utf-8', 'iso-2022-jp');
+ $newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);
+
+ $this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
+ $this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
+ $this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
+ $this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
+ }
+
+ protected function _getEmailByOldStyleCharset($charset, $headerCharset) {
+ $email = new CakeEmail(array('transport' => 'Debug'));
+
+ if (! empty($charset)) {
+ $email->charset = $charset;
+ }
+ if (! empty($headerCharset)) {
+ $email->headerCharset = $headerCharset;
+ }
+
+ $email->from('someone@example.com', 'どこかの誰か');
+ $email->to('someperson@example.jp', 'どこかのどなたか');
+ $email->cc('miku@example.net', 'ミク');
+ $email->subject('テストメール');
+ $email->send('テストメールの本文');
+
+ return $email;
+ }
+
+ protected function _getEmailByNewStyleCharset($charset, $headerCharset) {
+ $email = new CakeEmail(array('transport' => 'Debug'));
+
+ if (! empty($charset)) {
+ $email->charset($charset);
+ }
+ if (! empty($headerCharset)) {
+ $email->headerCharset($headerCharset);
+ }
+
+ $email->from('someone@example.com', 'どこかの誰か');
+ $email->to('someperson@example.jp', 'どこかのどなたか');
+ $email->cc('miku@example.net', 'ミク');
+ $email->subject('テストメール');
+ $email->send('テストメールの本文');
+
+ return $email;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php
new file mode 100644
index 0000000..11512fd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/DebugTransportTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * DebugTransportTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeEmail', 'Network/Email');
+App::uses('AbstractTransport', 'Network/Email');
+App::uses('DebugTransport', 'Network/Email');
+
+/**
+ * Test case
+ *
+ */
+class DebugTransportTest extends CakeTestCase {
+
+/**
+ * Setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ $this->DebugTransport = new DebugTransport();
+ }
+
+/**
+ * testSend method
+ *
+ * @return void
+ */
+ public function testSend() {
+ $this->getMock('CakeEmail', array('message'), array(), 'DebugCakeEmail');
+ $email = new DebugCakeEmail();
+ $email->from('noreply@cakephp.org', 'CakePHP Test');
+ $email->to('cake@cakephp.org', 'CakePHP');
+ $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
+ $email->bcc('phpnut@cakephp.org');
+ $email->messageID('<4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>');
+ $email->subject('Testing Message');
+ $date = date(DATE_RFC2822);
+ $email->setHeaders(array('X-Mailer' => DebugCakeEmail::EMAIL_CLIENT, 'Date' => $date));
+ $email->expects($this->any())->method('message')->will($this->returnValue(array('First Line', 'Second Line', '.Third Line', '')));
+
+ $headers = "From: CakePHP Test <noreply@cakephp.org>\r\n";
+ $headers .= "To: CakePHP <cake@cakephp.org>\r\n";
+ $headers .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
+ $headers .= "X-Mailer: CakePHP Email\r\n";
+ $headers .= "Date: " . $date . "\r\n";
+ $headers .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n";
+ $headers .= "Subject: Testing Message\r\n";
+ $headers .= "MIME-Version: 1.0\r\n";
+ $headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
+ $headers .= "Content-Transfer-Encoding: 8bit";
+
+ $data = "First Line\r\n";
+ $data .= "Second Line\r\n";
+ $data .= ".Third Line\r\n"; // Not use 'RFC5321 4.5.2.Transparency' in DebugTransport.
+
+ $result = $this->DebugTransport->send($email);
+
+ $this->assertEquals($headers, $result['headers']);
+ $this->assertEquals($data, $result['message']);
+ }
+
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php
new file mode 100644
index 0000000..0310e53
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * SmtpTransportTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network.Email
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeEmail', 'Network/Email');
+App::uses('AbstractTransport', 'Network/Email');
+App::uses('SmtpTransport', 'Network/Email');
+
+/**
+ * Help to test SmtpTransport
+ *
+ */
+class SmtpTestTransport extends SmtpTransport {
+
+/**
+ * Helper to change the socket
+ *
+ * @param object $socket
+ * @return void
+ */
+ public function setSocket(CakeSocket $socket) {
+ $this->_socket = $socket;
+ }
+
+/**
+ * Helper to change the CakeEmail
+ *
+ * @param object $cakeEmail
+ * @return void
+ */
+ public function setCakeEmail($cakeEmail) {
+ $this->_cakeEmail = $cakeEmail;
+ }
+
+/**
+ * Disabled the socket change
+ *
+ * @return void
+ */
+ protected function _generateSocket() {
+ }
+
+/**
+ * Magic function to call protected methods
+ *
+ * @param string $method
+ * @param string $args
+ * @return mixed
+ */
+ public function __call($method, $args) {
+ $method = '_' . $method;
+ return $this->$method();
+ }
+
+}
+
+/**
+ * Test case
+ *
+ */
+class SmtpTransportTest extends CakeTestCase {
+
+/**
+ * Setup
+ *
+ * @return void
+ */
+ public function setUp() {
+ if (!class_exists('MockSocket')) {
+ $this->getMock('CakeSocket', array('read', 'write', 'connect'), array(), 'MockSocket');
+ }
+ $this->socket = new MockSocket();
+
+ $this->SmtpTransport = new SmtpTestTransport();
+ $this->SmtpTransport->setSocket($this->socket);
+ $this->SmtpTransport->config(array('client' => 'localhost'));
+ }
+
+/**
+ * testConnectEhlo method
+ *
+ * @return void
+ */
+ public function testConnectEhlo() {
+ $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
+ $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
+ $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
+ $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("250 Accepted\r\n"));
+ $this->SmtpTransport->connect();
+ }
+
+/**
+ * testConnectHelo method
+ *
+ * @return void
+ */
+ public function testConnectHelo() {
+ $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
+ $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
+ $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
+ $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
+ $this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n");
+ $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("250 Accepted\r\n"));
+ $this->SmtpTransport->connect();
+ }
+
+/**
+ * testConnectFail method
+ *
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testConnectFail() {
+ $this->socket->expects($this->any())->method('connect')->will($this->returnValue(true));
+ $this->socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
+ $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
+ $this->socket->expects($this->at(3))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(4))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
+ $this->socket->expects($this->at(5))->method('write')->with("HELO localhost\r\n");
+ $this->socket->expects($this->at(6))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(7))->method('read')->will($this->returnValue("200 Not Accepted\r\n"));
+ $this->SmtpTransport->connect();
+ }
+
+/**
+ * testAuth method
+ *
+ * @return void
+ */
+ public function testAuth() {
+ $this->socket->expects($this->at(0))->method('write')->with("AUTH LOGIN\r\n");
+ $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("334 Login\r\n"));
+ $this->socket->expects($this->at(3))->method('write')->with("bWFyaw==\r\n");
+ $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("334 Pass\r\n"));
+ $this->socket->expects($this->at(6))->method('write')->with("c3Rvcnk=\r\n");
+ $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("235 OK\r\n"));
+ $this->SmtpTransport->config(array('username' => 'mark', 'password' => 'story'));
+ $this->SmtpTransport->auth();
+ }
+
+/**
+ * testAuthNoAuth method
+ *
+ * @return void
+ */
+ public function testAuthNoAuth() {
+ $this->socket->expects($this->never())->method('write')->with("AUTH LOGIN\r\n");
+ $this->SmtpTransport->config(array('username' => null, 'password' => null));
+ $this->SmtpTransport->auth();
+ }
+
+/**
+ * testRcpt method
+ *
+ * @return void
+ */
+ public function testRcpt() {
+ $email = new CakeEmail();
+ $email->from('noreply@cakephp.org', 'CakePHP Test');
+ $email->to('cake@cakephp.org', 'CakePHP');
+ $email->bcc('phpnut@cakephp.org');
+ $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
+
+ $this->socket->expects($this->at(0))->method('write')->with("MAIL FROM:<noreply@cakephp.org>\r\n");
+ $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("250 OK\r\n"));
+ $this->socket->expects($this->at(3))->method('write')->with("RCPT TO:<cake@cakephp.org>\r\n");
+ $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
+ $this->socket->expects($this->at(6))->method('write')->with("RCPT TO:<mark@cakephp.org>\r\n");
+ $this->socket->expects($this->at(7))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(8))->method('read')->will($this->returnValue("250 OK\r\n"));
+ $this->socket->expects($this->at(9))->method('write')->with("RCPT TO:<juan@cakephp.org>\r\n");
+ $this->socket->expects($this->at(10))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(11))->method('read')->will($this->returnValue("250 OK\r\n"));
+ $this->socket->expects($this->at(12))->method('write')->with("RCPT TO:<phpnut@cakephp.org>\r\n");
+ $this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(14))->method('read')->will($this->returnValue("250 OK\r\n"));
+
+ $this->SmtpTransport->setCakeEmail($email);
+ $this->SmtpTransport->sendRcpt();
+ }
+
+/**
+ * testSendData method
+ *
+ * @return void
+ */
+ public function testSendData() {
+ $this->getMock('CakeEmail', array('message'), array(), 'SmtpCakeEmail');
+ $email = new SmtpCakeEmail();
+ $email->from('noreply@cakephp.org', 'CakePHP Test');
+ $email->returnPath('pleasereply@cakephp.org', 'CakePHP Return');
+ $email->to('cake@cakephp.org', 'CakePHP');
+ $email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
+ $email->bcc('phpnut@cakephp.org');
+ $email->messageID('<4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>');
+ $email->subject('Testing SMTP');
+ $date = date(DATE_RFC2822);
+ $email->setHeaders(array('X-Mailer' => SmtpCakeEmail::EMAIL_CLIENT, 'Date' => $date));
+ $email->expects($this->any())->method('message')->will($this->returnValue(array('First Line', 'Second Line', '.Third Line', '')));
+
+ $data = "From: CakePHP Test <noreply@cakephp.org>\r\n";
+ $data .= "Return-Path: CakePHP Return <pleasereply@cakephp.org>\r\n";
+ $data .= "To: CakePHP <cake@cakephp.org>\r\n";
+ $data .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
+ $data .= "X-Mailer: CakePHP Email\r\n";
+ $data .= "Date: " . $date . "\r\n";
+ $data .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n";
+ $data .= "Subject: Testing SMTP\r\n";
+ $data .= "MIME-Version: 1.0\r\n";
+ $data .= "Content-Type: text/plain; charset=UTF-8\r\n";
+ $data .= "Content-Transfer-Encoding: 8bit\r\n";
+ $data .= "\r\n";
+ $data .= "First Line\r\n";
+ $data .= "Second Line\r\n";
+ $data .= "..Third Line\r\n"; // RFC5321 4.5.2.Transparency
+ $data .= "\r\n";
+ $data .= "\r\n\r\n.\r\n";
+
+ $this->socket->expects($this->at(0))->method('write')->with("DATA\r\n");
+ $this->socket->expects($this->at(1))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(2))->method('read')->will($this->returnValue("354 OK\r\n"));
+ $this->socket->expects($this->at(3))->method('write')->with($data);
+ $this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
+ $this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
+
+ $this->SmtpTransport->setCakeEmail($email);
+ $this->SmtpTransport->sendData();
+ }
+
+/**
+ * testQuit method
+ *
+ * @return void
+ */
+ public function testQuit() {
+ $this->socket->expects($this->at(0))->method('write')->with("QUIT\r\n");
+ $this->SmtpTransport->disconnect();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/BasicAuthenticationTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/BasicAuthenticationTest.php
new file mode 100644
index 0000000..6ea7789
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/BasicAuthenticationTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * BasicAuthenticationTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network.Http
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HttpSocket', 'Network/Http');
+App::uses('BasicAuthentication', 'Network/Http');
+
+/**
+ * BasicMethodTest class
+ *
+ * @package Cake.Test.Case.Network.Http
+ */
+class BasicAuthenticationTest extends CakeTestCase {
+
+/**
+ * testAuthentication method
+ *
+ * @return void
+ */
+ public function testAuthentication() {
+ $http = new HttpSocket();
+ $auth = array(
+ 'method' => 'Basic',
+ 'user' => 'mark',
+ 'pass' => 'secret'
+ );
+
+ BasicAuthentication::authentication($http, $auth);
+ $this->assertEquals('Basic bWFyazpzZWNyZXQ=', $http->request['header']['Authorization']);
+ }
+
+/**
+ * testProxyAuthentication method
+ *
+ * @return void
+ */
+ public function testProxyAuthentication() {
+ $http = new HttpSocket();
+ $proxy = array(
+ 'method' => 'Basic',
+ 'user' => 'mark',
+ 'pass' => 'secret'
+ );
+
+ BasicAuthentication::proxyAuthentication($http, $proxy);
+ $this->assertEquals('Basic bWFyazpzZWNyZXQ=', $http->request['header']['Proxy-Authorization']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/DigestAuthenticationTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/DigestAuthenticationTest.php
new file mode 100644
index 0000000..a03a536
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/DigestAuthenticationTest.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * DigestAuthenticationTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network.Http
+ * @since CakePHP(tm) v 2.0.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HttpSocket', 'Network/Http');
+App::uses('DigestAuthentication', 'Network/Http');
+
+class DigestHttpSocket extends HttpSocket {
+
+/**
+ * nextHeader attribute
+ *
+ * @var string
+ */
+ public $nextHeader = '';
+
+/**
+ * request method
+ *
+ * @param mixed $request
+ * @return void
+ */
+ public function request($request = array()) {
+ if ($request === false) {
+ if (isset($this->response['header']['WWW-Authenticate'])) {
+ unset($this->response['header']['WWW-Authenticate']);
+ }
+ return;
+ }
+ $this->response['header']['WWW-Authenticate'] = $this->nextHeader;
+ }
+
+}
+
+/**
+ * DigestAuthenticationTest class
+ *
+ * @package Cake.Test.Case.Network.Http
+ */
+class DigestAuthenticationTest extends CakeTestCase {
+
+/**
+ * Socket property
+ *
+ * @var mixed null
+ */
+ public $HttpSocket = null;
+
+/**
+ * This function sets up a HttpSocket instance we are going to use for testing
+ *
+ * @return void
+ */
+ public function setUp() {
+ $this->HttpSocket = new DigestHttpSocket();
+ $this->HttpSocket->request['method'] = 'GET';
+ $this->HttpSocket->request['uri']['path'] = '/';
+ }
+
+/**
+ * We use this function to clean up after the test case was executed
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->HttpSocket);
+ }
+
+/**
+ * testBasic method
+ *
+ * @return void
+ */
+ public function testBasic() {
+ $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
+ $this->assertFalse(isset($this->HttpSocket->request['header']['Authorization']));
+
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $this->assertTrue(isset($this->HttpSocket->request['header']['Authorization']));
+ $this->assertEquals('The batcave', $auth['realm']);
+ $this->assertEquals('4cded326c6c51', $auth['nonce']);
+ }
+
+/**
+ * testQop method
+ *
+ * @return void
+ */
+ public function testQop() {
+ $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $expected = 'Digest username="admin", realm="The batcave", nonce="4cded326c6c51", uri="/", response="da7e2a46b471d77f70a9bb3698c8902b"';
+ $this->assertEquals($expected, $this->HttpSocket->request['header']['Authorization']);
+ $this->assertFalse(isset($auth['qop']));
+ $this->assertFalse(isset($auth['nc']));
+
+ $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",qop="auth"';
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $expected = '@Digest username="admin", realm="The batcave", nonce="4cded326c6c51", uri="/", response="[a-z0-9]{32}", qop="auth", nc=00000001, cnonce="[a-z0-9]+"@';
+ $this->assertRegExp($expected, $this->HttpSocket->request['header']['Authorization']);
+ $this->assertEquals('auth', $auth['qop']);
+ $this->assertEquals(2, $auth['nc']);
+ }
+
+/**
+ * testOpaque method
+ *
+ * @return void
+ */
+ public function testOpaque() {
+ $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $this->assertFalse(strpos($this->HttpSocket->request['header']['Authorization'], 'opaque="d8ea7aa61a1693024c4cc3a516f49b3c"'));
+
+ $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",opaque="d8ea7aa61a1693024c4cc3a516f49b3c"';
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'opaque="d8ea7aa61a1693024c4cc3a516f49b3c"') > 0);
+ }
+
+/**
+ * testMultipleRequest method
+ *
+ * @return void
+ */
+ public function testMultipleRequest() {
+ $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",qop="auth"';
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000001') > 0);
+ $this->assertEquals(2, $auth['nc']);
+
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000002') > 0);
+ $this->assertEquals(3, $auth['nc']);
+ $responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response=');
+ $response = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32);
+
+ $this->HttpSocket->nextHeader = '';
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000003') > 0);
+ $this->assertEquals(4, $auth['nc']);
+ $responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response=');
+ $responseB = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32);
+ $this->assertNotEquals($response, $responseB);
+ }
+
+/**
+ * testPathChanged method
+ *
+ * @return void
+ */
+ public function testPathChanged() {
+ $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"';
+ $this->HttpSocket->request['uri']['path'] = '/admin';
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response=');
+ $response = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32);
+ $this->assertNotEquals('da7e2a46b471d77f70a9bb3698c8902b', $response);
+ }
+
+/**
+ * testNoDigestResponse method
+ *
+ * @return void
+ */
+ public function testNoDigestResponse() {
+ $this->HttpSocket->nextHeader = false;
+ $this->HttpSocket->request['uri']['path'] = '/admin';
+ $auth = array('user' => 'admin', 'pass' => '1234');
+ DigestAuthentication::authentication($this->HttpSocket, $auth);
+ $this->assertFalse(isset($this->HttpSocket->request['header']['Authorization']));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php
new file mode 100644
index 0000000..2f98098
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpResponseTest.php
@@ -0,0 +1,558 @@
+<?php
+/**
+ * HttpResponseTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network.Http
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HttpResponse', 'Network/Http');
+
+/**
+ * TestHttpResponse class
+ *
+ * @package Cake.Test.Case.Network.Http
+ */
+class TestHttpResponse extends HttpResponse {
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param array $header Header as an indexed array (field => value)
+ * @return array Parsed header
+ */
+ public function parseHeader($header) {
+ return parent::_parseHeader($header);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param string $body A string containing the body to decode
+ * @param boolean|string $encoding Can be false in case no encoding is being used, or a string representing the encoding
+ * @return mixed Array or false
+ */
+ public function decodeBody($body, $encoding = 'chunked') {
+ return parent::_decodeBody($body, $encoding);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param string $body A string containing the chunked body to decode
+ * @return mixed Array or false
+ */
+ public function decodeChunkedBody($body) {
+ return parent::_decodeChunkedBody($body);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param string $token Token to unescape
+ * @return string Unescaped token
+ */
+ public function unescapeToken($token, $chars = null) {
+ return parent::_unescapeToken($token, $chars);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param boolean $hex true to get them as HEX values, false otherwise
+ * @return array Escape chars
+ */
+ public function tokenEscapeChars($hex = true, $chars = null) {
+ return parent::_tokenEscapeChars($hex, $chars);
+ }
+
+}
+
+/**
+ * HttpResponseTest class
+ *
+ * @package Cake.Test.Case.Network.Http
+ */
+class HttpResponseTest extends CakeTestCase {
+
+/**
+ * This function sets up a HttpResponse
+ *
+ * @return void
+ */
+ public function setUp() {
+ $this->HttpResponse = new TestHttpResponse();
+ }
+
+/**
+ * testBody
+ *
+ * @return void
+ */
+ public function testBody() {
+ $this->HttpResponse->body = 'testing';
+ $this->assertEquals('testing', $this->HttpResponse->body());
+
+ $this->HttpResponse->body = null;
+ $this->assertSame($this->HttpResponse->body(), '');
+ }
+
+/**
+ * testToString
+ *
+ * @return void
+ */
+ public function testToString() {
+ $this->HttpResponse->body = 'other test';
+ $this->assertEquals('other test', $this->HttpResponse->body());
+ $this->assertEquals('other test', (string)$this->HttpResponse);
+ $this->assertTrue(strpos($this->HttpResponse, 'test') > 0);
+
+ $this->HttpResponse->body = null;
+ $this->assertEquals('', (string)$this->HttpResponse);
+ }
+
+/**
+ * testGetHeader
+ *
+ * @return void
+ */
+ public function testGetHeader() {
+ $this->HttpResponse->headers = array(
+ 'foo' => 'Bar',
+ 'Some' => 'ok',
+ 'HeAdEr' => 'value',
+ 'content-Type' => 'text/plain'
+ );
+
+ $this->assertEquals('Bar', $this->HttpResponse->getHeader('foo'));
+ $this->assertEquals('Bar', $this->HttpResponse->getHeader('Foo'));
+ $this->assertEquals('Bar', $this->HttpResponse->getHeader('FOO'));
+ $this->assertEquals('value', $this->HttpResponse->getHeader('header'));
+ $this->assertEquals('text/plain', $this->HttpResponse->getHeader('Content-Type'));
+ $this->assertSame($this->HttpResponse->getHeader(0), null);
+
+ $this->assertEquals('Bar', $this->HttpResponse->getHeader('foo', false));
+ $this->assertEquals('not from class', $this->HttpResponse->getHeader('foo', array('foo' => 'not from class')));
+ }
+
+/**
+ * testIsOk
+ *
+ * @return void
+ */
+ public function testIsOk() {
+ $this->HttpResponse->code = 0;
+ $this->assertFalse($this->HttpResponse->isOk());
+ $this->HttpResponse->code = -1;
+ $this->assertFalse($this->HttpResponse->isOk());
+ $this->HttpResponse->code = 201;
+ $this->assertFalse($this->HttpResponse->isOk());
+ $this->HttpResponse->code = 'what?';
+ $this->assertFalse($this->HttpResponse->isOk());
+ $this->HttpResponse->code = 200;
+ $this->assertTrue($this->HttpResponse->isOk());
+ }
+
+/**
+ * testIsRedirect
+ *
+ * @return void
+ */
+ public function testIsRedirect() {
+ $this->HttpResponse->code = 0;
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = -1;
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 201;
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 'what?';
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 301;
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 302;
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 303;
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 307;
+ $this->assertFalse($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 301;
+ $this->HttpResponse->headers['Location'] = 'http://somewhere/';
+ $this->assertTrue($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 302;
+ $this->HttpResponse->headers['Location'] = 'http://somewhere/';
+ $this->assertTrue($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 303;
+ $this->HttpResponse->headers['Location'] = 'http://somewhere/';
+ $this->assertTrue($this->HttpResponse->isRedirect());
+ $this->HttpResponse->code = 307;
+ $this->HttpResponse->headers['Location'] = 'http://somewhere/';
+ $this->assertTrue($this->HttpResponse->isRedirect());
+ }
+
+/**
+ * Test that HttpSocket::parseHeader can take apart a given (and valid) $header string and turn it into an array.
+ *
+ * @return void
+ */
+ public function testParseHeader() {
+ $r = $this->HttpResponse->parseHeader(array('foo' => 'Bar', 'fOO-bAr' => 'quux'));
+ $this->assertEquals(array('foo' => 'Bar', 'fOO-bAr' => 'quux'), $r);
+
+ $r = $this->HttpResponse->parseHeader(true);
+ $this->assertEquals(false, $r);
+
+ $header = "Host: cakephp.org\t\r\n";
+ $r = $this->HttpResponse->parseHeader($header);
+ $expected = array(
+ 'Host' => 'cakephp.org'
+ );
+ $this->assertEquals($expected, $r);
+
+ $header = "Date:Sat, 07 Apr 2007 10:10:25 GMT\r\nX-Powered-By: PHP/5.1.2\r\n";
+ $r = $this->HttpResponse->parseHeader($header);
+ $expected = array(
+ 'Date' => 'Sat, 07 Apr 2007 10:10:25 GMT',
+ 'X-Powered-By' => 'PHP/5.1.2'
+ );
+ $this->assertEquals($expected, $r);
+
+ $header = "people: Jim,John\r\nfoo-LAND: Bar\r\ncAKe-PHP: rocks\r\n";
+ $r = $this->HttpResponse->parseHeader($header);
+ $expected = array(
+ 'people' => 'Jim,John',
+ 'foo-LAND' => 'Bar',
+ 'cAKe-PHP' => 'rocks'
+ );
+ $this->assertEquals($expected, $r);
+
+ $header = "People: Jim,John,Tim\r\nPeople: Lisa,Tina,Chelsea\r\n";
+ $r = $this->HttpResponse->parseHeader($header);
+ $expected = array(
+ 'People' => array('Jim,John,Tim', 'Lisa,Tina,Chelsea')
+ );
+ $this->assertEquals($expected, $r);
+
+ $header = "Multi-Line: I am a \r\nmulti line\t\r\nfield value.\r\nSingle-Line: I am not\r\n";
+ $r = $this->HttpResponse->parseHeader($header);
+ $expected = array(
+ 'Multi-Line' => "I am a\r\nmulti line\r\nfield value.",
+ 'Single-Line' => 'I am not'
+ );
+ $this->assertEquals($expected, $r);
+
+ $header = "Esc\"@\"ped: value\r\n";
+ $r = $this->HttpResponse->parseHeader($header);
+ $expected = array(
+ 'Esc@ped' => 'value'
+ );
+ $this->assertEquals($expected, $r);
+ }
+
+/**
+ * testParseResponse method
+ *
+ * @return void
+ */
+ public function testParseResponse() {
+ $tests = array(
+ 'simple-request' => array(
+ 'response' => array(
+ 'status-line' => "HTTP/1.x 200 OK\r\n",
+ 'header' => "Date: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\n",
+ 'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
+ ),
+ 'expectations' => array(
+ 'httpVersion' => 'HTTP/1.x',
+ 'code' => 200,
+ 'reasonPhrase' => 'OK',
+ 'headers' => array('Date' => 'Mon, 16 Apr 2007 04:14:16 GMT', 'Server' => 'CakeHttp Server'),
+ 'body' => "<h1>Hello World</h1>\r\n<p>It's good to be html</p>"
+ )
+ ),
+ 'no-header' => array(
+ 'response' => array(
+ 'status-line' => "HTTP/1.x 404 OK\r\n",
+ 'header' => null
+ ),
+ 'expectations' => array(
+ 'code' => 404,
+ 'headers' => array()
+ )
+ )
+ );
+
+ $testResponse = array();
+ $expectations = array();
+
+ foreach ($tests as $name => $test) {
+ $testResponse = array_merge($testResponse, $test['response']);
+ $testResponse['response'] = $testResponse['status-line'] . $testResponse['header'] . "\r\n" . $testResponse['body'];
+ $this->HttpResponse->parseResponse($testResponse['response']);
+ $expectations = array_merge($expectations, $test['expectations']);
+
+ foreach ($expectations as $property => $expectedVal) {
+ $this->assertEquals($expectedVal, $this->HttpResponse->{$property}, 'Test "' . $name . '": response.' . $property . ' - %s');
+ }
+
+ foreach (array('status-line', 'header', 'body', 'response') as $field) {
+ $this->assertEquals($this->HttpResponse['raw'][$field], $testResponse[$field], 'Test response.raw.' . $field . ': %s');
+ }
+ }
+ }
+
+/**
+ * data provider function for testInvalidParseResponseData
+ *
+ * @return array
+ */
+ public static function invalidParseResponseDataProvider() {
+ return array(
+ array(array('foo' => 'bar')),
+ array(true),
+ array("HTTP Foo\r\nBar: La"),
+ array('HTTP/1.1 TEST ERROR')
+ );
+ }
+
+/**
+ * testInvalidParseResponseData
+ *
+ * @dataProvider invalidParseResponseDataProvider
+ * @expectedException SocketException
+ * return void
+ */
+ public function testInvalidParseResponseData($value) {
+ $this->HttpResponse->parseResponse($value);
+ }
+
+/**
+ * testDecodeBody method
+ *
+ * @return void
+ */
+ public function testDecodeBody() {
+ $r = $this->HttpResponse->decodeBody(true);
+ $this->assertEquals(false, $r);
+
+ $r = $this->HttpResponse->decodeBody('Foobar', false);
+ $this->assertEquals(array('body' => 'Foobar', 'header' => false), $r);
+
+ $encoding = 'chunked';
+ $sample = array(
+ 'encoded' => "19\r\nThis is a chunked message\r\n0\r\n",
+ 'decoded' => array('body' => "This is a chunked message", 'header' => false)
+ );
+
+ $r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
+ $this->assertEquals($r, $sample['decoded']);
+
+ $encoding = 'chunked';
+ $sample = array(
+ 'encoded' => "19\nThis is a chunked message\r\n0\n",
+ 'decoded' => array('body' => "This is a chunked message", 'header' => false)
+ );
+
+ $r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
+ $this->assertEquals($r, $sample['decoded'], 'Inconsistent line terminators should be tolerated.');
+ }
+
+/**
+ * testDecodeFooCoded
+ *
+ * @return void
+ */
+ public function testDecodeFooCoded() {
+ $r = $this->HttpResponse->decodeBody(true);
+ $this->assertEquals(false, $r);
+
+ $r = $this->HttpResponse->decodeBody('Foobar', false);
+ $this->assertEquals(array('body' => 'Foobar', 'header' => false), $r);
+
+ $encoding = 'foo-bar';
+ $sample = array(
+ 'encoded' => '!Foobar!',
+ 'decoded' => array('body' => '!Foobar!', 'header' => false),
+ );
+
+ $r = $this->HttpResponse->decodeBody($sample['encoded'], $encoding);
+ $this->assertEquals($r, $sample['decoded']);
+ }
+
+/**
+ * testDecodeChunkedBody method
+ *
+ * @return void
+ */
+ public function testDecodeChunkedBody() {
+ $r = $this->HttpResponse->decodeChunkedBody(true);
+ $this->assertEquals(false, $r);
+
+ $encoded = "19\r\nThis is a chunked message\r\n0\r\n";
+ $decoded = "This is a chunked message";
+ $r = $this->HttpResponse->decodeChunkedBody($encoded);
+ $this->assertEquals($r['body'], $decoded);
+ $this->assertEquals(false, $r['header']);
+
+ $encoded = "19 \r\nThis is a chunked message\r\n0\r\n";
+ $r = $this->HttpResponse->decodeChunkedBody($encoded);
+ $this->assertEquals($r['body'], $decoded);
+
+ $encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\n";
+ $decoded = "This is a chunked message\nThat is cool\n";
+ $r = $this->HttpResponse->decodeChunkedBody($encoded);
+ $this->assertEquals($r['body'], $decoded);
+ $this->assertEquals(false, $r['header']);
+
+ $encoded = "19\r\nThis is a chunked message\r\nE;foo-chunk=5\r\n\nThat is cool\n\r\n0\r\n";
+ $r = $this->HttpResponse->decodeChunkedBody($encoded);
+ $this->assertEquals($r['body'], $decoded);
+ $this->assertEquals(false, $r['header']);
+
+ $encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n0\r\nfoo-header: bar\r\ncake: PHP\r\n\r\n";
+ $r = $this->HttpResponse->decodeChunkedBody($encoded);
+ $this->assertEquals($r['body'], $decoded);
+ $this->assertEquals(array('foo-header' => 'bar', 'cake' => 'PHP'), $r['header']);
+ }
+
+/**
+ * testDecodeChunkedBodyError method
+ *
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testDecodeChunkedBodyError() {
+ $encoded = "19\r\nThis is a chunked message\r\nE\r\n\nThat is cool\n\r\n";
+ $r = $this->HttpResponse->decodeChunkedBody($encoded);
+ }
+
+/**
+ * testParseCookies method
+ *
+ * @return void
+ */
+ public function testParseCookies() {
+ $header = array(
+ 'Set-Cookie' => array(
+ 'foo=bar',
+ 'people=jim,jack,johnny";";Path=/accounts',
+ 'google=not=nice'
+ ),
+ 'Transfer-Encoding' => 'chunked',
+ 'Date' => 'Sun, 18 Nov 2007 18:57:42 GMT',
+ );
+ $cookies = $this->HttpResponse->parseCookies($header);
+ $expected = array(
+ 'foo' => array(
+ 'value' => 'bar'
+ ),
+ 'people' => array(
+ 'value' => 'jim,jack,johnny";"',
+ 'path' => '/accounts',
+ ),
+ 'google' => array(
+ 'value' => 'not=nice',
+ )
+ );
+ $this->assertEquals($expected, $cookies);
+
+ $header['Set-Cookie'][] = 'cakephp=great; Secure';
+ $expected['cakephp'] = array('value' => 'great', 'secure' => true);
+ $cookies = $this->HttpResponse->parseCookies($header);
+ $this->assertEquals($expected, $cookies);
+
+ $header['Set-Cookie'] = 'foo=bar';
+ unset($expected['people'], $expected['cakephp'], $expected['google']);
+ $cookies = $this->HttpResponse->parseCookies($header);
+ $this->assertEquals($expected, $cookies);
+ }
+
+/**
+ * Test that escaped token strings are properly unescaped by HttpSocket::unescapeToken
+ *
+ * @return void
+ */
+ public function testUnescapeToken() {
+ $this->assertEquals('Foo', $this->HttpResponse->unescapeToken('Foo'));
+
+ $escape = $this->HttpResponse->tokenEscapeChars(false);
+ foreach ($escape as $char) {
+ $token = 'My-special-"' . $char . '"-Token';
+ $unescapedToken = $this->HttpResponse->unescapeToken($token);
+ $expectedToken = 'My-special-' . $char . '-Token';
+
+ $this->assertEquals($expectedToken, $unescapedToken, 'Test token unescaping for ASCII ' . ord($char));
+ }
+
+ $token = 'Extreme-":"Token-" "-""""@"-test';
+ $escapedToken = $this->HttpResponse->unescapeToken($token);
+ $expectedToken = 'Extreme-:Token- -"@-test';
+ $this->assertEquals($expectedToken, $escapedToken);
+ }
+
+/**
+ * testArrayAccess
+ *
+ * @return void
+ */
+ public function testArrayAccess() {
+ $this->HttpResponse->httpVersion = 'HTTP/1.1';
+ $this->HttpResponse->code = 200;
+ $this->HttpResponse->reasonPhrase = 'OK';
+ $this->HttpResponse->headers = array(
+ 'Server' => 'CakePHP',
+ 'ContEnt-Type' => 'text/plain'
+ );
+ $this->HttpResponse->cookies = array(
+ 'foo' => array('value' => 'bar'),
+ 'bar' => array('value' => 'foo')
+ );
+ $this->HttpResponse->body = 'This is a test!';
+ $this->HttpResponse->raw = "HTTP/1.1 200 OK\r\nServer: CakePHP\r\nContEnt-Type: text/plain\r\n\r\nThis is a test!";
+ $expectedOne = "HTTP/1.1 200 OK\r\n";
+ $this->assertEquals($expectedOne, $this->HttpResponse['raw']['status-line']);
+ $expectedTwo = "Server: CakePHP\r\nContEnt-Type: text/plain\r\n";
+ $this->assertEquals($expectedTwo, $this->HttpResponse['raw']['header']);
+ $expectedThree = 'This is a test!';
+ $this->assertEquals($expectedThree, $this->HttpResponse['raw']['body']);
+ $expected = $expectedOne . $expectedTwo . "\r\n" . $expectedThree;
+ $this->assertEquals($expected, $this->HttpResponse['raw']['response']);
+
+ $expected = 'HTTP/1.1';
+ $this->assertEquals($expected, $this->HttpResponse['status']['http-version']);
+ $expected = 200;
+ $this->assertEquals($expected, $this->HttpResponse['status']['code']);
+ $expected = 'OK';
+ $this->assertEquals($expected, $this->HttpResponse['status']['reason-phrase']);
+
+ $expected = array(
+ 'Server' => 'CakePHP',
+ 'ContEnt-Type' => 'text/plain'
+ );
+ $this->assertEquals($expected, $this->HttpResponse['header']);
+
+ $expected = 'This is a test!';
+ $this->assertEquals($expected, $this->HttpResponse['body']);
+
+ $expected = array(
+ 'foo' => array('value' => 'bar'),
+ 'bar' => array('value' => 'foo')
+ );
+ $this->assertEquals($expected, $this->HttpResponse['cookies']);
+
+ $this->HttpResponse->raw = "HTTP/1.1 200 OK\r\n\r\nThis is a test!";
+ $this->assertSame($this->HttpResponse['raw']['header'], null);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php
new file mode 100644
index 0000000..dfd7db9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Network/Http/HttpSocketTest.php
@@ -0,0 +1,1629 @@
+<?php
+/**
+ * HttpSocketTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Network.Http
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HttpSocket', 'Network/Http');
+App::uses('HttpResponse', 'Network/Http');
+
+/**
+ * TestAuthentication class
+ *
+ * @package Cake.Test.Case.Network.Http
+ * @package Cake.Test.Case.Network.Http
+ */
+class TestAuthentication {
+
+/**
+ * authentication method
+ *
+ * @param HttpSocket $http
+ * @param array $authInfo
+ * @return void
+ */
+ public static function authentication(HttpSocket $http, &$authInfo) {
+ $http->request['header']['Authorization'] = 'Test ' . $authInfo['user'] . '.' . $authInfo['pass'];
+ }
+
+/**
+ * proxyAuthentication method
+ *
+ * @param HttpSocket $http
+ * @param array $proxyInfo
+ * @return void
+ */
+ public static function proxyAuthentication(HttpSocket $http, &$proxyInfo) {
+ $http->request['header']['Proxy-Authorization'] = 'Test ' . $proxyInfo['user'] . '.' . $proxyInfo['pass'];
+ }
+
+}
+
+/**
+ * CustomResponse
+ *
+ */
+class CustomResponse {
+
+/**
+ * First 10 chars
+ *
+ * @var string
+ */
+ public $first10;
+
+/**
+ * Constructor
+ *
+ */
+ public function __construct($message) {
+ $this->first10 = substr($message, 0, 10);
+ }
+
+}
+
+/**
+ * TestHttpSocket
+ *
+ */
+class TestHttpSocket extends HttpSocket {
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param string|array $uri URI (see {@link _parseUri()})
+ * @return array Current configuration settings
+ */
+ public function configUri($uri = null) {
+ return parent::_configUri($uri);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param string|array $uri URI to parse
+ * @param boolean|array $base If true use default URI config, otherwise indexed array to set 'scheme', 'host', 'port', etc.
+ * @return array Parsed URI
+ */
+ public function parseUri($uri = null, $base = array()) {
+ return parent::_parseUri($uri, $base);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param array $uri A $uri array, or uses $this->config if left empty
+ * @param string $uriTemplate The Uri template/format to use
+ * @return string A fully qualified URL formatted according to $uriTemplate
+ */
+ public function buildUri($uri = array(), $uriTemplate = '%scheme://%user:%pass@%host:%port/%path?%query#%fragment') {
+ return parent::_buildUri($uri, $uriTemplate);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param array $header Header to build
+ * @return string Header built from array
+ */
+ public function buildHeader($header, $mode = 'standard') {
+ return parent::_buildHeader($header, $mode);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param string|array $query A query string to parse into an array or an array to return directly "as is"
+ * @return array The $query parsed into a possibly multi-level array. If an empty $query is given, an empty array is returned.
+ */
+ public function parseQuery($query) {
+ return parent::_parseQuery($query);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param array $request Needs to contain a 'uri' key. Should also contain a 'method' key, otherwise defaults to GET.
+ * @param string $versionToken The version token to use, defaults to HTTP/1.1
+ * @return string Request line
+ */
+ public function buildRequestLine($request = array(), $versionToken = 'HTTP/1.1') {
+ return parent::_buildRequestLine($request, $versionToken);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param boolean $hex true to get them as HEX values, false otherwise
+ * @return array Escape chars
+ */
+ public function tokenEscapeChars($hex = true, $chars = null) {
+ return parent::_tokenEscapeChars($hex, $chars);
+ }
+
+/**
+ * Convenience method for testing protected method
+ *
+ * @param string $token Token to escape
+ * @return string Escaped token
+ */
+ public function escapeToken($token, $chars = null) {
+ return parent::_escapeToken($token, $chars);
+ }
+
+}
+
+/**
+ * HttpSocketTest class
+ *
+ * @package Cake.Test.Case.Network.Http
+ */
+class HttpSocketTest extends CakeTestCase {
+
+/**
+ * Socket property
+ *
+ * @var mixed null
+ */
+ public $Socket = null;
+
+/**
+ * RequestSocket property
+ *
+ * @var mixed null
+ */
+ public $RequestSocket = null;
+
+/**
+ * This function sets up a TestHttpSocket instance we are going to use for testing
+ *
+ * @return void
+ */
+ public function setUp() {
+ if (!class_exists('MockHttpSocket')) {
+ $this->getMock('TestHttpSocket', array('read', 'write', 'connect'), array(), 'MockHttpSocket');
+ $this->getMock('TestHttpSocket', array('read', 'write', 'connect', 'request'), array(), 'MockHttpSocketRequests');
+ }
+
+ $this->Socket = new MockHttpSocket();
+ $this->RequestSocket = new MockHttpSocketRequests();
+ }
+
+/**
+ * We use this function to clean up after the test case was executed
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->Socket, $this->RequestSocket);
+ }
+
+/**
+ * Test that HttpSocket::__construct does what one would expect it to do
+ *
+ * @return void
+ */
+ public function testConstruct() {
+ $this->Socket->reset();
+ $baseConfig = $this->Socket->config;
+ $this->Socket->expects($this->never())->method('connect');
+ $this->Socket->__construct(array('host' => 'foo-bar'));
+ $baseConfig['host'] = 'foo-bar';
+ $baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
+ $this->assertEquals($this->Socket->config, $baseConfig);
+
+ $this->Socket->reset();
+ $baseConfig = $this->Socket->config;
+ $this->Socket->__construct('http://www.cakephp.org:23/');
+ $baseConfig['host'] = $baseConfig['request']['uri']['host'] = 'www.cakephp.org';
+ $baseConfig['port'] = $baseConfig['request']['uri']['port'] = 23;
+ $baseConfig['request']['uri']['scheme'] = 'http';
+ $baseConfig['protocol'] = getprotobyname($baseConfig['protocol']);
+ $this->assertEquals($this->Socket->config, $baseConfig);
+
+ $this->Socket->reset();
+ $this->Socket->__construct(array('request' => array('uri' => 'http://www.cakephp.org:23/')));
+ $this->assertEquals($this->Socket->config, $baseConfig);
+ }
+
+/**
+ * Test that HttpSocket::configUri works properly with different types of arguments
+ *
+ * @return void
+ */
+ public function testConfigUri() {
+ $this->Socket->reset();
+ $r = $this->Socket->configUri('https://bob:secret@www.cakephp.org:23/?query=foo');
+ $expected = array(
+ 'persistent' => false,
+ 'host' => 'www.cakephp.org',
+ 'protocol' => 'tcp',
+ 'port' => 23,
+ 'timeout' => 30,
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => 'https',
+ 'host' => 'www.cakephp.org',
+ 'port' => 23
+ ),
+ 'redirect' => false,
+ 'cookies' => array()
+ )
+ );
+ $this->assertEquals($expected, $this->Socket->config);
+ $this->assertTrue($r);
+ $r = $this->Socket->configUri(array('host' => 'www.foo-bar.org'));
+ $expected['host'] = 'www.foo-bar.org';
+ $expected['request']['uri']['host'] = 'www.foo-bar.org';
+ $this->assertEquals($expected, $this->Socket->config);
+ $this->assertTrue($r);
+
+ $r = $this->Socket->configUri('http://www.foo.com');
+ $expected = array(
+ 'persistent' => false,
+ 'host' => 'www.foo.com',
+ 'protocol' => 'tcp',
+ 'port' => 80,
+ 'timeout' => 30,
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => 'www.foo.com',
+ 'port' => 80
+ ),
+ 'redirect' => false,
+ 'cookies' => array()
+ )
+ );
+ $this->assertEquals($expected, $this->Socket->config);
+ $this->assertTrue($r);
+
+ $r = $this->Socket->configUri('/this-is-broken');
+ $this->assertEquals($expected, $this->Socket->config);
+ $this->assertFalse($r);
+
+ $r = $this->Socket->configUri(false);
+ $this->assertEquals($expected, $this->Socket->config);
+ $this->assertFalse($r);
+ }
+
+/**
+ * Tests that HttpSocket::request (the heart of the HttpSocket) is working properly.
+ *
+ * @return void
+ */
+ public function testRequest() {
+ $this->Socket->reset();
+
+ $response = $this->Socket->request(true);
+ $this->assertFalse($response);
+
+ $tests = array(
+ array(
+ 'request' => 'http://www.cakephp.org/?foo=bar',
+ 'expectation' => array(
+ 'config' => array(
+ 'persistent' => false,
+ 'host' => 'www.cakephp.org',
+ 'protocol' => 'tcp',
+ 'port' => 80,
+ 'timeout' => 30,
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => 'www.cakephp.org',
+ 'port' => 80
+ ),
+ 'redirect' => false,
+ 'cookies' => array()
+ )
+ ),
+ 'request' => array(
+ 'method' => 'GET',
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => 'www.cakephp.org',
+ 'port' => 80,
+ 'user' => null,
+ 'pass' => null,
+ 'path' => '/',
+ 'query' => array('foo' => 'bar'),
+ 'fragment' => null
+ ),
+ 'version' => '1.1',
+ 'body' => '',
+ 'line' => "GET /?foo=bar HTTP/1.1\r\n",
+ 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n",
+ 'raw' => "",
+ 'redirect' => false,
+ 'cookies' => array(),
+ 'proxy' => array(),
+ 'auth' => array()
+ )
+ )
+ ),
+ array(
+ 'request' => array(
+ 'uri' => array(
+ 'host' => 'www.cakephp.org',
+ 'query' => '?foo=bar'
+ )
+ )
+ ),
+ array(
+ 'request' => 'www.cakephp.org/?foo=bar'
+ ),
+ array(
+ 'request' => array(
+ 'host' => '192.168.0.1',
+ 'uri' => 'http://www.cakephp.org/?foo=bar'
+ ),
+ 'expectation' => array(
+ 'request' => array(
+ 'uri' => array('host' => 'www.cakephp.org')
+ ),
+ 'config' => array(
+ 'request' => array(
+ 'uri' => array('host' => 'www.cakephp.org')
+ ),
+ 'host' => '192.168.0.1'
+ )
+ )
+ ),
+ 'reset4' => array(
+ 'request.uri.query' => array()
+ ),
+ array(
+ 'request' => array(
+ 'header' => array('Foo@woo' => 'bar-value')
+ ),
+ 'expectation' => array(
+ 'request' => array(
+ 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n",
+ 'line' => "GET / HTTP/1.1\r\n"
+ )
+ )
+ ),
+ array(
+ 'request' => array('header' => array('Foo@woo' => 'bar-value', 'host' => 'foo.com'), 'uri' => 'http://www.cakephp.org/'),
+ 'expectation' => array(
+ 'request' => array(
+ 'header' => "Host: foo.com\r\nConnection: close\r\nUser-Agent: CakePHP\r\nFoo\"@\"woo: bar-value\r\n"
+ ),
+ 'config' => array(
+ 'host' => 'www.cakephp.org'
+ )
+ )
+ ),
+ array(
+ 'request' => array('header' => "Foo: bar\r\n"),
+ 'expectation' => array(
+ 'request' => array(
+ 'header' => "Foo: bar\r\n"
+ )
+ )
+ ),
+ array(
+ 'request' => array('header' => "Foo: bar\r\n", 'uri' => 'http://www.cakephp.org/search?q=http_socket#ignore-me'),
+ 'expectation' => array(
+ 'request' => array(
+ 'uri' => array(
+ 'path' => '/search',
+ 'query' => array('q' => 'http_socket'),
+ 'fragment' => 'ignore-me'
+ ),
+ 'line' => "GET /search?q=http_socket HTTP/1.1\r\n"
+ )
+ )
+ ),
+ 'reset8' => array(
+ 'request.uri.query' => array()
+ ),
+ array(
+ 'request' => array(
+ 'method' => 'POST',
+ 'uri' => 'http://www.cakephp.org/posts/add',
+ 'body' => array(
+ 'name' => 'HttpSocket-is-released',
+ 'date' => 'today'
+ )
+ ),
+ 'expectation' => array(
+ 'request' => array(
+ 'method' => 'POST',
+ 'uri' => array(
+ 'path' => '/posts/add',
+ 'fragment' => null
+ ),
+ 'body' => "name=HttpSocket-is-released&date=today",
+ 'line' => "POST /posts/add HTTP/1.1\r\n",
+ 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\n",
+ 'raw' => "name=HttpSocket-is-released&date=today"
+ )
+ )
+ ),
+ array(
+ 'request' => array(
+ 'method' => 'POST',
+ 'uri' => 'http://www.cakephp.org:8080/posts/add',
+ 'body' => array(
+ 'name' => 'HttpSocket-is-released',
+ 'date' => 'today'
+ )
+ ),
+ 'expectation' => array(
+ 'config' => array(
+ 'port' => 8080,
+ 'request' => array(
+ 'uri' => array(
+ 'port' => 8080
+ )
+ )
+ ),
+ 'request' => array(
+ 'uri' => array(
+ 'port' => 8080
+ ),
+ 'header' => "Host: www.cakephp.org:8080\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\n"
+ )
+ )
+ ),
+ array(
+ 'request' => array(
+ 'method' => 'POST',
+ 'uri' => 'https://www.cakephp.org/posts/add',
+ 'body' => array(
+ 'name' => 'HttpSocket-is-released',
+ 'date' => 'today'
+ )
+ ),
+ 'expectation' => array(
+ 'config' => array(
+ 'port' => 443,
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => 'https',
+ 'port' => 443
+ )
+ )
+ ),
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => 'https',
+ 'port' => 443
+ ),
+ 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\n"
+ )
+ )
+ ),
+ array(
+ 'request' => array(
+ 'method' => 'POST',
+ 'uri' => 'https://www.cakephp.org/posts/add',
+ 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'),
+ 'cookies' => array('foo' => array('value' => 'bar'))
+ ),
+ 'expectation' => array(
+ 'request' => array(
+ 'header' => "Host: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 38\r\nCookie: foo=bar\r\n",
+ 'cookies' => array(
+ 'foo' => array('value' => 'bar'),
+ )
+ )
+ )
+ )
+ );
+
+ $expectation = array();
+ foreach ($tests as $i => $test) {
+ if (strpos($i, 'reset') === 0) {
+ foreach ($test as $path => $val) {
+ $expectation = Hash::insert($expectation, $path, $val);
+ }
+ continue;
+ }
+
+ if (isset($test['expectation'])) {
+ $expectation = Hash::merge($expectation, $test['expectation']);
+ }
+ $this->Socket->request($test['request']);
+
+ $raw = $expectation['request']['raw'];
+ $expectation['request']['raw'] = $expectation['request']['line'] . $expectation['request']['header'] . "\r\n" . $raw;
+
+ $r = array('config' => $this->Socket->config, 'request' => $this->Socket->request);
+ $v = $this->assertEquals($r, $expectation, 'Failed test #' . $i . ' ');
+ $expectation['request']['raw'] = $raw;
+ }
+
+ $this->Socket->reset();
+ $request = array('method' => 'POST', 'uri' => 'http://www.cakephp.org/posts/add', 'body' => array('name' => 'HttpSocket-is-released', 'date' => 'today'));
+ $response = $this->Socket->request($request);
+ $this->assertEquals("name=HttpSocket-is-released&date=today", $this->Socket->request['body']);
+ }
+
+/**
+ * Test the scheme + port keys
+ *
+ * @return void
+ */
+ public function testGetWithSchemeAndPort() {
+ $this->Socket->reset();
+ $request = array(
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => 'cakephp.org',
+ 'port' => 8080,
+ 'path' => '/',
+ ),
+ 'method' => 'GET'
+ );
+ $response = $this->Socket->request($request);
+ $this->assertContains('Host: cakephp.org:8080', $this->Socket->request['header']);
+ }
+
+/**
+ * Test urls like http://cakephp.org/index.php?somestring without key/value pair for query
+ *
+ * @return void
+ */
+ public function testRequestWithStringQuery() {
+ $this->Socket->reset();
+ $request = array(
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => 'cakephp.org',
+ 'path' => 'index.php',
+ 'query' => 'somestring'
+ ),
+ 'method' => 'GET'
+ );
+ $response = $this->Socket->request($request);
+ $this->assertContains("GET /index.php?somestring HTTP/1.1", $this->Socket->request['line']);
+ }
+
+/**
+ * The "*" asterisk character is only allowed for the following methods: OPTIONS.
+ *
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testRequestNotAllowedUri() {
+ $this->Socket->reset();
+ $request = array('uri' => '*', 'method' => 'GET');
+ $response = $this->Socket->request($request);
+ }
+
+/**
+ * testRequest2 method
+ *
+ * @return void
+ */
+ public function testRequest2() {
+ $this->Socket->reset();
+ $request = array('uri' => 'htpp://www.cakephp.org/');
+ $number = mt_rand(0, 9999999);
+ $this->Socket->expects($this->once())->method('connect')->will($this->returnValue(true));
+ $serverResponse = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>Hello, your lucky number is " . $number . "</h1>";
+ $this->Socket->expects($this->at(0))->method('read')->will($this->returnValue(false));
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->expects($this->once())->method('write')
+ ->with("GET / HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n\r\n");
+ $response = (string)$this->Socket->request($request);
+ $this->assertEquals($response, "<h1>Hello, your lucky number is " . $number . "</h1>");
+ }
+
+/**
+ * testRequest3 method
+ *
+ * @return void
+ */
+ public function testRequest3() {
+ $request = array('uri' => 'htpp://www.cakephp.org/');
+ $serverResponse = "HTTP/1.x 200 OK\r\nSet-Cookie: foo=bar\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a cookie test!</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->connected = true;
+ $this->Socket->request($request);
+ $result = $this->Socket->response['cookies'];
+ $expect = array(
+ 'foo' => array(
+ 'value' => 'bar'
+ )
+ );
+ $this->assertEquals($expect, $result);
+ $this->assertEquals($this->Socket->config['request']['cookies']['www.cakephp.org'], $expect);
+ $this->assertFalse($this->Socket->connected);
+ }
+
+/**
+ * testRequestWithConstructor method
+ *
+ * @return void
+ */
+ public function testRequestWithConstructor() {
+ $request = array(
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => 'localhost',
+ 'port' => '5984',
+ 'user' => null,
+ 'pass' => null
+ )
+ )
+ );
+ $http = new MockHttpSocketRequests($request);
+
+ $expected = array('method' => 'GET', 'uri' => '/_test');
+ $http->expects($this->at(0))->method('request')->with($expected);
+ $http->get('/_test');
+
+ $expected = array('method' => 'GET', 'uri' => 'http://localhost:5984/_test?count=4');
+ $http->expects($this->at(0))->method('request')->with($expected);
+ $http->get('/_test', array('count' => 4));
+ }
+
+/**
+ * testRequestWithResource
+ *
+ * @return void
+ */
+ public function testRequestWithResource() {
+ $serverResponse = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a test!</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
+ $this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->connected = true;
+
+ $f = fopen(TMP . 'download.txt', 'w');
+ if (!$f) {
+ $this->markTestSkipped('Can not write in TMP directory.');
+ }
+
+ $this->Socket->setContentResource($f);
+ $result = (string)$this->Socket->request('http://www.cakephp.org/');
+ $this->assertEquals('', $result);
+ $this->assertEquals('CakeHttp Server', $this->Socket->response['header']['Server']);
+ fclose($f);
+ $this->assertEquals(file_get_contents(TMP . 'download.txt'), '<h1>This is a test!</h1>');
+ unlink(TMP . 'download.txt');
+
+ $this->Socket->setContentResource(false);
+ $result = (string)$this->Socket->request('http://www.cakephp.org/');
+ $this->assertEquals('<h1>This is a test!</h1>', $result);
+ }
+
+/**
+ * testRequestWithCrossCookie
+ *
+ * @return void
+ */
+ public function testRequestWithCrossCookie() {
+ $this->Socket->connected = true;
+ $this->Socket->config['request']['cookies'] = array();
+
+ $serverResponse = "HTTP/1.x 200 OK\r\nSet-Cookie: foo=bar\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a test!</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
+ $expected = array('www.cakephp.org' => array('foo' => array('value' => 'bar')));
+ $this->Socket->request('http://www.cakephp.org/');
+ $this->assertEquals($expected, $this->Socket->config['request']['cookies']);
+
+ $serverResponse = "HTTP/1.x 200 OK\r\nSet-Cookie: bar=foo\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a test!</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
+ $this->Socket->request('http://www.cakephp.org/other');
+ $this->assertEquals(array('foo' => array('value' => 'bar')), $this->Socket->request['cookies']);
+ $expected['www.cakephp.org'] += array('bar' => array('value' => 'foo'));
+ $this->assertEquals($expected, $this->Socket->config['request']['cookies']);
+
+ $serverResponse = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a test!</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
+ $this->Socket->request('/other2');
+ $this->assertEquals($expected, $this->Socket->config['request']['cookies']);
+
+ $serverResponse = "HTTP/1.x 200 OK\r\nSet-Cookie: foobar=ok\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a test!</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
+ $this->Socket->request('http://www.cake.com');
+ $this->assertTrue(empty($this->Socket->request['cookies']));
+ $expected['www.cake.com'] = array('foobar' => array('value' => 'ok'));
+ $this->assertEquals($expected, $this->Socket->config['request']['cookies']);
+ }
+
+/**
+ * testRequestCustomResponse
+ *
+ * @return void
+ */
+ public function testRequestCustomResponse() {
+ $this->Socket->connected = true;
+ $serverResponse = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>This is a test!</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse));
+ $this->Socket->expects($this->at(2))->method('read')->will($this->returnValue(false));
+
+ $this->Socket->responseClass = 'CustomResponse';
+ $response = $this->Socket->request('http://www.cakephp.org/');
+ $this->assertInstanceOf('CustomResponse', $response);
+ $this->assertEquals('HTTP/1.x 2', $response->first10);
+ }
+
+/**
+ * testRequestWithRedirect method
+ *
+ * @return void
+ */
+ public function testRequestWithRedirectAsTrue() {
+ $request = array(
+ 'uri' => 'http://localhost/oneuri',
+ 'redirect' => true
+ );
+ $serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/anotheruri\r\n\r\n";
+ $serverResponse2 = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>You have been redirected</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse1));
+ $this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse2));
+
+ $response = $this->Socket->request($request);
+ $this->assertEquals('<h1>You have been redirected</h1>', $response->body());
+ }
+
+ public function testRequestWithRedirectAsInt() {
+ $request = array(
+ 'uri' => 'http://localhost/oneuri',
+ 'redirect' => 2
+ );
+ $serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/anotheruri\r\n\r\n";
+ $serverResponse2 = "HTTP/1.x 200 OK\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\n\r\n<h1>You have been redirected</h1>";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse1));
+ $this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse2));
+
+ $response = $this->Socket->request($request);
+ $this->assertEquals(1, $this->Socket->request['redirect']);
+ }
+
+ public function testRequestWithRedirectAsIntReachingZero() {
+ $request = array(
+ 'uri' => 'http://localhost/oneuri',
+ 'redirect' => 1
+ );
+ $serverResponse1 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/oneruri\r\n\r\n";
+ $serverResponse2 = "HTTP/1.x 302 Found\r\nDate: Mon, 16 Apr 2007 04:14:16 GMT\r\nServer: CakeHttp Server\r\nContent-Type: text/html\r\nLocation: http://localhost/anotheruri\r\n\r\n";
+ $this->Socket->expects($this->at(1))->method('read')->will($this->returnValue($serverResponse1));
+ $this->Socket->expects($this->at(4))->method('read')->will($this->returnValue($serverResponse2));
+
+ $response = $this->Socket->request($request);
+ $this->assertEquals(0, $this->Socket->request['redirect']);
+ $this->assertEquals(302, $response->code);
+ $this->assertEquals('http://localhost/anotheruri', $response->getHeader('Location'));
+ }
+
+/**
+ * testProxy method
+ *
+ * @return void
+ */
+ public function testProxy() {
+ $this->Socket->reset();
+ $this->Socket->expects($this->any())->method('connect')->will($this->returnValue(true));
+ $this->Socket->expects($this->any())->method('read')->will($this->returnValue(false));
+
+ $this->Socket->configProxy('proxy.server', 123);
+ $expected = "GET http://www.cakephp.org/ HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n\r\n";
+ $this->Socket->request('http://www.cakephp.org/');
+ $this->assertEquals($expected, $this->Socket->request['raw']);
+ $this->assertEquals('proxy.server', $this->Socket->config['host']);
+ $this->assertEquals(123, $this->Socket->config['port']);
+ $expected = array(
+ 'host' => 'proxy.server',
+ 'port' => 123,
+ 'method' => null,
+ 'user' => null,
+ 'pass' => null
+ );
+ $this->assertEquals($expected, $this->Socket->request['proxy']);
+
+ $expected = "GET http://www.cakephp.org/bakery HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\n\r\n";
+ $this->Socket->request('/bakery');
+ $this->assertEquals($expected, $this->Socket->request['raw']);
+ $this->assertEquals('proxy.server', $this->Socket->config['host']);
+ $this->assertEquals(123, $this->Socket->config['port']);
+ $expected = array(
+ 'host' => 'proxy.server',
+ 'port' => 123,
+ 'method' => null,
+ 'user' => null,
+ 'pass' => null
+ );
+ $this->assertEquals($expected, $this->Socket->request['proxy']);
+
+ $expected = "GET http://www.cakephp.org/ HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nProxy-Authorization: Test mark.secret\r\n\r\n";
+ $this->Socket->configProxy('proxy.server', 123, 'Test', 'mark', 'secret');
+ $this->Socket->request('http://www.cakephp.org/');
+ $this->assertEquals($expected, $this->Socket->request['raw']);
+ $this->assertEquals('proxy.server', $this->Socket->config['host']);
+ $this->assertEquals(123, $this->Socket->config['port']);
+ $expected = array(
+ 'host' => 'proxy.server',
+ 'port' => 123,
+ 'method' => 'Test',
+ 'user' => 'mark',
+ 'pass' => 'secret'
+ );
+ $this->assertEquals($expected, $this->Socket->request['proxy']);
+
+ $this->Socket->configAuth('Test', 'login', 'passwd');
+ $expected = "GET http://www.cakephp.org/ HTTP/1.1\r\nHost: www.cakephp.org\r\nConnection: close\r\nUser-Agent: CakePHP\r\nProxy-Authorization: Test mark.secret\r\nAuthorization: Test login.passwd\r\n\r\n";
+ $this->Socket->request('http://www.cakephp.org/');
+ $this->assertEquals($expected, $this->Socket->request['raw']);
+ $expected = array(
+ 'host' => 'proxy.server',
+ 'port' => 123,
+ 'method' => 'Test',
+ 'user' => 'mark',
+ 'pass' => 'secret'
+ );
+ $this->assertEquals($expected, $this->Socket->request['proxy']);
+ $expected = array(
+ 'Test' => array(
+ 'user' => 'login',
+ 'pass' => 'passwd'
+ )
+ );
+ $this->assertEquals($expected, $this->Socket->request['auth']);
+ }
+
+/**
+ * testUrl method
+ *
+ * @return void
+ */
+ public function testUrl() {
+ $this->Socket->reset(true);
+
+ $this->assertEquals(false, $this->Socket->url(true));
+
+ $url = $this->Socket->url('www.cakephp.org');
+ $this->assertEquals('http://www.cakephp.org/', $url);
+
+ $url = $this->Socket->url('https://www.cakephp.org/posts/add');
+ $this->assertEquals('https://www.cakephp.org/posts/add', $url);
+ $url = $this->Socket->url('http://www.cakephp/search?q=socket', '/%path?%query');
+ $this->assertEquals('/search?q=socket', $url);
+
+ $this->Socket->config['request']['uri']['host'] = 'bakery.cakephp.org';
+ $url = $this->Socket->url();
+ $this->assertEquals('http://bakery.cakephp.org/', $url);
+
+ $this->Socket->configUri('http://www.cakephp.org');
+ $url = $this->Socket->url('/search?q=bar');
+ $this->assertEquals('http://www.cakephp.org/search?q=bar', $url);
+
+ $url = $this->Socket->url(array('host' => 'www.foobar.org', 'query' => array('q' => 'bar')));
+ $this->assertEquals('http://www.foobar.org/?q=bar', $url);
+
+ $url = $this->Socket->url(array('path' => '/supersearch', 'query' => array('q' => 'bar')));
+ $this->assertEquals('http://www.cakephp.org/supersearch?q=bar', $url);
+
+ $this->Socket->configUri('http://www.google.com');
+ $url = $this->Socket->url('/search?q=socket');
+ $this->assertEquals('http://www.google.com/search?q=socket', $url);
+
+ $url = $this->Socket->url();
+ $this->assertEquals('http://www.google.com/', $url);
+
+ $this->Socket->configUri('https://www.google.com');
+ $url = $this->Socket->url('/search?q=socket');
+ $this->assertEquals('https://www.google.com/search?q=socket', $url);
+
+ $this->Socket->reset();
+ $this->Socket->configUri('www.google.com:443');
+ $url = $this->Socket->url('/search?q=socket');
+ $this->assertEquals('https://www.google.com/search?q=socket', $url);
+
+ $this->Socket->reset();
+ $this->Socket->configUri('www.google.com:8080');
+ $url = $this->Socket->url('/search?q=socket');
+ $this->assertEquals('http://www.google.com:8080/search?q=socket', $url);
+ }
+
+/**
+ * testGet method
+ *
+ * @return void
+ */
+ public function testGet() {
+ $this->RequestSocket->reset();
+
+ $this->RequestSocket->expects($this->at(0))
+ ->method('request')
+ ->with(array('method' => 'GET', 'uri' => 'http://www.google.com/'));
+
+ $this->RequestSocket->expects($this->at(1))
+ ->method('request')
+ ->with(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar'));
+
+ $this->RequestSocket->expects($this->at(2))
+ ->method('request')
+ ->with(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=bar'));
+
+ $this->RequestSocket->expects($this->at(3))
+ ->method('request')
+ ->with(array('method' => 'GET', 'uri' => 'http://www.google.com/?foo=23&foobar=42'));
+
+ $this->RequestSocket->expects($this->at(4))
+ ->method('request')
+ ->with(array('method' => 'GET', 'uri' => 'http://www.google.com/', 'version' => '1.0'));
+
+ $this->RequestSocket->expects($this->at(5))
+ ->method('request')
+ ->with(array('method' => 'GET', 'uri' => 'https://secure.example.com/test.php?one=two'));
+
+ $this->RequestSocket->expects($this->at(6))
+ ->method('request')
+ ->with(array('method' => 'GET', 'uri' => 'https://example.com/oauth/access?clientid=123&redirect_uri=http%3A%2F%2Fexample.com&code=456'));
+
+ $this->RequestSocket->get('http://www.google.com/');
+ $this->RequestSocket->get('http://www.google.com/', array('foo' => 'bar'));
+ $this->RequestSocket->get('http://www.google.com/', 'foo=bar');
+ $this->RequestSocket->get('http://www.google.com/?foo=bar', array('foobar' => '42', 'foo' => '23'));
+ $this->RequestSocket->get('http://www.google.com/', null, array('version' => '1.0'));
+ $this->RequestSocket->get('https://secure.example.com/test.php', array('one' => 'two'));
+ $this->RequestSocket->get('https://example.com/oauth/access', array(
+ 'clientid' => '123',
+ 'redirect_uri' => 'http://example.com',
+ 'code' => 456
+ ));
+ }
+
+/**
+ * Test authentication
+ *
+ * @return void
+ */
+ public function testAuth() {
+ $socket = new MockHttpSocket();
+ $socket->get('http://mark:secret@example.com/test');
+ $this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
+
+ $socket->configAuth(false);
+ $socket->get('http://example.com/test');
+ $this->assertFalse(strpos($socket->request['header'], 'Authorization:'));
+
+ $socket->configAuth('Test', 'mark', 'passwd');
+ $socket->get('http://example.com/test');
+ $this->assertTrue(strpos($socket->request['header'], 'Authorization: Test mark.passwd') !== false);
+ }
+
+/**
+ * test that two consecutive get() calls reset the authentication credentials.
+ *
+ * @return void
+ */
+ public function testConsecutiveGetResetsAuthCredentials() {
+ $socket = new MockHttpSocket();
+ $socket->get('http://mark:secret@example.com/test');
+ $this->assertEquals('mark', $socket->request['uri']['user']);
+ $this->assertEquals('secret', $socket->request['uri']['pass']);
+ $this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
+
+ $socket->get('/test2');
+ $this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
+
+ $socket->get('/test3');
+ $this->assertTrue(strpos($socket->request['header'], 'Authorization: Basic bWFyazpzZWNyZXQ=') !== false);
+ }
+
+/**
+ * testPostPutDelete method
+ *
+ * @return void
+ */
+ public function testPost() {
+ $this->RequestSocket->reset();
+ $this->RequestSocket->expects($this->at(0))
+ ->method('request')
+ ->with(array('method' => 'POST', 'uri' => 'http://www.google.com/', 'body' => array()));
+
+ $this->RequestSocket->expects($this->at(1))
+ ->method('request')
+ ->with(array('method' => 'POST', 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar')));
+
+ $this->RequestSocket->expects($this->at(2))
+ ->method('request')
+ ->with(array('method' => 'POST', 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server'));
+
+ $this->RequestSocket->post('http://www.google.com/');
+ $this->RequestSocket->post('http://www.google.com/', array('Foo' => 'bar'));
+ $this->RequestSocket->post('http://www.google.com/', null, array('line' => 'Hey Server'));
+ }
+
+/**
+ * testPut
+ *
+ * @return void
+ */
+ public function testPut() {
+ $this->RequestSocket->reset();
+ $this->RequestSocket->expects($this->at(0))
+ ->method('request')
+ ->with(array('method' => 'PUT', 'uri' => 'http://www.google.com/', 'body' => array()));
+
+ $this->RequestSocket->expects($this->at(1))
+ ->method('request')
+ ->with(array('method' => 'PUT', 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar')));
+
+ $this->RequestSocket->expects($this->at(2))
+ ->method('request')
+ ->with(array('method' => 'PUT', 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server'));
+
+ $this->RequestSocket->put('http://www.google.com/');
+ $this->RequestSocket->put('http://www.google.com/', array('Foo' => 'bar'));
+ $this->RequestSocket->put('http://www.google.com/', null, array('line' => 'Hey Server'));
+ }
+
+/**
+ * testDelete
+ *
+ * @return void
+ */
+ public function testDelete() {
+ $this->RequestSocket->reset();
+ $this->RequestSocket->expects($this->at(0))
+ ->method('request')
+ ->with(array('method' => 'DELETE', 'uri' => 'http://www.google.com/', 'body' => array()));
+
+ $this->RequestSocket->expects($this->at(1))
+ ->method('request')
+ ->with(array('method' => 'DELETE', 'uri' => 'http://www.google.com/', 'body' => array('Foo' => 'bar')));
+
+ $this->RequestSocket->expects($this->at(2))
+ ->method('request')
+ ->with(array('method' => 'DELETE', 'uri' => 'http://www.google.com/', 'body' => null, 'line' => 'Hey Server'));
+
+ $this->RequestSocket->delete('http://www.google.com/');
+ $this->RequestSocket->delete('http://www.google.com/', array('Foo' => 'bar'));
+ $this->RequestSocket->delete('http://www.google.com/', null, array('line' => 'Hey Server'));
+ }
+
+/**
+ * testBuildRequestLine method
+ *
+ * @return void
+ */
+ public function testBuildRequestLine() {
+ $this->Socket->reset();
+
+ $this->Socket->quirksMode = true;
+ $r = $this->Socket->buildRequestLine('Foo');
+ $this->assertEquals('Foo', $r);
+ $this->Socket->quirksMode = false;
+
+ $r = $this->Socket->buildRequestLine(true);
+ $this->assertEquals(false, $r);
+
+ $r = $this->Socket->buildRequestLine(array('foo' => 'bar', 'method' => 'foo'));
+ $this->assertEquals(false, $r);
+
+ $r = $this->Socket->buildRequestLine(array('method' => 'GET', 'uri' => 'http://www.cakephp.org/search?q=socket'));
+ $this->assertEquals("GET /search?q=socket HTTP/1.1\r\n", $r);
+
+ $request = array(
+ 'method' => 'GET',
+ 'uri' => array(
+ 'path' => '/search',
+ 'query' => array('q' => 'socket')
+ )
+ );
+ $r = $this->Socket->buildRequestLine($request);
+ $this->assertEquals("GET /search?q=socket HTTP/1.1\r\n", $r);
+
+ unset($request['method']);
+ $r = $this->Socket->buildRequestLine($request);
+ $this->assertEquals("GET /search?q=socket HTTP/1.1\r\n", $r);
+
+ $r = $this->Socket->buildRequestLine($request, 'CAKE-HTTP/0.1');
+ $this->assertEquals("GET /search?q=socket CAKE-HTTP/0.1\r\n", $r);
+
+ $request = array('method' => 'OPTIONS', 'uri' => '*');
+ $r = $this->Socket->buildRequestLine($request);
+ $this->assertEquals("OPTIONS * HTTP/1.1\r\n", $r);
+
+ $request['method'] = 'GET';
+ $this->Socket->quirksMode = true;
+ $r = $this->Socket->buildRequestLine($request);
+ $this->assertEquals("GET * HTTP/1.1\r\n", $r);
+
+ $r = $this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
+ $this->assertEquals("GET * HTTP/1.1\r\n", $r);
+ }
+
+/**
+ * testBadBuildRequestLine method
+ *
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testBadBuildRequestLine() {
+ $r = $this->Socket->buildRequestLine('Foo');
+ }
+
+/**
+ * testBadBuildRequestLine2 method
+ *
+ * @expectedException SocketException
+ * @return void
+ */
+ public function testBadBuildRequestLine2() {
+ $r = $this->Socket->buildRequestLine("GET * HTTP/1.1\r\n");
+ }
+
+/**
+ * Asserts that HttpSocket::parseUri is working properly
+ *
+ * @return void
+ */
+ public function testParseUri() {
+ $this->Socket->reset();
+
+ $uri = $this->Socket->parseUri(array('invalid' => 'uri-string'));
+ $this->assertEquals(false, $uri);
+
+ $uri = $this->Socket->parseUri(array('invalid' => 'uri-string'), array('host' => 'somehost'));
+ $this->assertEquals(array('host' => 'somehost', 'invalid' => 'uri-string'), $uri);
+
+ $uri = $this->Socket->parseUri(false);
+ $this->assertEquals(false, $uri);
+
+ $uri = $this->Socket->parseUri('/my-cool-path');
+ $this->assertEquals(array('path' => '/my-cool-path'), $uri);
+
+ $uri = $this->Socket->parseUri('http://bob:foo123@www.cakephp.org:40/search?q=dessert#results');
+ $this->assertEquals($uri, array(
+ 'scheme' => 'http',
+ 'host' => 'www.cakephp.org',
+ 'port' => 40,
+ 'user' => 'bob',
+ 'pass' => 'foo123',
+ 'path' => '/search',
+ 'query' => array('q' => 'dessert'),
+ 'fragment' => 'results'
+ ));
+
+ $uri = $this->Socket->parseUri('http://www.cakephp.org/');
+ $this->assertEquals($uri, array(
+ 'scheme' => 'http',
+ 'host' => 'www.cakephp.org',
+ 'path' => '/'
+ ));
+
+ $uri = $this->Socket->parseUri('http://www.cakephp.org', true);
+ $this->assertEquals($uri, array(
+ 'scheme' => 'http',
+ 'host' => 'www.cakephp.org',
+ 'port' => 80,
+ 'user' => null,
+ 'pass' => null,
+ 'path' => '/',
+ 'query' => array(),
+ 'fragment' => null
+ ));
+
+ $uri = $this->Socket->parseUri('https://www.cakephp.org', true);
+ $this->assertEquals($uri, array(
+ 'scheme' => 'https',
+ 'host' => 'www.cakephp.org',
+ 'port' => 443,
+ 'user' => null,
+ 'pass' => null,
+ 'path' => '/',
+ 'query' => array(),
+ 'fragment' => null
+ ));
+
+ $uri = $this->Socket->parseUri('www.cakephp.org:443/query?foo', true);
+ $this->assertEquals($uri, array(
+ 'scheme' => 'https',
+ 'host' => 'www.cakephp.org',
+ 'port' => 443,
+ 'user' => null,
+ 'pass' => null,
+ 'path' => '/query',
+ 'query' => array('foo' => ""),
+ 'fragment' => null
+ ));
+
+ $uri = $this->Socket->parseUri('http://www.cakephp.org', array('host' => 'piephp.org', 'user' => 'bob', 'fragment' => 'results'));
+ $this->assertEquals($uri, array(
+ 'host' => 'www.cakephp.org',
+ 'user' => 'bob',
+ 'fragment' => 'results',
+ 'scheme' => 'http'
+ ));
+
+ $uri = $this->Socket->parseUri('https://www.cakephp.org', array('scheme' => 'http', 'port' => 23));
+ $this->assertEquals($uri, array(
+ 'scheme' => 'https',
+ 'port' => 23,
+ 'host' => 'www.cakephp.org'
+ ));
+
+ $uri = $this->Socket->parseUri('www.cakephp.org:59', array('scheme' => array('http', 'https'), 'port' => 80));
+ $this->assertEquals($uri, array(
+ 'scheme' => 'http',
+ 'port' => 59,
+ 'host' => 'www.cakephp.org'
+ ));
+
+ $uri = $this->Socket->parseUri(array('scheme' => 'http', 'host' => 'www.google.com', 'port' => 8080), array('scheme' => array('http', 'https'), 'host' => 'www.google.com', 'port' => array(80, 443)));
+ $this->assertEquals($uri, array(
+ 'scheme' => 'http',
+ 'host' => 'www.google.com',
+ 'port' => 8080
+ ));
+
+ $uri = $this->Socket->parseUri('http://www.cakephp.org/?param1=value1&param2=value2%3Dvalue3');
+ $this->assertEquals($uri, array(
+ 'scheme' => 'http',
+ 'host' => 'www.cakephp.org',
+ 'path' => '/',
+ 'query' => array(
+ 'param1' => 'value1',
+ 'param2' => 'value2=value3'
+ )
+ ));
+
+ $uri = $this->Socket->parseUri('http://www.cakephp.org/?param1=value1&param2=value2=value3');
+ $this->assertEquals($uri, array(
+ 'scheme' => 'http',
+ 'host' => 'www.cakephp.org',
+ 'path' => '/',
+ 'query' => array(
+ 'param1' => 'value1',
+ 'param2' => 'value2=value3'
+ )
+ ));
+ }
+
+/**
+ * Tests that HttpSocket::buildUri can turn all kinds of uri arrays (and strings) into fully or partially qualified URI's
+ *
+ * @return void
+ */
+ public function testBuildUri() {
+ $this->Socket->reset();
+
+ $r = $this->Socket->buildUri(true);
+ $this->assertEquals(false, $r);
+
+ $r = $this->Socket->buildUri('foo.com');
+ $this->assertEquals('http://foo.com/', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'));
+ $this->assertEquals('http://www.cakephp.org/', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https'));
+ $this->assertEquals('https://www.cakephp.org/', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'port' => 23));
+ $this->assertEquals('http://www.cakephp.org:23/', $r);
+
+ $r = $this->Socket->buildUri(array('path' => 'www.google.com/search', 'query' => 'q=cakephp'));
+ $this->assertEquals('http://www.google.com/search?q=cakephp', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'scheme' => 'https', 'port' => 79));
+ $this->assertEquals('https://www.cakephp.org:79/', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => 'foo'));
+ $this->assertEquals('http://www.cakephp.org/foo', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/foo'));
+ $this->assertEquals('http://www.cakephp.org/foo', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'path' => '/search', 'query' => array('q' => 'HttpSocket')));
+ $this->assertEquals('http://www.cakephp.org/search?q=HttpSocket', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'));
+ $this->assertEquals('http://www.cakephp.org/#bar', $r);
+
+ $r = $this->Socket->buildUri(array(
+ 'scheme' => 'https',
+ 'host' => 'www.cakephp.org',
+ 'port' => 25,
+ 'user' => 'bob',
+ 'pass' => 'secret',
+ 'path' => '/cool',
+ 'query' => array('foo' => 'bar'),
+ 'fragment' => 'comment'
+ ));
+ $this->assertEquals('https://bob:secret@www.cakephp.org:25/cool?foo=bar#comment', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org', 'fragment' => 'bar'), '%fragment?%host');
+ $this->assertEquals('bar?www.cakephp.org', $r);
+
+ $r = $this->Socket->buildUri(array('host' => 'www.cakephp.org'), '%fragment???%host');
+ $this->assertEquals('???www.cakephp.org', $r);
+
+ $r = $this->Socket->buildUri(array('path' => '*'), '/%path?%query');
+ $this->assertEquals('*', $r);
+
+ $r = $this->Socket->buildUri(array('scheme' => 'foo', 'host' => 'www.cakephp.org'));
+ $this->assertEquals('foo://www.cakephp.org:80/', $r);
+ }
+
+/**
+ * Asserts that HttpSocket::parseQuery is working properly
+ *
+ * @return void
+ */
+ public function testParseQuery() {
+ $this->Socket->reset();
+
+ $query = $this->Socket->parseQuery(array('framework' => 'cakephp'));
+ $this->assertEquals(array('framework' => 'cakephp'), $query);
+
+ $query = $this->Socket->parseQuery('');
+ $this->assertEquals(array(), $query);
+
+ $query = $this->Socket->parseQuery('framework=cakephp');
+ $this->assertEquals(array('framework' => 'cakephp'), $query);
+
+ $query = $this->Socket->parseQuery('?framework=cakephp');
+ $this->assertEquals(array('framework' => 'cakephp'), $query);
+
+ $query = $this->Socket->parseQuery('a&b&c');
+ $this->assertEquals(array('a' => '', 'b' => '', 'c' => ''), $query);
+
+ $query = $this->Socket->parseQuery('value=12345');
+ $this->assertEquals(array('value' => '12345'), $query);
+
+ $query = $this->Socket->parseQuery('a[0]=foo&a[1]=bar&a[2]=cake');
+ $this->assertEquals(array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')), $query);
+
+ $query = $this->Socket->parseQuery('a[]=foo&a[]=bar&a[]=cake');
+ $this->assertEquals(array('a' => array(0 => 'foo', 1 => 'bar', 2 => 'cake')), $query);
+
+ $query = $this->Socket->parseQuery('a[][]=foo&a[][]=bar&a[][]=cake');
+ $expectedQuery = array(
+ 'a' => array(
+ 0 => array(
+ 0 => 'foo'
+ ),
+ 1 => array(
+ 0 => 'bar'
+ ),
+ array(
+ 0 => 'cake'
+ )
+ )
+ );
+ $this->assertEquals($expectedQuery, $query);
+
+ $query = $this->Socket->parseQuery('a[][]=foo&a[bar]=php&a[][]=bar&a[][]=cake');
+ $expectedQuery = array(
+ 'a' => array(
+ array('foo'),
+ 'bar' => 'php',
+ array('bar'),
+ array('cake')
+ )
+ );
+ $this->assertEquals($expectedQuery, $query);
+
+ $query = $this->Socket->parseQuery('user[]=jim&user[3]=tom&user[]=bob');
+ $expectedQuery = array(
+ 'user' => array(
+ 0 => 'jim',
+ 3 => 'tom',
+ 4 => 'bob'
+ )
+ );
+ $this->assertEquals($expectedQuery, $query);
+
+ $queryStr = 'user[0]=foo&user[0][items][]=foo&user[0][items][]=bar&user[][name]=jim&user[1][items][personal][]=book&user[1][items][personal][]=pen&user[1][items][]=ball&user[count]=2&empty';
+ $query = $this->Socket->parseQuery($queryStr);
+ $expectedQuery = array(
+ 'user' => array(
+ 0 => array(
+ 'items' => array(
+ 'foo',
+ 'bar'
+ )
+ ),
+ 1 => array(
+ 'name' => 'jim',
+ 'items' => array(
+ 'personal' => array(
+ 'book'
+ , 'pen'
+ ),
+ 'ball'
+ )
+ ),
+ 'count' => '2'
+ ),
+ 'empty' => ''
+ );
+ $this->assertEquals($expectedQuery, $query);
+
+ $query = 'openid.ns=example.com&foo=bar&foo=baz';
+ $result = $this->Socket->parseQuery($query);
+ $expected = array(
+ 'openid.ns' => 'example.com',
+ 'foo' => array('bar', 'baz')
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests that HttpSocket::buildHeader can turn a given $header array into a proper header string according to
+ * HTTP 1.1 specs.
+ *
+ * @return void
+ */
+ public function testBuildHeader() {
+ $this->Socket->reset();
+
+ $r = $this->Socket->buildHeader(true);
+ $this->assertEquals(false, $r);
+
+ $r = $this->Socket->buildHeader('My raw header');
+ $this->assertEquals('My raw header', $r);
+
+ $r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org'));
+ $this->assertEquals("Host: www.cakephp.org\r\n", $r);
+
+ $r = $this->Socket->buildHeader(array('Host' => 'www.cakephp.org', 'Connection' => 'Close'));
+ $this->assertEquals("Host: www.cakephp.org\r\nConnection: Close\r\n", $r);
+
+ $r = $this->Socket->buildHeader(array('People' => array('Bob', 'Jim', 'John')));
+ $this->assertEquals("People: Bob,Jim,John\r\n", $r);
+
+ $r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\nMulti Line field"));
+ $this->assertEquals("Multi-Line-Field: This is my\r\n Multi Line field\r\n", $r);
+
+ $r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n Multi Line field"));
+ $this->assertEquals("Multi-Line-Field: This is my\r\n Multi Line field\r\n", $r);
+
+ $r = $this->Socket->buildHeader(array('Multi-Line-Field' => "This is my\r\n\tMulti Line field"));
+ $this->assertEquals("Multi-Line-Field: This is my\r\n\tMulti Line field\r\n", $r);
+
+ $r = $this->Socket->buildHeader(array('Test@Field' => "My value"));
+ $this->assertEquals("Test\"@\"Field: My value\r\n", $r);
+ }
+
+/**
+ * testBuildCookies method
+ *
+ * @return void
+ * @todo Test more scenarios
+ */
+ public function testBuildCookies() {
+ $cookies = array(
+ 'foo' => array(
+ 'value' => 'bar'
+ ),
+ 'people' => array(
+ 'value' => 'jim,jack,johnny;',
+ 'path' => '/accounts'
+ )
+ );
+ $expect = "Cookie: foo=bar; people=jim,jack,johnny\";\"\r\n";
+ $result = $this->Socket->buildCookies($cookies);
+ $this->assertEquals($expect, $result);
+ }
+
+/**
+ * Tests that HttpSocket::_tokenEscapeChars() returns the right characters.
+ *
+ * @return void
+ */
+ public function testTokenEscapeChars() {
+ $this->Socket->reset();
+
+ $expected = array(
+ '\x22','\x28','\x29','\x3c','\x3e','\x40','\x2c','\x3b','\x3a','\x5c','\x2f','\x5b','\x5d','\x3f','\x3d','\x7b',
+ '\x7d','\x20','\x00','\x01','\x02','\x03','\x04','\x05','\x06','\x07','\x08','\x09','\x0a','\x0b','\x0c','\x0d',
+ '\x0e','\x0f','\x10','\x11','\x12','\x13','\x14','\x15','\x16','\x17','\x18','\x19','\x1a','\x1b','\x1c','\x1d',
+ '\x1e','\x1f','\x7f'
+ );
+ $r = $this->Socket->tokenEscapeChars();
+ $this->assertEquals($expected, $r);
+
+ foreach ($expected as $key => $char) {
+ $expected[$key] = chr(hexdec(substr($char, 2)));
+ }
+
+ $r = $this->Socket->tokenEscapeChars(false);
+ $this->assertEquals($expected, $r);
+ }
+
+/**
+ * Test that HttpSocket::escapeToken is escaping all characters as described in RFC 2616 (HTTP 1.1 specs)
+ *
+ * @return void
+ */
+ public function testEscapeToken() {
+ $this->Socket->reset();
+
+ $this->assertEquals('Foo', $this->Socket->escapeToken('Foo'));
+
+ $escape = $this->Socket->tokenEscapeChars(false);
+ foreach ($escape as $char) {
+ $token = 'My-special-' . $char . '-Token';
+ $escapedToken = $this->Socket->escapeToken($token);
+ $expectedToken = 'My-special-"' . $char . '"-Token';
+
+ $this->assertEquals($expectedToken, $escapedToken, 'Test token escaping for ASCII ' . ord($char));
+ }
+
+ $token = 'Extreme-:Token- -"@-test';
+ $escapedToken = $this->Socket->escapeToken($token);
+ $expectedToken = 'Extreme-":"Token-" "-""""@"-test';
+ $this->assertEquals($expectedToken, $escapedToken);
+ }
+
+/**
+ * This tests asserts HttpSocket::reset() resets a HttpSocket instance to it's initial state (before Object::__construct
+ * got executed)
+ *
+ * @return void
+ */
+ public function testReset() {
+ $this->Socket->reset();
+
+ $initialState = get_class_vars('HttpSocket');
+ foreach ($initialState as $property => $value) {
+ $this->Socket->{$property} = 'Overwritten';
+ }
+
+ $return = $this->Socket->reset();
+
+ foreach ($initialState as $property => $value) {
+ $this->assertEquals($this->Socket->{$property}, $value);
+ }
+
+ $this->assertEquals(true, $return);
+ }
+
+/**
+ * This tests asserts HttpSocket::reset(false) resets certain HttpSocket properties to their initial state (before
+ * Object::__construct got executed).
+ *
+ * @return void
+ */
+ public function testPartialReset() {
+ $this->Socket->reset();
+
+ $partialResetProperties = array('request', 'response');
+ $initialState = get_class_vars('HttpSocket');
+
+ foreach ($initialState as $property => $value) {
+ $this->Socket->{$property} = 'Overwritten';
+ }
+
+ $return = $this->Socket->reset(false);
+
+ foreach ($initialState as $property => $originalValue) {
+ if (in_array($property, $partialResetProperties)) {
+ $this->assertEquals($this->Socket->{$property}, $originalValue);
+ } else {
+ $this->assertEquals('Overwritten', $this->Socket->{$property});
+ }
+ }
+ $this->assertEquals(true, $return);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/DispatcherTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/DispatcherTest.php
new file mode 100644
index 0000000..a0e3df7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/DispatcherTest.php
@@ -0,0 +1,1746 @@
+<?php
+/**
+ * DispatcherTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Routing
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Dispatcher', 'Routing');
+
+if (!class_exists('AppController', false)) {
+ require_once CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS . 'AppController.php';
+} elseif (!defined('APP_CONTROLLER_EXISTS')) {
+ define('APP_CONTROLLER_EXISTS', true);
+}
+
+/**
+ * A testing stub that doesn't send headers.
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class DispatcherMockCakeResponse extends CakeResponse {
+
+ protected function _sendHeader($name, $value = null) {
+ return $name . ' ' . $value;
+ }
+
+}
+
+/**
+ * TestDispatcher class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class TestDispatcher extends Dispatcher {
+
+/**
+ * Controller instance, made publicly available for testing
+ *
+ * @var Controller
+ */
+ public $controller;
+
+/**
+ * invoke method
+ *
+ * @param Controller $controller
+ * @param CakeRequest $request
+ * @param CakeResponse $response
+ * @return void
+ */
+ protected function _invoke(Controller $controller, CakeRequest $request, CakeResponse $response) {
+ $this->controller = $controller;
+ return parent::_invoke($controller, $request, $response);
+ }
+
+/**
+ * Helper function to test single method attaching for dispatcher filters
+ *
+ * @param CakeEvent $event
+ * @return void
+ */
+ public function filterTest($event) {
+ $event->data['request']->params['eventName'] = $event->name();
+ }
+
+/**
+ * Helper function to test single method attaching for dispatcher filters
+ *
+ * @param CakeEvent
+ * @return void
+ */
+ public function filterTest2($event) {
+ $event->stopPropagation();
+ return $event->data['response'];
+ }
+
+}
+
+/**
+ * MyPluginAppController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class MyPluginAppController extends AppController {
+}
+
+abstract class DispatcherTestAbstractController extends Controller {
+
+ abstract public function index();
+
+}
+
+interface DispatcherTestInterfaceController {
+
+ public function index();
+
+}
+
+/**
+ * MyPluginController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class MyPluginController extends MyPluginAppController {
+
+/**
+ * name property
+ *
+ * @var string 'MyPlugin'
+ */
+ public $name = 'MyPlugin';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ return true;
+ }
+
+/**
+ * add method
+ *
+ * @return void
+ */
+ public function add() {
+ return true;
+ }
+
+/**
+ * admin_add method
+ *
+ * @param mixed $id
+ * @return void
+ */
+ public function admin_add($id = null) {
+ return $id;
+ }
+
+}
+
+/**
+ * SomePagesController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class SomePagesController extends AppController {
+
+/**
+ * name property
+ *
+ * @var string 'SomePages'
+ */
+ public $name = 'SomePages';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * display method
+ *
+ * @param string $page
+ * @return void
+ */
+ public function display($page = null) {
+ return $page;
+ }
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ return true;
+ }
+
+/**
+ * Test method for returning responses.
+ *
+ * @return CakeResponse
+ */
+ public function responseGenerator() {
+ return new CakeResponse(array('body' => 'new response'));
+ }
+
+}
+
+/**
+ * OtherPagesController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class OtherPagesController extends MyPluginAppController {
+
+/**
+ * name property
+ *
+ * @var string 'OtherPages'
+ */
+ public $name = 'OtherPages';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * display method
+ *
+ * @param string $page
+ * @return void
+ */
+ public function display($page = null) {
+ return $page;
+ }
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ return true;
+ }
+
+}
+
+/**
+ * TestDispatchPagesController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class TestDispatchPagesController extends AppController {
+
+/**
+ * name property
+ *
+ * @var string 'TestDispatchPages'
+ */
+ public $name = 'TestDispatchPages';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * admin_index method
+ *
+ * @return void
+ */
+ public function admin_index() {
+ return true;
+ }
+
+/**
+ * camelCased method
+ *
+ * @return void
+ */
+ public function camelCased() {
+ return true;
+ }
+
+}
+
+/**
+ * ArticlesTestAppController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class ArticlesTestAppController extends AppController {
+}
+
+/**
+ * ArticlesTestController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class ArticlesTestController extends ArticlesTestAppController {
+
+/**
+ * name property
+ *
+ * @var string 'ArticlesTest'
+ */
+ public $name = 'ArticlesTest';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * admin_index method
+ *
+ * @return void
+ */
+ public function admin_index() {
+ return true;
+ }
+
+/**
+ * fake index method.
+ *
+ * @return void
+ */
+ public function index() {
+ return true;
+ }
+
+}
+
+/**
+ * SomePostsController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class SomePostsController extends AppController {
+
+/**
+ * name property
+ *
+ * @var string 'SomePosts'
+ */
+ public $name = 'SomePosts';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * autoRender property
+ *
+ * @var bool false
+ */
+ public $autoRender = false;
+
+/**
+ * beforeFilter method
+ *
+ * @return void
+ */
+ public function beforeFilter() {
+ if ($this->params['action'] == 'index') {
+ $this->params['action'] = 'view';
+ } else {
+ $this->params['action'] = 'change';
+ }
+ $this->params['pass'] = array('changed');
+ }
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ return true;
+ }
+
+/**
+ * change method
+ *
+ * @return void
+ */
+ public function change() {
+ return true;
+ }
+
+}
+
+/**
+ * TestCachedPagesController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class TestCachedPagesController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'TestCachedPages'
+ */
+ public $name = 'TestCachedPages';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * helpers property
+ *
+ * @var array
+ */
+ public $helpers = array('Cache', 'Html');
+
+/**
+ * cacheAction property
+ *
+ * @var array
+ */
+ public $cacheAction = array(
+ 'index' => '+2 sec',
+ 'test_nocache_tags' => '+2 sec',
+ 'view' => '+2 sec'
+ );
+
+/**
+ * Mock out the response object so it doesn't send headers.
+ *
+ * @var string
+ */
+ protected $_responseClass = 'DispatcherMockCakeResponse';
+
+/**
+ * viewPath property
+ *
+ * @var string 'posts'
+ */
+ public $viewPath = 'Posts';
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ $this->render();
+ }
+
+/**
+ * test_nocache_tags method
+ *
+ * @return void
+ */
+ public function test_nocache_tags() {
+ $this->render();
+ }
+
+/**
+ * view method
+ *
+ * @return void
+ */
+ public function view($id = null) {
+ $this->render('index');
+ }
+
+/**
+ * test cached forms / tests view object being registered
+ *
+ * @return void
+ */
+ public function cache_form() {
+ $this->cacheAction = 10;
+ $this->helpers[] = 'Form';
+ }
+
+/**
+ * Test cached views with themes.
+ */
+ public function themed() {
+ $this->cacheAction = 10;
+ $this->viewClass = 'Theme';
+ $this->theme = 'TestTheme';
+ }
+
+}
+
+/**
+ * TimesheetsController class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class TimesheetsController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'Timesheets'
+ */
+ public $name = 'Timesheets';
+
+/**
+ * uses property
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ return true;
+ }
+
+}
+
+/**
+ * DispatcherTest class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class DispatcherTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ $this->_get = $_GET;
+ $_GET = array();
+ $this->_post = $_POST;
+ $this->_files = $_FILES;
+ $this->_server = $_SERVER;
+
+ $this->_app = Configure::read('App');
+ Configure::write('App.base', false);
+ Configure::write('App.baseUrl', false);
+ Configure::write('App.dir', 'app');
+ Configure::write('App.webroot', 'webroot');
+
+ $this->_cache = Configure::read('Cache');
+ Configure::write('Cache.disable', true);
+
+ $this->_debug = Configure::read('debug');
+
+ App::build();
+ App::objects('plugin', null, false);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ $_GET = $this->_get;
+ $_POST = $this->_post;
+ $_FILES = $this->_files;
+ $_SERVER = $this->_server;
+ App::build();
+ CakePlugin::unload();
+ Configure::write('App', $this->_app);
+ Configure::write('Cache', $this->_cache);
+ Configure::write('debug', $this->_debug);
+ Configure::write('Dispatcher.filters', array());
+ }
+
+/**
+ * testParseParamsWithoutZerosAndEmptyPost method
+ *
+ * @return void
+ */
+ public function testParseParamsWithoutZerosAndEmptyPost() {
+ $Dispatcher = new Dispatcher();
+ $request = new CakeRequest("/testcontroller/testaction/params1/params2/params3");
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
+ $Dispatcher->parseParams($event);
+ $this->assertSame($request['controller'], 'testcontroller');
+ $this->assertSame($request['action'], 'testaction');
+ $this->assertSame($request['pass'][0], 'params1');
+ $this->assertSame($request['pass'][1], 'params2');
+ $this->assertSame($request['pass'][2], 'params3');
+ $this->assertFalse(!empty($request['form']));
+ }
+
+/**
+ * testParseParamsReturnsPostedData method
+ *
+ * @return void
+ */
+ public function testParseParamsReturnsPostedData() {
+ $_POST['testdata'] = "My Posted Content";
+ $Dispatcher = new Dispatcher();
+ $request = new CakeRequest("/");
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
+ $Dispatcher->parseParams($event);
+ $test = $Dispatcher->parseParams($event);
+ $this->assertEquals("My Posted Content", $request['data']['testdata']);
+ }
+
+/**
+ * testParseParamsWithSingleZero method
+ *
+ * @return void
+ */
+ public function testParseParamsWithSingleZero() {
+ $Dispatcher = new Dispatcher();
+ $test = new CakeRequest("/testcontroller/testaction/1/0/23");
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
+ $Dispatcher->parseParams($event);
+
+ $this->assertSame($test['controller'], 'testcontroller');
+ $this->assertSame($test['action'], 'testaction');
+ $this->assertSame($test['pass'][0], '1');
+ $this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][1]);
+ $this->assertSame($test['pass'][2], '23');
+ }
+
+/**
+ * testParseParamsWithManySingleZeros method
+ *
+ * @return void
+ */
+ public function testParseParamsWithManySingleZeros() {
+ $Dispatcher = new Dispatcher();
+ $test = new CakeRequest("/testcontroller/testaction/0/0/0/0/0/0");
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
+ $Dispatcher->parseParams($event);
+
+ $this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][0]);
+ $this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][1]);
+ $this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][2]);
+ $this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][3]);
+ $this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][4]);
+ $this->assertRegExp('/\\A(?:0)\\z/', $test['pass'][5]);
+ }
+
+/**
+ * testParseParamsWithManyZerosInEachSectionOfUrl method
+ *
+ * @return void
+ */
+ public function testParseParamsWithManyZerosInEachSectionOfUrl() {
+ $Dispatcher = new Dispatcher();
+ $test = new CakeRequest("/testcontroller/testaction/000/0000/00000/000000/000000/0000000");
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
+ $Dispatcher->parseParams($event);
+
+ $this->assertRegExp('/\\A(?:000)\\z/', $test['pass'][0]);
+ $this->assertRegExp('/\\A(?:0000)\\z/', $test['pass'][1]);
+ $this->assertRegExp('/\\A(?:00000)\\z/', $test['pass'][2]);
+ $this->assertRegExp('/\\A(?:000000)\\z/', $test['pass'][3]);
+ $this->assertRegExp('/\\A(?:000000)\\z/', $test['pass'][4]);
+ $this->assertRegExp('/\\A(?:0000000)\\z/', $test['pass'][5]);
+ }
+
+/**
+ * testParseParamsWithMixedOneToManyZerosInEachSectionOfUrl method
+ *
+ * @return void
+ */
+ public function testParseParamsWithMixedOneToManyZerosInEachSectionOfUrl() {
+ $Dispatcher = new Dispatcher();
+ $test = new CakeRequest("/testcontroller/testaction/01/0403/04010/000002/000030/0000400");
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $test));
+ $Dispatcher->parseParams($event);
+
+ $this->assertRegExp('/\\A(?:01)\\z/', $test['pass'][0]);
+ $this->assertRegExp('/\\A(?:0403)\\z/', $test['pass'][1]);
+ $this->assertRegExp('/\\A(?:04010)\\z/', $test['pass'][2]);
+ $this->assertRegExp('/\\A(?:000002)\\z/', $test['pass'][3]);
+ $this->assertRegExp('/\\A(?:000030)\\z/', $test['pass'][4]);
+ $this->assertRegExp('/\\A(?:0000400)\\z/', $test['pass'][5]);
+ }
+
+/**
+ * testQueryStringOnRoot method
+ *
+ * @return void
+ */
+ public function testQueryStringOnRoot() {
+ Router::reload();
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+ Router::connect('/:controller/:action/*');
+
+ $_GET = array('coffee' => 'life', 'sleep' => 'sissies');
+ $Dispatcher = new Dispatcher();
+ $request = new CakeRequest('posts/home/?coffee=life&sleep=sissies');
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
+ $Dispatcher->parseParams($event);
+
+ $this->assertRegExp('/posts/', $request['controller']);
+ $this->assertRegExp('/home/', $request['action']);
+ $this->assertTrue(isset($request['url']['sleep']));
+ $this->assertTrue(isset($request['url']['coffee']));
+
+ $Dispatcher = new Dispatcher();
+ $request = new CakeRequest('/?coffee=life&sleep=sissy');
+
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $request));
+ $Dispatcher->parseParams($event);
+ $this->assertRegExp('/pages/', $request['controller']);
+ $this->assertRegExp('/display/', $request['action']);
+ $this->assertTrue(isset($request['url']['sleep']));
+ $this->assertTrue(isset($request['url']['coffee']));
+ $this->assertEquals('life', $request['url']['coffee']);
+ }
+
+/**
+ * testMissingController method
+ *
+ * @expectedException MissingControllerException
+ * @expectedExceptionMessage Controller class SomeControllerController could not be found.
+ * @return void
+ */
+ public function testMissingController() {
+ Router::connect('/:controller/:action/*');
+
+ $Dispatcher = new TestDispatcher();
+ Configure::write('App.baseUrl', '/index.php');
+ $url = new CakeRequest('some_controller/home/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ }
+
+/**
+ * testMissingControllerInterface method
+ *
+ * @expectedException MissingControllerException
+ * @expectedExceptionMessage Controller class DispatcherTestInterfaceController could not be found.
+ * @return void
+ */
+ public function testMissingControllerInterface() {
+ Router::connect('/:controller/:action/*');
+
+ $Dispatcher = new TestDispatcher();
+ Configure::write('App.baseUrl', '/index.php');
+ $url = new CakeRequest('dispatcher_test_interface/index');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ }
+
+/**
+ * testMissingControllerInterface method
+ *
+ * @expectedException MissingControllerException
+ * @expectedExceptionMessage Controller class DispatcherTestAbstractController could not be found.
+ * @return void
+ */
+ public function testMissingControllerAbstract() {
+ Router::connect('/:controller/:action/*');
+
+ $Dispatcher = new TestDispatcher();
+ Configure::write('App.baseUrl', '/index.php');
+ $url = new CakeRequest('dispatcher_test_abstract/index');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ }
+
+/**
+ * testDispatch method
+ *
+ * @return void
+ */
+ public function testDispatchBasic() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $Dispatcher = new TestDispatcher();
+ Configure::write('App.baseUrl', '/index.php');
+ $url = new CakeRequest('pages/home/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $expected = 'Pages';
+ $this->assertEquals($expected, $Dispatcher->controller->name);
+
+ $expected = array('0' => 'home', 'param' => 'value', 'param2' => 'value2');
+ $this->assertSame($expected, $Dispatcher->controller->passedArgs);
+
+ Configure::write('App.baseUrl', '/pages/index.php');
+
+ $url = new CakeRequest('pages/home');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $expected = 'Pages';
+ $this->assertEquals($expected, $Dispatcher->controller->name);
+
+ $url = new CakeRequest('pages/home/');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertNull($Dispatcher->controller->plugin);
+
+ $expected = 'Pages';
+ $this->assertEquals($expected, $Dispatcher->controller->name);
+
+ unset($Dispatcher);
+
+ require CAKE . 'Config' . DS . 'routes.php';
+ $Dispatcher = new TestDispatcher();
+ Configure::write('App.baseUrl', '/timesheets/index.php');
+
+ $url = new CakeRequest('timesheets');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $expected = 'Timesheets';
+ $this->assertEquals($expected, $Dispatcher->controller->name);
+
+ $url = new CakeRequest('timesheets/');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $this->assertEquals('Timesheets', $Dispatcher->controller->name);
+ $this->assertEquals('/timesheets/index.php', $url->base);
+
+ $url = new CakeRequest('test_dispatch_pages/camelCased');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
+
+ $url = new CakeRequest('test_dispatch_pages/camelCased/something. .');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertEquals('something. .', $Dispatcher->controller->params['pass'][0], 'Period was chopped off. %s');
+ }
+
+/**
+ * Test that Dispatcher handles actions that return response objects.
+ *
+ * @return void
+ */
+ public function testDispatchActionReturnsResponse() {
+ Router::connect('/:controller/:action');
+ $Dispatcher = new Dispatcher();
+ $request = new CakeRequest('some_pages/responseGenerator');
+ $response = $this->getMock('CakeResponse', array('_sendHeader'));
+
+ ob_start();
+ $Dispatcher->dispatch($request, $response);
+ $result = ob_get_clean();
+
+ $this->assertEquals('new response', $result);
+ }
+
+/**
+ * testAdminDispatch method
+ *
+ * @return void
+ */
+ public function testAdminDispatch() {
+ $_POST = array();
+ $Dispatcher = new TestDispatcher();
+ Configure::write('Routing.prefixes', array('admin'));
+ Configure::write('App.baseUrl','/cake/repo/branches/1.2.x.x/index.php');
+ $url = new CakeRequest('admin/test_dispatch_pages/index/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+
+ Router::reload();
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $this->assertEquals('TestDispatchPages', $Dispatcher->controller->name);
+
+ $this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
+ $this->assertTrue($Dispatcher->controller->params['admin']);
+
+ $expected = '/cake/repo/branches/1.2.x.x/index.php/admin/test_dispatch_pages/index/param:value/param2:value2';
+ $this->assertSame($expected, $Dispatcher->controller->here);
+
+ $expected = '/cake/repo/branches/1.2.x.x/index.php';
+ $this->assertSame($expected, $Dispatcher->controller->base);
+ }
+
+/**
+ * testPluginDispatch method
+ *
+ * @return void
+ */
+ public function testPluginDispatch() {
+ $_POST = array();
+
+ Router::reload();
+ $Dispatcher = new TestDispatcher();
+ Router::connect(
+ '/my_plugin/:controller/*',
+ array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'display')
+ );
+
+ $url = new CakeRequest('my_plugin/some_pages/home/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $event = new CakeEvent('DispatcherTest', $Dispatcher, array('request' => $url));
+ $Dispatcher->parseParams($event);
+ $expected = array(
+ 'pass' => array('home'),
+ 'named' => array('param' => 'value', 'param2' => 'value2'), 'plugin' => 'my_plugin',
+ 'controller' => 'some_pages', 'action' => 'display'
+ );
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $url[$key], 'Value mismatch ' . $key . ' %');
+ }
+
+ $this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->name, 'SomePages');
+ $this->assertSame($Dispatcher->controller->params['controller'], 'some_pages');
+ $this->assertSame($Dispatcher->controller->passedArgs, array('0' => 'home', 'param' => 'value', 'param2' => 'value2'));
+ }
+
+/**
+ * testAutomaticPluginDispatch method
+ *
+ * @return void
+ */
+ public function testAutomaticPluginDispatch() {
+ $_POST = array();
+ $_SERVER['PHP_SELF'] = '/cake/repo/branches/1.2.x.x/index.php';
+
+ Router::reload();
+ $Dispatcher = new TestDispatcher();
+ Router::connect(
+ '/my_plugin/:controller/:action/*',
+ array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'display')
+ );
+
+ $Dispatcher->base = false;
+
+ $url = new CakeRequest('my_plugin/other_pages/index/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->name, 'OtherPages');
+ $this->assertSame($Dispatcher->controller->action, 'index');
+ $this->assertSame($Dispatcher->controller->passedArgs, array('param' => 'value', 'param2' => 'value2'));
+
+ $expected = '/cake/repo/branches/1.2.x.x/my_plugin/other_pages/index/param:value/param2:value2';
+ $this->assertSame($expected, $url->here);
+
+ $expected = '/cake/repo/branches/1.2.x.x';
+ $this->assertSame($expected, $url->base);
+ }
+
+/**
+ * testAutomaticPluginControllerDispatch method
+ *
+ * @return void
+ */
+ public function testAutomaticPluginControllerDispatch() {
+ $plugins = App::objects('plugin');
+ $plugins[] = 'MyPlugin';
+ $plugins[] = 'ArticlesTest';
+
+ CakePlugin::load('MyPlugin', array('path' => '/fake/path'));
+
+ Router::reload();
+ $Dispatcher = new TestDispatcher();
+ $Dispatcher->base = false;
+
+ $url = new CakeRequest('my_plugin/my_plugin/add/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->name, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->action, 'add');
+ $this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $Dispatcher = new TestDispatcher();
+ $Dispatcher->base = false;
+
+ // Simulates the Route for a real plugin, installed in APP/plugins
+ Router::connect('/my_plugin/:controller/:action/*', array('plugin' => 'my_plugin'));
+
+ $plugin = 'MyPlugin';
+ $pluginUrl = Inflector::underscore($plugin);
+
+ $url = new CakeRequest($pluginUrl);
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->name, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->action, 'index');
+
+ $expected = $pluginUrl;
+ $this->assertEquals($expected, $Dispatcher->controller->params['controller']);
+
+ Configure::write('Routing.prefixes', array('admin'));
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $Dispatcher = new TestDispatcher();
+
+ $url = new CakeRequest('admin/my_plugin/my_plugin/add/5/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
+ $this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
+ $this->assertEquals('admin_add', $Dispatcher->controller->params['action']);
+ $this->assertEquals(array(5), $Dispatcher->controller->params['pass']);
+ $this->assertEquals(array('param' => 'value', 'param2' => 'value2'), $Dispatcher->controller->params['named']);
+ $this->assertSame($Dispatcher->controller->plugin, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->name, 'MyPlugin');
+ $this->assertSame($Dispatcher->controller->action, 'admin_add');
+
+ $expected = array(0 => 5, 'param' => 'value', 'param2' => 'value2');
+ $this->assertEquals($expected, $Dispatcher->controller->passedArgs);
+
+ Configure::write('Routing.prefixes', array('admin'));
+ CakePlugin::load('ArticlesTest', array('path' => '/fake/path'));
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+
+ $Dispatcher = new TestDispatcher();
+
+ $Dispatcher->dispatch(new CakeRequest('admin/articles_test'), $response, array('return' => 1));
+ $this->assertSame($Dispatcher->controller->plugin, 'ArticlesTest');
+ $this->assertSame($Dispatcher->controller->name, 'ArticlesTest');
+ $this->assertSame($Dispatcher->controller->action, 'admin_index');
+
+ $expected = array(
+ 'pass' => array(),
+ 'named' => array(),
+ 'controller' => 'articles_test',
+ 'plugin' => 'articles_test',
+ 'action' => 'admin_index',
+ 'prefix' => 'admin',
+ 'admin' => true,
+ 'return' => 1
+ );
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($expected[$key], $Dispatcher->controller->request[$key], 'Value mismatch ' . $key);
+ }
+ }
+
+/**
+ * test Plugin dispatching without controller name and using
+ * plugin short form instead.
+ *
+ * @return void
+ */
+ public function testAutomaticPluginDispatchWithShortAccess() {
+ CakePlugin::load('MyPlugin', array('path' => '/fake/path'));
+ Router::reload();
+
+ $Dispatcher = new TestDispatcher();
+ $Dispatcher->base = false;
+
+ $url = new CakeRequest('my_plugin/');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertEquals('my_plugin', $Dispatcher->controller->params['controller']);
+ $this->assertEquals('my_plugin', $Dispatcher->controller->params['plugin']);
+ $this->assertEquals('index', $Dispatcher->controller->params['action']);
+ $this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
+ }
+
+/**
+ * test plugin shortcut urls with controllers that need to be loaded,
+ * the above test uses a controller that has already been included.
+ *
+ * @return void
+ */
+ public function testPluginShortCutUrlsWithControllerThatNeedsToBeLoaded() {
+ $loaded = class_exists('TestPluginController', false);
+ $this->skipIf($loaded, 'TestPluginController already loaded.');
+
+ Router::reload();
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+
+ $Dispatcher = new TestDispatcher();
+ $Dispatcher->base = false;
+
+ $url = new CakeRequest('test_plugin/');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertEquals('test_plugin', $Dispatcher->controller->params['controller']);
+ $this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
+ $this->assertEquals('index', $Dispatcher->controller->params['action']);
+ $this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
+
+ $url = new CakeRequest('/test_plugin/tests/index');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertEquals('tests', $Dispatcher->controller->params['controller']);
+ $this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
+ $this->assertEquals('index', $Dispatcher->controller->params['action']);
+ $this->assertFalse(isset($Dispatcher->controller->params['pass'][0]));
+
+ $url = new CakeRequest('/test_plugin/tests/index/some_param');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertEquals('tests', $Dispatcher->controller->params['controller']);
+ $this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
+ $this->assertEquals('index', $Dispatcher->controller->params['action']);
+ $this->assertEquals('some_param', $Dispatcher->controller->params['pass'][0]);
+
+ App::build();
+ }
+
+/**
+ * testAutomaticPluginControllerMissingActionDispatch method
+ *
+ * @expectedException MissingActionException
+ * @expectedExceptionMessage Action MyPluginController::not_here() could not be found.
+ * @return void
+ */
+ public function testAutomaticPluginControllerMissingActionDispatch() {
+ Router::reload();
+ $Dispatcher = new TestDispatcher();
+
+ $url = new CakeRequest('my_plugin/not_here/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ }
+
+/**
+ * testAutomaticPluginControllerMissingActionDispatch method
+ *
+ * @expectedException MissingActionException
+ * @expectedExceptionMessage Action MyPluginController::param:value() could not be found.
+ * @return void
+ */
+
+ public function testAutomaticPluginControllerIndexMissingAction() {
+ Router::reload();
+ $Dispatcher = new TestDispatcher();
+
+ $url = new CakeRequest('my_plugin/param:value/param2:value2');
+ $response = $this->getMock('CakeResponse');
+
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ }
+
+/**
+ * Test dispatching into the TestPlugin in the test_app
+ *
+ * @return void
+ */
+ public function testTestPluginDispatch() {
+ $Dispatcher = new TestDispatcher();
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+ Router::reload();
+ Router::parse('/');
+
+ $url = new CakeRequest('/test_plugin/tests/index');
+ $response = $this->getMock('CakeResponse');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->assertTrue(class_exists('TestsController'));
+ $this->assertTrue(class_exists('TestPluginAppController'));
+ $this->assertTrue(class_exists('PluginsComponent'));
+
+ $this->assertEquals('tests', $Dispatcher->controller->params['controller']);
+ $this->assertEquals('test_plugin', $Dispatcher->controller->params['plugin']);
+ $this->assertEquals('index', $Dispatcher->controller->params['action']);
+
+ App::build();
+ }
+
+/**
+ * Tests that it is possible to attach filter classes to the dispatch cycle
+ *
+ * @return void
+ */
+ public function testDispatcherFilterSuscriber() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+
+ CakePlugin::load('TestPlugin');
+ Configure::write('Dispatcher.filters', array(
+ array('callable' => 'TestPlugin.TestDispatcherFilter')
+ ));
+ $dispatcher = new TestDispatcher();
+ $request = new CakeRequest('/');
+ $request->params['altered'] = false;
+ $response = $this->getMock('CakeResponse', array('send'));
+
+ $dispatcher->dispatch($request, $response);
+ $this->assertTrue($request->params['altered']);
+ $this->assertEquals(304, $response->statusCode());
+
+ Configure::write('Dispatcher.filters', array(
+ 'TestPlugin.Test2DispatcherFilter',
+ 'TestPlugin.TestDispatcherFilter'
+ ));
+ $dispatcher = new TestDispatcher();
+ $request = new CakeRequest('/');
+ $request->params['altered'] = false;
+ $response = $this->getMock('CakeResponse', array('send'));
+
+ $dispatcher->dispatch($request, $response);
+ $this->assertFalse($request->params['altered']);
+ $this->assertEquals(500, $response->statusCode());
+ $this->assertNull($dispatcher->controller);
+ }
+
+/**
+ * Tests that attaching an inexistent class as filter will throw an exception
+ *
+ * @expectedException MissingDispatcherFilterException
+ * @return void
+ */
+ public function testDispatcherFilterSuscriberMissing() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+
+ CakePlugin::load('TestPlugin');
+ Configure::write('Dispatcher.filters', array(
+ array('callable' => 'TestPlugin.NotAFilter')
+ ));
+ $dispatcher = new TestDispatcher();
+ $request = new CakeRequest('/');
+ $response = $this->getMock('CakeResponse', array('send'));
+ $dispatcher->dispatch($request, $response);
+ }
+
+/**
+ * Tests it is possible to attach single callables as filters
+ *
+ * @return void
+ */
+ public function testDispatcherFilterCallable() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), App::RESET);
+
+ $dispatcher = new TestDispatcher();
+ Configure::write('Dispatcher.filters', array(
+ array('callable' => array($dispatcher, 'filterTest'), 'on' => 'before')
+ ));
+
+ $request = new CakeRequest('/');
+ $response = $this->getMock('CakeResponse', array('send'));
+ $dispatcher->dispatch($request, $response);
+ $this->assertEquals('Dispatcher.beforeDispatch', $request->params['eventName']);
+
+ $dispatcher = new TestDispatcher();
+ Configure::write('Dispatcher.filters', array(
+ array('callable' => array($dispatcher, 'filterTest'), 'on' => 'after')
+ ));
+
+ $request = new CakeRequest('/');
+ $response = $this->getMock('CakeResponse', array('send'));
+ $dispatcher->dispatch($request, $response);
+ $this->assertEquals('Dispatcher.afterDispatch', $request->params['eventName']);
+
+ // Test that it is possible to skip the route connection process
+ $dispatcher = new TestDispatcher();
+ Configure::write('Dispatcher.filters', array(
+ array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
+ ));
+
+ $request = new CakeRequest('/');
+ $response = $this->getMock('CakeResponse', array('send'));
+ $dispatcher->dispatch($request, $response);
+ $this->assertEmpty($dispatcher->controller);
+ $expected = array('controller' => null, 'action' => null, 'plugin' => null, 'named' => array(), 'pass' => array());
+ $this->assertEquals($expected, $request->params);
+
+ $dispatcher = new TestDispatcher();
+ Configure::write('Dispatcher.filters', array(
+ array('callable' => array($dispatcher, 'filterTest2'), 'on' => 'before', 'priority' => 1)
+ ));
+
+ $request = new CakeRequest('/');
+ $request->params['return'] = true;
+ $response = $this->getMock('CakeResponse', array('send'));
+ $response->body('this is a body');
+ $result = $dispatcher->dispatch($request, $response);
+ $this->assertEquals('this is a body', $result);
+
+ $request = new CakeRequest('/');
+ $response = $this->getMock('CakeResponse', array('send'));
+ $response->expects($this->once())->method('send');
+ $response->body('this is a body');
+ $result = $dispatcher->dispatch($request, $response);
+ $this->assertNull($result);
+ }
+
+/**
+ * testChangingParamsFromBeforeFilter method
+ *
+ * @return void
+ */
+ public function testChangingParamsFromBeforeFilter() {
+ $Dispatcher = new TestDispatcher();
+ $response = $this->getMock('CakeResponse');
+ $url = new CakeRequest('some_posts/index/param:value/param2:value2');
+
+ try {
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+ $this->fail('No exception.');
+ } catch (MissingActionException $e) {
+ $this->assertEquals('Action SomePostsController::view() could not be found.', $e->getMessage());
+ }
+
+ $url = new CakeRequest('some_posts/something_else/param:value/param2:value2');
+ $Dispatcher->dispatch($url, $response, array('return' => 1));
+
+ $expected = 'SomePosts';
+ $this->assertEquals($expected, $Dispatcher->controller->name);
+
+ $expected = 'change';
+ $this->assertEquals($expected, $Dispatcher->controller->action);
+
+ $expected = array('changed');
+ $this->assertSame($expected, $Dispatcher->controller->params['pass']);
+ }
+
+/**
+ * testStaticAssets method
+ *
+ * @return void
+ */
+ public function testAssets() {
+ Router::reload();
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Vendor' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+ Configure::write('Dispatcher.filters', array('AssetDispatcher'));
+
+ $Dispatcher = new TestDispatcher();
+ $response = $this->getMock('CakeResponse', array('_sendHeader'));
+
+ try {
+ $Dispatcher->dispatch(new CakeRequest('theme/test_theme/../webroot/css/test_asset.css'), $response);
+ $this->fail('No exception');
+ } catch (MissingControllerException $e) {
+ $this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
+ }
+
+ try {
+ $Dispatcher->dispatch(new CakeRequest('theme/test_theme/pdfs'), $response);
+ $this->fail('No exception');
+ } catch (MissingControllerException $e) {
+ $this->assertEquals('Controller class ThemeController could not be found.', $e->getMessage());
+ }
+ }
+
+/**
+ * Data provider for asset filter
+ *
+ * - theme assets.
+ * - plugin assets.
+ * - plugin assets in sub directories.
+ * - unknown plugin assets.
+ *
+ * @return array
+ */
+ public static function assetProvider() {
+ return array(
+ array(
+ 'theme/test_theme/flash/theme_test.swf',
+ 'View/Themed/TestTheme/webroot/flash/theme_test.swf'
+ ),
+ array(
+ 'theme/test_theme/pdfs/theme_test.pdf',
+ 'View/Themed/TestTheme/webroot/pdfs/theme_test.pdf'
+ ),
+ array(
+ 'theme/test_theme/img/test.jpg',
+ 'View/Themed/TestTheme/webroot/img/test.jpg'
+ ),
+ array(
+ 'theme/test_theme/css/test_asset.css',
+ 'View/Themed/TestTheme/webroot/css/test_asset.css'
+ ),
+ array(
+ 'theme/test_theme/js/theme.js',
+ 'View/Themed/TestTheme/webroot/js/theme.js'
+ ),
+ array(
+ 'theme/test_theme/js/one/theme_one.js',
+ 'View/Themed/TestTheme/webroot/js/one/theme_one.js'
+ ),
+ array(
+ 'theme/test_theme/space%20image.text',
+ 'View/Themed/TestTheme/webroot/space image.text'
+ ),
+ array(
+ 'test_plugin/root.js',
+ 'Plugin/TestPlugin/webroot/root.js'
+ ),
+ array(
+ 'test_plugin/flash/plugin_test.swf',
+ 'Plugin/TestPlugin/webroot/flash/plugin_test.swf'
+ ),
+ array(
+ 'test_plugin/pdfs/plugin_test.pdf',
+ 'Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf'
+ ),
+ array(
+ 'test_plugin/js/test_plugin/test.js',
+ 'Plugin/TestPlugin/webroot/js/test_plugin/test.js'
+ ),
+ array(
+ 'test_plugin/css/test_plugin_asset.css',
+ 'Plugin/TestPlugin/webroot/css/test_plugin_asset.css'
+ ),
+ array(
+ 'test_plugin/img/cake.icon.gif',
+ 'Plugin/TestPlugin/webroot/img/cake.icon.gif'
+ ),
+ array(
+ 'plugin_js/js/plugin_js.js',
+ 'Plugin/PluginJs/webroot/js/plugin_js.js'
+ ),
+ array(
+ 'plugin_js/js/one/plugin_one.js',
+ 'Plugin/PluginJs/webroot/js/one/plugin_one.js'
+ ),
+ array(
+ 'test_plugin/css/unknown.extension',
+ 'Plugin/TestPlugin/webroot/css/unknown.extension'
+ ),
+ array(
+ 'test_plugin/css/theme_one.htc',
+ 'Plugin/TestPlugin/webroot/css/theme_one.htc'
+ ),
+ );
+ }
+
+/**
+ * Test assets
+ *
+ * @dataProvider assetProvider
+ * @outputBuffering enabled
+ * @return void
+ */
+ public function testAsset($url, $file) {
+ Router::reload();
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Vendor' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ CakePlugin::load(array('TestPlugin', 'PluginJs'));
+ Configure::write('Dispatcher.filters', array('AssetDispatcher'));
+
+ $Dispatcher = new TestDispatcher();
+ $response = $this->getMock('CakeResponse', array('_sendHeader'));
+
+ $Dispatcher->dispatch(new CakeRequest($url), $response);
+ $result = ob_get_clean();
+
+ $path = CAKE . 'Test' . DS . 'test_app' . DS . str_replace('/', DS, $file);
+ $file = file_get_contents($path);
+ $this->assertEquals($file, $result);
+
+ $expected = filesize($path);
+ $headers = $response->header();
+ $this->assertEquals($expected, $headers['Content-Length']);
+ }
+
+/**
+ * test that missing asset processors trigger a 404 with no response body.
+ *
+ * @return void
+ */
+ public function testMissingAssetProcessor404() {
+ $response = $this->getMock('CakeResponse', array('send'));
+ $Dispatcher = new TestDispatcher();
+ Configure::write('Asset.filter', array(
+ 'js' => '',
+ 'css' => null
+ ));
+ Configure::write('Dispatcher.filters', array('AssetDispatcher'));
+
+ $request = new CakeRequest('ccss/cake.generic.css');
+ $Dispatcher->dispatch($request, $response);
+ $this->assertEquals('404', $response->statusCode());
+ }
+
+/**
+ * Data provider for cached actions.
+ *
+ * - Test simple views
+ * - Test views with nocache tags
+ * - Test requests with named + passed params.
+ * - Test requests with query string params
+ * - Test themed views.
+ *
+ * @return array
+ */
+ public static function cacheActionProvider() {
+ return array(
+ array('/'),
+ array('test_cached_pages/index'),
+ array('TestCachedPages/index'),
+ array('test_cached_pages/test_nocache_tags'),
+ array('TestCachedPages/test_nocache_tags'),
+ array('test_cached_pages/view/param/param'),
+ array('test_cached_pages/view/foo:bar/value:goo'),
+ array('test_cached_pages/view?q=cakephp'),
+ array('test_cached_pages/themed'),
+ );
+ }
+
+/**
+ * testFullPageCachingDispatch method
+ *
+ * @dataProvider cacheActionProvider
+ * @return void
+ */
+ public function testFullPageCachingDispatch($url) {
+ Configure::write('Cache.disable', false);
+ Configure::write('Cache.check', true);
+ Configure::write('debug', 2);
+
+ Router::reload();
+ Router::connect('/', array('controller' => 'test_cached_pages', 'action' => 'index'));
+ Router::connect('/:controller/:action/*');
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
+ ), App::RESET);
+
+ $dispatcher = new TestDispatcher();
+ $request = new CakeRequest($url);
+ $response = $this->getMock('CakeResponse', array('send'));
+
+ $dispatcher->dispatch($request, $response);
+ $out = $response->body();
+
+ Configure::write('Dispatcher.filters', array('CacheDispatcher'));
+ $request = new CakeRequest($url);
+ $response = $this->getMock('CakeResponse', array('send'));
+ $dispatcher = new TestDispatcher();
+ $dispatcher->dispatch($request, $response);
+ $cached = $response->body();
+
+ $cached = preg_replace('/<!--+[^<>]+-->/', '', $cached);
+
+ $this->assertTextEquals($out, $cached);
+
+ $filename = $this->__cachePath($request->here());
+ unlink($filename);
+ }
+
+/**
+ * testHttpMethodOverrides method
+ *
+ * @return void
+ */
+ public function testHttpMethodOverrides() {
+ Router::reload();
+ Router::mapResources('Posts');
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $dispatcher = new Dispatcher();
+
+ $request = new CakeRequest('/posts');
+ $event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
+ $dispatcher->parseParams($event);
+ $expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST');
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
+ }
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
+
+ $request = new CakeRequest('/posts/5');
+ $event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
+ $dispatcher->parseParams($event);
+ $expected = array(
+ 'pass' => array('5'),
+ 'named' => array(),
+ 'id' => '5',
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'edit',
+ '[method]' => 'PUT'
+ );
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
+ }
+
+ unset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+
+ $request = new CakeRequest('/posts/5');
+ $event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
+ $dispatcher->parseParams($event);
+ $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET');
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
+ }
+
+ $_POST['_method'] = 'PUT';
+
+ $request = new CakeRequest('/posts/5');
+ $event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
+ $dispatcher->parseParams($event);
+ $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT');
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
+ }
+
+ $_POST['_method'] = 'POST';
+ $_POST['data'] = array('Post' => array('title' => 'New Post'));
+ $_POST['extra'] = 'data';
+ $_SERVER = array();
+
+ $request = new CakeRequest('/posts');
+ $event = new CakeEvent('DispatcherTest', $dispatcher, array('request' => $request));
+ $dispatcher->parseParams($event);
+ $expected = array(
+ 'pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add',
+ '[method]' => 'POST', 'data' => array('extra' => 'data', 'Post' => array('title' => 'New Post')),
+ );
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $request[$key], 'Value mismatch for ' . $key . ' %s');
+ }
+
+ unset($_POST['_method']);
+ }
+
+/**
+ * backupEnvironment method
+ *
+ * @return void
+ */
+ protected function __backupEnvironment() {
+ return array(
+ 'App' => Configure::read('App'),
+ 'GET' => $_GET,
+ 'POST' => $_POST,
+ 'SERVER' => $_SERVER
+ );
+ }
+
+/**
+ * reloadEnvironment method
+ *
+ * @return void
+ */
+ protected function __reloadEnvironment() {
+ foreach ($_GET as $key => $val) {
+ unset($_GET[$key]);
+ }
+ foreach ($_POST as $key => $val) {
+ unset($_POST[$key]);
+ }
+ foreach ($_SERVER as $key => $val) {
+ unset($_SERVER[$key]);
+ }
+ Configure::write('App', array());
+ }
+
+/**
+ * loadEnvironment method
+ *
+ * @param array $env
+ * @return void
+ */
+ protected function __loadEnvironment($env) {
+ if ($env['reload']) {
+ $this->__reloadEnvironment();
+ }
+
+ if (isset($env['App'])) {
+ Configure::write('App', $env['App']);
+ }
+
+ if (isset($env['GET'])) {
+ foreach ($env['GET'] as $key => $val) {
+ $_GET[$key] = $val;
+ }
+ }
+
+ if (isset($env['POST'])) {
+ foreach ($env['POST'] as $key => $val) {
+ $_POST[$key] = $val;
+ }
+ }
+
+ if (isset($env['SERVER'])) {
+ foreach ($env['SERVER'] as $key => $val) {
+ $_SERVER[$key] = $val;
+ }
+ }
+ }
+
+/**
+ * cachePath method
+ *
+ * @param string $here
+ * @return string
+ */
+ protected function __cachePath($here) {
+ $path = $here;
+ if ($here == '/') {
+ $path = 'home';
+ }
+ $path = strtolower(Inflector::slug($path));
+
+ $filename = CACHE . 'views' . DS . $path . '.php';
+
+ if (!file_exists($filename)) {
+ $filename = CACHE . 'views' . DS . $path . '_index.php';
+ }
+ return $filename;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php
new file mode 100644
index 0000000..28d44b4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package Cake.Test.Case.Routing.Filter
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AssetDispatcher', 'Routing/Filter');
+App::uses('CakeEvent', 'Event');
+App::uses('CakeResponse', 'Network');
+
+class AssetDispatcherTest extends CakeTestCase {
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ Configure::write('Dispatcher.filters', array());
+ }
+
+/**
+ * test that asset filters work for theme and plugin assets
+ *
+ * @return void
+ */
+ public function testAssetFilterForThemeAndPlugins() {
+ $filter = new AssetDispatcher();
+ $response = $this->getMock('CakeResponse', array('_sendHeader'));
+ Configure::write('Asset.filter', array(
+ 'js' => '',
+ 'css' => ''
+ ));
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), APP::RESET);
+
+ $request = new CakeRequest('theme/test_theme/ccss/cake.generic.css');
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+ $this->assertSame($response, $filter->beforeDispatch($event));
+ $this->assertTrue($event->isStopped());
+
+ $request = new CakeRequest('theme/test_theme/cjs/debug_kit.js');
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+ $this->assertSame($response, $filter->beforeDispatch($event));
+ $this->assertTrue($event->isStopped());
+
+ $request = new CakeRequest('test_plugin/ccss/cake.generic.css');
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+ $this->assertSame($response, $filter->beforeDispatch($event));
+ $this->assertTrue($event->isStopped());
+
+ $request = new CakeRequest('test_plugin/cjs/debug_kit.js');
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+ $this->assertSame($response, $filter->beforeDispatch($event));
+ $this->assertTrue($event->isStopped());
+
+ $request = new CakeRequest('css/ccss/debug_kit.css');
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+ $this->assertNull($filter->beforeDispatch($event));
+ $this->assertFalse($event->isStopped());
+
+ $request = new CakeRequest('js/cjs/debug_kit.js');
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+ $this->assertNull($filter->beforeDispatch($event));
+ $this->assertFalse($event->isStopped());
+ }
+
+/**
+ * Tests that $response->checkNotModified() is called and bypasses
+ * file dispatching
+ *
+ * @return void
+ */
+ public function testNotModified() {
+ $filter = new AssetDispatcher();
+ Configure::write('Asset.filter', array(
+ 'js' => '',
+ 'css' => ''
+ ));
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $time = filemtime(App::themePath('TestTheme') . 'webroot' . DS . 'img' . DS . 'cake.power.gif');
+ $time = new DateTime('@' . $time);
+
+ $response = $this->getMock('CakeResponse', array('send', 'checkNotModified'));
+ $request = new CakeRequest('theme/test_theme/img/cake.power.gif');
+
+ $response->expects($this->once())->method('checkNotModified')
+ ->with($request)
+ ->will($this->returnValue(true));
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+
+ ob_start();
+ $this->assertSame($response, $filter->beforeDispatch($event));
+ ob_end_clean();
+ $this->assertEquals(200, $response->statusCode());
+ $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
+
+ $response = $this->getMock('CakeResponse', array('_sendHeader', 'checkNotModified'));
+ $request = new CakeRequest('theme/test_theme/img/cake.power.gif');
+
+ $response->expects($this->once())->method('checkNotModified')
+ ->with($request)
+ ->will($this->returnValue(true));
+ $response->expects($this->never())->method('send');
+ $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response'));
+
+ $this->assertSame($response, $filter->beforeDispatch($event));
+ $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified());
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php
new file mode 100644
index 0000000..c393dc2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/CakeRouteTest.php
@@ -0,0 +1,883 @@
+<?php
+/**
+ * CakeRequest Test case file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Routing.Route
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeRoute', 'Routing/Route');
+App::uses('Router', 'Routing');
+
+/**
+ * Test case for CakeRoute
+ *
+ * @package Cake.Test.Case.Routing.Route
+ **/
+class CakeRouteTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Routing', array('admin' => null, 'prefixes' => array()));
+ }
+
+/**
+ * Test the construction of a CakeRoute
+ *
+ * @return void
+ **/
+ public function testConstruction() {
+ $route = new CakeRoute('/:controller/:action/:id', array(), array('id' => '[0-9]+'));
+
+ $this->assertEquals('/:controller/:action/:id', $route->template);
+ $this->assertEquals(array(), $route->defaults);
+ $this->assertEquals(array('id' => '[0-9]+'), $route->options);
+ $this->assertFalse($route->compiled());
+ }
+
+/**
+ * test Route compiling.
+ *
+ * @return void
+ **/
+ public function testBasicRouteCompiling() {
+ $route = new CakeRoute('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+ $result = $route->compile();
+ $expected = '#^/*$#';
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(array(), $route->keys);
+
+ $route = new CakeRoute('/:controller/:action', array('controller' => 'posts'));
+ $result = $route->compile();
+
+ $this->assertRegExp($result, '/posts/edit');
+ $this->assertRegExp($result, '/posts/super_delete');
+ $this->assertNotRegExp($result, '/posts');
+ $this->assertNotRegExp($result, '/posts/super_delete/1');
+
+ $route = new CakeRoute('/posts/foo:id', array('controller' => 'posts', 'action' => 'view'));
+ $result = $route->compile();
+
+ $this->assertRegExp($result, '/posts/foo:1');
+ $this->assertRegExp($result, '/posts/foo:param');
+ $this->assertNotRegExp($result, '/posts');
+ $this->assertNotRegExp($result, '/posts/');
+
+ $this->assertEquals(array('id'), $route->keys);
+
+ $route = new CakeRoute('/:plugin/:controller/:action/*', array('plugin' => 'test_plugin', 'action' => 'index'));
+ $result = $route->compile();
+ $this->assertRegExp($result, '/test_plugin/posts/index');
+ $this->assertRegExp($result, '/test_plugin/posts/edit/5');
+ $this->assertRegExp($result, '/test_plugin/posts/edit/5/name:value/nick:name');
+ }
+
+/**
+ * test that route parameters that overlap don't cause errors.
+ *
+ * @return void
+ */
+ public function testRouteParameterOverlap() {
+ $route = new CakeRoute('/invoices/add/:idd/:id', array('controller' => 'invoices', 'action' => 'add'));
+ $result = $route->compile();
+ $this->assertRegExp($result, '/invoices/add/1/3');
+
+ $route = new CakeRoute('/invoices/add/:id/:idd', array('controller' => 'invoices', 'action' => 'add'));
+ $result = $route->compile();
+ $this->assertRegExp($result, '/invoices/add/1/3');
+ }
+
+/**
+ * test compiling routes with keys that have patterns
+ *
+ * @return void
+ **/
+ public function testRouteCompilingWithParamPatterns() {
+ $route = new CakeRoute(
+ '/:controller/:action/:id',
+ array(),
+ array('id' => Router::ID)
+ );
+ $result = $route->compile();
+ $this->assertRegExp($result, '/posts/edit/1');
+ $this->assertRegExp($result, '/posts/view/518098');
+ $this->assertNotRegExp($result, '/posts/edit/name-of-post');
+ $this->assertNotRegExp($result, '/posts/edit/4/other:param');
+ $this->assertEquals(array('controller', 'action', 'id'), $route->keys);
+
+ $route = new CakeRoute(
+ '/:lang/:controller/:action/:id',
+ array('controller' => 'testing4'),
+ array('id' => Router::ID, 'lang' => '[a-z]{3}')
+ );
+ $result = $route->compile();
+ $this->assertRegExp($result, '/eng/posts/edit/1');
+ $this->assertRegExp($result, '/cze/articles/view/1');
+ $this->assertNotRegExp($result, '/language/articles/view/2');
+ $this->assertNotRegExp($result, '/eng/articles/view/name-of-article');
+ $this->assertEquals(array('lang', 'controller', 'action', 'id'), $route->keys);
+
+ foreach (array(':', '@', ';', '$', '-') as $delim) {
+ $route = new CakeRoute('/posts/:id' . $delim . ':title');
+ $result = $route->compile();
+
+ $this->assertRegExp($result, '/posts/1' . $delim . 'name-of-article');
+ $this->assertRegExp($result, '/posts/13244' . $delim . 'name-of_Article[]');
+ $this->assertNotRegExp($result, '/posts/11!nameofarticle');
+ $this->assertNotRegExp($result, '/posts/11');
+
+ $this->assertEquals(array('id', 'title'), $route->keys);
+ }
+
+ $route = new CakeRoute(
+ '/posts/:id::title/:year',
+ array('controller' => 'posts', 'action' => 'view'),
+ array('id' => Router::ID, 'year' => Router::YEAR, 'title' => '[a-z-_]+')
+ );
+ $result = $route->compile();
+ $this->assertRegExp($result, '/posts/1:name-of-article/2009/');
+ $this->assertRegExp($result, '/posts/13244:name-of-article/1999');
+ $this->assertNotRegExp($result, '/posts/hey_now:nameofarticle');
+ $this->assertNotRegExp($result, '/posts/:nameofarticle/2009');
+ $this->assertNotRegExp($result, '/posts/:nameofarticle/01');
+ $this->assertEquals(array('id', 'title', 'year'), $route->keys);
+
+ $route = new CakeRoute(
+ '/posts/:url_title-(uuid::id)',
+ array('controller' => 'posts', 'action' => 'view'),
+ array('pass' => array('id', 'url_title'), 'id' => Router::ID)
+ );
+ $result = $route->compile();
+ $this->assertRegExp($result, '/posts/some_title_for_article-(uuid:12534)/');
+ $this->assertRegExp($result, '/posts/some_title_for_article-(uuid:12534)');
+ $this->assertNotRegExp($result, '/posts/');
+ $this->assertNotRegExp($result, '/posts/nameofarticle');
+ $this->assertNotRegExp($result, '/posts/nameofarticle-12347');
+ $this->assertEquals(array('url_title', 'id'), $route->keys);
+ }
+
+/**
+ * test more complex route compiling & parsing with mid route greedy stars
+ * and optional routing parameters
+ *
+ * @return void
+ */
+ public function testComplexRouteCompilingAndParsing() {
+ $route = new CakeRoute(
+ '/posts/:month/:day/:year/*',
+ array('controller' => 'posts', 'action' => 'view'),
+ array('year' => Router::YEAR, 'month' => Router::MONTH, 'day' => Router::DAY)
+ );
+ $result = $route->compile();
+ $this->assertRegExp($result, '/posts/08/01/2007/title-of-post');
+ $result = $route->parse('/posts/08/01/2007/title-of-post');
+
+ $this->assertEquals(7, count($result));
+ $this->assertEquals('posts', $result['controller']);
+ $this->assertEquals('view', $result['action']);
+ $this->assertEquals('2007', $result['year']);
+ $this->assertEquals('08', $result['month']);
+ $this->assertEquals('01', $result['day']);
+ $this->assertEquals('title-of-post', $result['pass'][0]);
+
+ $route = new CakeRoute(
+ "/:extra/page/:slug/*",
+ array('controller' => 'pages', 'action' => 'view', 'extra' => null),
+ array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+', "action" => 'view')
+ );
+ $result = $route->compile();
+
+ $this->assertRegExp($result, '/some_extra/page/this_is_the_slug');
+ $this->assertRegExp($result, '/page/this_is_the_slug');
+ $this->assertEquals(array('extra', 'slug'), $route->keys);
+ $this->assertEquals(array('extra' => '[a-z1-9_]*', 'slug' => '[a-z1-9_]+', 'action' => 'view'), $route->options);
+ $expected = array(
+ 'controller' => 'pages',
+ 'action' => 'view'
+ );
+ $this->assertEquals($expected, $route->defaults);
+
+ $route = new CakeRoute(
+ '/:controller/:action/*',
+ array('project' => false),
+ array(
+ 'controller' => 'source|wiki|commits|tickets|comments|view',
+ 'action' => 'branches|history|branch|logs|view|start|add|edit|modify'
+ )
+ );
+ $this->assertFalse($route->parse('/chaw_test/wiki'));
+
+ $result = $route->compile();
+ $this->assertNotRegExp($result, '/some_project/source');
+ $this->assertRegExp($result, '/source/view');
+ $this->assertRegExp($result, '/source/view/other/params');
+ $this->assertNotRegExp($result, '/chaw_test/wiki');
+ $this->assertNotRegExp($result, '/source/wierd_action');
+ }
+
+/**
+ * test that routes match their pattern.
+ *
+ * @return void
+ **/
+ public function testMatchBasic() {
+ $route = new CakeRoute('/:controller/:action/:id', array('plugin' => null));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 0));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 1));
+ $this->assertEquals('/posts/view/1', $result);
+
+ $route = new CakeRoute('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+ $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'home'));
+ $this->assertEquals('/', $result);
+
+ $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'about'));
+ $this->assertFalse($result);
+
+ $route = new CakeRoute('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+ $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'home'));
+ $this->assertEquals('/pages/home', $result);
+
+ $result = $route->match(array('controller' => 'pages', 'action' => 'display', 'about'));
+ $this->assertEquals('/pages/about', $result);
+
+ $route = new CakeRoute('/blog/:action', array('controller' => 'posts'));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view'));
+ $this->assertEquals('/blog/view', $result);
+
+ $result = $route->match(array('controller' => 'nodes', 'action' => 'view'));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 1));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'id' => 2));
+ $this->assertFalse($result);
+
+ $route = new CakeRoute('/foo/:controller/:action', array('action' => 'index'));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view'));
+ $this->assertEquals('/foo/posts/view', $result);
+
+ $route = new CakeRoute('/:plugin/:id/*', array('controller' => 'posts', 'action' => 'view'));
+ $result = $route->match(array('plugin' => 'test', 'controller' => 'posts', 'action' => 'view', 'id' => '1'));
+ $this->assertEquals('/test/1/', $result);
+
+ $result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'view', 'id' => '1', '0'));
+ $this->assertEquals('/fo/1/0', $result);
+
+ $result = $route->match(array('plugin' => 'fo', 'controller' => 'nodes', 'action' => 'view', 'id' => 1));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('plugin' => 'fo', 'controller' => 'posts', 'action' => 'edit', 'id' => 1));
+ $this->assertFalse($result);
+
+ $route = new CakeRoute('/admin/subscriptions/:action/*', array(
+ 'controller' => 'subscribe', 'admin' => true, 'prefix' => 'admin'
+ ));
+
+ $url = array('controller' => 'subscribe', 'admin' => true, 'action' => 'edit', 1);
+ $result = $route->match($url);
+ $expected = '/admin/subscriptions/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $url = array(
+ 'controller' => 'subscribe',
+ 'admin' => true,
+ 'action' => 'edit_admin_e',
+ 1
+ );
+ $result = $route->match($url);
+ $expected = '/admin/subscriptions/edit_admin_e/1';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that non-greedy routes fail with extra passed args
+ *
+ * @return void
+ */
+ public function testGreedyRouteFailurePassedArg() {
+ $route = new CakeRoute('/:controller/:action', array('plugin' => null));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', '0'));
+ $this->assertFalse($result);
+
+ $route = new CakeRoute('/:controller/:action', array('plugin' => null));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'test'));
+ $this->assertFalse($result);
+ }
+
+/**
+ * test that non-greedy routes fail with extra passed args
+ *
+ * @return void
+ */
+ public function testGreedyRouteFailureNamedParam() {
+ $route = new CakeRoute('/:controller/:action', array('plugin' => null));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'page' => 1));
+ $this->assertFalse($result);
+ }
+
+/**
+ * test that falsey values do not interrupt a match.
+ *
+ * @return void
+ */
+ public function testMatchWithFalseyValues() {
+ $route = new CakeRoute('/:controller/:action/*', array('plugin' => null));
+ $result = $route->match(array(
+ 'controller' => 'posts', 'action' => 'index', 'plugin' => null, 'admin' => false
+ ));
+ $this->assertEquals('/posts/index/', $result);
+ }
+
+/**
+ * test match() with greedy routes, named parameters and passed args.
+ *
+ * @return void
+ */
+ public function testMatchWithNamedParametersAndPassedArgs() {
+ Router::connectNamed(true);
+
+ $route = new CakeRoute('/:controller/:action/*', array('plugin' => null));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'index', 'plugin' => null, 'page' => 1));
+ $this->assertEquals('/posts/index/page:1', $result);
+
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5));
+ $this->assertEquals('/posts/view/5', $result);
+
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 0));
+ $this->assertEquals('/posts/view/0', $result);
+
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, '0'));
+ $this->assertEquals('/posts/view/0', $result);
+
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 5, 'page' => 1, 'limit' => 20, 'order' => 'title'));
+ $this->assertEquals('/posts/view/5/page:1/limit:20/order:title', $result);
+
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'plugin' => null, 'word space', 'order' => 'Θ'));
+ $this->assertEquals('/posts/view/word%20space/order:%CE%98', $result);
+
+ $route = new CakeRoute('/test2/*', array('controller' => 'pages', 'action' => 'display', 2));
+ $result = $route->match(array('controller' => 'pages', 'action' => 'display', 1));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('controller' => 'pages', 'action' => 'display', 2, 'something'));
+ $this->assertEquals('/test2/something', $result);
+
+ $result = $route->match(array('controller' => 'pages', 'action' => 'display', 5, 'something'));
+ $this->assertFalse($result);
+ }
+
+/**
+ * Ensure that named parameters are urldecoded
+ *
+ * @return void
+ */
+ public function testParseNamedParametersUrlDecode() {
+ Router::connectNamed(true);
+ $route = new CakeRoute('/:controller/:action/*', array('plugin' => null));
+
+ $result = $route->parse('/posts/index/page:%CE%98');
+ $this->assertEquals('Θ', $result['named']['page']);
+
+ $result = $route->parse('/posts/index/page[]:%CE%98');
+ $this->assertEquals('Θ', $result['named']['page'][0]);
+
+ $result = $route->parse('/posts/index/something%20else/page[]:%CE%98');
+ $this->assertEquals('Θ', $result['named']['page'][0]);
+ $this->assertEquals('something else', $result['pass'][0]);
+ }
+
+/**
+ * Ensure that keys at named parameters are urldecoded
+ *
+ * @return void
+ */
+ public function testParseNamedKeyUrlDecode() {
+ Router::connectNamed(true);
+ $route = new CakeRoute('/:controller/:action/*', array('plugin' => null));
+
+ // checking /post/index/user[0]:a/user[1]:b
+ $result = $route->parse('/posts/index/user%5B0%5D:a/user%5B1%5D:b');
+ $this->assertArrayHasKey('user', $result['named']);
+ $this->assertEquals(array('a', 'b'), $result['named']['user']);
+
+ // checking /post/index/user[]:a/user[]:b
+ $result = $route->parse('/posts/index/user%5B%5D:a/user%5B%5D:b');
+ $this->assertArrayHasKey('user', $result['named']);
+ $this->assertEquals(array('a', 'b'), $result['named']['user']);
+ }
+
+/**
+ * test that named params with null/false are excluded
+ *
+ * @return void
+ */
+ public function testNamedParamsWithNullFalse() {
+ $route = new CakeRoute('/:controller/:action/*');
+ $result = $route->match(array('controller' => 'posts', 'action' => 'index', 'page' => null, 'sort' => false));
+ $this->assertEquals('/posts/index/', $result);
+ }
+
+/**
+ * test that match with patterns works.
+ *
+ * @return void
+ */
+ public function testMatchWithPatterns() {
+ $route = new CakeRoute('/:controller/:action/:id', array('plugin' => null), array('id' => '[0-9]+'));
+ $result = $route->match(array('controller' => 'posts', 'action' => 'view', 'id' => 'foo'));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '9'));
+ $this->assertEquals('/posts/view/9', $result);
+
+ $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '922'));
+ $this->assertEquals('/posts/view/922', $result);
+
+ $result = $route->match(array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 'a99'));
+ $this->assertFalse($result);
+ }
+
+/**
+ * test persistParams ability to persist parameters from $params and remove params.
+ *
+ * @return void
+ */
+ public function testPersistParams() {
+ $route = new CakeRoute(
+ '/:lang/:color/blog/:action',
+ array('controller' => 'posts'),
+ array('persist' => array('lang', 'color'))
+ );
+ $url = array('controller' => 'posts', 'action' => 'index');
+ $params = array('lang' => 'en', 'color' => 'blue');
+ $result = $route->persistParams($url, $params);
+ $this->assertEquals('en', $result['lang']);
+ $this->assertEquals('blue', $result['color']);
+
+ $url = array('controller' => 'posts', 'action' => 'index', 'color' => 'red');
+ $params = array('lang' => 'en', 'color' => 'blue');
+ $result = $route->persistParams($url, $params);
+ $this->assertEquals('en', $result['lang']);
+ $this->assertEquals('red', $result['color']);
+ }
+
+/**
+ * test the parse method of CakeRoute.
+ *
+ * @return void
+ */
+ public function testParse() {
+ $route = new CakeRoute(
+ '/:controller/:action/:id',
+ array('controller' => 'testing4', 'id' => null),
+ array('id' => Router::ID)
+ );
+ $route->compile();
+ $result = $route->parse('/posts/view/1');
+ $this->assertEquals('posts', $result['controller']);
+ $this->assertEquals('view', $result['action']);
+ $this->assertEquals('1', $result['id']);
+
+ $route = new Cakeroute(
+ '/admin/:controller',
+ array('prefix' => 'admin', 'admin' => 1, 'action' => 'index')
+ );
+ $route->compile();
+ $result = $route->parse('/admin/');
+ $this->assertFalse($result);
+
+ $result = $route->parse('/admin/posts');
+ $this->assertEquals('posts', $result['controller']);
+ $this->assertEquals('index', $result['action']);
+ }
+
+/**
+ * Test that :key elements are urldecoded
+ *
+ * @return void
+ */
+ public function testParseUrlDecodeElements() {
+ $route = new Cakeroute(
+ '/:controller/:slug',
+ array('action' => 'view')
+ );
+ $route->compile();
+ $result = $route->parse('/posts/%E2%88%82%E2%88%82');
+ $this->assertEquals('posts', $result['controller']);
+ $this->assertEquals('view', $result['action']);
+ $this->assertEquals('∂∂', $result['slug']);
+
+ $result = $route->parse('/posts/∂∂');
+ $this->assertEquals('posts', $result['controller']);
+ $this->assertEquals('view', $result['action']);
+ $this->assertEquals('∂∂', $result['slug']);
+ }
+
+/**
+ * test numerically indexed defaults, get appended to pass
+ *
+ * @return void
+ */
+ public function testParseWithPassDefaults() {
+ $route = new Cakeroute('/:controller', array('action' => 'display', 'home'));
+ $result = $route->parse('/posts');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'display',
+ 'pass' => array('home'),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that http header conditions can cause route failures.
+ *
+ * @return void
+ */
+ public function testParseWithHttpHeaderConditions() {
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $route = new CakeRoute('/sample', array('controller' => 'posts', 'action' => 'index', '[method]' => 'POST'));
+
+ $this->assertFalse($route->parse('/sample'));
+ }
+
+/**
+ * test that patterns work for :action
+ *
+ * @return void
+ */
+ public function testPatternOnAction() {
+ $route = new CakeRoute(
+ '/blog/:action/*',
+ array('controller' => 'blog_posts'),
+ array('action' => 'other|actions')
+ );
+ $result = $route->match(array('controller' => 'blog_posts', 'action' => 'foo'));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('controller' => 'blog_posts', 'action' => 'actions'));
+ $this->assertNotEmpty($result);
+
+ $result = $route->parse('/blog/other');
+ $expected = array('controller' => 'blog_posts', 'action' => 'other', 'pass' => array(), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ $result = $route->parse('/blog/foobar');
+ $this->assertFalse($result);
+ }
+
+/**
+ * test the parseArgs method
+ *
+ * @return void
+ */
+ public function testParsePassedArgument() {
+ $route = new CakeRoute('/:controller/:action/*');
+ $result = $route->parse('/posts/edit/1/2/0');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'edit',
+ 'pass' => array('1', '2', '0'),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $route->parse('/posts/edit/a-string/page:1/sort:value');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'edit',
+ 'pass' => array('a-string'),
+ 'named' => array(
+ 'page' => 1,
+ 'sort' => 'value'
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that only named parameter rules are followed.
+ *
+ * @return void
+ */
+ public function testParseNamedParametersWithRules() {
+ $route = new CakeRoute('/:controller/:action/*', array(), array(
+ 'named' => array(
+ 'wibble',
+ 'fish' => array('action' => 'index'),
+ 'fizz' => array('controller' => array('comments', 'other')),
+ 'pattern' => 'val-[\d]+'
+ )
+ ));
+ $result = $route->parse('/posts/display/wibble:spin/fish:trout/fizz:buzz/unknown:value');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'display',
+ 'pass' => array('fish:trout', 'fizz:buzz', 'unknown:value'),
+ 'named' => array(
+ 'wibble' => 'spin'
+ )
+ );
+ $this->assertEquals($expected, $result, 'Fish should not be parsed, as action != index');
+
+ $result = $route->parse('/posts/index/wibble:spin/fish:trout/fizz:buzz');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'pass' => array('fizz:buzz'),
+ 'named' => array(
+ 'wibble' => 'spin',
+ 'fish' => 'trout'
+ )
+ );
+ $this->assertEquals($expected, $result, 'Fizz should be parsed, as controller == comments|other');
+
+ $result = $route->parse('/comments/index/wibble:spin/fish:trout/fizz:buzz');
+ $expected = array(
+ 'controller' => 'comments',
+ 'action' => 'index',
+ 'pass' => array(),
+ 'named' => array(
+ 'wibble' => 'spin',
+ 'fish' => 'trout',
+ 'fizz' => 'buzz'
+ )
+ );
+ $this->assertEquals($expected, $result, 'All params should be parsed as conditions were met.');
+
+ $result = $route->parse('/comments/index/pattern:val--');
+ $expected = array(
+ 'controller' => 'comments',
+ 'action' => 'index',
+ 'pass' => array('pattern:val--'),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result, 'Named parameter pattern unmet.');
+
+ $result = $route->parse('/comments/index/pattern:val-2');
+ $expected = array(
+ 'controller' => 'comments',
+ 'action' => 'index',
+ 'pass' => array(),
+ 'named' => array('pattern' => 'val-2')
+ );
+ $this->assertEquals($expected, $result, 'Named parameter pattern met.');
+ }
+
+/**
+ * test that greedyNamed ignores rules.
+ *
+ * @return void
+ */
+ public function testParseGreedyNamed() {
+ $route = new CakeRoute('/:controller/:action/*', array(), array(
+ 'named' => array(
+ 'fizz' => array('controller' => 'comments'),
+ 'pattern' => 'val-[\d]+',
+ ),
+ 'greedyNamed' => true
+ ));
+ $result = $route->parse('/posts/display/wibble:spin/fizz:buzz/pattern:ignored');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'display',
+ 'pass' => array('fizz:buzz', 'pattern:ignored'),
+ 'named' => array(
+ 'wibble' => 'spin',
+ )
+ );
+ $this->assertEquals($expected, $result, 'Greedy named grabs everything, rules are followed');
+ }
+
+/**
+ * Having greedNamed enabled should not capture routing.prefixes.
+ *
+ * @return void
+ */
+ public function testMatchGreedyNamedExcludesPrefixes() {
+ Configure::write('Routing.prefixes', array('admin'));
+ Router::reload();
+
+ $route = new CakeRoute('/sales/*', array('controller' => 'sales', 'action' => 'index'));
+ $this->assertFalse($route->match(array('controller' => 'sales', 'action' => 'index', 'admin' => 1)), 'Greedy named consume routing prefixes.');
+ }
+
+/**
+ * test that parsing array format named parameters works
+ *
+ * @return void
+ */
+ public function testParseArrayNamedParameters() {
+ $route = new CakeRoute('/:controller/:action/*');
+ $result = $route->parse('/tests/action/var[]:val1/var[]:val2');
+ $expected = array(
+ 'controller' => 'tests',
+ 'action' => 'action',
+ 'named' => array(
+ 'var' => array(
+ 'val1',
+ 'val2'
+ )
+ ),
+ 'pass' => array(),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $route->parse('/tests/action/theanswer[is]:42/var[]:val2/var[]:val3');
+ $expected = array(
+ 'controller' => 'tests',
+ 'action' => 'action',
+ 'named' => array(
+ 'theanswer' => array(
+ 'is' => 42
+ ),
+ 'var' => array(
+ 'val2',
+ 'val3'
+ )
+ ),
+ 'pass' => array(),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $route->parse('/tests/action/theanswer[is][not]:42/theanswer[]:5/theanswer[is]:6');
+ $expected = array(
+ 'controller' => 'tests',
+ 'action' => 'action',
+ 'named' => array(
+ 'theanswer' => array(
+ 5,
+ 'is' => array(
+ 6,
+ 'not' => 42
+ )
+ ),
+ ),
+ 'pass' => array(),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that match can handle array named parameters
+ *
+ * @return void
+ */
+ public function testMatchNamedParametersArray() {
+ $route = new CakeRoute('/:controller/:action/*');
+
+ $url = array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'filter' => array(
+ 'one',
+ 'model' => 'value'
+ )
+ );
+ $result = $route->match($url);
+ $expected = '/posts/index/filter%5B0%5D:one/filter%5Bmodel%5D:value';
+ $this->assertEquals($expected, $result);
+
+ $url = array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'filter' => array(
+ 'one',
+ 'model' => array(
+ 'two',
+ 'order' => 'field'
+ )
+ )
+ );
+ $result = $route->match($url);
+ $expected = '/posts/index/filter%5B0%5D:one/filter%5Bmodel%5D%5B0%5D:two/filter%5Bmodel%5D%5Border%5D:field';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test restructuring args with pass key
+ *
+ * @return void
+ */
+ public function testPassArgRestructure() {
+ $route = new CakeRoute('/:controller/:action/:slug', array(), array(
+ 'pass' => array('slug')
+ ));
+ $result = $route->parse('/posts/view/my-title');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'slug' => 'my-title',
+ 'pass' => array('my-title'),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result, 'Slug should have moved');
+ }
+
+/**
+ * Test the /** special type on parsing.
+ *
+ * @return void
+ */
+ public function testParseTrailing() {
+ $route = new CakeRoute('/:controller/:action/**');
+ $result = $route->parse('/posts/index/1/2/3/foo:bar');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'pass' => array('1/2/3/foo:bar'),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $route->parse('/posts/index/http://example.com');
+ $expected = array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'pass' => array('http://example.com'),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the /** special type on parsing - UTF8.
+ *
+ * @return void
+ */
+ public function testParseTrailingUTF8() {
+ $route = new CakeRoute('/category/**', array('controller' => 'categories','action' => 'index'));
+ $result = $route->parse('/category/%D9%85%D9%88%D8%A8%D8%A7%DB%8C%D9%84');
+ $expected = array(
+ 'controller' => 'categories',
+ 'action' => 'index',
+ 'pass' => array('موبایل'),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/PluginShortRouteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/PluginShortRouteTest.php
new file mode 100644
index 0000000..4438d47
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/PluginShortRouteTest.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * CakeRequest Test case file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Routing.Route
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('PluginShortRoute', 'Routing/Route');
+App::uses('Router', 'Routing');
+
+/**
+ * test case for PluginShortRoute
+ *
+ * @package Cake.Test.Case.Routing.Route
+ */
+class PluginShortRouteTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Routing', array('admin' => null, 'prefixes' => array()));
+ Router::reload();
+ }
+
+/**
+ * test the parsing of routes.
+ *
+ * @return void
+ */
+ public function testParsing() {
+ $route = new PluginShortRoute('/:plugin', array('action' => 'index'), array('plugin' => 'foo|bar'));
+
+ $result = $route->parse('/foo');
+ $this->assertEquals('foo', $result['plugin']);
+ $this->assertEquals('foo', $result['controller']);
+ $this->assertEquals('index', $result['action']);
+
+ $result = $route->parse('/wrong');
+ $this->assertFalse($result, 'Wrong plugin name matched %s');
+ }
+
+/**
+ * test the reverse routing of the plugin shortcut urls.
+ *
+ * @return void
+ */
+ public function testMatch() {
+ $route = new PluginShortRoute('/:plugin', array('action' => 'index'), array('plugin' => 'foo|bar'));
+
+ $result = $route->match(array('plugin' => 'foo', 'controller' => 'posts', 'action' => 'index'));
+ $this->assertFalse($result, 'plugin controller mismatch was converted. %s');
+
+ $result = $route->match(array('plugin' => 'foo', 'controller' => 'foo', 'action' => 'index'));
+ $this->assertEquals('/foo', $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/RedirectRouteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/RedirectRouteTest.php
new file mode 100644
index 0000000..33b4276
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/Route/RedirectRouteTest.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * CakeRequest Test case file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.Routing.Route
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('RedirectRoute', 'Routing/Route');
+App::uses('CakeResponse', 'Network');
+App::uses('Router', 'Routing');
+
+/**
+ * test case for RedirectRoute
+ *
+ * @package Cake.Test.Case.Routing.Route
+ */
+class RedirectRouteTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Routing', array('admin' => null, 'prefixes' => array()));
+ Router::reload();
+ }
+
+/**
+ * test the parsing of routes.
+ *
+ * @return void
+ */
+ public function testParsing() {
+ $route = new RedirectRoute('/home', array('controller' => 'posts'));
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/home');
+ $header = $route->response->header();
+ $this->assertEquals(Router::url('/posts', true), $header['Location']);
+
+ $route = new RedirectRoute('/home', array('controller' => 'posts', 'action' => 'index'));
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/home');
+ $header = $route->response->header();
+ $this->assertEquals(Router::url('/posts', true), $header['Location']);
+ $this->assertEquals(301, $route->response->statusCode());
+
+ $route = new RedirectRoute('/google', 'http://google.com');
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/google');
+ $header = $route->response->header();
+ $this->assertEquals('http://google.com', $header['Location']);
+
+ $route = new RedirectRoute('/posts/*', array('controller' => 'posts', 'action' => 'view'), array('status' => 302));
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/posts/2');
+ $header = $route->response->header();
+ $this->assertEquals(Router::url('/posts/view', true), $header['Location']);
+ $this->assertEquals(302, $route->response->statusCode());
+
+ $route = new RedirectRoute('/posts/*', array('controller' => 'posts', 'action' => 'view'), array('persist' => true));
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/posts/2');
+ $header = $route->response->header();
+ $this->assertEquals(Router::url('/posts/view/2', true), $header['Location']);
+
+ $route = new RedirectRoute('/posts/*', '/test', array('persist' => true));
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/posts/2');
+ $header = $route->response->header();
+ $this->assertEquals(Router::url('/test', true), $header['Location']);
+
+ $route = new RedirectRoute('/my_controllers/:action/*', array('controller' => 'tags', 'action' => 'add'), array('persist' => true));
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/my_controllers/do_something/passme/named:param');
+ $header = $route->response->header();
+ $this->assertEquals(Router::url('/tags/add/passme/named:param', true), $header['Location']);
+
+ $route = new RedirectRoute('/my_controllers/:action/*', array('controller' => 'tags', 'action' => 'add'));
+ $route->stop = false;
+ $route->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $result = $route->parse('/my_controllers/do_something/passme/named:param');
+ $header = $route->response->header();
+ $this->assertEquals(Router::url('/tags/add', true), $header['Location']);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/RouterTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/RouterTest.php
new file mode 100644
index 0000000..44bf6aa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Routing/RouterTest.php
@@ -0,0 +1,2669 @@
+<?php
+/**
+ * RouterTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Routing
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Router', 'Routing');
+App::uses('CakeResponse', 'Network');
+
+if (!defined('FULL_BASE_URL')) {
+ define('FULL_BASE_URL', 'http://cakephp.org');
+}
+
+/**
+ * RouterTest class
+ *
+ * @package Cake.Test.Case.Routing
+ */
+class RouterTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('Routing', array('admin' => null, 'prefixes' => array()));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ }
+
+/**
+ * testFullBaseURL method
+ *
+ * @return void
+ */
+ public function testFullBaseURL() {
+ $skip = PHP_SAPI == 'cli';
+ if ($skip) {
+ $this->markTestSkipped('Cannot validate base urls in CLI');
+ }
+ $this->assertRegExp('/^http(s)?:\/\//', Router::url('/', true));
+ $this->assertRegExp('/^http(s)?:\/\//', Router::url(null, true));
+ $this->assertRegExp('/^http(s)?:\/\//', Router::url(array('full_base' => true)));
+ $this->assertSame(FULL_BASE_URL . '/', Router::url(array('full_base' => true)));
+ }
+
+/**
+ * testRouteDefaultParams method
+ *
+ * @return void
+ */
+ public function testRouteDefaultParams() {
+ Router::connect('/:controller', array('controller' => 'posts'));
+ $this->assertEquals(Router::url(array('action' => 'index')), '/');
+ }
+
+/**
+ * testMapResources method
+ *
+ * @return void
+ */
+ public function testMapResources() {
+ $resources = Router::mapResources('Posts');
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/posts');
+ $this->assertEquals(array('pass' => array(), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'index', '[method]' => 'GET'), $result);
+ $this->assertEquals(array('posts'), $resources);
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/posts/13');
+ $this->assertEquals(array('pass' => array('13'), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'view', 'id' => '13', '[method]' => 'GET'), $result);
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $result = Router::parse('/posts');
+ $this->assertEquals(array('pass' => array(), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST'), $result);
+
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $result = Router::parse('/posts/13');
+ $this->assertEquals(array('pass' => array('13'), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'edit', 'id' => '13', '[method]' => 'PUT'), $result);
+
+ $result = Router::parse('/posts/475acc39-a328-44d3-95fb-015000000000');
+ $this->assertEquals(array('pass' => array('475acc39-a328-44d3-95fb-015000000000'), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'edit', 'id' => '475acc39-a328-44d3-95fb-015000000000', '[method]' => 'PUT'), $result);
+
+ $_SERVER['REQUEST_METHOD'] = 'DELETE';
+ $result = Router::parse('/posts/13');
+ $this->assertEquals(array('pass' => array('13'), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'delete', 'id' => '13', '[method]' => 'DELETE'), $result);
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/posts/add');
+ $this->assertEquals(array(), $result);
+
+ Router::reload();
+ $resources = Router::mapResources('Posts', array('id' => '[a-z0-9_]+'));
+ $this->assertEquals(array('posts'), $resources);
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/posts/add');
+ $this->assertEquals(array('pass' => array('add'), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'view', 'id' => 'add', '[method]' => 'GET'), $result);
+
+ $_SERVER['REQUEST_METHOD'] = 'PUT';
+ $result = Router::parse('/posts/name');
+ $this->assertEquals(array('pass' => array('name'), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'edit', 'id' => 'name', '[method]' => 'PUT'), $result);
+ }
+
+/**
+ * testMapResources with plugin controllers.
+ *
+ * @return void
+ */
+ public function testPluginMapResources() {
+ App::build(array(
+ 'Plugin' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ )
+ ));
+ $resources = Router::mapResources('TestPlugin.TestPlugin');
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/test_plugin/test_plugin');
+ $expected = array(
+ 'pass' => array(),
+ 'named' => array(),
+ 'plugin' => 'test_plugin',
+ 'controller' => 'test_plugin',
+ 'action' => 'index',
+ '[method]' => 'GET'
+ );
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(array('test_plugin'), $resources);
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/test_plugin/test_plugin/13');
+ $expected = array(
+ 'pass' => array('13'),
+ 'named' => array(),
+ 'plugin' => 'test_plugin',
+ 'controller' => 'test_plugin',
+ 'action' => 'view',
+ 'id' => '13',
+ '[method]' => 'GET'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test mapResources with a plugin and prefix.
+ *
+ * @return void
+ */
+ public function testPluginMapResourcesWithPrefix() {
+ App::build(array(
+ 'Plugin' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ )
+ ));
+ $resources = Router::mapResources('TestPlugin.TestPlugin', array('prefix' => '/api/'));
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/api/test_plugin');
+ $expected = array(
+ 'pass' => array(),
+ 'named' => array(),
+ 'plugin' => 'test_plugin',
+ 'controller' => 'test_plugin',
+ 'action' => 'index',
+ '[method]' => 'GET'
+ );
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(array('test_plugin'), $resources);
+ }
+
+/**
+ * testMultipleResourceRoute method
+ *
+ * @return void
+ */
+ public function testMultipleResourceRoute() {
+ Router::connect('/:controller', array('action' => 'index', '[method]' => array('GET', 'POST')));
+
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+ $result = Router::parse('/posts');
+ $this->assertEquals(array('pass' => array(), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'index', '[method]' => array('GET', 'POST')), $result);
+
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $result = Router::parse('/posts');
+ $this->assertEquals(array('pass' => array(), 'named' => array(), 'plugin' => '', 'controller' => 'posts', 'action' => 'index', '[method]' => array('GET', 'POST')), $result);
+ }
+
+/**
+ * testGenerateUrlResourceRoute method
+ *
+ * @return void
+ */
+ public function testGenerateUrlResourceRoute() {
+ Router::mapResources('Posts');
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '[method]' => 'GET'));
+ $expected = '/posts';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'view', '[method]' => 'GET', 'id' => 10));
+ $expected = '/posts/10';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'add', '[method]' => 'POST'));
+ $expected = '/posts';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT', 'id' => 10));
+ $expected = '/posts/10';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'delete', '[method]' => 'DELETE', 'id' => 10));
+ $expected = '/posts/10';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'edit', '[method]' => 'POST', 'id' => 10));
+ $expected = '/posts/10';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUrlNormalization method
+ *
+ * @return void
+ */
+ public function testUrlNormalization() {
+ $expected = '/users/logout';
+
+ $result = Router::normalize('/users/logout/');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::normalize('//users//logout//');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::normalize('users/logout');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::normalize(array('controller' => 'users', 'action' => 'logout'));
+ $this->assertEquals($expected, $result);
+
+ $result = Router::normalize('/');
+ $this->assertEquals('/', $result);
+
+ $result = Router::normalize('http://google.com/');
+ $this->assertEquals('http://google.com/', $result);
+
+ $result = Router::normalize('http://google.com//');
+ $this->assertEquals('http://google.com//', $result);
+
+ $result = Router::normalize('/users/login/scope://foo');
+ $this->assertEquals('/users/login/scope:/foo', $result);
+
+ $result = Router::normalize('/recipe/recipes/add');
+ $this->assertEquals('/recipe/recipes/add', $result);
+
+ $request = new CakeRequest();
+ $request->base = '/us';
+ Router::setRequestInfo($request);
+ $result = Router::normalize('/us/users/logout/');
+ $this->assertEquals('/users/logout', $result);
+
+ Router::reload();
+
+ $request = new CakeRequest();
+ $request->base = '/cake_12';
+ Router::setRequestInfo($request);
+ $result = Router::normalize('/cake_12/users/logout/');
+ $this->assertEquals('/users/logout', $result);
+
+ Router::reload();
+ $_back = Configure::read('App.baseUrl');
+ Configure::write('App.baseUrl', '/');
+
+ $request = new CakeRequest();
+ $request->base = '/';
+ Router::setRequestInfo($request);
+ $result = Router::normalize('users/login');
+ $this->assertEquals('/users/login', $result);
+ Configure::write('App.baseUrl', $_back);
+
+ Router::reload();
+ $request = new CakeRequest();
+ $request->base = 'beer';
+ Router::setRequestInfo($request);
+ $result = Router::normalize('beer/admin/beers_tags/add');
+ $this->assertEquals('/admin/beers_tags/add', $result);
+
+ $result = Router::normalize('/admin/beers_tags/add');
+ $this->assertEquals('/admin/beers_tags/add', $result);
+ }
+
+/**
+ * test generation of basic urls.
+ *
+ * @return void
+ */
+ public function testUrlGenerationBasic() {
+ extract(Router::getNamedExpressions());
+
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'action' => 'index', 'plugin' => null, 'controller' => 'subscribe', 'admin' => true
+ ));
+ $request->base = '/magazine';
+ $request->here = '/magazine';
+ $request->webroot = '/magazine/';
+ Router::setRequestInfo($request);
+
+ $result = Router::url();
+ $this->assertEquals('/magazine', $result);
+
+ Router::reload();
+
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+ $out = Router::url(array('controller' => 'pages', 'action' => 'display', 'home'));
+ $this->assertEquals('/', $out);
+
+ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+ $result = Router::url(array('controller' => 'pages', 'action' => 'display', 'about'));
+ $expected = '/pages/about';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:plugin/:id/*', array('controller' => 'posts', 'action' => 'view'), array('id' => $ID));
+ Router::parse('/');
+
+ $result = Router::url(array('plugin' => 'cake_plugin', 'controller' => 'posts', 'action' => 'view', 'id' => '1'));
+ $expected = '/cake_plugin/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('plugin' => 'cake_plugin', 'controller' => 'posts', 'action' => 'view', 'id' => '1', '0'));
+ $expected = '/cake_plugin/1/0';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:controller/:action/:id', array(), array('id' => $ID));
+ Router::parse('/');
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'view', 'id' => '1'));
+ $expected = '/posts/view/1';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:controller/:id', array('action' => 'view'));
+ Router::parse('/');
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'view', 'id' => '1'));
+ $expected = '/posts/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '0'));
+ $expected = '/posts/index/0';
+ $this->assertEquals($expected, $result);
+
+ Router::connect('/view/*', array('controller' => 'posts', 'action' => 'view'));
+ Router::promote();
+ $result = Router::url(array('controller' => 'posts', 'action' => 'view', '1'));
+ $expected = '/view/1';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'action' => 'index', 'plugin' => null, 'controller' => 'real_controller_name'
+ ));
+ $request->base = '/';
+ $request->here = '/';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+
+ Router::connect('short_controller_name/:action/*', array('controller' => 'real_controller_name'));
+ Router::parse('/');
+
+ $result = Router::url(array('controller' => 'real_controller_name', 'page' => '1'));
+ $expected = '/short_controller_name/index/page:1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'add'));
+ $expected = '/short_controller_name/add';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::parse('/');
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'action' => 'index', 'plugin' => null, 'controller' => 'users', 'url' => array('url' => 'users')
+ ));
+ $request->base = '/';
+ $request->here = '/';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+
+ $result = Router::url(array('action' => 'login'));
+ $expected = '/users/login';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/page/*', array('plugin' => null, 'controller' => 'pages', 'action' => 'view'));
+ Router::parse('/');
+
+ $result = Router::url(array('plugin' => 'my_plugin', 'controller' => 'pages', 'action' => 'view', 'my-page'));
+ $expected = '/my_plugin/pages/view/my-page';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/contact/:action', array('plugin' => 'contact', 'controller' => 'contact'));
+ Router::parse('/');
+
+ $result = Router::url(array('plugin' => 'contact', 'controller' => 'contact', 'action' => 'me'));
+
+ $expected = '/contact/me';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'action' => 'index', 'plugin' => 'myplugin', 'controller' => 'mycontroller', 'admin' => false
+ ));
+ $request->base = '/';
+ $request->here = '/';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'myothercontroller'));
+ $expected = '/myothercontroller';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests using arrays in named parameters
+ *
+ * @return void
+ */
+ public function testArrayNamedParameters() {
+ $result = Router::url(array('controller' => 'tests', 'pages' => array(
+ 1, 2, 3
+ )));
+ $expected = '/tests/index/pages[0]:1/pages[1]:2/pages[2]:3';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'tests',
+ 'pages' => array(
+ 'param1' => array(
+ 'one',
+ 'two'
+ ),
+ 'three'
+ )
+ ));
+ $expected = '/tests/index/pages[param1][0]:one/pages[param1][1]:two/pages[0]:three';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'tests',
+ 'pages' => array(
+ 'param1' => array(
+ 'one' => 1,
+ 'two' => 2
+ ),
+ 'three'
+ )
+ ));
+ $expected = '/tests/index/pages[param1][one]:1/pages[param1][two]:2/pages[0]:three';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'tests',
+ 'super' => array(
+ 'nested' => array(
+ 'array' => 'awesome',
+ 'something' => 'else'
+ ),
+ 'cool'
+ )
+ ));
+ $expected = '/tests/index/super[nested][array]:awesome/super[nested][something]:else/super[0]:cool';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'tests', 'namedParam' => array(
+ 'keyed' => 'is an array',
+ 'test'
+ )));
+ $expected = '/tests/index/namedParam[keyed]:is%20an%20array/namedParam[0]:test';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test generation of routes with query string parameters.
+ *
+ * @return void
+ **/
+ public function testUrlGenerationWithQueryStrings() {
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '0', '?' => 'var=test&var2=test2'));
+ $expected = '/posts/index/0?var=test&var2=test2';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', '0', '?' => 'var=test&var2=test2'));
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', '0', '?' => array('var' => 'test', 'var2' => 'test2')));
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', '0', '?' => array('var' => null)));
+ $this->assertEquals('/posts/index/0', $result);
+
+ $result = Router::url(array('controller' => 'posts', '0', '?' => 'var=test&var2=test2', '#' => 'unencoded string %'));
+ $expected = '/posts/index/0?var=test&var2=test2#unencoded string %';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that regex validation of keyed route params is working.
+ *
+ * @return void
+ **/
+ public function testUrlGenerationWithRegexQualifiedParams() {
+ Router::connect(
+ ':language/galleries',
+ array('controller' => 'galleries', 'action' => 'index'),
+ array('language' => '[a-z]{3}')
+ );
+
+ Router::connect(
+ '/:language/:admin/:controller/:action/*',
+ array('admin' => 'admin'),
+ array('language' => '[a-z]{3}', 'admin' => 'admin')
+ );
+
+ Router::connect('/:language/:controller/:action/*',
+ array(),
+ array('language' => '[a-z]{3}')
+ );
+
+ $result = Router::url(array('admin' => false, 'language' => 'dan', 'action' => 'index', 'controller' => 'galleries'));
+ $expected = '/dan/galleries';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('admin' => false, 'language' => 'eng', 'action' => 'index', 'controller' => 'galleries'));
+ $expected = '/eng/galleries';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:language/pages',
+ array('controller' => 'pages', 'action' => 'index'),
+ array('language' => '[a-z]{3}')
+ );
+ Router::connect('/:language/:controller/:action/*', array(), array('language' => '[a-z]{3}'));
+
+ $result = Router::url(array('language' => 'eng', 'action' => 'index', 'controller' => 'pages'));
+ $expected = '/eng/pages';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('language' => 'eng', 'controller' => 'pages'));
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('language' => 'eng', 'controller' => 'pages', 'action' => 'add'));
+ $expected = '/eng/pages/add';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/forestillinger/:month/:year/*',
+ array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
+ array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
+ );
+ Router::parse('/');
+
+ $result = Router::url(array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar', 'month' => 10, 'year' => 2007, 'min-forestilling'));
+ $expected = '/forestillinger/10/2007/min-forestilling';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/kalender/:month/:year/*',
+ array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
+ array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
+ );
+ Router::connect('/kalender/*', array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'));
+ Router::parse('/');
+
+ $result = Router::url(array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar', 'min-forestilling'));
+ $expected = '/kalender/min-forestilling';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar', 'year' => 2007, 'month' => 10, 'min-forestilling'));
+ $expected = '/kalender/10/2007/min-forestilling';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:controller/:action/*', array(), array(
+ 'controller' => 'source|wiki|commits|tickets|comments|view',
+ 'action' => 'branches|history|branch|logs|view|start|add|edit|modify'
+ ));
+ }
+
+/**
+ * Test url generation with an admin prefix
+ *
+ * @return void
+ */
+ public function testUrlGenerationWithAdminPrefix() {
+ Configure::write('Routing.prefixes', array('admin'));
+ Router::reload();
+
+ Router::connectNamed(array('event', 'lang'));
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+ Router::connect('/pages/contact_us', array('controller' => 'pages', 'action' => 'contact_us'));
+ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+ Router::connect('/reset/*', array('admin' => true, 'controller' => 'users', 'action' => 'reset'));
+ Router::connect('/tests', array('controller' => 'tests', 'action' => 'index'));
+ Router::parseExtensions('rss');
+
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'controller' => 'registrations', 'action' => 'admin_index',
+ 'plugin' => null, 'prefix' => 'admin', 'admin' => true,
+ 'ext' => 'html'
+ ));
+ $request->base = '';
+ $request->here = '/admin/registrations/index';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+
+ $result = Router::url(array('page' => 2));
+ $expected = '/admin/registrations/index/page:2';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'controller' => 'subscriptions', 'action' => 'admin_index',
+ 'plugin' => null, 'admin' => true,
+ 'url' => array('url' => 'admin/subscriptions/index/page:2')
+ ));
+ $request->base = '/magazine';
+ $request->here = '/magazine/admin/subscriptions/index/page:2';
+ $request->webroot = '/magazine/';
+ Router::setRequestInfo($request);
+
+ Router::parse('/');
+
+ $result = Router::url(array('page' => 3));
+ $expected = '/magazine/admin/subscriptions/index/page:3';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/admin/subscriptions/:action/*', array('controller' => 'subscribe', 'admin' => true, 'prefix' => 'admin'));
+ Router::parse('/');
+
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'action' => 'admin_index', 'plugin' => null, 'controller' => 'subscribe',
+ 'admin' => true, 'url' => array('url' => 'admin/subscriptions/edit/1')
+ ));
+ $request->base = '/magazine';
+ $request->here = '/magazine/admin/subscriptions/edit/1';
+ $request->webroot = '/magazine/';
+ Router::setRequestInfo($request);
+
+ $result = Router::url(array('action' => 'edit', 1));
+ $expected = '/magazine/admin/subscriptions/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('admin' => true, 'controller' => 'users', 'action' => 'login'));
+ $expected = '/magazine/admin/users/login';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'admin' => true, 'action' => 'index', 'plugin' => null, 'controller' => 'users',
+ 'url' => array('url' => 'users')
+ ));
+ $request->base = '/';
+ $request->here = '/';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+
+ Router::connect('/page/*', array('controller' => 'pages', 'action' => 'view', 'admin' => true, 'prefix' => 'admin'));
+ Router::parse('/');
+
+ $result = Router::url(array('admin' => true, 'controller' => 'pages', 'action' => 'view', 'my-page'));
+ $expected = '/page/my-page';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'pages', 'action' => 'admin_add', 'prefix' => 'admin', 'admin' => true,
+ 'url' => array('url' => 'admin/pages/add')
+ ));
+ $request->base = '';
+ $request->here = '/admin/pages/add';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+ Router::parse('/');
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
+ $expected = '/admin/pages/add';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::parse('/');
+ $request = new CakeRequest();
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'pages', 'action' => 'admin_add', 'prefix' => 'admin', 'admin' => true,
+ 'url' => array('url' => 'admin/pages/add')
+ ));
+ $request->base = '';
+ $request->here = '/admin/pages/add';
+ $request->webroot = '/';
+ Router::setRequestInfo($request);
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
+ $expected = '/admin/pages/add';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/admin/:controller/:action/:id', array('admin' => true), array('id' => '[0-9]+'));
+ Router::parse('/');
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'pages', 'action' => 'admin_edit', 'pass' => array('284'),
+ 'prefix' => 'admin', 'admin' => true,
+ 'url' => array('url' => 'admin/pages/edit/284')
+ ))->addPaths(array(
+ 'base' => '', 'here' => '/admin/pages/edit/284', 'webroot' => '/'
+ ))
+ );
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'edit', 'id' => '284'));
+ $expected = '/admin/pages/edit/284';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::parse('/');
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'pages', 'action' => 'admin_add', 'prefix' => 'admin',
+ 'admin' => true, 'url' => array('url' => 'admin/pages/add')
+ ))->addPaths(array(
+ 'base' => '', 'here' => '/admin/pages/add', 'webroot' => '/'
+ ))
+ );
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'add', 'id' => false));
+ $expected = '/admin/pages/add';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::parse('/');
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'pages', 'action' => 'admin_edit', 'prefix' => 'admin',
+ 'admin' => true, 'pass' => array('284'), 'url' => array('url' => 'admin/pages/edit/284')
+ ))->addPaths(array(
+ 'base' => '', 'here' => '/admin/pages/edit/284', 'webroot' => '/'
+ ))
+ );
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'pages', 'action' => 'edit', 284));
+ $expected = '/admin/pages/edit/284';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/admin/posts/*', array('controller' => 'posts', 'action' => 'index', 'admin' => true));
+ Router::parse('/');
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'posts', 'action' => 'admin_index', 'prefix' => 'admin',
+ 'admin' => true, 'pass' => array('284'), 'url' => array('url' => 'admin/posts')
+ ))->addPaths(array(
+ 'base' => '', 'here' => '/admin/posts', 'webroot' => '/'
+ ))
+ );
+
+ $result = Router::url(array('all'));
+ $expected = '/admin/posts/all';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUrlGenerationWithExtensions method
+ *
+ * @return void
+ */
+ public function testUrlGenerationWithExtensions() {
+ Router::parse('/');
+ $result = Router::url(array('plugin' => null, 'controller' => 'articles', 'action' => 'add', 'id' => null, 'ext' => 'json'));
+ $expected = '/articles/add.json';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'articles', 'action' => 'add', 'ext' => 'json'));
+ $expected = '/articles/add.json';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'articles', 'action' => 'index', 'id' => null, 'ext' => 'json'));
+ $expected = '/articles.json';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('plugin' => null, 'controller' => 'articles', 'action' => 'index', 'ext' => 'json'));
+ $expected = '/articles.json';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testPluginUrlGeneration method
+ *
+ * @return void
+ */
+ public function testUrlGenerationPlugins() {
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => 'test', 'controller' => 'controller', 'action' => 'index'
+ ))->addPaths(array(
+ 'base' => '/base', 'here' => '/clients/sage/portal/donations', 'webroot' => '/base/'
+ ))
+ );
+
+ $this->assertEquals(Router::url('read/1'), '/base/test/controller/read/1');
+
+ Router::reload();
+ Router::connect('/:lang/:plugin/:controller/*', array('action' => 'index'));
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'lang' => 'en',
+ 'plugin' => 'shows', 'controller' => 'shows', 'action' => 'index',
+ 'url' => array('url' => 'en/shows/'),
+ ))->addPaths(array(
+ 'base' => '', 'here' => '/en/shows', 'webroot' => '/'
+ ))
+ );
+
+ Router::parse('/en/shows/');
+
+ $result = Router::url(array(
+ 'lang' => 'en',
+ 'controller' => 'shows', 'action' => 'index', 'page' => '1',
+ ));
+ $expected = '/en/shows/shows/page:1';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that you can leave active plugin routes with plugin = null
+ *
+ * @return void
+ */
+ public function testCanLeavePlugin() {
+ Router::reload();
+ Router::connect(
+ '/admin/other/:controller/:action/*',
+ array(
+ 'admin' => 1,
+ 'plugin' => 'aliased',
+ 'prefix' => 'admin'
+ )
+ );
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'pass' => array(),
+ 'admin' => true,
+ 'prefix' => 'admin',
+ 'plugin' => 'this',
+ 'action' => 'admin_index',
+ 'controller' => 'interesting',
+ 'url' => array('url' => 'admin/this/interesting/index'),
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/admin/this/interesting/index',
+ 'webroot' => '/',
+ ))
+ );
+ $result = Router::url(array('plugin' => null, 'controller' => 'posts', 'action' => 'index'));
+ $this->assertEquals('/admin/posts', $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index'));
+ $this->assertEquals('/admin/this/posts', $result);
+
+ $result = Router::url(array('plugin' => 'aliased', 'controller' => 'posts', 'action' => 'index'));
+ $this->assertEquals('/admin/other/posts/index', $result);
+ }
+
+/**
+ * testUrlParsing method
+ *
+ * @return void
+ */
+ public function testUrlParsing() {
+ extract(Router::getNamedExpressions());
+
+ Router::connect('/posts/:value/:somevalue/:othervalue/*', array('controller' => 'posts', 'action' => 'view'), array('value','somevalue', 'othervalue'));
+ $result = Router::parse('/posts/2007/08/01/title-of-post-here');
+ $expected = array('value' => '2007', 'somevalue' => '08', 'othervalue' => '01', 'controller' => 'posts', 'action' => 'view', 'plugin' => '', 'pass' => array('0' => 'title-of-post-here'), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/:year/:month/:day/*', array('controller' => 'posts', 'action' => 'view'), array('year' => $Year, 'month' => $Month, 'day' => $Day));
+ $result = Router::parse('/posts/2007/08/01/title-of-post-here');
+ $expected = array('year' => '2007', 'month' => '08', 'day' => '01', 'controller' => 'posts', 'action' => 'view', 'plugin' => '', 'pass' => array('0' => 'title-of-post-here'), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/:day/:year/:month/*', array('controller' => 'posts', 'action' => 'view'), array('year' => $Year, 'month' => $Month, 'day' => $Day));
+ $result = Router::parse('/posts/01/2007/08/title-of-post-here');
+ $expected = array('day' => '01', 'year' => '2007', 'month' => '08', 'controller' => 'posts', 'action' => 'view', 'plugin' => '', 'pass' => array('0' => 'title-of-post-here'), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/:month/:day/:year/*', array('controller' => 'posts', 'action' => 'view'), array('year' => $Year, 'month' => $Month, 'day' => $Day));
+ $result = Router::parse('/posts/08/01/2007/title-of-post-here');
+ $expected = array('month' => '08', 'day' => '01', 'year' => '2007', 'controller' => 'posts', 'action' => 'view', 'plugin' => '', 'pass' => array('0' => 'title-of-post-here'), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/:year/:month/:day/*', array('controller' => 'posts', 'action' => 'view'));
+ $result = Router::parse('/posts/2007/08/01/title-of-post-here');
+ $expected = array('year' => '2007', 'month' => '08', 'day' => '01', 'controller' => 'posts', 'action' => 'view', 'plugin' => '', 'pass' => array('0' => 'title-of-post-here'), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $result = Router::parse('/pages/display/home');
+ $expected = array('plugin' => null, 'pass' => array('home'), 'controller' => 'pages', 'action' => 'display', 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('pages/display/home/');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('pages/display/home');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/page/*', array('controller' => 'test'));
+ $result = Router::parse('/page/my-page');
+ $expected = array('pass' => array('my-page'), 'plugin' => null, 'controller' => 'test', 'action' => 'index', 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:language/contact', array('language' => 'eng', 'plugin' => 'contact', 'controller' => 'contact', 'action' => 'index'), array('language' => '[a-z]{3}'));
+ $result = Router::parse('/eng/contact');
+ $expected = array('pass' => array(), 'named' => array(), 'language' => 'eng', 'plugin' => 'contact', 'controller' => 'contact', 'action' => 'index');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/forestillinger/:month/:year/*',
+ array('plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar'),
+ array('month' => '0[1-9]|1[012]', 'year' => '[12][0-9]{3}')
+ );
+
+ $result = Router::parse('/forestillinger/10/2007/min-forestilling');
+ $expected = array('pass' => array('min-forestilling'), 'plugin' => 'shows', 'controller' => 'shows', 'action' => 'calendar', 'year' => 2007, 'month' => 10, 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:controller/:action/*');
+ Router::connect('/', array('plugin' => 'pages', 'controller' => 'pages', 'action' => 'display'));
+ $result = Router::parse('/');
+ $expected = array('pass' => array(), 'named' => array(), 'controller' => 'pages', 'action' => 'display', 'plugin' => 'pages');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/posts/edit/0');
+ $expected = array('pass' => array(0), 'named' => array(), 'controller' => 'posts', 'action' => 'edit', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/:id::url_title', array('controller' => 'posts', 'action' => 'view'), array('pass' => array('id', 'url_title'), 'id' => '[\d]+'));
+ $result = Router::parse('/posts/5:sample-post-title');
+ $expected = array('pass' => array('5', 'sample-post-title'), 'named' => array(), 'id' => 5, 'url_title' => 'sample-post-title', 'plugin' => null, 'controller' => 'posts', 'action' => 'view');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/:id::url_title/*', array('controller' => 'posts', 'action' => 'view'), array('pass' => array('id', 'url_title'), 'id' => '[\d]+'));
+ $result = Router::parse('/posts/5:sample-post-title/other/params/4');
+ $expected = array('pass' => array('5', 'sample-post-title', 'other', 'params', '4'), 'named' => array(), 'id' => 5, 'url_title' => 'sample-post-title', 'plugin' => null, 'controller' => 'posts', 'action' => 'view');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/:url_title-(uuid::id)', array('controller' => 'posts', 'action' => 'view'), array('pass' => array('id', 'url_title'), 'id' => $UUID));
+ $result = Router::parse('/posts/sample-post-title-(uuid:47fc97a9-019c-41d1-a058-1fa3cbdd56cb)');
+ $expected = array('pass' => array('47fc97a9-019c-41d1-a058-1fa3cbdd56cb', 'sample-post-title'), 'named' => array(), 'id' => '47fc97a9-019c-41d1-a058-1fa3cbdd56cb', 'url_title' => 'sample-post-title', 'plugin' => null, 'controller' => 'posts', 'action' => 'view');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/view/*', array('controller' => 'posts', 'action' => 'view'), array('named' => false));
+ $result = Router::parse('/posts/view/foo:bar/routing:fun');
+ $expected = array('pass' => array('foo:bar', 'routing:fun'), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'view');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/view/*', array('controller' => 'posts', 'action' => 'view'), array('named' => array('foo', 'answer')));
+ $result = Router::parse('/posts/view/foo:bar/routing:fun/answer:42');
+ $expected = array('pass' => array('routing:fun'), 'named' => array('foo' => 'bar', 'answer' => '42'), 'plugin' => null, 'controller' => 'posts', 'action' => 'view');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/posts/view/*', array('controller' => 'posts', 'action' => 'view'), array('named' => array('foo', 'answer'), 'greedyNamed' => true));
+ $result = Router::parse('/posts/view/foo:bar/routing:fun/answer:42');
+ $expected = array('pass' => array(), 'named' => array('foo' => 'bar', 'routing' => 'fun', 'answer' => '42'), 'plugin' => null, 'controller' => 'posts', 'action' => 'view');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that the persist key works.
+ *
+ * @return void
+ */
+ public function testPersistentParameters() {
+ Router::reload();
+ Router::connect(
+ '/:lang/:color/posts/view/*',
+ array('controller' => 'posts', 'action' => 'view'),
+ array('persist' => array('lang', 'color')
+ ));
+ Router::connect(
+ '/:lang/:color/posts/index',
+ array('controller' => 'posts', 'action' => 'index'),
+ array('persist' => array('lang')
+ ));
+ Router::connect('/:lang/:color/posts/edit/*', array('controller' => 'posts', 'action' => 'edit'));
+ Router::connect('/about', array('controller' => 'pages', 'action' => 'view', 'about'));
+ Router::parse('/en/red/posts/view/5');
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'lang' => 'en',
+ 'color' => 'red',
+ 'prefix' => 'admin',
+ 'plugin' => null,
+ 'action' => 'view',
+ 'controller' => 'posts',
+ ))->addPaths(array(
+ 'base' => '/',
+ 'here' => '/en/red/posts/view/5',
+ 'webroot' => '/',
+ ))
+ );
+ $expected = '/en/red/posts/view/6';
+ $result = Router::url(array('controller' => 'posts', 'action' => 'view', 6));
+ $this->assertEquals($expected, $result);
+
+ $expected = '/en/blue/posts/index';
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', 'color' => 'blue'));
+ $this->assertEquals($expected, $result);
+
+ $expected = '/posts/edit/6';
+ $result = Router::url(array('controller' => 'posts', 'action' => 'edit', 6, 'color' => null, 'lang' => null));
+ $this->assertEquals($expected, $result);
+
+ $expected = '/posts';
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index'));
+ $this->assertEquals($expected, $result);
+
+ $expected = '/posts/edit/7';
+ $result = Router::url(array('controller' => 'posts', 'action' => 'edit', 7));
+ $this->assertEquals($expected, $result);
+
+ $expected = '/about';
+ $result = Router::url(array('controller' => 'pages', 'action' => 'view', 'about'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testUuidRoutes method
+ *
+ * @return void
+ */
+ public function testUuidRoutes() {
+ Router::connect(
+ '/subjects/add/:category_id',
+ array('controller' => 'subjects', 'action' => 'add'),
+ array('category_id' => '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}')
+ );
+ $result = Router::parse('/subjects/add/4795d601-19c8-49a6-930e-06a8b01d17b7');
+ $expected = array('pass' => array(), 'named' => array(), 'category_id' => '4795d601-19c8-49a6-930e-06a8b01d17b7', 'plugin' => null, 'controller' => 'subjects', 'action' => 'add');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRouteSymmetry method
+ *
+ * @return void
+ */
+ public function testRouteSymmetry() {
+ Router::connect(
+ "/:extra/page/:slug/*",
+ array('controller' => 'pages', 'action' => 'view', 'extra' => null),
+ array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+', "action" => 'view')
+ );
+
+ $result = Router::parse('/some_extra/page/this_is_the_slug');
+ $expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'view', 'slug' => 'this_is_the_slug', 'extra' => 'some_extra');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/page/this_is_the_slug');
+ $expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'view', 'slug' => 'this_is_the_slug', 'extra' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect(
+ "/:extra/page/:slug/*",
+ array('controller' => 'pages', 'action' => 'view', 'extra' => null),
+ array("extra" => '[a-z1-9_]*', "slug" => '[a-z1-9_]+')
+ );
+ Router::parse('/');
+
+ $result = Router::url(array('admin' => null, 'plugin' => null, 'controller' => 'pages', 'action' => 'view', 'slug' => 'this_is_the_slug', 'extra' => null));
+ $expected = '/page/this_is_the_slug';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('admin' => null, 'plugin' => null, 'controller' => 'pages', 'action' => 'view', 'slug' => 'this_is_the_slug', 'extra' => 'some_extra'));
+ $expected = '/some_extra/page/this_is_the_slug';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that Routing.prefixes are used when a Router instance is created
+ * or reset
+ *
+ * @return void
+ */
+ public function testRoutingPrefixesSetting() {
+ $restore = Configure::read('Routing');
+
+ Configure::write('Routing.prefixes', array('admin', 'member', 'super_user'));
+ Router::reload();
+ $result = Router::prefixes();
+ $expected = array('admin', 'member', 'super_user');
+ $this->assertEquals($expected, $result);
+
+ Configure::write('Routing.prefixes', array('admin', 'member'));
+ Router::reload();
+ $result = Router::prefixes();
+ $expected = array('admin', 'member');
+ $this->assertEquals($expected, $result);
+
+ Configure::write('Routing', $restore);
+ }
+
+/**
+ * Test prefix routing and plugin combinations
+ *
+ * @return void
+ */
+ public function testPrefixRoutingAndPlugins() {
+ Configure::write('Routing.prefixes', array('admin'));
+ $paths = App::path('plugins');
+ App::build(array(
+ 'plugins' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ )
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin'));
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'admin' => true, 'controller' => 'controller', 'action' => 'action',
+ 'plugin' => null, 'prefix' => 'admin'
+ ))->addPaths(array(
+ 'base' => '/',
+ 'here' => '/',
+ 'webroot' => '/base/',
+ ))
+ );
+ Router::parse('/');
+
+ $result = Router::url(array('plugin' => 'test_plugin', 'controller' => 'test_plugin', 'action' => 'index'));
+ $expected = '/admin/test_plugin';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => 'test_plugin', 'controller' => 'show_tickets', 'action' => 'admin_edit',
+ 'pass' => array('6'), 'prefix' => 'admin', 'admin' => true, 'form' => array(),
+ 'url' => array('url' => 'admin/shows/show_tickets/edit/6')
+ ))->addPaths(array(
+ 'base' => '/',
+ 'here' => '/admin/shows/show_tickets/edit/6',
+ 'webroot' => '/',
+ ))
+ );
+
+ $result = Router::url(array(
+ 'plugin' => 'test_plugin', 'controller' => 'show_tickets', 'action' => 'edit', 6,
+ 'admin' => true, 'prefix' => 'admin'
+ ));
+ $expected = '/admin/test_plugin/show_tickets/edit/6';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array(
+ 'plugin' => 'test_plugin', 'controller' => 'show_tickets', 'action' => 'index', 'admin' => true
+ ));
+ $expected = '/admin/test_plugin/show_tickets';
+ $this->assertEquals($expected, $result);
+
+ App::build(array('plugins' => $paths));
+ }
+
+/**
+ * testParseExtensions method
+ *
+ * @return void
+ */
+ public function testParseExtensions() {
+ $this->assertEquals(array(), Router::extensions());
+
+ Router::parseExtensions('rss');
+ $this->assertEquals(array('rss'), Router::extensions());
+ }
+
+/**
+ * testSetExtensions method
+ *
+ * @return void
+ */
+ public function testSetExtensions() {
+ Router::setExtensions(array('rss'));
+ $this->assertEquals(array('rss'), Router::extensions());
+
+ require CAKE . 'Config' . DS . 'routes.php';
+ $result = Router::parse('/posts.rss');
+ $this->assertFalse(isset($result['ext']));
+
+ Router::parseExtensions();
+ $result = Router::parse('/posts.rss');
+ $this->assertEquals('rss', $result['ext']);
+
+ $result = Router::parse('/posts.xml');
+ $this->assertFalse(isset($result['ext']));
+
+ Router::setExtensions(array('xml'));
+ $result = Router::extensions();
+ $this->assertEquals(array('rss', 'xml'), $result);
+
+ $result = Router::parse('/posts.xml');
+ $this->assertEquals('xml', $result['ext']);
+
+ $result = Router::setExtensions(array('pdf'), false);
+ $this->assertEquals(array('pdf'), $result);
+ }
+
+/**
+ * testExtensionParsing method
+ *
+ * @return void
+ */
+ public function testExtensionParsing() {
+ Router::parseExtensions();
+ require CAKE . 'Config' . DS . 'routes.php';
+
+ $result = Router::parse('/posts.rss');
+ $expected = array('plugin' => null, 'controller' => 'posts', 'action' => 'index', 'ext' => 'rss', 'pass' => array(), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/posts/view/1.rss');
+ $expected = array('plugin' => null, 'controller' => 'posts', 'action' => 'view', 'pass' => array('1'), 'named' => array(), 'ext' => 'rss', 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/posts/view/1.rss?query=test');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/posts/view/1.atom');
+ $expected['ext'] = 'atom';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+
+ Router::parseExtensions('rss', 'xml');
+
+ $result = Router::parse('/posts.xml');
+ $expected = array('plugin' => null, 'controller' => 'posts', 'action' => 'index', 'ext' => 'xml', 'pass' => array(), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/posts.atom?hello=goodbye');
+ $expected = array('plugin' => null, 'controller' => 'posts.atom', 'action' => 'index', 'pass' => array(), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', 'ext' => 'rss'));
+ $result = Router::parse('/controller/action');
+ $expected = array('controller' => 'controller', 'action' => 'action', 'plugin' => null, 'ext' => 'rss', 'named' => array(), 'pass' => array());
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::parseExtensions('rss');
+ Router::connect('/controller/action', array('controller' => 'controller', 'action' => 'action', 'ext' => 'rss'));
+ $result = Router::parse('/controller/action');
+ $expected = array('controller' => 'controller', 'action' => 'action', 'plugin' => null, 'ext' => 'rss', 'named' => array(), 'pass' => array());
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testQuerystringGeneration method
+ *
+ * @return void
+ */
+ public function testQuerystringGeneration() {
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '0', '?' => 'var=test&var2=test2'));
+ $expected = '/posts/index/0?var=test&var2=test2';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '0', '?' => array('var' => 'test', 'var2' => 'test2')));
+ $this->assertEquals($expected, $result);
+
+ $expected .= '&more=test+data';
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '0', '?' => array('var' => 'test', 'var2' => 'test2', 'more' => 'test data')));
+ $this->assertEquals($expected, $result);
+
+ // Test bug #4614
+ $restore = ini_get('arg_separator.output');
+ ini_set('arg_separator.output', '&amp;');
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '0', '?' => array('var' => 'test', 'var2' => 'test2', 'more' => 'test data')));
+ $this->assertEquals($expected, $result);
+ ini_set('arg_separator.output', $restore);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', '0', '?' => array('var' => 'test', 'var2' => 'test2')), array('escape' => true));
+ $expected = '/posts/index/0?var=test&amp;var2=test2';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testConnectNamed method
+ *
+ * @return void
+ */
+ public function testConnectNamed() {
+ $named = Router::connectNamed(false, array('default' => true));
+ $this->assertFalse($named['greedyNamed']);
+ $this->assertEquals(array_keys($named['rules']), $named['default']);
+
+ Router::reload();
+ Router::connect('/foo/*', array('controller' => 'bar', 'action' => 'fubar'));
+ Router::connectNamed(array(), array('separator' => '='));
+ $result = Router::parse('/foo/param1=value1/param2=value2');
+ $expected = array('pass' => array(), 'named' => array('param1' => 'value1', 'param2' => 'value2'), 'controller' => 'bar', 'action' => 'fubar', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/controller/action/*', array('controller' => 'controller', 'action' => 'action'), array('named' => array('param1' => 'value[\d]')));
+ Router::connectNamed(array(), array('greedy' => false, 'separator' => '='));
+ $result = Router::parse('/controller/action/param1=value1/param2=value2');
+ $expected = array('pass' => array('param2=value2'), 'named' => array('param1' => 'value1'), 'controller' => 'controller', 'action' => 'action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/:controller/:action/*');
+ Router::connectNamed(array('page'), array('default' => false, 'greedy' => false));
+ $result = Router::parse('/categories/index/limit=5');
+ $this->assertTrue(empty($result['named']));
+ }
+
+/**
+ * testNamedArgsUrlGeneration method
+ *
+ * @return void
+ */
+ public function testNamedArgsUrlGeneration() {
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', 'published' => 1, 'deleted' => 1));
+ $expected = '/posts/index/published:1/deleted:1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'index', 'published' => 0, 'deleted' => 0));
+ $expected = '/posts/index/published:0/deleted:0';
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ extract(Router::getNamedExpressions());
+ Router::connectNamed(array('file' => '[\w\.\-]+\.(html|png)'));
+ Router::connect('/', array('controller' => 'graphs', 'action' => 'index'));
+ Router::connect('/:id/*', array('controller' => 'graphs', 'action' => 'view'), array('id' => $ID));
+
+ $result = Router::url(array('controller' => 'graphs', 'action' => 'view', 'id' => 12, 'file' => 'asdf.png'));
+ $expected = '/12/file:asdf.png';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'graphs', 'action' => 'view', 12, 'file' => 'asdf.foo'));
+ $expected = '/graphs/view/12/file:asdf.foo';
+ $this->assertEquals($expected, $result);
+
+ Configure::write('Routing.prefixes', array('admin'));
+
+ Router::reload();
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'admin' => true, 'controller' => 'controller', 'action' => 'index', 'plugin' => null
+ ))->addPaths(array(
+ 'base' => '/',
+ 'here' => '/',
+ 'webroot' => '/base/',
+ ))
+ );
+ Router::parse('/');
+
+ $result = Router::url(array('page' => 1, 0 => null, 'sort' => 'controller', 'direction' => 'asc', 'order' => null));
+ $expected = "/admin/controller/index/page:1/sort:controller/direction:asc";
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ $request = new CakeRequest('admin/controller/index');
+ $request->addParams(array(
+ 'admin' => true, 'controller' => 'controller', 'action' => 'index', 'plugin' => null
+ ));
+ $request->base = '/';
+ Router::setRequestInfo($request);
+
+ $result = Router::parse('/admin/controller/index/type:whatever');
+ $result = Router::url(array('type' => 'new'));
+ $expected = "/admin/controller/index/type:new";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testNamedArgsUrlParsing method
+ *
+ * @return void
+ */
+ public function testNamedArgsUrlParsing() {
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $result = Router::parse('/controller/action/param1:value1:1/param2:value2:3/param:value');
+ $expected = array('pass' => array(), 'named' => array('param1' => 'value1:1', 'param2' => 'value2:3', 'param' => 'value'), 'controller' => 'controller', 'action' => 'action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $result = Router::connectNamed(false);
+ $this->assertEquals(array(), array_keys($result['rules']));
+ $this->assertFalse($result['greedyNamed']);
+ $result = Router::parse('/controller/action/param1:value1:1/param2:value2:3/param:value');
+ $expected = array('pass' => array('param1:value1:1', 'param2:value2:3', 'param:value'), 'named' => array(), 'controller' => 'controller', 'action' => 'action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ $result = Router::connectNamed(true);
+ $named = Router::namedConfig();
+ $this->assertEquals($named['default'], array_keys($result['rules']));
+ $this->assertTrue($result['greedyNamed']);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ Router::connectNamed(array('param1' => 'not-matching'));
+ $result = Router::parse('/controller/action/param1:value1:1/param2:value2:3/param:value');
+ $expected = array('pass' => array('param1:value1:1'), 'named' => array('param2' => 'value2:3', 'param' => 'value'), 'controller' => 'controller', 'action' => 'action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/foo/view/param1:value1:1/param2:value2:3/param:value');
+ $expected = array('pass' => array('param1:value1:1'), 'named' => array('param2' => 'value2:3', 'param' => 'value'), 'controller' => 'foo', 'action' => 'view', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ Router::connectNamed(array('param1' => '[\d]', 'param2' => '[a-z]', 'param3' => '[\d]'));
+ $result = Router::parse('/controller/action/param1:1/param2:2/param3:3');
+ $expected = array('pass' => array('param2:2'), 'named' => array('param1' => '1', 'param3' => '3'), 'controller' => 'controller', 'action' => 'action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ Router::connectNamed(array('param1' => '[\d]', 'param2' => true, 'param3' => '[\d]'));
+ $result = Router::parse('/controller/action/param1:1/param2:2/param3:3');
+ $expected = array('pass' => array(), 'named' => array('param1' => '1', 'param2' => '2', 'param3' => '3'), 'controller' => 'controller', 'action' => 'action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ Router::connectNamed(array('param1' => 'value[\d]+:[\d]+'), array('greedy' => false));
+ $result = Router::parse('/controller/action/param1:value1:1/param2:value2:3/param3:value');
+ $expected = array('pass' => array('param2:value2:3', 'param3:value'), 'named' => array('param1' => 'value1:1'), 'controller' => 'controller', 'action' => 'action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test url generation with legacy (1.2) style prefix routes.
+ *
+ * @return void
+ * @todo Remove tests related to legacy style routes.
+ * @see testUrlGenerationWithAutoPrefixes
+ */
+ public function testUrlGenerationWithLegacyPrefixes() {
+ Router::reload();
+ Router::connect('/protected/:controller/:action/*', array(
+ 'prefix' => 'protected',
+ 'protected' => true
+ ));
+ Router::parse('/');
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'images', 'action' => 'index',
+ 'prefix' => null, 'admin' => false,'url' => array('url' => 'images/index')
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/images/index',
+ 'webroot' => '/',
+ ))
+ );
+
+ $result = Router::url(array('protected' => true));
+ $expected = '/protected/images/index';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add'));
+ $expected = '/images/add';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add', 'protected' => true));
+ $expected = '/protected/images/add';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'edit', 1));
+ $expected = '/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'edit', 1, 'protected' => true));
+ $expected = '/protected/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'protected_edit', 1, 'protected' => true));
+ $expected = '/protected/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'edit', 1, 'protected' => true));
+ $expected = '/protected/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1));
+ $expected = '/others/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'protected' => true));
+ $expected = '/protected/others/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'protected' => true, 'page' => 1));
+ $expected = '/protected/others/edit/1/page:1';
+ $this->assertEquals($expected, $result);
+
+ Router::connectNamed(array('random'));
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'protected' => true, 'random' => 'my-value'));
+ $expected = '/protected/others/edit/1/random:my-value';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test newer style automatically generated prefix routes.
+ *
+ * @return void
+ */
+ public function testUrlGenerationWithAutoPrefixes() {
+ Configure::write('Routing.prefixes', array('protected'));
+ Router::reload();
+ Router::parse('/');
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'images', 'action' => 'index',
+ 'prefix' => null, 'protected' => false, 'url' => array('url' => 'images/index')
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/images/index',
+ 'webroot' => '/',
+ ))
+ );
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add'));
+ $expected = '/images/add';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add', 'protected' => true));
+ $expected = '/protected/images/add';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add_protected_test', 'protected' => true));
+ $expected = '/protected/images/add_protected_test';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'edit', 1));
+ $expected = '/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'edit', 1, 'protected' => true));
+ $expected = '/protected/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'protected_edit', 1, 'protected' => true));
+ $expected = '/protected/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'protectededit', 1, 'protected' => true));
+ $expected = '/protected/images/protectededit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'edit', 1, 'protected' => true));
+ $expected = '/protected/images/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1));
+ $expected = '/others/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'protected' => true));
+ $expected = '/protected/others/edit/1';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'protected' => true, 'page' => 1));
+ $expected = '/protected/others/edit/1/page:1';
+ $this->assertEquals($expected, $result);
+
+ Router::connectNamed(array('random'));
+ $result = Router::url(array('controller' => 'others', 'action' => 'edit', 1, 'protected' => true, 'random' => 'my-value'));
+ $expected = '/protected/others/edit/1/random:my-value';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that auto-generated prefix routes persist
+ *
+ * @return void
+ */
+ public function testAutoPrefixRoutePersistence() {
+ Configure::write('Routing.prefixes', array('protected'));
+ Router::reload();
+ Router::parse('/');
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'images', 'action' => 'index', 'prefix' => 'protected',
+ 'protected' => true, 'url' => array('url' => 'protected/images/index')
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/protected/images/index',
+ 'webroot' => '/',
+ ))
+ );
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add'));
+ $expected = '/protected/images/add';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add', 'protected' => false));
+ $expected = '/images/add';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that setting a prefix override the current one
+ *
+ * @return void
+ */
+ public function testPrefixOverride() {
+ Configure::write('Routing.prefixes', array('protected', 'admin'));
+ Router::reload();
+ Router::parse('/');
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'images', 'action' => 'index', 'prefix' => 'protected',
+ 'protected' => true, 'url' => array('url' => 'protected/images/index')
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/protected/images/index',
+ 'webroot' => '/',
+ ))
+ );
+
+ $result = Router::url(array('controller' => 'images', 'action' => 'add', 'admin' => true));
+ $expected = '/admin/images/add';
+ $this->assertEquals($expected, $result);
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'images', 'action' => 'index', 'prefix' => 'admin',
+ 'admin' => true, 'url' => array('url' => 'admin/images/index')
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/admin/images/index',
+ 'webroot' => '/',
+ ))
+ );
+ $result = Router::url(array('controller' => 'images', 'action' => 'add', 'protected' => true));
+ $expected = '/protected/images/add';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that setting a prefix to false is ignored, as its generally user error.
+ *
+ * @return void
+ */
+ public function testPrefixFalseIgnored() {
+ Configure::write('Routing.prefixes', array('admin'));
+ Router::reload();
+
+ Router::connect('/cache_css/*', array('admin' => false, 'controller' => 'asset_compress', 'action' => 'get'));
+
+ $url = Router::url(array('controller' => 'asset_compress', 'action' => 'get', 'test'));
+ $expected = '/cache_css/test';
+ $this->assertEquals($expected, $url);
+
+ $url = Router::url(array('admin' => false, 'controller' => 'asset_compress', 'action' => 'get', 'test'));
+ $expected = '/cache_css/test';
+ $this->assertEquals($expected, $url);
+
+ $url = Router::url(array('admin' => true, 'controller' => 'asset_compress', 'action' => 'get', 'test'));
+ $this->assertEquals('/admin/asset_compress/get/test', $url);
+ }
+
+/**
+ * testRemoveBase method
+ *
+ * @return void
+ */
+ public function testRemoveBase() {
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'controller', 'action' => 'index',
+ 'bare' => 0, 'url' => array('url' => 'protected/images/index')
+ ))->addPaths(array(
+ 'base' => '/base',
+ 'here' => '/',
+ 'webroot' => '/base/',
+ ))
+ );
+
+ $result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action'));
+ $expected = '/base/my_controller/my_action';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action', 'base' => false));
+ $expected = '/my_controller/my_action';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'my_controller', 'action' => 'my_action', 'base' => true));
+ $expected = '/base/my_controller/my_action/base:1';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testPagesUrlParsing method
+ *
+ * @return void
+ */
+ public function testPagesUrlParsing() {
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+
+ $result = Router::parse('/');
+ $expected = array('pass' => array('home'), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/pages/home/');
+ $expected = array('pass' => array('home'), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+
+ $result = Router::parse('/');
+ $expected = array('pass' => array('home'), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/pages/display/home/event:value');
+ $expected = array('pass' => array('home'), 'named' => array('event' => 'value'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/pages/display/home/event:Val_u2');
+ $expected = array('pass' => array('home'), 'named' => array('event' => 'Val_u2'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/pages/display/home/event:val-ue');
+ $expected = array('pass' => array('home'), 'named' => array('event' => 'val-ue'), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+ Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
+ Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+ $result = Router::parse('/pages/contact/');
+
+ $expected = array('pass' => array('contact'), 'named' => array(), 'plugin' => null, 'controller' => 'pages', 'action' => 'display');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that requests with a trailing dot don't loose the do.
+ *
+ * @return void
+ */
+ public function testParsingWithTrailingPeriod() {
+ Router::reload();
+ Router::connect('/:controller/:action/*');
+ $result = Router::parse('/posts/view/something.');
+ $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
+
+ $result = Router::parse('/posts/view/something. . .');
+ $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
+ }
+
+/**
+ * test that requests with a trailing dot don't loose the do.
+ *
+ * @return void
+ */
+ public function testParsingWithTrailingPeriodAndParseExtensions() {
+ Router::reload();
+ Router::connect('/:controller/:action/*');
+ Router::parseExtensions('json');
+
+ $result = Router::parse('/posts/view/something.');
+ $this->assertEquals('something.', $result['pass'][0], 'Period was chopped off %s');
+
+ $result = Router::parse('/posts/view/something. . .');
+ $this->assertEquals('something. . .', $result['pass'][0], 'Period was chopped off %s');
+ }
+
+/**
+ * test that patterns work for :action
+ *
+ * @return void
+ */
+ public function testParsingWithPatternOnAction() {
+ Router::reload();
+ Router::connect(
+ '/blog/:action/*',
+ array('controller' => 'blog_posts'),
+ array('action' => 'other|actions')
+ );
+ $result = Router::parse('/blog/other');
+ $expected = array(
+ 'plugin' => null,
+ 'controller' => 'blog_posts',
+ 'action' => 'other',
+ 'pass' => array(),
+ 'named' => array()
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/blog/foobar');
+ $this->assertEquals(array(), $result);
+
+ $result = Router::url(array('controller' => 'blog_posts', 'action' => 'foo'));
+ $this->assertEquals('/blog_posts/foo', $result);
+
+ $result = Router::url(array('controller' => 'blog_posts', 'action' => 'actions'));
+ $this->assertEquals('/blog/actions', $result);
+ }
+
+/**
+ * testParsingWithPrefixes method
+ *
+ * @return void
+ */
+ public function testParsingWithPrefixes() {
+ $adminParams = array('prefix' => 'admin', 'admin' => true);
+ Router::connect('/admin/:controller', $adminParams);
+ Router::connect('/admin/:controller/:action', $adminParams);
+ Router::connect('/admin/:controller/:action/*', $adminParams);
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'controller', 'action' => 'index'
+ ))->addPaths(array(
+ 'base' => '/base',
+ 'here' => '/',
+ 'webroot' => '/base/',
+ ))
+ );
+
+ $result = Router::parse('/admin/posts/');
+ $expected = array('pass' => array(), 'named' => array(), 'prefix' => 'admin', 'plugin' => null, 'controller' => 'posts', 'action' => 'admin_index', 'admin' => true);
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/admin/posts');
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('admin' => true, 'controller' => 'posts'));
+ $expected = '/base/admin/posts';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::prefixes();
+ $expected = array('admin');
+ $this->assertEquals($expected, $result);
+
+ Router::reload();
+
+ $prefixParams = array('prefix' => 'members', 'members' => true);
+ Router::connect('/members/:controller', $prefixParams);
+ Router::connect('/members/:controller/:action', $prefixParams);
+ Router::connect('/members/:controller/:action/*', $prefixParams);
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'controller', 'action' => 'index',
+ 'bare' => 0
+ ))->addPaths(array(
+ 'base' => '/base',
+ 'here' => '/',
+ 'webroot' => '/',
+ ))
+ );
+
+ $result = Router::parse('/members/posts/index');
+ $expected = array('pass' => array(), 'named' => array(), 'prefix' => 'members', 'plugin' => null, 'controller' => 'posts', 'action' => 'members_index', 'members' => true);
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('members' => true, 'controller' => 'posts', 'action' => 'index', 'page' => 2));
+ $expected = '/base/members/posts/index/page:2';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('members' => true, 'controller' => 'users', 'action' => 'add'));
+ $expected = '/base/members/users/add';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Tests URL generation with flags and prefixes in and out of context
+ *
+ * @return void
+ */
+ public function testUrlWritingWithPrefixes() {
+ Router::connect('/company/:controller/:action/*', array('prefix' => 'company', 'company' => true));
+ Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
+
+ $result = Router::url(array('controller' => 'users', 'action' => 'login', 'company' => true));
+ $expected = '/company/users/login';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'users', 'action' => 'company_login', 'company' => true));
+ $expected = '/company/users/login';
+ $this->assertEquals($expected, $result);
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'users', 'action' => 'login',
+ 'company' => true
+ ))->addPaths(array(
+ 'base' => '/',
+ 'here' => '/',
+ 'webroot' => '/base/',
+ ))
+ );
+
+ $result = Router::url(array('controller' => 'users', 'action' => 'login', 'company' => false));
+ $expected = '/login';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test url generation with prefixes and custom routes
+ *
+ * @return void
+ */
+ public function testUrlWritingWithPrefixesAndCustomRoutes() {
+ Router::connect(
+ '/admin/login',
+ array('controller' => 'users', 'action' => 'login', 'prefix' => 'admin', 'admin' => true)
+ );
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'posts', 'action' => 'index',
+ 'admin' => true, 'prefix' => 'admin'
+ ))->addPaths(array(
+ 'base' => '/',
+ 'here' => '/',
+ 'webroot' => '/',
+ ))
+ );
+ $result = Router::url(array('controller' => 'users', 'action' => 'login', 'admin' => true));
+ $this->assertEquals('/admin/login', $result);
+
+ $result = Router::url(array('controller' => 'users', 'action' => 'login'));
+ $this->assertEquals('/admin/login', $result);
+
+ $result = Router::url(array('controller' => 'users', 'action' => 'admin_login'));
+ $this->assertEquals('/admin/login', $result);
+ }
+
+/**
+ * testPassedArgsOrder method
+ *
+ * @return void
+ */
+ public function testPassedArgsOrder() {
+ Router::connect('/test-passed/*', array('controller' => 'pages', 'action' => 'display', 'home'));
+ Router::connect('/test2/*', array('controller' => 'pages', 'action' => 'display', 2));
+ Router::connect('/test/*', array('controller' => 'pages', 'action' => 'display', 1));
+ Router::parse('/');
+
+ $result = Router::url(array('controller' => 'pages', 'action' => 'display', 1, 'whatever'));
+ $expected = '/test/whatever';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'pages', 'action' => 'display', 2, 'whatever'));
+ $expected = '/test2/whatever';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('controller' => 'pages', 'action' => 'display', 'home', 'whatever'));
+ $expected = '/test-passed/whatever';
+ $this->assertEquals($expected, $result);
+
+ Configure::write('Routing.prefixes', array('admin'));
+ Router::reload();
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'images', 'action' => 'index',
+ 'url' => array('url' => 'protected/images/index')
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/protected/images/index',
+ 'webroot' => '/',
+ ))
+ );
+
+ Router::connect('/protected/:controller/:action/*', array(
+ 'controller' => 'users',
+ 'action' => 'index',
+ 'prefix' => 'protected'
+ ));
+
+ Router::parse('/');
+ $result = Router::url(array('controller' => 'images', 'action' => 'add'));
+ $expected = '/protected/images/add';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::prefixes();
+ $expected = array('admin', 'protected');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRegexRouteMatching method
+ *
+ * @return void
+ */
+ public function testRegexRouteMatching() {
+ Router::connect('/:locale/:controller/:action/*', array(), array('locale' => 'dan|eng'));
+
+ $result = Router::parse('/eng/test/test_action');
+ $expected = array('pass' => array(), 'named' => array(), 'locale' => 'eng', 'controller' => 'test', 'action' => 'test_action', 'plugin' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Router::parse('/badness/test/test_action');
+ $this->assertEquals(array(), $result);
+
+ Router::reload();
+ Router::connect('/:locale/:controller/:action/*', array(), array('locale' => 'dan|eng'));
+
+ $request = new CakeRequest();
+ Router::setRequestInfo(
+ $request->addParams(array(
+ 'plugin' => null, 'controller' => 'test', 'action' => 'index',
+ 'url' => array('url' => 'test/test_action')
+ ))->addPaths(array(
+ 'base' => '',
+ 'here' => '/test/test_action',
+ 'webroot' => '/',
+ ))
+ );
+
+ $result = Router::url(array('action' => 'test_another_action'));
+ $expected = '/test/test_another_action';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'test_another_action', 'locale' => 'eng'));
+ $expected = '/eng/test/test_another_action';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('action' => 'test_another_action', 'locale' => 'badness'));
+ $expected = '/test/test_another_action/locale:badness';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStripPlugin
+ *
+ * @return void
+ */
+ public function testStripPlugin() {
+ $pluginName = 'forums';
+ $url = 'example.com/' . $pluginName . '/';
+ $expected = 'example.com';
+
+ $this->assertEquals($expected, Router::stripPlugin($url, $pluginName));
+ $this->assertEquals(Router::stripPlugin($url), $url);
+ $this->assertEquals(Router::stripPlugin($url, null), $url);
+ }
+
+/**
+ * testCurrentRoute
+ *
+ * This test needs some improvement and actual requestAction() usage
+ *
+ * @return void
+ */
+ public function testCurrentRoute() {
+ $url = array('controller' => 'pages', 'action' => 'display', 'government');
+ Router::connect('/government', $url);
+ Router::parse('/government');
+ $route = Router::currentRoute();
+ $this->assertEquals(array_merge($url, array('plugin' => null)), $route->defaults);
+ }
+
+/**
+ * testRequestRoute
+ *
+ * @return void
+ */
+ public function testRequestRoute() {
+ $url = array('controller' => 'products', 'action' => 'display', 5);
+ Router::connect('/government', $url);
+ Router::parse('/government');
+ $route = Router::requestRoute();
+ $this->assertEquals(array_merge($url, array('plugin' => null)), $route->defaults);
+
+ // test that the first route is matched
+ $newUrl = array('controller' => 'products', 'action' => 'display', 6);
+ Router::connect('/government', $url);
+ Router::parse('/government');
+ $route = Router::requestRoute();
+ $this->assertEquals(array_merge($url, array('plugin' => null)), $route->defaults);
+
+ // test that an unmatched route does not change the current route
+ $newUrl = array('controller' => 'products', 'action' => 'display', 6);
+ Router::connect('/actor', $url);
+ Router::parse('/government');
+ $route = Router::requestRoute();
+ $this->assertEquals(array_merge($url, array('plugin' => null)), $route->defaults);
+ }
+
+/**
+ * testGetParams
+ *
+ * @return void
+ */
+ public function testGetParams() {
+ $paths = array('base' => '/', 'here' => '/products/display/5', 'webroot' => '/webroot');
+ $params = array('param1' => '1', 'param2' => '2');
+ Router::setRequestInfo(array($params, $paths));
+
+ $expected = array(
+ 'plugin' => null, 'controller' => false, 'action' => false,
+ 'named' => array(), 'pass' => array(),
+ 'param1' => '1', 'param2' => '2',
+ );
+ $this->assertEquals(Router::getParams(), $expected);
+ $this->assertEquals(Router::getParam('controller'), false);
+ $this->assertEquals(Router::getParam('param1'), '1');
+ $this->assertEquals(Router::getParam('param2'), '2');
+
+ Router::reload();
+
+ $params = array('controller' => 'pages', 'action' => 'display');
+ Router::setRequestInfo(array($params, $paths));
+ $expected = array(
+ 'plugin' => null, 'controller' => 'pages', 'action' => 'display',
+ 'named' => array(), 'pass' => array(),
+ );
+ $this->assertEquals(Router::getParams(), $expected);
+ $this->assertEquals(Router::getParams(true), $expected);
+ }
+
+/**
+ * test that connectDefaults() can disable default route connection
+ *
+ * @return void
+ */
+ public function testDefaultsMethod() {
+ Router::connect('/test/*', array('controller' => 'pages', 'action' => 'display', 2));
+ $result = Router::parse('/posts/edit/5');
+ $this->assertFalse(isset($result['controller']));
+ $this->assertFalse(isset($result['action']));
+ }
+
+/**
+ * test that the required default routes are connected.
+ *
+ * @return void
+ */
+ public function testConnectDefaultRoutes() {
+ App::build(array(
+ 'plugins' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS
+ )
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'PluginJs'));
+ Router::reload();
+ require CAKE . 'Config' . DS . 'routes.php';
+
+ $result = Router::url(array('plugin' => 'plugin_js', 'controller' => 'js_file', 'action' => 'index'));
+ $this->assertEquals('/plugin_js/js_file', $result);
+
+ $result = Router::parse('/plugin_js/js_file');
+ $expected = array(
+ 'plugin' => 'plugin_js', 'controller' => 'js_file', 'action' => 'index',
+ 'named' => array(), 'pass' => array()
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Router::url(array('plugin' => 'test_plugin', 'controller' => 'test_plugin', 'action' => 'index'));
+ $this->assertEquals('/test_plugin', $result);
+
+ $result = Router::parse('/test_plugin');
+ $expected = array(
+ 'plugin' => 'test_plugin', 'controller' => 'test_plugin', 'action' => 'index',
+ 'named' => array(), 'pass' => array()
+ );
+
+ $this->assertEquals($expected, $result, 'Plugin shortcut route broken. %s');
+ }
+
+/**
+ * test using a custom route class for route connection
+ *
+ * @return void
+ */
+ public function testUsingCustomRouteClass() {
+ $mock = $this->getMock('CakeRoute', array(), array(), 'MockConnectedRoute', false);
+ $routes = Router::connect(
+ '/:slug',
+ array('controller' => 'posts', 'action' => 'view'),
+ array('routeClass' => 'MockConnectedRoute', 'slug' => '[a-z_-]+')
+ );
+ $this->assertTrue(is_a($routes[0], 'MockConnectedRoute'), 'Incorrect class used. %s');
+ $expected = array('controller' => 'posts', 'action' => 'view', 'slug' => 'test');
+ $routes[0]->expects($this->any())
+ ->method('parse')
+ ->will($this->returnValue($expected));
+ $result = Router::parse('/test');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that route classes must extend CakeRoute
+ *
+ * @expectedException RouterException
+ * @return void
+ */
+ public function testCustomRouteException() {
+ Router::connect('/:controller', array(), array('routeClass' => 'Object'));
+ }
+
+/**
+ * test reversing parameter arrays back into strings.
+ *
+ * @return void
+ */
+ public function testRouterReverse() {
+ $params = array(
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'pass' => array(1),
+ 'named' => array(),
+ 'url' => array(),
+ 'autoRender' => 1,
+ 'bare' => 1,
+ 'return' => 1,
+ 'requested' => 1,
+ '_Token' => array('key' => 'sekret')
+ );
+ $result = Router::reverse($params);
+ $this->assertEquals('/posts/view/1', $result);
+
+ $params = array(
+ 'controller' => 'posts',
+ 'action' => 'index',
+ 'pass' => array(1),
+ 'named' => array('page' => 1, 'sort' => 'Article.title', 'direction' => 'desc'),
+ 'url' => array()
+ );
+ $result = Router::reverse($params);
+ $this->assertEquals('/posts/index/1/page:1/sort:Article.title/direction:desc', $result);
+
+ Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
+ $params = array(
+ 'lang' => 'eng',
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'pass' => array(1),
+ 'named' => array(),
+ 'url' => array('url' => 'eng/posts/view/1')
+ );
+ $result = Router::reverse($params);
+ $this->assertEquals('/eng/posts/view/1', $result);
+
+ $params = array(
+ 'lang' => 'eng',
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'pass' => array(1),
+ 'named' => array(),
+ 'url' => array('url' => 'eng/posts/view/1', 'foo' => 'bar', 'baz' => 'quu'),
+ 'paging' => array(),
+ 'models' => array()
+ );
+ $result = Router::reverse($params);
+ $this->assertEquals('/eng/posts/view/1?foo=bar&baz=quu', $result);
+
+ $request = new CakeRequest('/eng/posts/view/1');
+ $request->addParams(array(
+ 'lang' => 'eng',
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'pass' => array(1),
+ 'named' => array(),
+ ));
+ $request->query = array('url' => 'eng/posts/view/1', 'test' => 'value');
+ $result = Router::reverse($request);
+ $expected = '/eng/posts/view/1?test=value';
+ $this->assertEquals($expected, $result);
+
+ $params = array(
+ 'lang' => 'eng',
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'pass' => array(1),
+ 'named' => array(),
+ 'url' => array('url' => 'eng/posts/view/1')
+ );
+ $result = Router::reverse($params, true);
+ $this->assertRegExp('/^http(s)?:\/\//', $result);
+ }
+
+/**
+ * Test that extensions work with Router::reverse()
+ *
+ * @return void
+ */
+ public function testReverseWithExtension() {
+ Router::parseExtensions('json');
+
+ $request = new CakeRequest('/posts/view/1.json');
+ $request->addParams(array(
+ 'controller' => 'posts',
+ 'action' => 'view',
+ 'pass' => array(1),
+ 'named' => array(),
+ 'ext' => 'json',
+ ));
+ $request->query = array();
+ $result = Router::reverse($request);
+ $expected = '/posts/view/1.json';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that setRequestInfo can accept arrays and turn that into a CakeRequest object.
+ *
+ * @return void
+ */
+ public function testSetRequestInfoLegacy() {
+ Router::setRequestInfo(array(
+ array(
+ 'plugin' => null, 'controller' => 'images', 'action' => 'index',
+ 'url' => array('url' => 'protected/images/index')
+ ),
+ array(
+ 'base' => '',
+ 'here' => '/protected/images/index',
+ 'webroot' => '/',
+ )
+ ));
+ $result = Router::getRequest();
+ $this->assertEquals('images', $result->controller);
+ $this->assertEquals('index', $result->action);
+ $this->assertEquals('', $result->base);
+ $this->assertEquals('/protected/images/index', $result->here);
+ $this->assertEquals('/', $result->webroot);
+ }
+
+/**
+ * Test that Router::url() uses the first request
+ */
+ public function testUrlWithRequestAction() {
+ $firstRequest = new CakeRequest('/posts/index');
+ $firstRequest->addParams(array(
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ))->addPaths(array('base' => ''));
+
+ $secondRequest = new CakeRequest('/posts/index');
+ $secondRequest->addParams(array(
+ 'requested' => 1,
+ 'plugin' => null,
+ 'controller' => 'comments',
+ 'action' => 'listing'
+ ))->addPaths(array('base' => ''));
+
+ Router::setRequestInfo($firstRequest);
+ Router::setRequestInfo($secondRequest);
+
+ $result = Router::url(array('base' => false));
+ $this->assertEquals('/comments/listing', $result, 'with second requests, the last should win.');
+
+ Router::popRequest();
+ $result = Router::url(array('base' => false));
+ $this->assertEquals('/posts', $result, 'with second requests, the last should win.');
+ }
+
+/**
+ * test that a route object returning a full url is not modified.
+ *
+ * @return void
+ */
+ public function testUrlFullUrlReturnFromRoute() {
+ $url = 'http://example.com/posts/view/1';
+
+ $this->getMock('CakeRoute', array(), array('/'), 'MockReturnRoute');
+ $routes = Router::connect('/:controller/:action', array(), array('routeClass' => 'MockReturnRoute'));
+ $routes[0]->expects($this->any())->method('match')
+ ->will($this->returnValue($url));
+
+ $result = Router::url(array('controller' => 'posts', 'action' => 'view', 1));
+ $this->assertEquals($url, $result);
+ }
+
+/**
+ * test protocol in url
+ *
+ * @return void
+ */
+ public function testUrlProtocol() {
+ $url = 'http://example.com';
+ $this->assertEquals($url, Router::url($url));
+
+ $url = 'ed2k://example.com';
+ $this->assertEquals($url, Router::url($url));
+
+ $url = 'svn+ssh://example.com';
+ $this->assertEquals($url, Router::url($url));
+
+ $url = '://example.com';
+ $this->assertEquals($url, Router::url($url));
+ }
+
+/**
+ * Testing that patterns on the :action param work properly.
+ *
+ * @return void
+ */
+ public function testPatternOnAction() {
+ $route = new CakeRoute(
+ '/blog/:action/*',
+ array('controller' => 'blog_posts'),
+ array('action' => 'other|actions')
+ );
+ $result = $route->match(array('controller' => 'blog_posts', 'action' => 'foo'));
+ $this->assertFalse($result);
+
+ $result = $route->match(array('controller' => 'blog_posts', 'action' => 'actions'));
+ $this->assertEquals('/blog/actions/', $result);
+
+ $result = $route->parse('/blog/other');
+ $expected = array('controller' => 'blog_posts', 'action' => 'other', 'pass' => array(), 'named' => array());
+ $this->assertEquals($expected, $result);
+
+ $result = $route->parse('/blog/foobar');
+ $this->assertFalse($result);
+ }
+
+/**
+ * Tests resourceMap as getter and setter.
+ *
+ * @return void
+ */
+ public function testResourceMap() {
+ $default = Router::resourceMap();
+ $expected = array(
+ array('action' => 'index', 'method' => 'GET', 'id' => false),
+ array('action' => 'view', 'method' => 'GET', 'id' => true),
+ array('action' => 'add', 'method' => 'POST', 'id' => false),
+ array('action' => 'edit', 'method' => 'PUT', 'id' => true),
+ array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
+ array('action' => 'edit', 'method' => 'POST', 'id' => true)
+ );
+ $this->assertEquals($default, $expected);
+
+ $custom = array(
+ array('action' => 'index', 'method' => 'GET', 'id' => false),
+ array('action' => 'view', 'method' => 'GET', 'id' => true),
+ array('action' => 'add', 'method' => 'POST', 'id' => false),
+ array('action' => 'edit', 'method' => 'PUT', 'id' => true),
+ array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
+ array('action' => 'update', 'method' => 'POST', 'id' => true)
+ );
+ Router::resourceMap($custom);
+ $this->assertEquals(Router::resourceMap(), $custom);
+
+ Router::resourceMap($default);
+ }
+
+/**
+ * test setting redirect routes
+ *
+ * @return void
+ */
+ public function testRouteRedirection() {
+ Router::redirect('/blog', array('controller' => 'posts'), array('status' => 302));
+ $this->assertEquals(1, count(Router::$routes));
+ Router::$routes[0]->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ Router::$routes[0]->stop = false;
+ $this->assertEquals(302, Router::$routes[0]->options['status']);
+
+ Router::parse('/blog');
+ $header = Router::$routes[0]->response->header();
+ $this->assertEquals(Router::url('/posts', true), $header['Location']);
+ $this->assertEquals(302, Router::$routes[0]->response->statusCode());
+
+ Router::$routes[0]->response = $this->getMock('CakeResponse', array('_sendHeader'));
+ Router::parse('/not-a-match');
+ $this->assertEquals(array(), Router::$routes[0]->response->header());
+ }
+
+/**
+ * Test setting the default route class
+ *
+ * @return void
+ */
+ public function testDefaultRouteClass() {
+ $this->getMock('CakeRoute', array(), array('/test'), 'TestDefaultRouteClass');
+ Router::defaultRouteClass('TestDefaultRouteClass');
+
+ $result = Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+ $this->assertInstanceOf('TestDefaultRouteClass', $result[0]);
+ }
+
+/**
+ * Test getting the default route class
+ *
+ * @return void
+ */
+ public function testDefaultRouteClassGetter() {
+ $routeClass = 'TestDefaultRouteClass';
+ Router::defaultRouteClass($routeClass);
+
+ $this->assertEquals($routeClass, Router::defaultRouteClass());
+ $this->assertEquals($routeClass, Router::defaultRouteClass(null));
+ }
+
+/**
+ * Test that route classes must extend CakeRoute
+ *
+ * @expectedException RouterException
+ * @return void
+ */
+ public function testDefaultRouteException() {
+ Router::defaultRouteClass('');
+ Router::connect('/:controller', array());
+ }
+
+/**
+ * Test that route classes must extend CakeRoute
+ *
+ * @expectedException RouterException
+ * @return void
+ */
+ public function testSettingInvalidDefaultRouteException() {
+ Router::defaultRouteClass('Object');
+ }
+
+/**
+ * Test that class must exist
+ *
+ * @expectedException RouterException
+ * @return void
+ */
+ public function testSettingNonExistentDefaultRouteException() {
+ Router::defaultRouteClass('NonExistentClass');
+ }
+
+/**
+ * Tests generating well-formed querystrings
+ *
+ * @return void
+ */
+ public function testQueryString() {
+ $result = Router::queryString(array('var' => 'foo bar'));
+ $expected = '?var=foo+bar';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::queryString(false, array('some' => 'param', 'foo' => 'bar'));
+ $expected = '?some=param&foo=bar';
+ $this->assertEquals($expected, $result);
+
+ $existing = array('apple' => 'red', 'pear' => 'green');
+ $result = Router::queryString($existing, array('some' => 'param', 'foo' => 'bar'));
+ $expected = '?apple=red&pear=green&some=param&foo=bar';
+ $this->assertEquals($expected, $result);
+
+ $existing = 'apple=red&pear=green';
+ $result = Router::queryString($existing, array('some' => 'param', 'foo' => 'bar'));
+ $expected = '?apple=red&pear=green&some=param&foo=bar';
+ $this->assertEquals($expected, $result);
+
+ $existing = '?apple=red&pear=green';
+ $result = Router::queryString($existing, array('some' => 'param', 'foo' => 'bar'));
+ $expected = '?apple=red&pear=green&some=param&foo=bar';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::queryString('apple=red&pear=green');
+ $expected = '?apple=red&pear=green';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::queryString('foo=bar', array('php' => 'nut', 'jose' => 'zap'), true);
+ $expected = '?foo=bar&amp;php=nut&amp;jose=zap';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::queryString('foo=bar&amp;', array('php' => 'nut', 'jose' => 'zap'), true);
+ $expected = '?foo=bar&amp;php=nut&amp;jose=zap';
+ $this->assertEquals($expected, $result);
+
+ $result = Router::queryString('foo=bar&', array('php' => 'nut', 'jose' => 'zap'));
+ $expected = '?foo=bar&php=nut&jose=zap';
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php
new file mode 100644
index 0000000..ccc4356
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php
@@ -0,0 +1,342 @@
+<?php
+/**
+ * CakeTestCaseTest file
+ *
+ * Test Case for CakeTestCase class
+ *
+ * PHP version 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.TestSuite
+ * @since CakePHP v 1.2.0.4487
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('CakeHtmlReporter', 'TestSuite/Reporter');
+
+/**
+ * CakeTestCaseTest
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+class CakeTestCaseTest extends CakeTestCase {
+
+ public static function setUpBeforeClass() {
+ require_once CAKE . 'Test' . DS . 'Fixture' . DS . 'AssertTagsTestCase.php';
+ require_once CAKE . 'Test' . DS . 'Fixture' . DS . 'FixturizedTestCase.php';
+ }
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Reporter = $this->getMock('CakeHtmlReporter');
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Result);
+ unset($this->Reporter);
+ }
+
+/**
+ * testAssertGoodTags
+ *
+ * @return void
+ */
+ public function testAssertTagsQuotes() {
+ $test = new AssertTagsTestCase('testAssertTagsQuotes');
+ $result = $test->run();
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertTrue($result->wasSuccessful());
+ $this->assertEquals(0, $result->failureCount());
+
+ $input = '<a href="/test.html" class="active">My link</a>';
+ $pattern = array(
+ 'a' => array('href' => '/test.html', 'class' => 'active'),
+ 'My link',
+ '/a'
+ );
+ $this->assertTrue($test->assertTags($input, $pattern), 'Double quoted attributes %s');
+
+ $input = "<a href='/test.html' class='active'>My link</a>";
+ $pattern = array(
+ 'a' => array('href' => '/test.html', 'class' => 'active'),
+ 'My link',
+ '/a'
+ );
+ $this->assertTrue($test->assertTags($input, $pattern), 'Single quoted attributes %s');
+
+ $input = "<a href='/test.html' class='active'>My link</a>";
+ $pattern = array(
+ 'a' => array('href' => 'preg:/.*\.html/', 'class' => 'active'),
+ 'My link',
+ '/a'
+ );
+ $this->assertTrue($test->assertTags($input, $pattern), 'Single quoted attributes %s');
+
+ $input = "<span><strong>Text</strong></span>";
+ $pattern = array(
+ '<span',
+ '<strong',
+ 'Text',
+ '/strong',
+ '/span'
+ );
+ $this->assertTrue($test->assertTags($input, $pattern), 'Tags with no attributes');
+
+ $input = "<span class='active'><strong>Text</strong></span>";
+ $pattern = array(
+ 'span' => array('class'),
+ '<strong',
+ 'Text',
+ '/strong',
+ '/span'
+ );
+ $this->assertTrue($test->assertTags($input, $pattern), 'Test attribute presence');
+ }
+
+/**
+ * testNumericValuesInExpectationForAssertTags
+ *
+ * @return void
+ */
+ public function testNumericValuesInExpectationForAssertTags() {
+ $test = new AssertTagsTestCase('testNumericValuesInExpectationForAssertTags');
+ $result = $test->run();
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertTrue($result->wasSuccessful());
+ $this->assertEquals(0, $result->failureCount());
+ }
+
+/**
+ * testBadAssertTags
+ *
+ * @return void
+ */
+ public function testBadAssertTags() {
+ $test = new AssertTagsTestCase('testBadAssertTags');
+ $result = $test->run();
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertFalse($result->wasSuccessful());
+ $this->assertEquals(1, $result->failureCount());
+
+ $test = new AssertTagsTestCase('testBadAssertTags2');
+ $result = $test->run();
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertFalse($result->wasSuccessful());
+ $this->assertEquals(1, $result->failureCount());
+ }
+
+/**
+ * testLoadFixtures
+ *
+ * @return void
+ */
+ public function testLoadFixtures() {
+ $test = new FixturizedTestCase('testFixturePresent');
+ $manager = $this->getMock('CakeFixtureManager');
+ $manager->fixturize($test);
+ $test->fixtureManager = $manager;
+ $manager->expects($this->once())->method('load');
+ $manager->expects($this->once())->method('unload');
+ $result = $test->run();
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertTrue($result->wasSuccessful());
+ $this->assertEquals(0, $result->failureCount());
+ }
+
+/**
+ * testLoadFixturesOnDemand
+ *
+ * @return void
+ */
+ public function testLoadFixturesOnDemand() {
+ $test = new FixturizedTestCase('testFixtureLoadOnDemand');
+ $test->autoFixtures = false;
+ $manager = $this->getMock('CakeFixtureManager');
+ $manager->fixturize($test);
+ $test->fixtureManager = $manager;
+ $manager->expects($this->once())->method('loadSingle');
+ $result = $test->run();
+ $this->assertEquals(0, $result->errorCount());
+ }
+
+/**
+ * testLoadFixturesOnDemand
+ *
+ * @return void
+ */
+ public function testUnoadFixturesAfterFailure() {
+ $test = new FixturizedTestCase('testFixtureLoadOnDemand');
+ $test->autoFixtures = false;
+ $manager = $this->getMock('CakeFixtureManager');
+ $manager->fixturize($test);
+ $test->fixtureManager = $manager;
+ $manager->expects($this->once())->method('loadSingle');
+ $result = $test->run();
+ $this->assertEquals(0, $result->errorCount());
+ }
+
+/**
+ * testThrowException
+ *
+ * @return void
+ */
+ public function testThrowException() {
+ $test = new FixturizedTestCase('testThrowException');
+ $test->autoFixtures = false;
+ $manager = $this->getMock('CakeFixtureManager');
+ $manager->fixturize($test);
+ $test->fixtureManager = $manager;
+ $manager->expects($this->once())->method('unload');
+ $result = $test->run();
+ $this->assertEquals(1, $result->errorCount());
+ }
+
+/**
+ * testSkipIf
+ *
+ * @return void
+ */
+ public function testSkipIf() {
+ $test = new FixturizedTestCase('testSkipIfTrue');
+ $result = $test->run();
+ $this->assertEquals(1, $result->skippedCount());
+
+ $test = new FixturizedTestCase('testSkipIfFalse');
+ $result = $test->run();
+ $this->assertEquals(0, $result->skippedCount());
+ }
+
+/**
+ * Test that CakeTestCase::setUp() backs up values.
+ *
+ * @return void
+ */
+ public function testSetupBackUpValues() {
+ $this->assertArrayHasKey('debug', $this->_configure);
+ $this->assertArrayHasKey('Plugin', $this->_pathRestore);
+ }
+
+/**
+ * test assertTextNotEquals()
+ *
+ * @return void
+ */
+ public function testAssertTextNotEquals() {
+ $one = "\r\nOne\rTwooo";
+ $two = "\nOne\nTwo";
+ $this->assertTextNotEquals($one, $two);
+ }
+
+/**
+ * test assertTextEquals()
+ *
+ * @return void
+ */
+ public function testAssertTextEquals() {
+ $one = "\r\nOne\rTwo";
+ $two = "\nOne\nTwo";
+ $this->assertTextEquals($one, $two);
+ }
+
+/**
+ * test assertTextStartsWith()
+ *
+ * @return void
+ */
+ public function testAssertTextStartsWith() {
+ $stringDirty = "some\nstring\r\nwith\rdifferent\nline endings!";
+ $stringClean = "some\nstring\nwith\ndifferent\nline endings!";
+
+ $this->assertStringStartsWith("some\nstring", $stringDirty);
+ $this->assertStringStartsNotWith("some\r\nstring\r\nwith", $stringDirty);
+ $this->assertStringStartsNotWith("some\nstring\nwith", $stringDirty);
+
+ $this->assertTextStartsWith("some\nstring\nwith", $stringDirty);
+ $this->assertTextStartsWith("some\r\nstring\r\nwith", $stringDirty);
+ }
+
+/**
+ * test assertTextStartsNotWith()
+ *
+ * @return void
+ */
+ public function testAssertTextStartsNotWith() {
+ $stringDirty = "some\nstring\r\nwith\rdifferent\nline endings!";
+ $stringClean = "some\nstring\nwith\ndifferent\nline endings!";
+
+ $this->assertTextStartsNotWith("some\nstring\nwithout", $stringDirty);
+ }
+
+/**
+ * test assertTextEndsWith()
+ *
+ * @return void
+ */
+ public function testAssertTextEndsWith() {
+ $stringDirty = "some\nstring\r\nwith\rdifferent\nline endings!";
+ $stringClean = "some\nstring\nwith\ndifferent\nline endings!";
+
+ $this->assertTextEndsWith("string\nwith\r\ndifferent\rline endings!", $stringDirty);
+ $this->assertTextEndsWith("string\r\nwith\ndifferent\nline endings!", $stringDirty);
+ }
+
+/**
+ * test assertTextEndsNotWith()
+ *
+ * @return void
+ */
+ public function testAssertTextEndsNotWith() {
+ $stringDirty = "some\nstring\r\nwith\rdifferent\nline endings!";
+ $stringClean = "some\nstring\nwith\ndifferent\nline endings!";
+
+ $this->assertStringEndsNotWith("different\nline endings", $stringDirty);
+ $this->assertTextEndsNotWith("different\rline endings", $stringDirty);
+ }
+
+/**
+ * test assertTextContains()
+ *
+ * @return void
+ */
+ public function testAssertTextContains() {
+ $stringDirty = "some\nstring\r\nwith\rdifferent\nline endings!";
+ $stringClean = "some\nstring\nwith\ndifferent\nline endings!";
+
+ $this->assertContains("different", $stringDirty);
+ $this->assertNotContains("different\rline", $stringDirty);
+
+ $this->assertTextContains("different\rline", $stringDirty);
+ }
+
+/**
+ * test assertTextNotContains()
+ *
+ * @return void
+ */
+ public function testAssertTextNotContains() {
+ $stringDirty = "some\nstring\r\nwith\rdifferent\nline endings!";
+ $stringClean = "some\nstring\nwith\ndifferent\nline endings!";
+
+ $this->assertTextNotContains("different\rlines", $stringDirty);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php
new file mode 100644
index 0000000..5565548
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestFixtureTest.php
@@ -0,0 +1,499 @@
+<?php
+/**
+ * CakeTestFixture file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.TestSuite
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('DboSource', 'Model/Datasource');
+App::uses('Model', 'Model');
+App::uses('CakeTestFixture', 'TestSuite/Fixture');
+
+/**
+ * CakeTestFixtureTestFixture class
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+class CakeTestFixtureTestFixture extends CakeTestFixture {
+
+/**
+ * Name property
+ *
+ * @var string
+ */
+ public $name = 'FixtureTest';
+
+/**
+ * Table property
+ *
+ * @var string
+ */
+ public $table = 'fixture_tests';
+
+/**
+ * Fields array
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => '255'),
+ 'created' => array('type' => 'datetime')
+ );
+
+/**
+ * Records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Gandalf', 'created' => '2009-04-28 19:20:00'),
+ array('name' => 'Captain Picard', 'created' => '2009-04-28 19:20:00'),
+ array('name' => 'Chewbacca', 'created' => '2009-04-28 19:20:00')
+ );
+}
+
+/**
+ * StringFieldsTestFixture class
+ *
+ * @package Cake.Test.Case.TestSuite
+ * @subpackage cake.cake.tests.cases.libs
+ */
+class StringsTestFixture extends CakeTestFixture {
+
+/**
+ * Name property
+ *
+ * @var string
+ */
+ public $name = 'Strings';
+
+/**
+ * Table property
+ *
+ * @var string
+ */
+ public $table = 'strings';
+
+/**
+ * Fields array
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => '255'),
+ 'email' => array('type' => 'string', 'length' => '255'),
+ 'age' => array('type' => 'integer', 'default' => 10)
+ );
+
+/**
+ * Records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Mark Doe', 'email' => 'mark.doe@email.com'),
+ array('name' => 'John Doe', 'email' => 'john.doe@email.com', 'age' => 20),
+ array('email' => 'jane.doe@email.com', 'name' => 'Jane Doe', 'age' => 30)
+ );
+}
+
+
+/**
+ * CakeTestFixtureImportFixture class
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+class CakeTestFixtureImportFixture extends CakeTestFixture {
+
+/**
+ * Name property
+ *
+ * @var string
+ */
+ public $name = 'ImportFixture';
+
+/**
+ * Import property
+ *
+ * @var mixed
+ */
+ public $import = array('table' => 'fixture_tests', 'connection' => 'fixture_test_suite');
+}
+
+/**
+ * CakeTestFixtureDefaultImportFixture class
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+class CakeTestFixtureDefaultImportFixture extends CakeTestFixture {
+
+/**
+ * Name property
+ *
+ * @var string
+ */
+ public $name = 'ImportFixture';
+}
+
+/**
+ * FixtureImportTestModel class
+ *
+ * @package Cake.Test.Case.TestSuite
+ * @package Cake.Test.Case.TestSuite
+ */
+class FixtureImportTestModel extends Model {
+
+ public $name = 'FixtureImport';
+
+ public $useTable = 'fixture_tests';
+
+ public $useDbConfig = 'test';
+
+}
+
+class FixturePrefixTest extends Model {
+
+ public $name = 'FixturePrefix';
+
+ public $useTable = '_tests';
+
+ public $tablePrefix = 'fixture';
+
+ public $useDbConfig = 'test';
+}
+
+
+/**
+ * Test case for CakeTestFixture
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+class CakeTestFixtureTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ $methods = array_diff(get_class_methods('DboSource'), array('enabled'));
+ $methods[] = 'connect';
+
+ $this->criticDb = $this->getMock('DboSource', $methods);
+ $this->criticDb->fullDebug = true;
+ $this->db = ConnectionManager::getDataSource('test');
+ $this->_backupConfig = $this->db->config;
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->criticDb);
+ $this->db->config = $this->_backupConfig;
+ }
+
+/**
+ * testInit
+ *
+ * @return void
+ */
+ public function testInit() {
+ $Fixture = new CakeTestFixtureTestFixture();
+ unset($Fixture->table);
+ $Fixture->init();
+ $this->assertEquals('fixture_tests', $Fixture->table);
+ $this->assertEquals('id', $Fixture->primaryKey);
+
+ $Fixture = new CakeTestFixtureTestFixture();
+ $Fixture->primaryKey = 'my_random_key';
+ $Fixture->init();
+ $this->assertEquals('my_random_key', $Fixture->primaryKey);
+ }
+
+/**
+ * test that init() correctly sets the fixture table when the connection
+ * or model have prefixes defined.
+ *
+ * @return void
+ */
+ public function testInitDbPrefix() {
+ $this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
+ $db = ConnectionManager::getDataSource('test');
+ $Source = new CakeTestFixtureTestFixture();
+ $Source->drop($db);
+ $Source->create($db);
+ $Source->insert($db);
+
+ $Fixture = new CakeTestFixtureTestFixture();
+ $expected = array('id', 'name', 'created');
+ $this->assertEquals($expected, array_keys($Fixture->fields));
+
+ $config = $db->config;
+ $config['prefix'] = 'fixture_test_suite_';
+ ConnectionManager::create('fixture_test_suite', $config);
+
+ $Fixture->fields = $Fixture->records = null;
+ $Fixture->import = array('table' => 'fixture_tests', 'connection' => 'test', 'records' => true);
+ $Fixture->init();
+ $this->assertEquals(count($Fixture->records), count($Source->records));
+ $Fixture->create(ConnectionManager::getDataSource('fixture_test_suite'));
+
+ $Fixture = new CakeTestFixtureImportFixture();
+ $Fixture->fields = $Fixture->records = $Fixture->table = null;
+ $Fixture->import = array('model' => 'FixtureImportTestModel', 'connection' => 'test');
+ $Fixture->init();
+ $this->assertEquals(array('id', 'name', 'created'), array_keys($Fixture->fields));
+ $this->assertEquals('fixture_tests', $Fixture->table);
+
+ $keys = array_flip(ClassRegistry::keys());
+ $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys));
+
+ $Fixture->drop(ConnectionManager::getDataSource('fixture_test_suite'));
+ $Source->drop($db);
+ }
+
+/**
+ * test that fixtures don't duplicate the test db prefix.
+ *
+ * @return void
+ */
+ public function testInitDbPrefixDuplication() {
+ $this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
+ $db = ConnectionManager::getDataSource('test');
+ $backPrefix = $db->config['prefix'];
+ $db->config['prefix'] = 'cake_fixture_test_';
+ ConnectionManager::create('fixture_test_suite', $db->config);
+ $newDb = ConnectionManager::getDataSource('fixture_test_suite');
+ $newDb->config['prefix'] = 'cake_fixture_test_';
+
+ $Source = new CakeTestFixtureTestFixture();
+ $Source->create($db);
+ $Source->insert($db);
+
+ $Fixture = new CakeTestFixtureImportFixture();
+ $Fixture->fields = $Fixture->records = $Fixture->table = null;
+ $Fixture->import = array('model' => 'FixtureImportTestModel', 'connection' => 'test');
+
+ $Fixture->init();
+ $this->assertEquals(array('id', 'name', 'created'), array_keys($Fixture->fields));
+ $this->assertEquals('fixture_tests', $Fixture->table);
+
+ $Source->drop($db);
+ $db->config['prefix'] = $backPrefix;
+ }
+
+/**
+ * test init with a model that has a tablePrefix declared.
+ *
+ * @return void
+ */
+ public function testInitModelTablePrefix() {
+ $this->skipIf($this->db instanceof Sqlite, 'Cannot open 2 connections to Sqlite');
+ $this->skipIf(!empty($this->db->config['prefix']), 'Cannot run this test, you have a database connection prefix.');
+
+ $Source = new CakeTestFixtureTestFixture();
+ $Source->create($this->db);
+ $Source->insert($this->db);
+
+ $Fixture = new CakeTestFixtureTestFixture();
+ unset($Fixture->table);
+ $Fixture->fields = $Fixture->records = null;
+ $Fixture->import = array('model' => 'FixturePrefixTest', 'connection' => 'test', 'records' => false);
+ $Fixture->init();
+ $this->assertEquals('fixture_tests', $Fixture->table);
+
+ $keys = array_flip(ClassRegistry::keys());
+ $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys));
+
+ $Source->drop($this->db);
+ }
+
+/**
+ * testImport
+ *
+ * @return void
+ */
+ public function testImport() {
+ $testSuiteDb = ConnectionManager::getDataSource('test');
+ $testSuiteConfig = $testSuiteDb->config;
+ ConnectionManager::create('new_test_suite', array_merge($testSuiteConfig, array('prefix' => 'new_' . $testSuiteConfig['prefix'])));
+ $newTestSuiteDb = ConnectionManager::getDataSource('new_test_suite');
+
+ $Source = new CakeTestFixtureTestFixture();
+ $Source->create($newTestSuiteDb);
+ $Source->insert($newTestSuiteDb);
+
+ $Fixture = new CakeTestFixtureDefaultImportFixture();
+ $Fixture->fields = $Fixture->records = null;
+ $Fixture->import = array('model' => 'FixtureImportTestModel', 'connection' => 'new_test_suite');
+ $Fixture->init();
+ $this->assertEquals(array('id', 'name', 'created'), array_keys($Fixture->fields));
+
+ $keys = array_flip(ClassRegistry::keys());
+ $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys));
+
+ $Source->drop($newTestSuiteDb);
+ }
+
+/**
+ * test that importing with records works. Make sure to try with postgres as its
+ * handling of aliases is a workaround at best.
+ *
+ * @return void
+ */
+ public function testImportWithRecords() {
+ $testSuiteDb = ConnectionManager::getDataSource('test');
+ $testSuiteConfig = $testSuiteDb->config;
+ ConnectionManager::create('new_test_suite', array_merge($testSuiteConfig, array('prefix' => 'new_' . $testSuiteConfig['prefix'])));
+ $newTestSuiteDb = ConnectionManager::getDataSource('new_test_suite');
+
+ $Source = new CakeTestFixtureTestFixture();
+ $Source->create($newTestSuiteDb);
+ $Source->insert($newTestSuiteDb);
+
+ $Fixture = new CakeTestFixtureDefaultImportFixture();
+ $Fixture->fields = $Fixture->records = null;
+ $Fixture->import = array(
+ 'model' => 'FixtureImportTestModel', 'connection' => 'new_test_suite', 'records' => true
+ );
+ $Fixture->init();
+ $this->assertEquals(array('id', 'name', 'created'), array_keys($Fixture->fields));
+ $this->assertFalse(empty($Fixture->records[0]), 'No records loaded on importing fixture.');
+ $this->assertTrue(isset($Fixture->records[0]['name']), 'No name loaded for first record');
+
+ $Source->drop($newTestSuiteDb);
+ }
+
+/**
+ * test create method
+ *
+ * @return void
+ */
+ public function testCreate() {
+ $Fixture = new CakeTestFixtureTestFixture();
+ $this->criticDb->expects($this->atLeastOnce())->method('execute');
+ $this->criticDb->expects($this->atLeastOnce())->method('createSchema');
+ $return = $Fixture->create($this->criticDb);
+ $this->assertTrue($this->criticDb->fullDebug);
+ $this->assertTrue($return);
+
+ unset($Fixture->fields);
+ $return = $Fixture->create($this->criticDb);
+ $this->assertFalse($return);
+ }
+
+/**
+ * test the insert method
+ *
+ * @return void
+ */
+ public function testInsert() {
+ $Fixture = new CakeTestFixtureTestFixture();
+ $this->criticDb->expects($this->atLeastOnce())
+ ->method('insertMulti')
+ ->will($this->returnCallback(array($this, 'insertCallback')));
+
+ $return = $Fixture->insert($this->criticDb);
+ $this->assertTrue(!empty($this->insertMulti));
+ $this->assertTrue($this->criticDb->fullDebug);
+ $this->assertTrue($return);
+ $this->assertEquals('fixture_tests', $this->insertMulti['table']);
+ $this->assertEquals(array('name', 'created'), $this->insertMulti['fields']);
+ $expected = array(
+ array('Gandalf', '2009-04-28 19:20:00'),
+ array('Captain Picard', '2009-04-28 19:20:00'),
+ array('Chewbacca', '2009-04-28 19:20:00')
+ );
+ $this->assertEquals($expected, $this->insertMulti['values']);
+ }
+
+/**
+ * Helper function to be used as callback and store the parameters of an insertMulti call
+ *
+ * @param string $table
+ * @param string $fields
+ * @param string $values
+ * @return boolean true
+ */
+ public function insertCallback($table, $fields, $values) {
+ $this->insertMulti['table'] = $table;
+ $this->insertMulti['fields'] = $fields;
+ $this->insertMulti['values'] = $values;
+ return true;
+ }
+
+/**
+ * test the insert method
+ *
+ * @return void
+ */
+ public function testInsertStrings() {
+ $Fixture = new StringsTestFixture();
+ $this->criticDb->expects($this->atLeastOnce())
+ ->method('insertMulti')
+ ->will($this->returnCallback(array($this, 'insertCallback')));
+
+ $return = $Fixture->insert($this->criticDb);
+ $this->assertTrue($this->criticDb->fullDebug);
+ $this->assertTrue($return);
+ $this->assertEquals('strings', $this->insertMulti['table']);
+ $this->assertEquals(array('email', 'name', 'age'), $this->insertMulti['fields']);
+ $expected = array(
+ array('Mark Doe', 'mark.doe@email.com', null),
+ array('John Doe', 'john.doe@email.com', 20),
+ array('Jane Doe', 'jane.doe@email.com', 30),
+ );
+ $this->assertEquals($expected, $this->insertMulti['values']);
+ }
+
+/**
+ * Test the drop method
+ *
+ * @return void
+ */
+ public function testDrop() {
+ $Fixture = new CakeTestFixtureTestFixture();
+ $this->criticDb->expects($this->at(1))->method('execute')->will($this->returnValue(true));
+ $this->criticDb->expects($this->at(3))->method('execute')->will($this->returnValue(false));
+ $this->criticDb->expects($this->exactly(2))->method('dropSchema');
+
+ $return = $Fixture->drop($this->criticDb);
+ $this->assertTrue($this->criticDb->fullDebug);
+ $this->assertTrue($return);
+
+ $return = $Fixture->drop($this->criticDb);
+ $this->assertTrue($return);
+
+ unset($Fixture->fields);
+ $return = $Fixture->drop($this->criticDb);
+ $this->assertFalse($return);
+ }
+
+/**
+ * Test the truncate method.
+ *
+ * @return void
+ */
+ public function testTruncate() {
+ $Fixture = new CakeTestFixtureTestFixture();
+ $this->criticDb->expects($this->atLeastOnce())->method('truncate');
+ $Fixture->truncate($this->criticDb);
+ $this->assertTrue($this->criticDb->fullDebug);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestSuiteTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestSuiteTest.php
new file mode 100644
index 0000000..a30fd5a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/CakeTestSuiteTest.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.TestSuite
+ * @since CakePHP v 1.2.0.4487
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * CakeTestSuiteTest
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+class CakeTestSuiteTest extends CakeTestCase {
+
+/**
+ * testAddTestDirectory
+ *
+ * @return void
+ */
+ public function testAddTestDirectory() {
+ $testFolder = CORE_TEST_CASES . DS . 'TestSuite';
+ $count = count(glob($testFolder . DS . '*Test.php'));
+
+ $suite = $this->getMock('CakeTestSuite', array('addTestFile'));
+ $suite
+ ->expects($this->exactly($count))
+ ->method('addTestFile');
+
+ $suite->addTestDirectory($testFolder);
+ }
+
+/**
+ * testAddTestDirectoryRecursive
+ *
+ * @return void
+ */
+ public function testAddTestDirectoryRecursive() {
+ $testFolder = CORE_TEST_CASES . DS . 'Cache';
+ $count = count(glob($testFolder . DS . '*Test.php'));
+ $count += count(glob($testFolder . DS . 'Engine' . DS . '*Test.php'));
+
+ $suite = $this->getMock('CakeTestSuite', array('addTestFile'));
+ $suite
+ ->expects($this->exactly($count))
+ ->method('addTestFile');
+
+ $suite->addTestDirectoryRecursive($testFolder);
+ }
+
+/**
+ * testAddTestDirectoryRecursiveWithHidden
+ *
+ * @return void
+ */
+ public function testAddTestDirectoryRecursiveWithHidden() {
+ $this->skipIf(!is_writeable(TMP), 'Cant addTestDirectoryRecursiveWithHidden unless the tmp folder is writable.');
+
+ $Folder = new Folder(TMP . 'MyTestFolder', true, 0777);
+ mkdir($Folder->path . DS . '.svn', 0777, true);
+ touch($Folder->path . DS . '.svn' . DS . 'InHiddenFolderTest.php');
+ touch($Folder->path . DS . 'NotHiddenTest.php');
+ touch($Folder->path . DS . '.HiddenTest.php');
+
+ $suite = $this->getMock('CakeTestSuite', array('addTestFile'));
+ $suite
+ ->expects($this->exactly(1))
+ ->method('addTestFile');
+
+ $suite->addTestDirectoryRecursive($Folder->pwd());
+
+ $Folder->delete();
+ }
+
+/**
+ * testAddTestDirectoryRecursiveWithNonPhp
+ *
+ * @return void
+ */
+ public function testAddTestDirectoryRecursiveWithNonPhp() {
+ $this->skipIf(!is_writeable(TMP), 'Cant addTestDirectoryRecursiveWithNonPhp unless the tmp folder is writable.');
+
+ $Folder = new Folder(TMP . 'MyTestFolder', true, 0777);
+ touch($Folder->path . DS . 'BackupTest.php~');
+ touch($Folder->path . DS . 'SomeNotesTest.txt');
+ touch($Folder->path . DS . 'NotHiddenTest.php');
+
+ $suite = $this->getMock('CakeTestSuite', array('addTestFile'));
+ $suite
+ ->expects($this->exactly(1))
+ ->method('addTestFile');
+
+ $suite->addTestDirectoryRecursive($Folder->pwd());
+
+ $Folder->delete();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php
new file mode 100644
index 0000000..cf6bbb8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/ControllerTestCaseTest.php
@@ -0,0 +1,564 @@
+<?php
+/**
+ * ControllerTestCaseTest file
+ *
+ * Test Case for ControllerTestCase class
+ *
+ * PHP version 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.TestSuite
+ * @since CakePHP v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('CakeHtmlReporter', 'TestSuite/Reporter');
+
+require_once dirname(dirname(__FILE__)) . DS . 'Model' . DS . 'models.php';
+
+/**
+ * AppController class
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+if (!class_exists('AppController', false)) {
+/**
+ * AppController class
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+ class AppController extends Controller {
+
+ /**
+ * helpers property
+ *
+ * @var array
+ * @access public
+ */
+ public $helpers = array('Html');
+
+ /**
+ * uses property
+ *
+ * @var array
+ * @access public
+ */
+ public $uses = array('ControllerPost');
+
+ /**
+ * components property
+ *
+ * @var array
+ * @access public
+ */
+ public $components = array('Cookie');
+
+ }
+} elseif (!defined('APP_CONTROLLER_EXISTS')) {
+ define('APP_CONTROLLER_EXISTS', true);
+}
+
+/**
+ * PostsController class
+ */
+if (!class_exists('PostsController')) {
+ class PostsController extends AppController {
+
+ /**
+ * Components array
+ *
+ * @var array
+ */
+ public $components = array(
+ 'RequestHandler',
+ 'Email',
+ 'Auth'
+ );
+ }
+}
+
+/**
+ * ControllerTestCaseTest controller
+ */
+class ControllerTestCaseTestController extends AppController {
+
+/**
+ * Uses array
+ *
+ * @param array
+ */
+ public $uses = array('TestPlugin.TestPluginComment');
+
+}
+
+/**
+ * ControllerTestCaseTest
+ *
+ * @package Cake.Test.Case.TestSuite
+ */
+class ControllerTestCaseTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.post', 'core.author', 'core.test_plugin_comment');
+
+/**
+ * reset environment.
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'Controller' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS),
+ 'Model' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
+ $this->Case = $this->getMockForAbstractClass('ControllerTestCase');
+ Router::reload();
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ $this->Case->controller = null;
+ }
+
+/**
+ * Test that ControllerTestCase::generate() creates mock objects correctly
+ */
+ public function testGenerate() {
+ if (defined('APP_CONTROLLER_EXISTS')) {
+ $this->markTestSkipped('AppController exists, cannot run.');
+ }
+ $Posts = $this->Case->generate('Posts');
+ $this->assertEquals('Posts', $Posts->name);
+ $this->assertEquals('Post', $Posts->modelClass);
+ $this->assertNull($Posts->response->send());
+
+ $Posts = $this->Case->generate('Posts', array(
+ 'methods' => array(
+ 'render'
+ )
+ ));
+ $this->assertNull($Posts->render('index'));
+
+ $Posts = $this->Case->generate('Posts', array(
+ 'models' => array('Post'),
+ 'components' => array('RequestHandler')
+ ));
+
+ $this->assertInstanceOf('Post', $Posts->Post);
+ $this->assertNull($Posts->Post->save(array()));
+ $this->assertNull($Posts->Post->find('all'));
+ $this->assertEquals('posts', $Posts->Post->useTable);
+ $this->assertNull($Posts->RequestHandler->isAjax());
+
+ $Posts = $this->Case->generate('Posts', array(
+ 'models' => array(
+ 'Post' => true
+ )
+ ));
+ $this->assertNull($Posts->Post->save(array()));
+ $this->assertNull($Posts->Post->find('all'));
+
+ $Posts = $this->Case->generate('Posts', array(
+ 'models' => array(
+ 'Post' => array('save'),
+ )
+ ));
+ $this->assertNull($Posts->Post->save(array()));
+ $this->assertInternalType('array', $Posts->Post->find('all'));
+
+ $Posts = $this->Case->generate('Posts', array(
+ 'models' => array('Post'),
+ 'components' => array(
+ 'RequestHandler' => array('isPut'),
+ 'Email' => array('send'),
+ 'Session'
+ )
+ ));
+ $Posts->RequestHandler->expects($this->once())
+ ->method('isPut')
+ ->will($this->returnValue(true));
+ $this->assertTrue($Posts->RequestHandler->isPut());
+
+ $Posts->Auth->Session->expects($this->any())
+ ->method('write')
+ ->will($this->returnValue('written!'));
+ $this->assertEquals('written!', $Posts->Auth->Session->write('something'));
+ }
+
+/**
+ * Tests ControllerTestCase::generate() using classes from plugins
+ */
+ public function testGenerateWithPlugin() {
+ $Tests = $this->Case->generate('TestPlugin.Tests', array(
+ 'models' => array(
+ 'TestPlugin.TestPluginComment'
+ ),
+ 'components' => array(
+ 'TestPlugin.Plugins'
+ )
+ ));
+ $this->assertEquals('Tests', $Tests->name);
+ $this->assertInstanceOf('PluginsComponent', $Tests->Plugins);
+
+ $result = ClassRegistry::init('TestPlugin.TestPluginComment');
+ $this->assertInstanceOf('TestPluginComment', $result);
+
+ $Tests = $this->Case->generate('ControllerTestCaseTest', array(
+ 'models' => array(
+ 'TestPlugin.TestPluginComment' => array('save')
+ )
+ ));
+ $this->assertInstanceOf('TestPluginComment', $Tests->TestPluginComment);
+ $Tests->TestPluginComment->expects($this->at(0))
+ ->method('save')
+ ->will($this->returnValue(true));
+ $Tests->TestPluginComment->expects($this->at(1))
+ ->method('save')
+ ->will($this->returnValue(false));
+ $this->assertTrue($Tests->TestPluginComment->save(array()));
+ $this->assertFalse($Tests->TestPluginComment->save(array()));
+ }
+
+/**
+ * Tests testAction
+ */
+ public function testTestAction() {
+ $Controller = $this->Case->generate('TestsApps');
+ $this->Case->testAction('/tests_apps/index');
+ $this->assertInternalType('array', $this->Case->controller->viewVars);
+
+ $this->Case->testAction('/tests_apps/set_action');
+ $results = $this->Case->controller->viewVars;
+ $expected = array(
+ 'var' => 'string'
+ );
+ $this->assertEquals($expected, $results);
+
+ $result = $this->Case->controller->response->body();
+ $this->assertRegExp('/This is the TestsAppsController index view/', $result);
+
+ $Controller = $this->Case->generate('TestsApps');
+ $this->Case->testAction('/tests_apps/redirect_to');
+ $results = $this->Case->headers;
+ $expected = array(
+ 'Location' => 'http://cakephp.org'
+ );
+ $this->assertEquals($expected, $results);
+ }
+
+/**
+ * Make sure testAction() can hit plugin controllers.
+ *
+ * @return void
+ */
+ public function testTestActionWithPlugin() {
+ $Controller = $this->Case->generate('TestPlugin.Tests');
+ $this->Case->testAction('/test_plugin/tests/index');
+ $this->assertEquals('It is a variable', $this->Case->controller->viewVars['test_value']);
+ }
+
+/**
+ * Tests using loaded routes during tests
+ *
+ * @return void
+ */
+ public function testUseRoutes() {
+ Router::connect('/:controller/:action/*');
+ include CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'routes.php';
+
+ $controller = $this->Case->generate('TestsApps');
+ $controller->Components->load('RequestHandler');
+ $result = $this->Case->testAction('/tests_apps/index.json', array('return' => 'contents'));
+ $result = json_decode($result, true);
+ $expected = array('cakephp' => 'cool');
+ $this->assertEquals($expected, $result);
+
+ include CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'routes.php';
+ $result = $this->Case->testAction('/some_alias');
+ $this->assertEquals(5, $result);
+ }
+
+/**
+ * Tests not using loaded routes during tests
+ *
+ * @expectedException MissingActionException
+ */
+ public function testSkipRoutes() {
+ Router::connect('/:controller/:action/*');
+ include CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS . 'routes.php';
+
+ $this->Case->loadRoutes = false;
+ $result = $this->Case->testAction('/tests_apps/missing_action.json', array('return' => 'view'));
+ }
+
+/**
+ * Tests backwards compatibility with setting the return type
+ */
+ public function testBCSetReturn() {
+ $this->Case->autoMock = true;
+
+ $result = $this->Case->testAction('/tests_apps/some_method');
+ $this->assertEquals(5, $result);
+
+ $data = array('var' => 'set');
+ $result = $this->Case->testAction('/tests_apps_posts/post_var', array(
+ 'data' => $data,
+ 'return' => 'vars'
+ ));
+ $this->assertEquals($data, $result['data']);
+
+ $result = $this->Case->testAction('/tests_apps/set_action', array(
+ 'return' => 'view'
+ ));
+ $this->assertEquals('This is the TestsAppsController index view string', $result);
+
+ $result = $this->Case->testAction('/tests_apps/set_action', array(
+ 'return' => 'contents'
+ ));
+ $this->assertRegExp('/<html/', $result);
+ $this->assertRegExp('/This is the TestsAppsController index view/', $result);
+ $this->assertRegExp('/<\/html>/', $result);
+ }
+
+/**
+ * Tests sending POST data to testAction
+ */
+ public function testTestActionPostData() {
+ $this->Case->autoMock = true;
+
+ $data = array(
+ 'Post' => array(
+ 'name' => 'Some Post'
+ )
+ );
+ $this->Case->testAction('/tests_apps_posts/post_var', array(
+ 'data' => $data
+ ));
+ $this->assertEquals($this->Case->controller->viewVars['data'], $data);
+ $this->assertEquals($this->Case->controller->data, $data);
+
+ $this->Case->testAction('/tests_apps_posts/post_var/named:param', array(
+ 'data' => $data
+ ));
+ $expected = array(
+ 'named' => 'param'
+ );
+ $this->assertEquals($expected, $this->Case->controller->request->named);
+ $this->assertEquals($this->Case->controller->data, $data);
+
+ $result = $this->Case->testAction('/tests_apps_posts/post_var', array(
+ 'return' => 'vars',
+ 'method' => 'post',
+ 'data' => array(
+ 'name' => 'is jonas',
+ 'pork' => 'and beans',
+ )
+ ));
+ $this->assertEquals(array('name', 'pork'), array_keys($result['data']));
+
+ $result = $this->Case->testAction('/tests_apps_posts/add', array('return' => 'vars'));
+ $this->assertTrue(array_key_exists('posts', $result));
+ $this->assertEquals(4, count($result['posts']));
+ $this->assertTrue($this->Case->controller->request->is('post'));
+ }
+
+/**
+ * Tests sending GET data to testAction
+ */
+ public function testTestActionGetData() {
+ $this->Case->autoMock = true;
+
+ $result = $this->Case->testAction('/tests_apps_posts/url_var', array(
+ 'method' => 'get',
+ 'data' => array(
+ 'some' => 'var',
+ 'lackof' => 'creativity'
+ )
+ ));
+ $this->assertEquals('var', $this->Case->controller->request->query['some']);
+ $this->assertEquals('creativity', $this->Case->controller->request->query['lackof']);
+
+ $result = $this->Case->testAction('/tests_apps_posts/url_var/var1:value1/var2:val2', array(
+ 'return' => 'vars',
+ 'method' => 'get',
+ ));
+ $this->assertEquals(array('var1', 'var2'), array_keys($result['params']['named']));
+
+ $result = $this->Case->testAction('/tests_apps_posts/url_var/gogo/val2', array(
+ 'return' => 'vars',
+ 'method' => 'get',
+ ));
+ $this->assertEquals(array('gogo', 'val2'), $result['params']['pass']);
+
+ $result = $this->Case->testAction('/tests_apps_posts/url_var', array(
+ 'return' => 'vars',
+ 'method' => 'get',
+ 'data' => array(
+ 'red' => 'health',
+ 'blue' => 'mana'
+ )
+ ));
+ $query = $this->Case->controller->request->query;
+ $this->assertTrue(isset($query['red']));
+ $this->assertTrue(isset($query['blue']));
+ }
+
+/**
+ * Test that REST actions with XML/JSON input work.
+ *
+ * @return void
+ */
+ public function testTestActionJsonData() {
+ $result = $this->Case->testAction('/tests_apps_posts/input_data', array(
+ 'return' => 'vars',
+ 'method' => 'post',
+ 'data' => '{"key":"value","json":true}'
+ ));
+ $this->assertEquals('value', $result['data']['key']);
+ $this->assertTrue($result['data']['json']);
+ }
+
+/**
+ * Tests autoMock ability
+ */
+ public function testAutoMock() {
+ $this->Case->autoMock = true;
+ $this->Case->testAction('/tests_apps/set_action');
+ $results = $this->Case->controller->viewVars;
+ $expected = array(
+ 'var' => 'string'
+ );
+ $this->assertEquals($expected, $results);
+ }
+
+/**
+ * Test using testAction and not mocking
+ */
+ public function testNoMocking() {
+ $result = $this->Case->testAction('/tests_apps/some_method');
+ $this->Case->assertEquals(5, $result);
+
+ $data = array('var' => 'set');
+ $result = $this->Case->testAction('/tests_apps_posts/post_var', array(
+ 'data' => $data,
+ 'return' => 'vars'
+ ));
+ $this->assertEquals($data, $result['data']);
+
+ $result = $this->Case->testAction('/tests_apps/set_action', array(
+ 'return' => 'view'
+ ));
+ $this->assertEquals('This is the TestsAppsController index view string', $result);
+
+ $result = $this->Case->testAction('/tests_apps/set_action', array(
+ 'return' => 'contents'
+ ));
+ $this->assertRegExp('/<html/', $result);
+ $this->assertRegExp('/This is the TestsAppsController index view/', $result);
+ $this->assertRegExp('/<\/html>/', $result);
+ }
+
+/**
+ * Test that controllers don't get reused.
+ *
+ * @return void
+ */
+ public function testNoControllerReuse() {
+ $this->Case->autoMock = true;
+ $result = $this->Case->testAction('/tests_apps/index', array(
+ 'data' => array('var' => 'first call'),
+ 'method' => 'get',
+ 'return' => 'contents',
+ ));
+ $this->assertContains('<html', $result);
+ $this->assertContains('This is the TestsAppsController index view', $result);
+ $this->assertContains('first call', $result);
+ $this->assertContains('</html>', $result);
+
+ $result = $this->Case->testAction('/tests_apps/index', array(
+ 'data' => array('var' => 'second call'),
+ 'method' => 'get',
+ 'return' => 'contents'
+ ));
+ $this->assertContains('second call', $result);
+
+ $result = $this->Case->testAction('/tests_apps/index', array(
+ 'data' => array('var' => 'third call'),
+ 'method' => 'get',
+ 'return' => 'contents'
+ ));
+ $this->assertContains('third call', $result);
+ }
+
+/**
+ * Test that multiple calls to redirect in the same test method don't cause issues.
+ *
+ * @return void
+ */
+ public function testTestActionWithMultipleRedirect() {
+ $Controller = $this->Case->generate('TestsApps');
+
+ $options = array('method' => 'get');
+ $this->Case->testAction('/tests_apps/redirect_to', $options);
+ $this->Case->testAction('/tests_apps/redirect_to', $options);
+ }
+
+/**
+ * Tests that Components storing response or request objects internally during construct
+ * will always have a fresh reference to those object available
+ *
+ * @return void
+ * @see http://cakephp.lighthouseapp.com/projects/42648-cakephp/tickets/2705-requesthandler-weird-behavior
+ */
+ public function testComponentsSameRequestAndResponse() {
+ $this->Case->generate('TestsApps');
+ $options = array('method' => 'get');
+ $this->Case->testAction('/tests_apps/index', $options);
+ $this->assertSame($this->Case->controller->response, $this->Case->controller->RequestHandler->response);
+ $this->assertSame($this->Case->controller->request, $this->Case->controller->RequestHandler->request);
+ }
+
+/**
+ * Test that testAction() doesn't destroy data in GET & POST
+ *
+ * @return void
+ */
+ public function testRestoreGetPost() {
+ $restored = array('new' => 'value');
+
+ $_GET = $restored;
+ $_POST = $restored;
+
+ $this->Case->generate('TestsApps');
+ $options = array('method' => 'get');
+ $this->Case->testAction('/tests_apps/index', $options);
+
+ $this->assertEquals($restored, $_GET);
+ $this->assertEquals($restored, $_POST);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php
new file mode 100644
index 0000000..8a5b7a3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/TestSuite/HtmlCoverageReportTest.php
@@ -0,0 +1,231 @@
+<?php
+/**
+ * Test case for HtmlCoverageReport
+ *
+ * PHP5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Case.TestSuite
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HtmlCoverageReport', 'TestSuite/Coverage');
+App::uses('CakeBaseReporter', 'TestSuite/Reporter');
+
+class HtmlCoverageReportTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ), App::RESET);
+ CakePlugin::load(array('TestPlugin'));
+ $reporter = new CakeBaseReporter();
+ $reporter->params = array('app' => false, 'plugin' => false, 'group' => false);
+ $coverage = array();
+ $this->Coverage = new HtmlCoverageReport($coverage, $reporter);
+ }
+
+/**
+ * test getting the path filters.
+ *
+ * @return void
+ */
+ public function testGetPathFilter() {
+ $this->Coverage->appTest = false;
+ $result = $this->Coverage->getPathFilter();
+ $this->assertEquals(CAKE, $result);
+
+ $this->Coverage->appTest = true;
+ $result = $this->Coverage->getPathFilter();
+ $this->assertEquals(ROOT . DS . APP_DIR . DS, $result);
+
+ $this->Coverage->appTest = false;
+ $this->Coverage->pluginTest = 'TestPlugin';
+ $result = $this->Coverage->getPathFilter();
+ $this->assertEquals(CakePlugin::path('TestPlugin'), $result);
+ }
+
+/**
+ * test filtering coverage data.
+ *
+ * @return void
+ */
+ public function testFilterCoverageDataByPathRemovingElements() {
+ $data = array(
+ CAKE . 'dispatcher.php' => array(
+ 10 => -1,
+ 12 => 1
+ ),
+ APP . 'app_model.php' => array(
+ 50 => 1,
+ 52 => -1
+ )
+ );
+ $this->Coverage->setCoverage($data);
+ $result = $this->Coverage->filterCoverageDataByPath(CAKE);
+ $this->assertTrue(isset($result[CAKE . 'dispatcher.php']));
+ $this->assertFalse(isset($result[APP . 'app_model.php']));
+ }
+
+/**
+ * test generating HTML reports from file arrays.
+ *
+ * @return void
+ */
+ public function testGenerateDiff() {
+ $file = array(
+ 'line 1',
+ 'line 2',
+ 'line 3',
+ 'line 4',
+ 'line 5',
+ 'line 6',
+ 'line 7',
+ 'line 8',
+ 'line 9',
+ 'line 10',
+ );
+ $coverage = array(
+ 1 => array(array('id' => 'HtmlCoverageReportTest::testGenerateDiff')),
+ 2 => -2,
+ 3 => array(array('id' => 'HtmlCoverageReportTest::testGenerateDiff')),
+ 4 => array(array('id' => 'HtmlCoverageReportTest::testGenerateDiff')),
+ 5 => -1,
+ 6 => array(array('id' => 'HtmlCoverageReportTest::testGenerateDiff')),
+ 7 => array(array('id' => 'HtmlCoverageReportTest::testGenerateDiff')),
+ 8 => array(array('id' => 'HtmlCoverageReportTest::testGenerateDiff')),
+ 9 => -1,
+ 10 => array(array('id' => 'HtmlCoverageReportTest::testGenerateDiff'))
+ );
+ $result = $this->Coverage->generateDiff('myfile.php', $file, $coverage);
+ $this->assertRegExp('/myfile\.php Code coverage\: \d+\.?\d*\%/', $result);
+ $this->assertRegExp('/<div class="code-coverage-results" id\="coverage\-myfile\.php"/', $result);
+ $this->assertRegExp('/<pre>/', $result);
+ foreach ($file as $i => $line) {
+ $this->assertTrue(strpos($line, $result) !== 0, 'Content is missing ' . $i);
+ $class = 'covered';
+ if (in_array($i + 1, array(5, 9, 2))) {
+ $class = 'uncovered';
+ }
+ if ($i + 1 == 2) {
+ $class .= ' dead';
+ }
+ $this->assertTrue(strpos($class, $result) !== 0, 'Class name is wrong ' . $i);
+ }
+ }
+
+/**
+ * Test that coverage works with phpunit 3.6 as the data formats from coverage are totally different.
+ *
+ * @return void
+ */
+ public function testPhpunit36Compatibility() {
+ $file = array(
+ 'line 1',
+ 'line 2',
+ 'line 3',
+ 'line 4',
+ 'line 5',
+ 'line 6',
+ 'line 7',
+ 'line 8',
+ 'line 9',
+ 'line 10',
+ );
+ $coverage = array(
+ 1 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 2 => null,
+ 3 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 4 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 5 => array(),
+ 6 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 7 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 8 => array('HtmlCoverageReportTest::testGenerateDiff'),
+ 9 => array(),
+ 10 => array('HtmlCoverageReportTest::testSomething', 'HtmlCoverageReportTest::testGenerateDiff')
+ );
+
+ $result = $this->Coverage->generateDiff('myfile.php', $file, $coverage);
+ $this->assertRegExp('/myfile\.php Code coverage\: \d+\.?\d*\%/', $result);
+ $this->assertRegExp('/<div class="code-coverage-results" id\="coverage\-myfile\.php"/', $result);
+ $this->assertRegExp('/<pre>/', $result);
+ foreach ($file as $i => $line) {
+ $this->assertTrue(strpos($line, $result) !== 0, 'Content is missing ' . $i);
+ $class = 'covered';
+ if (in_array($i + 1, array(5, 9, 2))) {
+ $class = 'uncovered';
+ }
+ if ($i + 1 == 2) {
+ $class .= ' dead';
+ }
+ $this->assertTrue(strpos($class, $result) !== 0, 'Class name is wrong ' . $i);
+ }
+ }
+
+/**
+ * test that covering methods show up as title attributes for lines.
+ *
+ * @return void
+ */
+ public function testCoveredLinesTitleAttributes() {
+ $file = array(
+ 'line 1',
+ 'line 2',
+ 'line 3',
+ 'line 4',
+ 'line 5',
+ );
+
+ $coverage = array(
+ 1 => array(array('id' => 'HtmlCoverageReportTest::testAwesomeness')),
+ 2 => -2,
+ 3 => array(array('id' => 'HtmlCoverageReportTest::testCakeIsSuperior')),
+ 4 => array(array('id' => 'HtmlCoverageReportTest::testOther')),
+ 5 => -1
+ );
+
+ $result = $this->Coverage->generateDiff('myfile.php', $file, $coverage);
+
+ $this->assertTrue(
+ strpos($result, "title=\"Covered by:\nHtmlCoverageReportTest::testAwesomeness\n\"><span class=\"line-num\">1") !== false,
+ 'Missing method coverage for line 1'
+ );
+ $this->assertTrue(
+ strpos($result, "title=\"Covered by:\nHtmlCoverageReportTest::testCakeIsSuperior\n\"><span class=\"line-num\">3") !== false,
+ 'Missing method coverage for line 3'
+ );
+ $this->assertTrue(
+ strpos($result, "title=\"Covered by:\nHtmlCoverageReportTest::testOther\n\"><span class=\"line-num\">4") !== false,
+ 'Missing method coverage for line 4'
+ );
+ $this->assertTrue(
+ strpos($result, "title=\"\"><span class=\"line-num\">5") !== false,
+ 'Coverage report is wrong for line 5'
+ );
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ CakePlugin::unload();
+ unset($this->Coverage);
+ parent::tearDown();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeNumberTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeNumberTest.php
new file mode 100644
index 0000000..bcae41d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeNumberTest.php
@@ -0,0 +1,526 @@
+<?php
+/**
+ * CakeNumberTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('CakeNumber', 'Utility');
+
+/**
+ * CakeNumberTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class CakeNumberTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Number = new CakeNumber();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Number);
+ }
+
+/**
+ * testFormatAndCurrency method
+ *
+ * @return void
+ */
+ public function testFormat() {
+ $value = '100100100';
+
+ $result = $this->Number->format($value, '#');
+ $expected = '#100,100,100';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->format($value, 3);
+ $expected = '100,100,100.000';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->format($value);
+ $expected = '100,100,100';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->format($value, '-');
+ $expected = '100-100-100';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMultibyteFormat
+ *
+ * @return void
+ */
+ public function testMultibyteFormat() {
+ $value = '5199100.0006';
+ $result = $this->Number->format($value, array(
+ 'thousands' => '&nbsp;',
+ 'decimals' => '&amp;',
+ 'places' => 3,
+ 'escape' => false,
+ 'before' => '',
+ ));
+ $expected = '5&nbsp;199&nbsp;100&amp;001';
+ $this->assertEquals($expected, $result);
+
+ $value = 1000.45;
+ $result = $this->Number->format($value, array(
+ 'thousands' => ',,',
+ 'decimals' => '.a',
+ 'escape' => false,
+ ));
+ $expected = '$1,,000.a45';
+ $this->assertEquals($expected, $result);
+
+ $value = 519919827593784.00;
+ $this->Number->addFormat('RUR', array(
+ 'thousands' => 'ø€ƒ‡™',
+ 'decimals' => '(§.§)',
+ 'escape' => false,
+ 'wholeSymbol' => '€',
+ 'wholePosition' => 'after',
+ ));
+ $result = $this->Number->currency($value, 'RUR');
+ $expected = '519ø€ƒ‡™919ø€ƒ‡™827ø€ƒ‡™593ø€ƒ‡™784(§.§)00€';
+ $this->assertEquals($expected, $result);
+
+ $value = '13371337.1337';
+ $result = CakeNumber::format($value, array(
+ 'thousands' => '- |-| /-\ >< () |2 -',
+ 'decimals' => '- £€€† -',
+ 'before' => ''
+ ));
+ $expected = '13- |-| /-\ &gt;&lt; () |2 -371- |-| /-\ &gt;&lt; () |2 -337- £€€† -13';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test currency method.
+ *
+ * @return void
+ */
+ public function testCurrency() {
+ $value = '100100100';
+
+ $result = $this->Number->currency($value);
+ $expected = '$100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, '#');
+ $expected = '#100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, false);
+ $expected = '100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'USD');
+ $expected = '$100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR');
+ $expected = '&#8364;100.100.100,00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP');
+ $expected = '&#163;100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, '', array('thousands' => ' ', 'wholeSymbol' => '€', 'wholePosition' => 'after', 'decimals' => ',', 'zero' => 'Gratuit'));
+ $expected = '100 100 100,00€';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(1000.45, null, array('after' => 'øre', 'before' => 'Kr. ', 'decimals' => ',', 'thousands' => '.'));
+ $expected = 'Kr. 1.000,45';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(0.5, 'USD');
+ $expected = '50c';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(0.5, null, array('after' => 'øre'));
+ $expected = '50øre';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(1, null, array('wholeSymbol' => '$ '));
+ $expected = '$ 1.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(1, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after'));
+ $expected = '1.00 $';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(0.2, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after', 'fractionSymbol' => 'cents'));
+ $expected = '20cents';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(0.2, null, array('wholeSymbol' => ' $', 'wholePosition' => 'after', 'fractionSymbol' => 'cents', 'fractionPosition' => 'before'));
+ $expected = 'cents20';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(311, 'USD', array('wholePosition' => 'after'));
+ $expected = '311.00$';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(0.2, 'EUR');
+ $expected = '&#8364;0,20';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(12, null, array('wholeSymbol' => ' dollars', 'wholePosition' => 'after', 'fractionSymbol' => ' cents', 'fractionPosition' => 'after'));
+ $expected = '12.00 dollars';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(0.12, null, array('wholeSymbol' => ' dollars', 'wholePosition' => 'after', 'fractionSymbol' => ' cents', 'fractionPosition' => 'after'));
+ $expected = '12 cents';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(0.5, null, array('fractionSymbol' => false, 'fractionPosition' => 'before', 'wholeSymbol' => '$'));
+ $expected = '$0.50';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test adding currency format options to the number helper
+ *
+ * @return void
+ */
+ public function testCurrencyAddFormat() {
+ $this->Number->addFormat('NOK', array('before' => 'Kr. '));
+ $result = $this->Number->currency(1000, 'NOK');
+ $expected = 'Kr. 1,000.00';
+ $this->assertEquals($expected, $result);
+
+ $this->Number->addFormat('Other', array('before' => '$$ ', 'after' => 'c!'));
+ $result = $this->Number->currency(0.22, 'Other');
+ $expected = '22c!';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency(-10, 'Other');
+ $expected = '($$ 10.00)';
+ $this->assertEquals($expected, $result);
+
+ $this->Number->addFormat('Other2', array('before' => '$ ', 'after' => false));
+ $result = $this->Number->currency(0.22, 'Other2');
+ $expected = '$ 0.22';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCurrencyPositive method
+ *
+ * @return void
+ */
+ public function testCurrencyPositive() {
+ $value = '100100100';
+
+ $result = $this->Number->currency($value);
+ $expected = '$100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'USD', array('before' => '#'));
+ $expected = '#100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, false);
+ $expected = '100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'USD');
+ $expected = '$100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR');
+ $expected = '&#8364;100.100.100,00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP');
+ $expected = '&#163;100,100,100.00';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCurrencyNegative method
+ *
+ * @return void
+ */
+ public function testCurrencyNegative() {
+ $value = '-100100100';
+
+ $result = $this->Number->currency($value);
+ $expected = '($100,100,100.00)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR');
+ $expected = '(&#8364;100.100.100,00)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP');
+ $expected = '(&#163;100,100,100.00)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'USD', array('negative' => '-'));
+ $expected = '-$100,100,100.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR', array('negative' => '-'));
+ $expected = '-&#8364;100.100.100,00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP', array('negative' => '-'));
+ $expected = '-&#163;100,100,100.00';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCurrencyCentsPositive method
+ *
+ * @return void
+ */
+ public function testCurrencyCentsPositive() {
+ $value = '0.99';
+
+ $result = $this->Number->currency($value, 'USD');
+ $expected = '99c';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR');
+ $expected = '&#8364;0,99';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP');
+ $expected = '99p';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCurrencyCentsNegative method
+ *
+ * @return void
+ */
+ public function testCurrencyCentsNegative() {
+ $value = '-0.99';
+
+ $result = $this->Number->currency($value, 'USD');
+ $expected = '(99c)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR');
+ $expected = '(&#8364;0,99)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP');
+ $expected = '(99p)';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'USD', array('negative' => '-'));
+ $expected = '-99c';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR', array('negative' => '-'));
+ $expected = '-&#8364;0,99';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP', array('negative' => '-'));
+ $expected = '-99p';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCurrencyZero method
+ *
+ * @return void
+ */
+ public function testCurrencyZero() {
+ $value = '0';
+
+ $result = $this->Number->currency($value, 'USD');
+ $expected = '$0.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'EUR');
+ $expected = '&#8364;0,00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP');
+ $expected = '&#163;0.00';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP', array('zero' => 'FREE!'));
+ $expected = 'FREE!';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCurrencyOptions method
+ *
+ * @return void
+ */
+ public function testCurrencyOptions() {
+ $value = '1234567.89';
+
+ $result = $this->Number->currency($value, null, array('before' => 'GBP'));
+ $expected = 'GBP1,234,567.89';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP', array('places' => 0));
+ $expected = '&#163;1,234,568';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency('1234567.8912345', null, array('before' => 'GBP', 'places' => 3));
+ $expected = 'GBP1,234,567.891';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency('650.120001', null, array('before' => 'GBP', 'places' => 4));
+ $expected = 'GBP650.1200';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency($value, 'GBP', array('escape' => true));
+ $expected = '&amp;#163;1,234,567.89';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency('0.35', 'USD', array('after' => false));
+ $expected = '$0.35';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency('0.35', 'GBP', array('after' => false));
+ $expected = '&#163;0.35';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency('0.35', 'GBP');
+ $expected = '35p';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->currency('0.35', 'EUR');
+ $expected = '&#8364;0,35';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testToReadableSize method
+ *
+ * @return void
+ */
+ public function testToReadableSize() {
+ $result = $this->Number->toReadableSize(0);
+ $expected = '0 Bytes';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1);
+ $expected = '1 Byte';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(45);
+ $expected = '45 Bytes';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1023);
+ $expected = '1023 Bytes';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024);
+ $expected = '1 KB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 512);
+ $expected = '512 KB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 - 1);
+ $expected = '1.00 MB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 512);
+ $expected = '512.00 MB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 1024 - 1);
+ $expected = '1.00 GB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 1024 * 512);
+ $expected = '512.00 GB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 1024 * 1024 - 1);
+ $expected = '1.00 TB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 1024 * 1024 * 512);
+ $expected = '512.00 TB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 1024 * 1024 * 1024 - 1);
+ $expected = '1024.00 TB';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 1024 * 1024 * 1024 * 1024);
+ $expected = (1024 * 1024) . '.00 TB';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test toReadableSize() with locales
+ *
+ * @return void
+ */
+ public function testReadableSizeLocalized() {
+ $restore = setlocale(LC_NUMERIC, 0);
+ setlocale(LC_NUMERIC, 'de_DE');
+ $result = $this->Number->toReadableSize(1321205);
+ $this->assertRegExp('/1[,.]26 MB/', $result);
+
+ $result = $this->Number->toReadableSize(1024 * 1024 * 1024 * 512);
+ $this->assertRegExp('/512[,.]00 GB/', $result);
+ setlocale(LC_NUMERIC, $restore);
+ }
+
+/**
+ * testToPercentage method
+ *
+ * @return void
+ */
+ public function testToPercentage() {
+ $result = $this->Number->toPercentage(45, 0);
+ $expected = '45%';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toPercentage(45, 2);
+ $expected = '45.00%';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toPercentage(0, 0);
+ $expected = '0%';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Number->toPercentage(0, 4);
+ $expected = '0.0000%';
+ $this->assertEquals($expected, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeTimeTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeTimeTest.php
new file mode 100644
index 0000000..13bf89d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/CakeTimeTest.php
@@ -0,0 +1,1052 @@
+<?php
+/**
+ * CakeTimeTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeTime', 'Utility');
+
+/**
+ * CakeTimeTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class CakeTimeTest extends CakeTestCase {
+
+/**
+ * Default system timezone identifier
+ *
+ * @var string
+ */
+ protected $_systemTimezoneIdentifier = null;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ $this->Time = new CakeTime();
+ $this->_systemTimezoneIdentifier = date_default_timezone_get();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->Time);
+ $this->_restoreSystemTimezone();
+ }
+
+/**
+ * Restored the original system timezone
+ *
+ * @param string $timezoneIdentifier Timezone string
+ * @return void
+ */
+ protected function _restoreSystemTimezone() {
+ date_default_timezone_set($this->_systemTimezoneIdentifier);
+ }
+
+/**
+ * testToQuarter method
+ *
+ * @return void
+ */
+ public function testToQuarter() {
+ $result = $this->Time->toQuarter('2007-12-25');
+ $this->assertEquals(4, $result);
+
+ $result = $this->Time->toQuarter('2007-9-25');
+ $this->assertEquals(3, $result);
+
+ $result = $this->Time->toQuarter('2007-3-25');
+ $this->assertEquals(1, $result);
+
+ $result = $this->Time->toQuarter('2007-3-25', true);
+ $this->assertEquals(array('2007-01-01', '2007-03-31'), $result);
+
+ $result = $this->Time->toQuarter('2007-5-25', true);
+ $this->assertEquals(array('2007-04-01', '2007-06-30'), $result);
+
+ $result = $this->Time->toQuarter('2007-8-25', true);
+ $this->assertEquals(array('2007-07-01', '2007-09-30'), $result);
+
+ $result = $this->Time->toQuarter('2007-12-25', true);
+ $this->assertEquals(array('2007-10-01', '2007-12-31'), $result);
+ }
+
+/**
+ * provider for timeAgoInWords() tests
+ *
+ * @return array
+ */
+ public static function timeAgoProvider() {
+ return array(
+ array('-12 seconds', '12 seconds ago'),
+ array('-12 minutes', '12 minutes ago'),
+ array('-2 hours', '2 hours ago'),
+ array('-1 day', '1 day ago'),
+ array('-2 days', '2 days ago'),
+ array('-2 days -3 hours', '2 days, 3 hours ago'),
+ array('-1 week', '1 week ago'),
+ array('-2 weeks -2 days', '2 weeks, 2 days ago'),
+ array('+1 week', '1 week'),
+ array('+1 week 1 day', '1 week, 1 day'),
+ array('+2 weeks 2 day', '2 weeks, 2 days'),
+ array('2007-9-24', 'on 24/9/07'),
+ array('now', 'just now'),
+ );
+ }
+
+/**
+ * testTimeAgoInWords method
+ *
+ * @dataProvider timeAgoProvider
+ * @return void
+ */
+ public function testTimeAgoInWords($input, $expected) {
+ $result = $this->Time->timeAgoInWords($input);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * provider for timeAgo with an end date.
+ *
+ * @return void
+ */
+ public function timeAgoEndProvider() {
+ return array(
+ array(
+ '+4 months +2 weeks +3 days',
+ '4 months, 2 weeks, 3 days',
+ '8 years'
+ ),
+ array(
+ '+4 months +2 weeks +1 day',
+ '4 months, 2 weeks, 1 day',
+ '8 years'
+ ),
+ array(
+ '+3 months +2 weeks',
+ '3 months, 2 weeks',
+ '8 years'
+ ),
+ array(
+ '+3 months +2 weeks +1 day',
+ '3 months, 2 weeks, 1 day',
+ '8 years'
+ ),
+ array(
+ '+1 months +1 week +1 day',
+ '1 month, 1 week, 1 day',
+ '8 years'
+ ),
+ array(
+ '+2 months +2 days',
+ '2 months, 2 days',
+ 'on ' . date('j/n/y', strtotime('+2 months +2 days'))
+ ),
+ array(
+ '+2 months +12 days',
+ '2 months, 1 week, 5 days',
+ '3 months'
+ ),
+ );
+ }
+
+/**
+ * test the end option for timeAgoInWords
+ *
+ * @dataProvider timeAgoEndProvider
+ * @return void
+ */
+ public function testTimeAgoInWordsEnd($input, $expected, $end) {
+ $result = $this->Time->timeAgoInWords(
+ $input, array('end' => $end)
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the accuracy option for timeAgoInWords()
+ *
+ * @return void
+ */
+ public function testTimeAgoInWordsAccuracy() {
+ $result = $this->Time->timeAgoInWords(
+ strtotime('+8 years +4 months +2 weeks +3 days'),
+ array('accuracy' => array('year' => 'year'), 'end' => '+10 years')
+ );
+ $expected = '8 years';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('+8 years +4 months +2 weeks +3 days'),
+ array('accuracy' => array('year' => 'month'), 'end' => '+10 years')
+ );
+ $expected = '8 years, 4 months';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('+8 years +4 months +2 weeks +3 days'),
+ array('accuracy' => array('year' => 'week'), 'end' => '+10 years')
+ );
+ $expected = '8 years, 4 months, 2 weeks';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('+8 years +4 months +2 weeks +3 days'),
+ array('accuracy' => array('year' => 'day'), 'end' => '+10 years')
+ );
+ $expected = '8 years, 4 months, 2 weeks, 3 days';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('+1 years +5 weeks'),
+ array('accuracy' => array('year' => 'year'), 'end' => '+10 years')
+ );
+ $expected = '1 year';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the format option of timeAgoInWords()
+ *
+ * @return void
+ */
+ public function testTimeAgoInWordsWithFormat() {
+ $result = $this->Time->timeAgoInWords('2007-9-25', 'Y-m-d');
+ $this->assertEquals('on 2007-09-25', $result);
+
+ $result = $this->Time->timeAgoInWords('2007-9-25', 'Y-m-d');
+ $this->assertEquals('on 2007-09-25', $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('+2 weeks +2 days'),
+ 'Y-m-d'
+ );
+ $this->assertRegExp('/^2 weeks, [1|2] day(s)?$/', $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('+2 months +2 days'),
+ array('end' => '1 month', 'format' => 'Y-m-d')
+ );
+ $this->assertEquals('on ' . date('Y-m-d', strtotime('+2 months +2 days')), $result);
+ }
+
+/**
+ * test timeAgoInWords() with negative values.
+ *
+ * @return void
+ */
+ public function testTimeAgoInWordsNegativeValues() {
+ $result = $this->Time->timeAgoInWords(
+ strtotime('-2 months -2 days'),
+ array('end' => '3 month')
+ );
+ $this->assertEquals('2 months, 2 days ago', $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('-2 months -2 days'),
+ array('end' => '3 month')
+ );
+ $this->assertEquals('2 months, 2 days ago', $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('-2 months -2 days'),
+ array('end' => '1 month', 'format' => 'Y-m-d')
+ );
+ $this->assertEquals('on ' . date('Y-m-d', strtotime('-2 months -2 days')), $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('-2 years -5 months -2 days'),
+ array('end' => '3 years')
+ );
+ $this->assertEquals('2 years, 5 months, 2 days ago', $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('-2 weeks -2 days'),
+ 'Y-m-d'
+ );
+ $this->assertEquals('2 weeks, 2 days ago', $result);
+
+ $time = strtotime('-3 years -12 months');
+ $result = $this->Time->timeAgoInWords($time);
+ $expected = 'on ' . date('j/n/y', $time);
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('-1 month -1 week -6 days'),
+ array('end' => '1 year', 'accuracy' => array('month' => 'month'))
+ );
+ $this->assertEquals('1 month ago', $result);
+
+ $timestamp = strtotime('-1 years -2 weeks -3 days');
+ $result = $this->Time->timeAgoInWords(
+ $timestamp,
+ array('accuracy' => array('year' => 'year'))
+ );
+ $expected = 'on ' . date('j/n/y', $timestamp);
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->timeAgoInWords(
+ strtotime('-13 months -5 days'),
+ array('end' => '2 years')
+ );
+ $this->assertEquals('1 year, 1 month, 5 days ago', $result);
+ }
+
+/**
+ * testNice method
+ *
+ * @return void
+ */
+ public function testNice() {
+ $time = time() + 2 * DAY;
+ $this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
+
+ $time = time() - 2 * DAY;
+ $this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
+
+ $time = time();
+ $this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
+
+ $time = 0;
+ $this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
+
+ $time = null;
+ $this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
+
+ $time = time();
+ $this->assertEquals(date('D', $time), $this->Time->nice($time, null, '%a'));
+ $this->assertEquals(date('M d, Y', $time), $this->Time->nice($time, null, '%b %d, %Y'));
+
+ $this->Time->niceFormat = '%Y-%d-%m';
+ $this->assertEquals(date('Y-d-m', $time), $this->Time->nice($time));
+ $this->assertEquals('%Y-%d-%m', $this->Time->niceFormat);
+
+ CakeTime::$niceFormat = '%Y-%d-%m %H:%M:%S';
+ $this->assertEquals(date('Y-d-m H:i:s', $time), $this->Time->nice($time));
+ $this->assertEquals('%Y-%d-%m %H:%M:%S', $this->Time->niceFormat);
+
+ date_default_timezone_set('UTC');
+ $result = $this->Time->nice(null, 'America/New_York');
+ $expected = $this->Time->nice(time(), 'America/New_York');
+ $this->assertEquals($expected, $result);
+
+ $this->_restoreSystemTimezone();
+ }
+
+/**
+ * testNiceShort method
+ *
+ * @return void
+ */
+ public function testNiceShort() {
+ $time = time();
+ $this->assertEquals('Today, ' . date('H:i', $time), $this->Time->niceShort($time));
+
+ $time = time() - DAY;
+ $this->assertEquals('Yesterday, ' . date('H:i', $time), $this->Time->niceShort($time));
+
+ $time = time() + DAY;
+ $this->assertEquals('Tomorrow, ' . date('H:i', $time), $this->Time->niceShort($time));
+
+ date_default_timezone_set('Europe/London');
+ $result = $this->Time->niceShort('2005-01-15 10:00:00', new DateTimeZone('Europe/Brussels'));
+ $this->assertEquals('Jan 15th 2005, 11:00', $result);
+
+ date_default_timezone_set('UTC');
+ $result = $this->Time->niceShort(null, 'America/New_York');
+ $expected = $this->Time->niceShort(time(), 'America/New_York');
+ $this->assertEquals($expected, $result);
+
+ $this->_restoreSystemTimezone();
+ }
+
+/**
+ * testDaysAsSql method
+ *
+ * @return void
+ */
+ public function testDaysAsSql() {
+ $begin = time();
+ $end = time() + DAY;
+ $field = 'my_field';
+ $expected = '(my_field >= \'' . date('Y-m-d', $begin) . ' 00:00:00\') AND (my_field <= \'' . date('Y-m-d', $end) . ' 23:59:59\')';
+ $this->assertEquals($expected, $this->Time->daysAsSql($begin, $end, $field));
+ }
+
+/**
+ * testDayAsSql method
+ *
+ * @return void
+ */
+ public function testDayAsSql() {
+ $time = time();
+ $field = 'my_field';
+ $expected = '(my_field >= \'' . date('Y-m-d', $time) . ' 00:00:00\') AND (my_field <= \'' . date('Y-m-d', $time) . ' 23:59:59\')';
+ $this->assertEquals($expected, $this->Time->dayAsSql($time, $field));
+ }
+
+/**
+ * testToUnix method
+ *
+ * @return void
+ */
+ public function testToUnix() {
+ $this->assertEquals(time(), $this->Time->toUnix(time()));
+ $this->assertEquals(strtotime('+1 day'), $this->Time->toUnix('+1 day'));
+ $this->assertEquals(strtotime('+0 days'), $this->Time->toUnix('+0 days'));
+ $this->assertEquals(strtotime('-1 days'), $this->Time->toUnix('-1 days'));
+ $this->assertEquals(false, $this->Time->toUnix(''));
+ $this->assertEquals(false, $this->Time->toUnix(null));
+ }
+
+/**
+ * testToServer method
+ *
+ * @return void
+ */
+ public function testToServer() {
+ date_default_timezone_set('Europe/Paris');
+
+ $time = time();
+ $this->assertEquals(date('Y-m-d H:i:s', $time), $this->Time->toServer($time));
+
+ date_default_timezone_set('America/New_York');
+ $time = time();
+ date_default_timezone_set('Europe/Paris');
+ $result = $this->Time->toServer($time, 'America/New_York');
+ $this->assertEquals(date('Y-m-d H:i:s', $time), $result);
+
+ date_default_timezone_set('Europe/Paris');
+ $time = '2005-10-25 10:00:00';
+ $result = $this->Time->toServer($time);
+ $date = new DateTime($time, new DateTimeZone('UTC'));
+ $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ $expected = $date->format('Y-m-d H:i:s');
+ $this->assertEquals($expected, $result);
+
+ $time = '2002-01-01 05:15:30';
+ $result = $this->Time->toServer($time, 'America/New_York');
+ $date = new DateTime($time, new DateTimeZone('America/New_York'));
+ $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ $expected = $date->format('Y-m-d H:i:s');
+ $this->assertEquals($expected, $result);
+
+ $time = '2010-01-28T15:00:00+10:00';
+ $result = $this->Time->toServer($time, 'America/New_York');
+ $date = new DateTime($time);
+ $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ $expected = $date->format('Y-m-d H:i:s');
+ $this->assertEquals($expected, $result);
+
+ $date = new DateTime(null, new DateTimeZone('America/New_York'));
+ $result = $this->Time->toServer($date, 'Pacific/Tahiti');
+ $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ $expected = $date->format('Y-m-d H:i:s');
+ $this->assertEquals($expected, $result);
+
+ $this->_restoreSystemTimezone();
+
+ $time = time();
+ $result = $this->Time->toServer($time, null, 'l jS \of F Y h:i:s A');
+ $expected = date('l jS \of F Y h:i:s A', $time);
+ $this->assertEquals($expected, $result);
+
+ $this->assertFalse($this->Time->toServer(time(), new Object()));
+
+ date_default_timezone_set('UTC');
+
+ $serverTime = new DateTime('now');
+
+ $timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
+ foreach ($timezones as $timezone) {
+ $result = $this->Time->toServer($serverTime->format('Y-m-d H:i:s'), $timezone, 'U');
+ $tz = new DateTimeZone($timezone);
+ $this->assertEquals($serverTime->format('U'), $result + $tz->getOffset($serverTime));
+ }
+
+ date_default_timezone_set('UTC');
+ $date = new DateTime('now', new DateTimeZone('America/New_York'));
+
+ $result = $this->Time->toServer($date, null, 'Y-m-d H:i:s');
+ $date->setTimezone($this->Time->timezone());
+ $expected = $date->format('Y-m-d H:i:s');
+ $this->assertEquals($expected, $result);
+
+ $this->_restoreSystemTimezone();
+ }
+
+/**
+ * testToAtom method
+ *
+ * @return void
+ */
+ public function testToAtom() {
+ $this->assertEquals(date('Y-m-d\TH:i:s\Z'), $this->Time->toAtom(time()));
+ }
+
+/**
+ * testToRss method
+ *
+ * @return void
+ */
+ public function testToRss() {
+ $this->assertEquals(date('r'), $this->Time->toRss(time()));
+
+ if (!$this->skipIf(!class_exists('DateTimeZone'), '%s DateTimeZone class not available.')) {
+ $timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
+ foreach ($timezones as $timezone) {
+ $yourTimezone = new DateTimeZone($timezone);
+ $yourTime = new DateTime('now', $yourTimezone);
+ $userOffset = $yourTimezone->getOffset($yourTime) / HOUR;
+ $this->assertEquals($yourTime->format('r'), $this->Time->toRss(time(), $userOffset));
+ $this->assertEquals($yourTime->format('r'), $this->Time->toRss(time(), $timezone));
+ }
+ }
+ }
+
+/**
+ * testFormat method
+ *
+ * @return void
+ */
+ public function testFormat() {
+ $format = 'D-M-Y';
+ $tz = date_default_timezone_get();
+ $arr = array(time(), strtotime('+1 days'), strtotime('+1 days'), strtotime('+0 days'));
+ foreach ($arr as $val) {
+ $this->assertEquals(date($format, $val), $this->Time->format($format, $val));
+ $this->assertEquals(date($format, $val), $this->Time->format($format, $val, false, $tz));
+ }
+
+ $result = $this->Time->format('Y-m-d', null, 'never');
+ $this->assertEquals('never', $result);
+
+ $result = $this->Time->format('2012-01-13', '%d-%m-%Y', 'invalid');
+ $this->assertEquals('13-01-2012', $result);
+
+ $result = $this->Time->format('nonsense', '%d-%m-%Y', 'invalid', 'UTC');
+ $this->assertEquals('invalid', $result);
+ }
+
+/**
+ * testOfGmt method
+ *
+ * @return void
+ */
+ public function testGmt() {
+ $hour = 3;
+ $min = 4;
+ $sec = 2;
+ $month = 5;
+ $day = 14;
+ $year = 2007;
+ $time = mktime($hour, $min, $sec, $month, $day, $year);
+ $expected = gmmktime($hour, $min, $sec, $month, $day, $year);
+ $this->assertEquals($expected, $this->Time->gmt(date('Y-n-j G:i:s', $time)));
+
+ $hour = date('H');
+ $min = date('i');
+ $sec = date('s');
+ $month = date('m');
+ $day = date('d');
+ $year = date('Y');
+ $expected = gmmktime($hour, $min, $sec, $month, $day, $year);
+ $this->assertEquals($expected, $this->Time->gmt(null));
+ }
+
+/**
+ * testIsToday method
+ *
+ * @return void
+ */
+ public function testIsToday() {
+ $result = $this->Time->isToday('+1 day');
+ $this->assertFalse($result);
+ $result = $this->Time->isToday('+1 days');
+ $this->assertFalse($result);
+ $result = $this->Time->isToday('+0 day');
+ $this->assertTrue($result);
+ $result = $this->Time->isToday('-1 day');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testIsThisWeek method
+ *
+ * @return void
+ */
+ public function testIsThisWeek() {
+ // A map of days which goes from -1 day of week to +1 day of week
+ $map = array(
+ 'Mon' => array(-1, 7), 'Tue' => array(-2, 6), 'Wed' => array(-3, 5),
+ 'Thu' => array(-4, 4), 'Fri' => array(-5, 3), 'Sat' => array(-6, 2),
+ 'Sun' => array(-7, 1)
+ );
+ $days = $map[date('D')];
+
+ for ($day = $days[0] + 1; $day < $days[1]; $day++) {
+ $this->assertTrue($this->Time->isThisWeek(($day > 0 ? '+' : '') . $day . ' days'));
+ }
+ $this->assertFalse($this->Time->isThisWeek($days[0] . ' days'));
+ $this->assertFalse($this->Time->isThisWeek('+' . $days[1] . ' days'));
+ }
+
+/**
+ * testIsThisMonth method
+ *
+ * @return void
+ */
+ public function testIsThisMonth() {
+ $result = $this->Time->isThisMonth('+0 day');
+ $this->assertTrue($result);
+ $result = $this->Time->isThisMonth($time = mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y')));
+ $this->assertTrue($result);
+ $result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') - mt_rand(1, 12)));
+ $this->assertFalse($result);
+ $result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') + mt_rand(1, 12)));
+ $this->assertFalse($result);
+ }
+
+/**
+ * testIsThisYear method
+ *
+ * @return void
+ */
+ public function testIsThisYear() {
+ $result = $this->Time->isThisYear('+0 day');
+ $this->assertTrue($result);
+ $result = $this->Time->isThisYear(mktime(0, 0, 0, mt_rand(1, 12), mt_rand(1, 28), date('Y')));
+ $this->assertTrue($result);
+ }
+
+/**
+ * testWasYesterday method
+ *
+ * @return void
+ */
+ public function testWasYesterday() {
+ $result = $this->Time->wasYesterday('+1 day');
+ $this->assertFalse($result);
+ $result = $this->Time->wasYesterday('+1 days');
+ $this->assertFalse($result);
+ $result = $this->Time->wasYesterday('+0 day');
+ $this->assertFalse($result);
+ $result = $this->Time->wasYesterday('-1 day');
+ $this->assertTrue($result);
+ $result = $this->Time->wasYesterday('-1 days');
+ $this->assertTrue($result);
+ $result = $this->Time->wasYesterday('-2 days');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testIsTomorrow method
+ *
+ * @return void
+ */
+ public function testIsTomorrow() {
+ $result = $this->Time->isTomorrow('+1 day');
+ $this->assertTrue($result);
+ $result = $this->Time->isTomorrow('+1 days');
+ $this->assertTrue($result);
+ $result = $this->Time->isTomorrow('+0 day');
+ $this->assertFalse($result);
+ $result = $this->Time->isTomorrow('-1 day');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testWasWithinLast method
+ *
+ * @return void
+ */
+ public function testWasWithinLast() {
+ $this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
+ $this->assertTrue($this->Time->wasWithinLast('1 week', '-1 week'));
+ $this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
+ $this->assertTrue($this->Time->wasWithinLast('1 second', '-1 second'));
+ $this->assertTrue($this->Time->wasWithinLast('1 minute', '-1 minute'));
+ $this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
+ $this->assertTrue($this->Time->wasWithinLast('1 month', '-1 month'));
+ $this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
+
+ $this->assertTrue($this->Time->wasWithinLast('1 week', '-1 day'));
+ $this->assertTrue($this->Time->wasWithinLast('2 week', '-1 week'));
+ $this->assertFalse($this->Time->wasWithinLast('1 second', '-1 year'));
+ $this->assertTrue($this->Time->wasWithinLast('10 minutes', '-1 second'));
+ $this->assertTrue($this->Time->wasWithinLast('23 minutes', '-1 minute'));
+ $this->assertFalse($this->Time->wasWithinLast('0 year', '-1 year'));
+ $this->assertTrue($this->Time->wasWithinLast('13 month', '-1 month'));
+ $this->assertTrue($this->Time->wasWithinLast('2 days', '-1 day'));
+
+ $this->assertFalse($this->Time->wasWithinLast('1 week', '-2 weeks'));
+ $this->assertFalse($this->Time->wasWithinLast('1 second', '-2 seconds'));
+ $this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
+ $this->assertFalse($this->Time->wasWithinLast('1 hour', '-2 hours'));
+ $this->assertFalse($this->Time->wasWithinLast('1 month', '-2 months'));
+ $this->assertFalse($this->Time->wasWithinLast('1 year', '-2 years'));
+
+ $this->assertFalse($this->Time->wasWithinLast('1 day', '-2 weeks'));
+ $this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
+ $this->assertFalse($this->Time->wasWithinLast('0 days', '-2 days'));
+ $this->assertTrue($this->Time->wasWithinLast('1 hour', '-20 seconds'));
+ $this->assertTrue($this->Time->wasWithinLast('1 year', '-60 minutes -30 seconds'));
+ $this->assertTrue($this->Time->wasWithinLast('3 years', '-2 months'));
+ $this->assertTrue($this->Time->wasWithinLast('5 months', '-4 months'));
+
+ $this->assertTrue($this->Time->wasWithinLast('5 ', '-3 days'));
+ $this->assertTrue($this->Time->wasWithinLast('1 ', '-1 hour'));
+ $this->assertTrue($this->Time->wasWithinLast('1 ', '-1 minute'));
+ $this->assertTrue($this->Time->wasWithinLast('1 ', '-23 hours -59 minutes -59 seconds'));
+ }
+
+/**
+ * testWasWithinLast method
+ *
+ * @return void
+ */
+ public function testIsWithinNext() {
+ $this->assertFalse($this->Time->isWithinNext('1 day', '-1 day'));
+ $this->assertFalse($this->Time->isWithinNext('1 week', '-1 week'));
+ $this->assertFalse($this->Time->isWithinNext('1 year', '-1 year'));
+ $this->assertFalse($this->Time->isWithinNext('1 second', '-1 second'));
+ $this->assertFalse($this->Time->isWithinNext('1 minute', '-1 minute'));
+ $this->assertFalse($this->Time->isWithinNext('1 year', '-1 year'));
+ $this->assertFalse($this->Time->isWithinNext('1 month', '-1 month'));
+ $this->assertFalse($this->Time->isWithinNext('1 day', '-1 day'));
+
+ $this->assertFalse($this->Time->isWithinNext('1 week', '-1 day'));
+ $this->assertFalse($this->Time->isWithinNext('2 week', '-1 week'));
+ $this->assertFalse($this->Time->isWithinNext('1 second', '-1 year'));
+ $this->assertFalse($this->Time->isWithinNext('10 minutes', '-1 second'));
+ $this->assertFalse($this->Time->isWithinNext('23 minutes', '-1 minute'));
+ $this->assertFalse($this->Time->isWithinNext('0 year', '-1 year'));
+ $this->assertFalse($this->Time->isWithinNext('13 month', '-1 month'));
+ $this->assertFalse($this->Time->isWithinNext('2 days', '-1 day'));
+
+ $this->assertFalse($this->Time->isWithinNext('1 week', '-2 weeks'));
+ $this->assertFalse($this->Time->isWithinNext('1 second', '-2 seconds'));
+ $this->assertFalse($this->Time->isWithinNext('1 day', '-2 days'));
+ $this->assertFalse($this->Time->isWithinNext('1 hour', '-2 hours'));
+ $this->assertFalse($this->Time->isWithinNext('1 month', '-2 months'));
+ $this->assertFalse($this->Time->isWithinNext('1 year', '-2 years'));
+
+ $this->assertFalse($this->Time->isWithinNext('1 day', '-2 weeks'));
+ $this->assertFalse($this->Time->isWithinNext('1 day', '-2 days'));
+ $this->assertFalse($this->Time->isWithinNext('0 days', '-2 days'));
+ $this->assertFalse($this->Time->isWithinNext('1 hour', '-20 seconds'));
+ $this->assertFalse($this->Time->isWithinNext('1 year', '-60 minutes -30 seconds'));
+ $this->assertFalse($this->Time->isWithinNext('3 years', '-2 months'));
+ $this->assertFalse($this->Time->isWithinNext('5 months', '-4 months'));
+
+ $this->assertFalse($this->Time->isWithinNext('5 ', '-3 days'));
+ $this->assertFalse($this->Time->isWithinNext('1 ', '-1 hour'));
+ $this->assertFalse($this->Time->isWithinNext('1 ', '-1 minute'));
+ $this->assertFalse($this->Time->isWithinNext('1 ', '-23 hours -59 minutes -59 seconds'));
+
+ $this->assertTrue($this->Time->isWithinNext('7 days', '6 days, 23 hours, 59 minutes, 59 seconds'));
+ $this->assertFalse($this->Time->isWithinNext('7 days', '6 days, 23 hours, 59 minutes, 61 seconds'));
+ }
+
+/**
+ * testUserOffset method
+ *
+ * @return void
+ */
+ public function testUserOffset() {
+ $timezoneServer = new DateTimeZone(date_default_timezone_get());
+ $timeServer = new DateTime('now', $timezoneServer);
+ $yourTimezone = $timezoneServer->getOffset($timeServer) / HOUR;
+
+ $expected = time();
+ $result = $this->Time->fromString(time(), $yourTimezone);
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->fromString(time(), $timezoneServer->getName());
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->fromString(time(), $timezoneServer);
+ $this->assertEquals($expected, $result);
+
+ Configure::write('Config.timezone', $timezoneServer->getName());
+ $result = $this->Time->fromString(time());
+ $this->assertEquals($expected, $result);
+ Configure::delete('Config.timezone');
+ }
+
+/**
+ * test fromString()
+ *
+ * @return void
+ */
+ public function testFromString() {
+ $result = $this->Time->fromString('');
+ $this->assertFalse($result);
+
+ $result = $this->Time->fromString(0, 0);
+ $this->assertFalse($result);
+
+ $result = $this->Time->fromString('+1 hour');
+ $expected = strtotime('+1 hour');
+ $this->assertEquals($expected, $result);
+
+ $timezone = date('Z', time());
+ $result = $this->Time->fromString('+1 hour', $timezone);
+ $expected = $this->Time->convert(strtotime('+1 hour'), $timezone);
+ $this->assertEquals($expected, $result);
+
+ $timezone = date_default_timezone_get();
+ $result = $this->Time->fromString('+1 hour', $timezone);
+ $expected = $this->Time->convert(strtotime('+1 hour'), $timezone);
+ $this->assertEquals($expected, $result);
+
+ date_default_timezone_set('UTC');
+ $date = new DateTime('now', new DateTimeZone('Europe/London'));
+ $this->Time->fromString($date);
+ $this->assertEquals('Europe/London', $date->getTimeZone()->getName());
+
+ $this->_restoreSystemTimezone();
+ }
+
+/**
+ * test fromString() with a DateTime object as the dateString
+ *
+ * @return void
+ */
+ public function testFromStringWithDateTime() {
+ date_default_timezone_set('UTC');
+
+ $date = new DateTime('+1 hour', new DateTimeZone('America/New_York'));
+ $result = $this->Time->fromString($date, 'UTC');
+ $date->setTimezone(new DateTimeZone('UTC'));
+ $expected = $date->format('U') + $date->getOffset();
+
+ $this->assertEquals($expected, $result);
+
+ date_default_timezone_set('Australia/Melbourne');
+
+ $date = new DateTime('+1 hour', new DateTimeZone('America/New_York'));
+ $result = $this->Time->fromString($date, 'Asia/Kuwait');
+ $date->setTimezone(new DateTimeZone('Asia/Kuwait'));
+ $expected = $date->format('U') + $date->getOffset();
+ $this->assertEquals($expected, $result);
+
+ $this->_restoreSystemTimezone();
+ }
+
+/**
+ * test converting time specifiers using a time definition localfe file
+ *
+ * @return void
+ */
+ public function testConvertSpecifiers() {
+ App::build(array(
+ 'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
+ ), App::RESET);
+ Configure::write('Config.language', 'time_test');
+ $time = strtotime('Thu Jan 14 11:43:39 2010');
+
+ $result = $this->Time->convertSpecifiers('%a', $time);
+ $expected = 'jue';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%A', $time);
+ $expected = 'jueves';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%c', $time);
+ $expected = 'jue %d ene %Y %H:%M:%S %Z';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%C', $time);
+ $expected = '20';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%D', $time);
+ $expected = '%m/%d/%y';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%b', $time);
+ $expected = 'ene';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%h', $time);
+ $expected = 'ene';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%B', $time);
+ $expected = 'enero';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%n', $time);
+ $expected = "\n";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%n', $time);
+ $expected = "\n";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%p', $time);
+ $expected = 'AM';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%P', $time);
+ $expected = 'am';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%r', $time);
+ $expected = '%I:%M:%S AM';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%R', $time);
+ $expected = '11:43';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%t', $time);
+ $expected = "\t";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%T', $time);
+ $expected = '%H:%M:%S';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%u', $time);
+ $expected = 4;
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%x', $time);
+ $expected = '%d/%m/%y';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%X', $time);
+ $expected = '%H:%M:%S';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test convert %e on windows.
+ *
+ * @return void
+ */
+ public function testConvertPercentE() {
+ $this->skipIf(DIRECTORY_SEPARATOR !== '\\', 'Cannot run windows tests on non-windows OS.');
+
+ $time = strtotime('Thu Jan 14 11:43:39 2010');
+ $result = $this->Time->convertSpecifiers('%e', $time);
+ $expected = '14';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->convertSpecifiers('%e', strtotime('2011-01-01'));
+ $expected = ' 1';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test formatting dates taking in account preferred i18n locale file
+ *
+ * @return void
+ */
+ public function testI18nFormat() {
+ App::build(array(
+ 'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
+ ), App::RESET);
+ Configure::write('Config.language', 'time_test');
+
+ $time = strtotime('Thu Jan 14 13:59:28 2010');
+
+ $result = $this->Time->i18nFormat($time);
+ $expected = '14/01/10';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->i18nFormat($time, '%c');
+ $expected = 'jue 14 ene 2010 13:59:28 ' . utf8_encode(strftime('%Z', $time));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
+ $expected = 'Time is 01:59:28 PM, and date is 14/01/10';
+ $this->assertEquals($expected, $result);
+
+ $time = strtotime('Wed Jan 13 13:59:28 2010');
+
+ $result = $this->Time->i18nFormat($time);
+ $expected = '13/01/10';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->i18nFormat($time, '%c');
+ $expected = 'mié 13 ene 2010 13:59:28 ' . utf8_encode(strftime('%Z', $time));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
+ $expected = 'Time is 01:59:28 PM, and date is 13/01/10';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Time->i18nFormat('invalid date', '%x', 'Date invalid');
+ $expected = 'Date invalid';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test new format() syntax which inverts first and second parameters
+ *
+ * @return void
+ */
+ public function testFormatNewSyntax() {
+ $time = time();
+ $this->assertEquals($this->Time->format($time), $this->Time->i18nFormat($time));
+ $this->assertEquals($this->Time->format($time, '%c'), $this->Time->i18nFormat($time, '%c'));
+ }
+
+/**
+ * testListTimezones
+ *
+ * @return void
+ */
+ public function testListTimezones() {
+ $return = CakeTime::listTimezones();
+ $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
+ $this->assertEquals('Bangkok', $return['Asia']['Asia/Bangkok']);
+ $this->assertTrue(isset($return['America']['America/Argentina/Buenos_Aires']));
+ $this->assertEquals('Argentina/Buenos_Aires', $return['America']['America/Argentina/Buenos_Aires']);
+ $this->assertTrue(isset($return['UTC']['UTC']));
+ $this->assertFalse(isset($return['Cuba']));
+ $this->assertFalse(isset($return['US']));
+
+ $return = CakeTime::listTimezones('#^Asia/#');
+ $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
+ $this->assertFalse(isset($return['Pacific']));
+
+ $return = CakeTime::listTimezones('#^(America|Pacific)/#', null, false);
+ $this->assertTrue(isset($return['America/Argentina/Buenos_Aires']));
+ $this->assertTrue(isset($return['Pacific/Tahiti']));
+
+ if (!$this->skipIf(version_compare(PHP_VERSION, '5.3.0', '<'))) {
+ $return = CakeTime::listTimezones(DateTimeZone::ASIA);
+ $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
+ $this->assertFalse(isset($return['Pacific']));
+
+ $return = CakeTime::listTimezones(DateTimeZone::PER_COUNTRY, 'US', false);
+ $this->assertTrue(isset($return['Pacific/Honolulu']));
+ $this->assertFalse(isset($return['Asia/Bangkok']));
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ClassRegistryTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ClassRegistryTest.php
new file mode 100644
index 0000000..eb20fce
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ClassRegistryTest.php
@@ -0,0 +1,349 @@
+<?php
+/**
+ * ClassRegistryTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ClassRegistry', 'Utility');
+
+/**
+ * ClassRegisterModel class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class ClassRegisterModel extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+}
+
+/**
+ * RegisterArticle class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class RegisterArticle extends ClassRegisterModel {
+
+/**
+ * name property
+ *
+ * @var string 'RegisterArticle'
+ */
+ public $name = 'RegisterArticle';
+}
+
+/**
+ * RegisterArticleFeatured class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class RegisterArticleFeatured extends ClassRegisterModel {
+
+/**
+ * name property
+ *
+ * @var string 'RegisterArticleFeatured'
+ */
+ public $name = 'RegisterArticleFeatured';
+}
+
+/**
+ * RegisterArticleTag class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class RegisterArticleTag extends ClassRegisterModel {
+
+/**
+ * name property
+ *
+ * @var string 'RegisterArticleTag'
+ */
+ public $name = 'RegisterArticleTag';
+}
+
+/**
+ * RegistryPluginAppModel class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class RegistryPluginAppModel extends ClassRegisterModel {
+
+/**
+ * tablePrefix property
+ *
+ * @var string 'something_'
+ */
+ public $tablePrefix = 'something_';
+}
+
+/**
+ * TestRegistryPluginModel class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class TestRegistryPluginModel extends RegistryPluginAppModel {
+
+/**
+ * name property
+ *
+ * @var string 'TestRegistryPluginModel'
+ */
+ public $name = 'TestRegistryPluginModel';
+}
+
+/**
+ * RegisterCategory class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class RegisterCategory extends ClassRegisterModel {
+
+/**
+ * name property
+ *
+ * @var string 'RegisterCategory'
+ */
+ public $name = 'RegisterCategory';
+}
+/**
+ * RegisterPrefixedDs class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class RegisterPrefixedDs extends ClassRegisterModel {
+
+/**
+ * useDbConfig property
+ *
+ * @var string 'doesnotexist'
+ */
+ public $useDbConfig = 'doesnotexist';
+}
+
+/**
+ * Abstract class for testing ClassRegistry.
+ */
+abstract class ClassRegistryAbstractModel extends ClassRegisterModel {
+
+ public abstract function doSomething();
+
+}
+
+/**
+ * Interface for testing ClassRegistry
+ */
+interface ClassRegistryInterfaceTest {
+
+ public function doSomething();
+
+}
+
+/**
+ * ClassRegistryTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class ClassRegistryTest extends CakeTestCase {
+
+/**
+ * testAddModel method
+ *
+ * @return void
+ */
+ public function testAddModel() {
+ $Tag = ClassRegistry::init('RegisterArticleTag');
+ $this->assertTrue(is_a($Tag, 'RegisterArticleTag'));
+
+ $TagCopy = ClassRegistry::isKeySet('RegisterArticleTag');
+ $this->assertTrue($TagCopy);
+
+ $Tag->name = 'SomeNewName';
+
+ $TagCopy = ClassRegistry::getObject('RegisterArticleTag');
+
+ $this->assertTrue(is_a($TagCopy, 'RegisterArticleTag'));
+ $this->assertSame($Tag, $TagCopy);
+
+ $NewTag = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'NewTag'));
+ $this->assertTrue(is_a($Tag, 'RegisterArticleTag'));
+
+ $NewTagCopy = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'NewTag'));
+
+ $this->assertNotSame($Tag, $NewTag);
+ $this->assertSame($NewTag, $NewTagCopy);
+
+ $NewTag->name = 'SomeOtherName';
+ $this->assertNotSame($Tag, $NewTag);
+ $this->assertSame($NewTag, $NewTagCopy);
+
+ $Tag->name = 'SomeOtherName';
+ $this->assertNotSame($Tag, $NewTag);
+
+ $this->assertTrue($TagCopy->name === 'SomeOtherName');
+
+ $User = ClassRegistry::init(array('class' => 'RegisterUser', 'alias' => 'User', 'table' => false));
+ $this->assertTrue(is_a($User, 'AppModel'));
+
+ $UserCopy = ClassRegistry::init(array('class' => 'RegisterUser', 'alias' => 'User', 'table' => false));
+ $this->assertTrue(is_a($UserCopy, 'AppModel'));
+ $this->assertEquals($User, $UserCopy);
+
+ $Category = ClassRegistry::init(array('class' => 'RegisterCategory'));
+ $this->assertTrue(is_a($Category, 'RegisterCategory'));
+
+ $ParentCategory = ClassRegistry::init(array('class' => 'RegisterCategory', 'alias' => 'ParentCategory'));
+ $this->assertTrue(is_a($ParentCategory, 'RegisterCategory'));
+ $this->assertNotSame($Category, $ParentCategory);
+
+ $this->assertNotEquals($Category->alias, $ParentCategory->alias);
+ $this->assertEquals('RegisterCategory', $Category->alias);
+ $this->assertEquals('ParentCategory', $ParentCategory->alias);
+ }
+
+/**
+ * testClassRegistryFlush method
+ *
+ * @return void
+ */
+ public function testClassRegistryFlush() {
+ $Tag = ClassRegistry::init('RegisterArticleTag');
+
+ $ArticleTag = ClassRegistry::getObject('RegisterArticleTag');
+ $this->assertTrue(is_a($ArticleTag, 'RegisterArticleTag'));
+ ClassRegistry::flush();
+
+ $NoArticleTag = ClassRegistry::isKeySet('RegisterArticleTag');
+ $this->assertFalse($NoArticleTag);
+ $this->assertTrue(is_a($ArticleTag, 'RegisterArticleTag'));
+ }
+
+/**
+ * testAddMultipleModels method
+ *
+ * @return void
+ */
+ public function testAddMultipleModels() {
+ $Article = ClassRegistry::isKeySet('Article');
+ $this->assertFalse($Article);
+
+ $Featured = ClassRegistry::isKeySet('Featured');
+ $this->assertFalse($Featured);
+
+ $Tag = ClassRegistry::isKeySet('Tag');
+ $this->assertFalse($Tag);
+
+ $models = array(array('class' => 'RegisterArticle', 'alias' => 'Article'),
+ array('class' => 'RegisterArticleFeatured', 'alias' => 'Featured'),
+ array('class' => 'RegisterArticleTag', 'alias' => 'Tag'));
+
+ $added = ClassRegistry::init($models);
+ $this->assertTrue($added);
+
+ $Article = ClassRegistry::isKeySet('Article');
+ $this->assertTrue($Article);
+
+ $Featured = ClassRegistry::isKeySet('Featured');
+ $this->assertTrue($Featured);
+
+ $Tag = ClassRegistry::isKeySet('Tag');
+ $this->assertTrue($Tag);
+
+ $Article = ClassRegistry::getObject('Article');
+ $this->assertTrue(is_a($Article, 'RegisterArticle'));
+
+ $Featured = ClassRegistry::getObject('Featured');
+ $this->assertTrue(is_a($Featured, 'RegisterArticleFeatured'));
+
+ $Tag = ClassRegistry::getObject('Tag');
+ $this->assertTrue(is_a($Tag, 'RegisterArticleTag'));
+ }
+
+/**
+ * testPluginAppModel method
+ *
+ * @return void
+ */
+ public function testPluginAppModel() {
+ $TestRegistryPluginModel = ClassRegistry::isKeySet('TestRegistryPluginModel');
+ $this->assertFalse($TestRegistryPluginModel);
+
+ //Faking a plugin
+ CakePlugin::load('RegistryPlugin', array('path' => '/fake/path'));
+ $TestRegistryPluginModel = ClassRegistry::init('RegistryPlugin.TestRegistryPluginModel');
+ $this->assertTrue(is_a($TestRegistryPluginModel, 'TestRegistryPluginModel'));
+
+ $this->assertEquals('something_', $TestRegistryPluginModel->tablePrefix);
+
+ $PluginUser = ClassRegistry::init(array('class' => 'RegistryPlugin.RegisterUser', 'alias' => 'RegistryPluginUser', 'table' => false));
+ $this->assertTrue(is_a($PluginUser, 'RegistryPluginAppModel'));
+
+ $PluginUserCopy = ClassRegistry::getObject('RegistryPluginUser');
+ $this->assertTrue(is_a($PluginUserCopy, 'RegistryPluginAppModel'));
+ $this->assertSame($PluginUser, $PluginUserCopy);
+ CakePlugin::unload();
+ }
+
+/**
+ * Tests prefixed datasource names for test purposes
+ *
+ */
+ public function testPrefixedTestDatasource() {
+ ClassRegistry::config(array('testing' => true));
+ $Model = ClassRegistry::init('RegisterPrefixedDs');
+ $this->assertEquals('test', $Model->useDbConfig);
+ ClassRegistry::removeObject('RegisterPrefixedDs');
+
+ $testConfig = ConnectionManager::getDataSource('test')->config;
+ ConnectionManager::create('test_doesnotexist', $testConfig);
+
+ $Model = ClassRegistry::init('RegisterArticle');
+ $this->assertEquals('test', $Model->useDbConfig);
+ $Model = ClassRegistry::init('RegisterPrefixedDs');
+ $this->assertEquals('test_doesnotexist', $Model->useDbConfig);
+ }
+
+/**
+ * Tests that passing the string parameter to init() will return false if the model does not exists
+ *
+ */
+ public function testInitStrict() {
+ $this->assertFalse(ClassRegistry::init('NonExistent', true));
+ }
+
+/**
+ * Test that you cannot init() an abstract class. An exception will be raised.
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testInitAbstractClass() {
+ ClassRegistry::init('ClassRegistryAbstractModel');
+ }
+
+/**
+ * Test that you cannot init() an abstract class. A exception will be raised.
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testInitInterface() {
+ ClassRegistry::init('ClassRegistryInterfaceTest');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/DebuggerTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/DebuggerTest.php
new file mode 100644
index 0000000..6d7d9ec
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/DebuggerTest.php
@@ -0,0 +1,499 @@
+<?php
+/**
+ * DebuggerTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Debugger', 'Utility');
+
+/**
+ * DebugggerTestCaseDebuggger class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class DebuggerTestCaseDebugger extends Debugger {
+}
+
+/**
+ * DebuggerTest class
+ *
+ * !!! Be careful with changing code below as it may
+ * !!! change line numbers which are used in the tests
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class DebuggerTest extends CakeTestCase {
+
+ protected $_restoreError = false;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ Configure::write('debug', 2);
+ Configure::write('log', false);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('log', true);
+ if ($this->_restoreError) {
+ restore_error_handler();
+ }
+ }
+
+/**
+ * testDocRef method
+ *
+ * @return void
+ */
+ public function testDocRef() {
+ ini_set('docref_root', '');
+ $this->assertEquals(ini_get('docref_root'), '');
+ $debugger = new Debugger();
+ $this->assertEquals(ini_get('docref_root'), 'http://php.net/');
+ }
+
+/**
+ * test Excerpt writing
+ *
+ * @return void
+ */
+ public function testExcerpt() {
+ $result = Debugger::excerpt(__FILE__, __LINE__, 2);
+ $this->assertTrue(is_array($result));
+ $this->assertEquals(5, count($result));
+ $this->assertRegExp('/function(.+)testExcerpt/', $result[1]);
+
+ $result = Debugger::excerpt(__FILE__, 2, 2);
+ $this->assertTrue(is_array($result));
+ $this->assertEquals(4, count($result));
+
+ $pattern = '/<code><span style\="color\: \#\d+">.*?&lt;\?php/';
+ $this->assertRegExp($pattern, $result[0]);
+
+ $return = Debugger::excerpt('[internal]', 2, 2);
+ $this->assertTrue(empty($return));
+ }
+
+/**
+ * testOutput method
+ *
+ * @return void
+ */
+ public function testOutput() {
+ set_error_handler('Debugger::showError');
+ $this->_restoreError = true;
+
+ $result = Debugger::output(false);
+ $this->assertEquals('', $result);
+ $out .= '';
+ $result = Debugger::output(true);
+
+ $this->assertEquals('Notice', $result[0]['error']);
+ $this->assertRegExp('/Undefined variable\:\s+out/', $result[0]['description']);
+ $this->assertRegExp('/DebuggerTest::testOutput/i', $result[0]['trace']);
+
+ ob_start();
+ Debugger::output('txt');
+ $other .= '';
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/Undefined variable:\s+other/', $result);
+ $this->assertRegExp('/Context:/', $result);
+ $this->assertRegExp('/DebuggerTest::testOutput/i', $result);
+
+ ob_start();
+ Debugger::output('html');
+ $wrong .= '';
+ $result = ob_get_clean();
+ $this->assertRegExp('/<pre class="cake-error">.+<\/pre>/', $result);
+ $this->assertRegExp('/<b>Notice<\/b>/', $result);
+ $this->assertRegExp('/variable:\s+wrong/', $result);
+
+ ob_start();
+ Debugger::output('js');
+ $buzz .= '';
+ $result = explode('</a>', ob_get_clean());
+ $this->assertTags($result[0], array(
+ 'pre' => array('class' => 'cake-error'),
+ 'a' => array(
+ 'href' => "javascript:void(0);",
+ 'onclick' => "preg:/document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display = " .
+ "\(document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display == 'none'" .
+ " \? '' \: 'none'\);/"
+ ),
+ 'b' => array(), 'Notice', '/b', ' (8)',
+ ));
+
+ $this->assertRegExp('/Undefined variable:\s+buzz/', $result[1]);
+ $this->assertRegExp('/<a[^>]+>Code/', $result[1]);
+ $this->assertRegExp('/<a[^>]+>Context/', $result[2]);
+ $this->assertContains('$wrong = &#039;&#039;', $result[3], 'Context should be HTML escaped.');
+ }
+
+/**
+ * Tests that changes in output formats using Debugger::output() change the templates used.
+ *
+ * @return void
+ */
+ public function testChangeOutputFormats() {
+ set_error_handler('Debugger::showError');
+ $this->_restoreError = true;
+
+ Debugger::output('js', array(
+ 'traceLine' => '{:reference} - <a href="txmt://open?url=file://{:file}' .
+ '&line={:line}">{:path}</a>, line {:line}'
+ ));
+ $result = Debugger::trace();
+ $this->assertRegExp('/' . preg_quote('txmt://open?url=file://', '/') . '(\/|[A-Z]:\\\\)' . '/', $result);
+
+ Debugger::output('xml', array(
+ 'error' => '<error><code>{:code}</code><file>{:file}</file><line>{:line}</line>' .
+ '{:description}</error>',
+ 'context' => "<context>{:context}</context>",
+ 'trace' => "<stack>{:trace}</stack>",
+ ));
+ Debugger::output('xml');
+
+ ob_start();
+ $foo .= '';
+ $result = ob_get_clean();
+
+ $data = array(
+ 'error' => array(),
+ 'code' => array(), '8', '/code',
+ 'file' => array(), 'preg:/[^<]+/', '/file',
+ 'line' => array(), '' . (intval(__LINE__) - 7), '/line',
+ 'preg:/Undefined variable:\s+foo/',
+ '/error'
+ );
+ $this->assertTags($result, $data, true);
+ }
+
+/**
+ * Test that outputAs works.
+ *
+ * @return void
+ */
+ public function testOutputAs() {
+ Debugger::outputAs('html');
+ $this->assertEquals('html', Debugger::outputAs());
+ }
+
+/**
+ * Test that choosing a non-existent format causes an exception
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testOutputAsException() {
+ Debugger::outputAs('Invalid junk');
+ }
+
+/**
+ * Tests that changes in output formats using Debugger::output() change the templates used.
+ *
+ * @return void
+ */
+ public function testAddFormat() {
+ set_error_handler('Debugger::showError');
+ $this->_restoreError = true;
+
+ Debugger::addFormat('js', array(
+ 'traceLine' => '{:reference} - <a href="txmt://open?url=file://{:file}' .
+ '&line={:line}">{:path}</a>, line {:line}'
+ ));
+ Debugger::outputAs('js');
+
+ $result = Debugger::trace();
+ $this->assertRegExp('/' . preg_quote('txmt://open?url=file://', '/') . '(\/|[A-Z]:\\\\)' . '/', $result);
+
+ Debugger::addFormat('xml', array(
+ 'error' => '<error><code>{:code}</code><file>{:file}</file><line>{:line}</line>' .
+ '{:description}</error>',
+ ));
+ Debugger::outputAs('xml');
+
+ ob_start();
+ $foo .= '';
+ $result = ob_get_clean();
+
+ $data = array(
+ '<error',
+ '<code', '8', '/code',
+ '<file', 'preg:/[^<]+/', '/file',
+ '<line', '' . (intval(__LINE__) - 7), '/line',
+ 'preg:/Undefined variable:\s+foo/',
+ '/error'
+ );
+ $this->assertTags($result, $data, true);
+ }
+
+/**
+ * Test adding a format that is handled by a callback.
+ *
+ * @return void
+ */
+ public function testAddFormatCallback() {
+ set_error_handler('Debugger::showError');
+ $this->_restoreError = true;
+
+ Debugger::addFormat('callback', array('callback' => array($this, 'customFormat')));
+ Debugger::outputAs('callback');
+
+ ob_start();
+ $foo .= '';
+ $result = ob_get_clean();
+ $this->assertContains('Notice: I eated an error', $result);
+ $this->assertContains('DebuggerTest.php', $result);
+ }
+
+/**
+ * Test method for testing addFormat with callbacks.
+ */
+ public function customFormat($error, $strings) {
+ return $error['error'] . ': I eated an error ' . $error['path'];
+ }
+
+/**
+ * testTrimPath method
+ *
+ * @return void
+ */
+ public function testTrimPath() {
+ $this->assertEquals(Debugger::trimPath(APP), 'APP' . DS);
+ $this->assertEquals(Debugger::trimPath(CAKE_CORE_INCLUDE_PATH), 'CORE');
+ }
+
+/**
+ * testExportVar method
+ *
+ * @return void
+ */
+ public function testExportVar() {
+ App::uses('Controller', 'Controller');
+ $Controller = new Controller();
+ $Controller->helpers = array('Html', 'Form');
+ $View = new View($Controller);
+ $View->int = 2;
+ $View->float = 1.333;
+
+ $result = Debugger::exportVar($View);
+ $expected = <<<TEXT
+object(View) {
+ Helpers => object(HelperCollection) {}
+ Blocks => object(ViewBlock) {}
+ plugin => null
+ name => ''
+ passedArgs => array()
+ helpers => array(
+ (int) 0 => 'Html',
+ (int) 1 => 'Form'
+ )
+ viewPath => ''
+ viewVars => array()
+ view => null
+ layout => 'default'
+ layoutPath => null
+ autoLayout => true
+ ext => '.ctp'
+ subDir => null
+ theme => null
+ cacheAction => false
+ validationErrors => array()
+ hasRendered => false
+ uuids => array()
+ request => object(CakeRequest) {}
+ response => object(CakeResponse) {}
+ elementCache => 'default'
+ int => (int) 2
+ float => (float) 1.333
+}
+TEXT;
+ $this->assertTextEquals($expected, $result);
+
+ $data = array(
+ 1 => 'Index one',
+ 5 => 'Index five'
+ );
+ $result = Debugger::exportVar($data);
+ $expected = <<<TEXT
+array(
+ (int) 1 => 'Index one',
+ (int) 5 => 'Index five'
+)
+TEXT;
+ $this->assertTextEquals($expected, $result);
+
+ $data = array(
+ 'key' => array(
+ 'value'
+ )
+ );
+ $result = Debugger::exportVar($data, 1);
+ $expected = <<<TEXT
+array(
+ 'key' => array(
+ [maximum depth reached]
+ )
+)
+TEXT;
+ $this->assertTextEquals($expected, $result);
+ }
+
+/**
+ * testLog method
+ *
+ * @return void
+ */
+ public function testLog() {
+ if (file_exists(LOGS . 'debug.log')) {
+ unlink(LOGS . 'debug.log');
+ }
+
+ Debugger::log('cool');
+ $result = file_get_contents(LOGS . 'debug.log');
+ $this->assertRegExp('/DebuggerTest\:\:testLog/i', $result);
+ $this->assertRegExp("/'cool'/", $result);
+
+ unlink(LOGS . 'debug.log');
+
+ Debugger::log(array('whatever', 'here'));
+ $result = file_get_contents(LOGS . 'debug.log');
+ $this->assertRegExp('/DebuggerTest\:\:testLog/i', $result);
+ $this->assertRegExp('/\[main\]/', $result);
+ $this->assertRegExp('/array/', $result);
+ $this->assertRegExp("/'whatever',/", $result);
+ $this->assertRegExp("/'here'/", $result);
+ }
+
+/**
+ * testDump method
+ *
+ * @return void
+ */
+ public function testDump() {
+ $var = array('People' => array(
+ array(
+ 'name' => 'joeseph',
+ 'coat' => 'technicolor',
+ 'hair_color' => 'brown'
+ ),
+ array(
+ 'name' => 'Shaft',
+ 'coat' => 'black',
+ 'hair' => 'black'
+ )
+ ));
+ ob_start();
+ Debugger::dump($var);
+ $result = ob_get_clean();
+ $expected = <<<TEXT
+<pre>array(
+ 'People' => array(
+ (int) 0 => array(
+ 'name' => 'joeseph',
+ 'coat' => 'technicolor',
+ 'hair_color' => 'brown'
+ ),
+ (int) 1 => array(
+ 'name' => 'Shaft',
+ 'coat' => 'black',
+ 'hair' => 'black'
+ )
+ )
+)</pre>
+TEXT;
+ $this->assertTextEquals($expected, $result);
+ }
+
+/**
+ * test getInstance.
+ *
+ * @return void
+ */
+ public function testGetInstance() {
+ $result = Debugger::getInstance();
+ $this->assertInstanceOf('Debugger', $result);
+
+ $result = Debugger::getInstance('DebuggerTestCaseDebugger');
+ $this->assertInstanceOf('DebuggerTestCaseDebugger', $result);
+
+ $result = Debugger::getInstance();
+ $this->assertInstanceOf('DebuggerTestCaseDebugger', $result);
+
+ $result = Debugger::getInstance('Debugger');
+ $this->assertInstanceOf('Debugger', $result);
+ }
+
+/**
+ * testNoDbCredentials
+ *
+ * If a connection error occurs, the config variable is passed through exportVar
+ * *** our database login credentials such that they are never visible
+ *
+ * @return void
+ */
+ public function testNoDbCredentials() {
+ $config = array(
+ 'datasource' => 'mysql',
+ 'persistent' => false,
+ 'host' => 'void.cakephp.org',
+ 'login' => 'cakephp-user',
+ 'password' => 'cakephp-password',
+ 'database' => 'cakephp-database',
+ 'prefix' => ''
+ );
+
+ $output = Debugger::exportVar($config);
+
+ $expectedArray = array(
+ 'datasource' => 'mysql',
+ 'persistent' => false,
+ 'host' => '*****',
+ 'login' => '*****',
+ 'password' => '*****',
+ 'database' => '*****',
+ 'prefix' => ''
+ );
+ $expected = Debugger::exportVar($expectedArray);
+
+ $this->assertEquals($expected, $output);
+ }
+
+/**
+ * test trace exclude
+ *
+ * @return void
+ */
+ public function testTraceExclude() {
+ $result = Debugger::trace();
+ $this->assertRegExp('/^DebuggerTest::testTraceExclude/', $result);
+
+ $result = Debugger::trace(array(
+ 'exclude' => array('DebuggerTest::testTraceExclude')
+ ));
+ $this->assertNotRegExp('/^DebuggerTest::testTraceExclude/', $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FileTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FileTest.php
new file mode 100644
index 0000000..e63bcbd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FileTest.php
@@ -0,0 +1,556 @@
+<?php
+/**
+ * FileTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('File', 'Utility');
+App::uses('Folder', 'Utility');
+
+/**
+ * FileTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class FileTest extends CakeTestCase {
+
+/**
+ * File property
+ *
+ * @var mixed null
+ */
+ public $File = null;
+
+/**
+ * setup the test case
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $file = __FILE__;
+ $this->File = new File($file);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ $this->File->close();
+ unset($this->File);
+
+ $Folder = new Folder();
+ $Folder->delete(TMP . 'tests' . DS . 'permissions');
+ }
+
+/**
+ * testBasic method
+ *
+ * @return void
+ */
+ public function testBasic() {
+ $file = __FILE__;
+
+ $result = $this->File->pwd();
+ $expecting = $file;
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->name;
+ $expecting = basename(__FILE__);
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->info();
+ $expecting = array(
+ 'dirname' => dirname(__FILE__),
+ 'basename' => basename(__FILE__),
+ 'extension' => 'php',
+ 'filename' => 'FileTest',
+ 'filesize' => filesize($file),
+ 'mime' => 'text/x-php'
+ );
+ if (!function_exists('finfo_open') && (!function_exists('mime_content_type') ||
+ function_exists('mime_content_type') && false === mime_content_type($this->File->pwd()))) {
+ $expecting['mime'] = false;
+ }
+
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->ext();
+ $expecting = 'php';
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->name();
+ $expecting = 'FileTest';
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->md5();
+ $expecting = md5_file($file);
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->md5(true);
+ $expecting = md5_file($file);
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->size();
+ $expecting = filesize($file);
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->owner();
+ $expecting = fileowner($file);
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->group();
+ $expecting = filegroup($file);
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->Folder();
+ $this->assertInstanceOf('Folder', $result);
+ }
+
+/**
+ * testPermission method
+ */
+ public function testPermission() {
+ $this->skipIf(DIRECTORY_SEPARATOR === '\\', 'File permissions tests not supported on Windows.');
+
+ $dir = TMP . 'tests' . DS . 'permissions' . DS;
+ $Folder = new Folder($dir);
+
+ $old = umask();
+
+ umask(0002);
+ $file = $dir . 'permission_' . uniqid();
+ $expecting = decoct(0664 & ~umask());
+ $File = new File($file, true);
+ $result = $File->perms();
+ $this->assertEquals($expecting, $result);
+ $File->delete();
+
+ umask(0022);
+ $file = $dir . 'permission_' . uniqid();
+ $expecting = decoct(0644 & ~umask());
+ $File = new File($file, true);
+ $result = $File->perms();
+ $this->assertEquals($expecting, $result);
+ $File->delete();
+
+ umask(0422);
+ $file = $dir . 'permission_' . uniqid();
+ $expecting = decoct(0244 & ~umask());
+ $File = new File($file, true);
+ $result = $File->perms();
+ $this->assertEquals($expecting, $result);
+ $File->delete();
+
+ umask(0444);
+ $file = $dir . 'permission_' . uniqid();
+ $expecting = decoct(0222 & ~umask());
+ $File = new File($file, true);
+ $result = $File->perms();
+ $this->assertEquals($expecting, $result);
+ $File->delete();
+
+ umask($old);
+ }
+
+/**
+ * testRead method
+ *
+ * @return void
+ */
+ public function testRead() {
+ $file = __FILE__;
+ $this->File = new File($file);
+
+ $result = $this->File->read();
+ $expecting = file_get_contents(__FILE__);
+ $this->assertEquals($expecting, $result);
+ $this->assertTrue(!is_resource($this->File->handle));
+
+ $this->File->lock = true;
+ $result = $this->File->read();
+ $expecting = file_get_contents(__FILE__);
+ $this->assertEquals(trim($expecting), $result);
+ $this->File->lock = null;
+
+ $data = $expecting;
+ $expecting = substr($data, 0, 3);
+ $result = $this->File->read(3);
+ $this->assertEquals($expecting, $result);
+ $this->assertTrue(is_resource($this->File->handle));
+
+ $expecting = substr($data, 3, 3);
+ $result = $this->File->read(3);
+ $this->assertEquals($expecting, $result);
+ }
+
+/**
+ * testOffset method
+ *
+ * @return void
+ */
+ public function testOffset() {
+ $this->File->close();
+
+ $result = $this->File->offset();
+ $this->assertFalse($result);
+
+ $this->assertFalse(is_resource($this->File->handle));
+ $success = $this->File->offset(0);
+ $this->assertTrue($success);
+ $this->assertTrue(is_resource($this->File->handle));
+
+ $result = $this->File->offset();
+ $expecting = 0;
+ $this->assertSame($result, $expecting);
+
+ $data = file_get_contents(__FILE__);
+ $success = $this->File->offset(5);
+ $expecting = substr($data, 5, 3);
+ $result = $this->File->read(3);
+ $this->assertTrue($success);
+ $this->assertEquals($expecting, $result);
+
+ $result = $this->File->offset();
+ $expecting = 5 + 3;
+ $this->assertSame($result, $expecting);
+ }
+
+/**
+ * testOpen method
+ *
+ * @return void
+ */
+ public function testOpen() {
+ $this->File->handle = null;
+
+ $r = $this->File->open();
+ $this->assertTrue(is_resource($this->File->handle));
+ $this->assertTrue($r);
+
+ $handle = $this->File->handle;
+ $r = $this->File->open();
+ $this->assertTrue($r);
+ $this->assertTrue($handle === $this->File->handle);
+ $this->assertTrue(is_resource($this->File->handle));
+
+ $r = $this->File->open('r', true);
+ $this->assertTrue($r);
+ $this->assertFalse($handle === $this->File->handle);
+ $this->assertTrue(is_resource($this->File->handle));
+ }
+
+/**
+ * testClose method
+ *
+ * @return void
+ */
+ public function testClose() {
+ $this->File->handle = null;
+ $this->assertFalse(is_resource($this->File->handle));
+ $this->assertTrue($this->File->close());
+ $this->assertFalse(is_resource($this->File->handle));
+
+ $this->File->handle = fopen(__FILE__, 'r');
+ $this->assertTrue(is_resource($this->File->handle));
+ $this->assertTrue($this->File->close());
+ $this->assertFalse(is_resource($this->File->handle));
+ }
+
+/**
+ * testCreate method
+ *
+ * @return void
+ */
+ public function testCreate() {
+ $tmpFile = TMP . 'tests' . DS . 'cakephp.file.test.tmp';
+ $File = new File($tmpFile, true, 0777);
+ $this->assertTrue($File->exists());
+ }
+
+/**
+ * testOpeningNonExistentFileCreatesIt method
+ *
+ * @return void
+ */
+ public function testOpeningNonExistentFileCreatesIt() {
+ $someFile = new File(TMP . 'some_file.txt', false);
+ $this->assertTrue($someFile->open());
+ $this->assertEquals('', $someFile->read());
+ $someFile->close();
+ $someFile->delete();
+ }
+
+/**
+ * testPrepare method
+ *
+ * @return void
+ */
+ public function testPrepare() {
+ $string = "some\nvery\ncool\r\nteststring here\n\n\nfor\r\r\n\n\r\n\nhere";
+ if (DS == '\\') {
+ $expected = "some\r\nvery\r\ncool\r\nteststring here\r\n\r\n\r\n";
+ $expected .= "for\r\n\r\n\r\n\r\n\r\nhere";
+ } else {
+ $expected = "some\nvery\ncool\nteststring here\n\n\nfor\n\n\n\n\nhere";
+ }
+ $this->assertSame(File::prepare($string), $expected);
+
+ $expected = "some\r\nvery\r\ncool\r\nteststring here\r\n\r\n\r\n";
+ $expected .= "for\r\n\r\n\r\n\r\n\r\nhere";
+ $this->assertSame(File::prepare($string, true), $expected);
+ }
+
+/**
+ * testReadable method
+ *
+ * @return void
+ */
+ public function testReadable() {
+ $someFile = new File(TMP . 'some_file.txt', false);
+ $this->assertTrue($someFile->open());
+ $this->assertTrue($someFile->readable());
+ $someFile->close();
+ $someFile->delete();
+ }
+
+/**
+ * testWritable method
+ *
+ * @return void
+ */
+ public function testWritable() {
+ $someFile = new File(TMP . 'some_file.txt', false);
+ $this->assertTrue($someFile->open());
+ $this->assertTrue($someFile->writable());
+ $someFile->close();
+ $someFile->delete();
+ }
+
+/**
+ * testExecutable method
+ *
+ * @return void
+ */
+ public function testExecutable() {
+ $someFile = new File(TMP . 'some_file.txt', false);
+ $this->assertTrue($someFile->open());
+ $this->assertFalse($someFile->executable());
+ $someFile->close();
+ $someFile->delete();
+ }
+
+/**
+ * testLastAccess method
+ *
+ * @return void
+ */
+ public function testLastAccess() {
+ $ts = time();
+ $someFile = new File(TMP . 'some_file.txt', false);
+ $this->assertFalse($someFile->lastAccess());
+ $this->assertTrue($someFile->open());
+ $this->assertTrue($someFile->lastAccess() >= $ts);
+ $someFile->close();
+ $someFile->delete();
+ }
+
+/**
+ * testLastChange method
+ *
+ * @return void
+ */
+ public function testLastChange() {
+ $ts = time();
+ $someFile = new File(TMP . 'some_file.txt', false);
+ $this->assertFalse($someFile->lastChange());
+ $this->assertTrue($someFile->open('r+'));
+ $this->assertTrue($someFile->lastChange() >= $ts);
+ $someFile->write('something');
+ $this->assertTrue($someFile->lastChange() >= $ts);
+ $someFile->close();
+ $someFile->delete();
+ }
+
+/**
+ * testWrite method
+ *
+ * @return void
+ */
+ public function testWrite() {
+ if (!$tmpFile = $this->_getTmpFile()) {
+ return false;
+ };
+ if (file_exists($tmpFile)) {
+ unlink($tmpFile);
+ }
+
+ $TmpFile = new File($tmpFile);
+ $this->assertFalse(file_exists($tmpFile));
+ $this->assertFalse(is_resource($TmpFile->handle));
+
+ $testData = array('CakePHP\'s', ' test suite', ' was here ...', '');
+ foreach ($testData as $data) {
+ $r = $TmpFile->write($data);
+ $this->assertTrue($r);
+ $this->assertTrue(file_exists($tmpFile));
+ $this->assertEquals($data, file_get_contents($tmpFile));
+ $this->assertTrue(is_resource($TmpFile->handle));
+ $TmpFile->close();
+
+ }
+ unlink($tmpFile);
+ }
+
+/**
+ * testAppend method
+ *
+ * @return void
+ */
+ public function testAppend() {
+ if (!$tmpFile = $this->_getTmpFile()) {
+ return false;
+ };
+ if (file_exists($tmpFile)) {
+ unlink($tmpFile);
+ }
+
+ $TmpFile = new File($tmpFile);
+ $this->assertFalse(file_exists($tmpFile));
+
+ $fragments = array('CakePHP\'s', ' test suite', ' was here ...', '');
+ $data = null;
+ foreach ($fragments as $fragment) {
+ $r = $TmpFile->append($fragment);
+ $this->assertTrue($r);
+ $this->assertTrue(file_exists($tmpFile));
+ $data = $data . $fragment;
+ $this->assertEquals($data, file_get_contents($tmpFile));
+ $TmpFile->close();
+ }
+ }
+
+/**
+ * testDelete method
+ *
+ * @return void
+ */
+ public function testDelete() {
+ if (!$tmpFile = $this->_getTmpFile()) {
+ return false;
+ }
+
+ if (!file_exists($tmpFile)) {
+ touch($tmpFile);
+ }
+ $TmpFile = new File($tmpFile);
+ $this->assertTrue(file_exists($tmpFile));
+ $result = $TmpFile->delete();
+ $this->assertTrue($result);
+ $this->assertFalse(file_exists($tmpFile));
+
+ $TmpFile = new File('/this/does/not/exist');
+ $result = $TmpFile->delete();
+ $this->assertFalse($result);
+ }
+
+/**
+ * Windows has issues unlinking files if there are
+ * active filehandles open.
+ *
+ * @return void
+ */
+ public function testDeleteAfterRead() {
+ if (!$tmpFile = $this->_getTmpFile()) {
+ return false;
+ }
+ if (!file_exists($tmpFile)) {
+ touch($tmpFile);
+ }
+ $File = new File($tmpFile);
+ $File->read();
+ $this->assertTrue($File->delete());
+ }
+
+/**
+ * testCopy method
+ *
+ * @return void
+ */
+ public function testCopy() {
+ $dest = TMP . 'tests' . DS . 'cakephp.file.test.tmp';
+ $file = __FILE__;
+ $this->File = new File($file);
+ $result = $this->File->copy($dest);
+ $this->assertTrue($result);
+
+ $result = $this->File->copy($dest, true);
+ $this->assertTrue($result);
+
+ $result = $this->File->copy($dest, false);
+ $this->assertFalse($result);
+
+ $this->File->close();
+ unlink($dest);
+
+ $TmpFile = new File('/this/does/not/exist');
+ $result = $TmpFile->copy($dest);
+ $this->assertFalse($result);
+
+ $TmpFile->close();
+ }
+
+/**
+ * Test mime()
+ *
+ * @return void
+ */
+ public function testMime() {
+ $this->skipIf(!function_exists('finfo_open') && !function_exists('mime_content_type'), 'Not able to read mime type');
+ $path = CAKE . 'Test' . DS . 'test_app' . DS . 'webroot' . DS . 'img' . DS . 'cake.power.gif';
+ $file = new File($path);
+ $expected = 'image/gif';
+ if (function_exists('mime_content_type') && false === mime_content_type($file->pwd())) {
+ $expected = false;
+ }
+ $this->assertEquals($expected, $file->mime());
+ }
+
+/**
+ * getTmpFile method
+ *
+ * @param bool $paintSkip
+ * @return void
+ */
+ protected function _getTmpFile($paintSkip = true) {
+ $tmpFile = TMP . 'tests' . DS . 'cakephp.file.test.tmp';
+ if (is_writable(dirname($tmpFile)) && (!file_exists($tmpFile) || is_writable($tmpFile))) {
+ return $tmpFile;
+ };
+
+ if ($paintSkip) {
+ $trace = debug_backtrace();
+ $caller = $trace[0]['function'];
+ $shortPath = dirname($tmpFile);
+
+ $message = __d('cake_dev', '[FileTest] Skipping %s because "%s" not writeable!', $caller, $shortPath);
+ $this->markTestSkipped($message);
+ }
+ return false;
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FolderTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FolderTest.php
new file mode 100644
index 0000000..76ee08a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/FolderTest.php
@@ -0,0 +1,937 @@
+<?php
+/**
+ * FolderTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Folder', 'Utility');
+App::uses('File', 'Utility');
+
+/**
+ * FolderTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class FolderTest extends CakeTestCase {
+
+ protected static $_tmp = array();
+
+/**
+ * Save the directory names in TMP
+ *
+ * @return void
+ */
+ public static function setUpBeforeClass() {
+ foreach (scandir(TMP) as $file) {
+ if (is_dir(TMP . $file) && !in_array($file, array('.', '..'))) {
+ self::$_tmp[] = $file;
+ }
+ }
+ }
+
+/**
+ * setUp clearstatcache() to flush file descriptors.
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ clearstatcache();
+ }
+
+/**
+ * Restore the TMP directory to its original state.
+ *
+ * @return void
+ */
+ public function tearDown() {
+ $exclude = array_merge(self::$_tmp, array('.', '..'));
+ foreach (scandir(TMP) as $dir) {
+ if (is_dir(TMP . $dir) && !in_array($dir, $exclude)) {
+ $iterator = new RecursiveDirectoryIterator(TMP . $dir);
+ foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file) {
+ if ($file->isFile() || $file->isLink()) {
+ unlink($file->getPathname());
+ } elseif ($file->isDir() && !in_array($file->getFilename(), array('.', '..'))) {
+ rmdir($file->getPathname());
+ }
+ }
+ rmdir(TMP . $dir);
+ }
+ }
+ }
+
+/**
+ * testBasic method
+ *
+ * @return void
+ */
+ public function testBasic() {
+ $path = dirname(__FILE__);
+ $Folder = new Folder($path);
+
+ $result = $Folder->pwd();
+ $this->assertEquals($path, $result);
+
+ $result = Folder::addPathElement($path, 'test');
+ $expected = $path . DS . 'test';
+ $this->assertEquals($expected, $result);
+
+ $result = $Folder->cd(ROOT);
+ $expected = ROOT;
+ $this->assertEquals($expected, $result);
+
+ $result = $Folder->cd(ROOT . DS . 'non-existent');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testInPath method
+ *
+ * @return void
+ */
+ public function testInPath() {
+ $path = dirname(dirname(__FILE__));
+ $inside = dirname($path) . DS;
+
+ $Folder = new Folder($path);
+
+ $result = $Folder->pwd();
+ $this->assertEquals($path, $result);
+
+ $result = Folder::isSlashTerm($inside);
+ $this->assertTrue($result);
+
+ $result = $Folder->realpath('Test/');
+ $this->assertEquals($path . DS . 'Test' . DS, $result);
+
+ $result = $Folder->inPath('Test' . DS);
+ $this->assertTrue($result);
+
+ $result = $Folder->inPath(DS . 'non-existing' . $inside);
+ $this->assertFalse($result);
+
+ $result = $Folder->inPath($path . DS . 'Model', true);
+ $this->assertTrue($result);
+ }
+
+/**
+ * test creation of single and multiple paths.
+ *
+ * @return void
+ */
+ public function testCreation() {
+ $Folder = new Folder(TMP . 'tests');
+ $result = $Folder->create(TMP . 'tests' . DS . 'first' . DS . 'second' . DS . 'third');
+ $this->assertTrue($result);
+
+ rmdir(TMP . 'tests' . DS . 'first' . DS . 'second' . DS . 'third');
+ rmdir(TMP . 'tests' . DS . 'first' . DS . 'second');
+ rmdir(TMP . 'tests' . DS . 'first');
+
+ $Folder = new Folder(TMP . 'tests');
+ $result = $Folder->create(TMP . 'tests' . DS . 'first');
+ $this->assertTrue($result);
+ rmdir(TMP . 'tests' . DS . 'first');
+ }
+
+/**
+ * test that creation of folders with trailing ds works
+ *
+ * @return void
+ */
+ public function testCreateWithTrailingDs() {
+ $Folder = new Folder(TMP);
+ $path = TMP . 'tests' . DS . 'trailing' . DS . 'dir' . DS;
+ $result = $Folder->create($path);
+ $this->assertTrue($result);
+
+ $this->assertTrue(is_dir($path), 'Folder was not made');
+
+ $Folder = new Folder(TMP . 'tests' . DS . 'trailing');
+ $this->assertTrue($Folder->delete());
+ }
+
+/**
+ * test recursive directory create failure.
+ *
+ * @return void
+ */
+ public function testRecursiveCreateFailure() {
+ $this->skipIf(DIRECTORY_SEPARATOR === '\\', 'Cant perform operations using permissions on windows.');
+
+ $path = TMP . 'tests' . DS . 'one';
+ mkdir($path);
+ chmod($path, '0444');
+
+ try {
+ $Folder = new Folder($path);
+ $result = $Folder->create($path . DS . 'two' . DS . 'three');
+ $this->assertFalse($result);
+ } catch (PHPUnit_Framework_Error $e) {
+ $this->assertTrue(true);
+ }
+
+ chmod($path, '0777');
+ rmdir($path);
+ }
+
+/**
+ * testOperations method
+ *
+ * @return void
+ */
+ public function testOperations() {
+ $path = CAKE . 'Console' . DS . 'Templates' . DS . 'skel';
+ $Folder = new Folder($path);
+
+ $result = is_dir($Folder->pwd());
+ $this->assertTrue($result);
+
+ $new = TMP . 'test_folder_new';
+ $result = $Folder->create($new);
+ $this->assertTrue($result);
+
+ $copy = TMP . 'test_folder_copy';
+ $result = $Folder->copy($copy);
+ $this->assertTrue($result);
+
+ $copy = TMP . 'test_folder_copy';
+ $result = $Folder->copy($copy);
+ $this->assertTrue($result);
+
+ $copy = TMP . 'test_folder_copy';
+ $result = $Folder->chmod($copy, 0755, false);
+ $this->assertTrue($result);
+
+ $result = $Folder->cd($copy);
+ $this->assertTrue((bool)$result);
+
+ $mv = TMP . 'test_folder_mv';
+ $result = $Folder->move($mv);
+ $this->assertTrue($result);
+
+ $mv = TMP . 'test_folder_mv_2';
+ $result = $Folder->move($mv);
+ $this->assertTrue($result);
+
+ $result = $Folder->delete($new);
+ $this->assertTrue($result);
+
+ $result = $Folder->delete($mv);
+ $this->assertTrue($result);
+
+ $result = $Folder->delete($mv);
+ $this->assertTrue($result);
+
+ $new = APP . 'index.php';
+ $result = $Folder->create($new);
+ $this->assertFalse($result);
+
+ $expected = $new . ' is a file';
+ $result = $Folder->errors();
+ $this->assertEquals($expected, $result[0]);
+
+ $new = TMP . 'test_folder_new';
+ $result = $Folder->create($new);
+ $this->assertTrue($result);
+
+ $result = $Folder->cd($new);
+ $this->assertTrue((bool)$result);
+
+ $result = $Folder->delete();
+ $this->assertTrue($result);
+
+ $Folder = new Folder('non-existent');
+ $result = $Folder->pwd();
+ $this->assertNull($result);
+ }
+
+/**
+ * testChmod method
+ *
+ * @return void
+ */
+ public function testChmod() {
+ $this->skipIf(DIRECTORY_SEPARATOR === '\\', 'Folder permissions tests not supported on Windows.');
+
+ $path = TMP;
+ $Folder = new Folder($path);
+
+ $subdir = 'test_folder_new';
+ $new = TMP . $subdir;
+
+ $this->assertTrue($Folder->create($new));
+ $this->assertTrue($Folder->create($new . DS . 'test1'));
+ $this->assertTrue($Folder->create($new . DS . 'test2'));
+
+ $filePath = $new . DS . 'test1.php';
+ $File = new File($filePath);
+ $this->assertTrue($File->create());
+
+ $filePath = $new . DS . 'skip_me.php';
+ $File = new File($filePath);
+ $this->assertTrue($File->create());
+
+ $this->assertTrue($Folder->chmod($new, 0755, true));
+ $perms = substr(sprintf('%o', fileperms($new . DS . 'test2')), -4);
+ $this->assertEquals('0755', $perms);
+
+ $this->assertTrue($Folder->chmod($new, 0744, true, array('skip_me.php', 'test2')));
+
+ $perms = substr(sprintf('%o', fileperms($new . DS . 'test2')), -4);
+ $this->assertEquals('0755', $perms);
+
+ $perms = substr(sprintf('%o', fileperms($new . DS . 'test1')), -4);
+ $this->assertEquals('0744', $perms);
+
+ $Folder->delete($new);
+ }
+
+/**
+ * testRealPathForWebroot method
+ *
+ * @return void
+ */
+ public function testRealPathForWebroot() {
+ $Folder = new Folder('files/');
+ $this->assertEquals(realpath('files/'), $Folder->path);
+ }
+
+/**
+ * testZeroAsDirectory method
+ *
+ * @return void
+ */
+ public function testZeroAsDirectory() {
+ $Folder = new Folder(TMP);
+ $new = TMP . '0';
+ $this->assertTrue($Folder->create($new));
+
+ $result = $Folder->read(true, true);
+ $expected = array('0', 'cache', 'logs', 'sessions', 'tests');
+ $this->assertEquals($expected, $result[0]);
+
+ $result = $Folder->read(true, array('logs'));
+ $expected = array('0', 'cache', 'sessions', 'tests');
+ $this->assertEquals($expected, $result[0]);
+
+ $result = $Folder->delete($new);
+ $this->assertTrue($result);
+ }
+
+/**
+ * test Adding path elements to a path
+ *
+ * @return void
+ */
+ public function testAddPathElement() {
+ $result = Folder::addPathElement(DS . 'some' . DS . 'dir', 'another_path');
+ $this->assertEquals(DS . 'some' . DS . 'dir' . DS . 'another_path', $result);
+
+ $result = Folder::addPathElement(DS . 'some' . DS . 'dir' . DS, 'another_path');
+ $this->assertEquals(DS . 'some' . DS . 'dir' . DS . 'another_path', $result);
+ }
+
+/**
+ * testFolderRead method
+ *
+ * @return void
+ */
+ public function testFolderRead() {
+ $Folder = new Folder(TMP);
+
+ $expected = array('cache', 'logs', 'sessions', 'tests');
+ $result = $Folder->read(true, true);
+ $this->assertEquals($expected, $result[0]);
+
+ $Folder->path = TMP . 'non-existent';
+ $expected = array(array(), array());
+ $result = $Folder->read(true, true);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFolderReadWithHiddenFiles method
+ *
+ * @return void
+ */
+ public function testFolderReadWithHiddenFiles() {
+ $this->skipIf(!is_writeable(TMP), 'Cant test Folder::read with hidden files unless the tmp folder is writable.');
+
+ $Folder = new Folder(TMP . 'folder_tree_hidden', true, 0777);
+ mkdir($Folder->path . DS . '.svn');
+ mkdir($Folder->path . DS . 'some_folder');
+ touch($Folder->path . DS . 'not_hidden.txt');
+ touch($Folder->path . DS . '.hidden.txt');
+
+ $expected = array(
+ array('some_folder'),
+ array('not_hidden.txt'),
+ );
+ $result = $Folder->read(true, true);
+ $this->assertEquals($expected, $result);
+
+ $expected = array(
+ array(
+ '.svn',
+ 'some_folder'
+ ),
+ array(
+ '.hidden.txt',
+ 'not_hidden.txt'
+ ),
+ );
+ $result = $Folder->read(true);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFolderTree method
+ *
+ * @return void
+ */
+ public function testFolderTree() {
+ $Folder = new Folder();
+ $expected = array(
+ array(
+ CAKE . 'Config',
+ CAKE . 'Config' . DS . 'unicode',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding'
+ ),
+ array(
+ CAKE . 'Config' . DS . 'config.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0080_00ff.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0100_017f.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0180_024F.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0250_02af.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0370_03ff.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0400_04ff.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0500_052f.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '0530_058f.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '1e00_1eff.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '1f00_1fff.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '2100_214f.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '2150_218f.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '2460_24ff.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '2c00_2c5f.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '2c60_2c7f.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . '2c80_2cff.php',
+ CAKE . 'Config' . DS . 'unicode' . DS . 'casefolding' . DS . 'ff00_ffef.php'
+ )
+ );
+
+ $result = $Folder->tree(CAKE . 'Config', false);
+ $this->assertSame(array(), array_diff($expected[0], $result[0]));
+ $this->assertSame(array(), array_diff($result[0], $expected[0]));
+
+ $result = $Folder->tree(CAKE . 'Config', false, 'dir');
+ $this->assertSame(array(), array_diff($expected[0], $result));
+ $this->assertSame(array(), array_diff($expected[0], $result));
+
+ $result = $Folder->tree(CAKE . 'Config', false, 'files');
+ $this->assertSame(array(), array_diff($expected[1], $result));
+ $this->assertSame(array(), array_diff($expected[1], $result));
+ }
+
+/**
+ * testFolderTreeWithHiddenFiles method
+ *
+ * @return void
+ */
+ public function testFolderTreeWithHiddenFiles() {
+ $this->skipIf(!is_writeable(TMP), 'Can\'t test Folder::tree with hidden files unless the tmp folder is writable.');
+
+ $Folder = new Folder(TMP . 'folder_tree_hidden', true, 0777);
+ mkdir($Folder->path . DS . '.svn', 0777, true);
+ touch($Folder->path . DS . '.svn' . DS . 'InHiddenFolder.php');
+ mkdir($Folder->path . DS . '.svn' . DS . 'inhiddenfolder');
+ touch($Folder->path . DS . '.svn' . DS . 'inhiddenfolder' . DS . 'NestedInHiddenFolder.php');
+ touch($Folder->path . DS . 'not_hidden.txt');
+ touch($Folder->path . DS . '.hidden.txt');
+ mkdir($Folder->path . DS . 'visible_folder' . DS . '.git', 0777, true);
+
+ $expected = array(
+ array(
+ $Folder->path,
+ $Folder->path . DS . 'visible_folder',
+ ),
+ array(
+ $Folder->path . DS . 'not_hidden.txt',
+ ),
+ );
+
+ $result = $Folder->tree(null, true);
+ $this->assertEquals($expected, $result);
+
+ $result = $Folder->tree(null, array('.'));
+ $this->assertEquals($expected, $result);
+
+ $expected = array(
+ array(
+ $Folder->path,
+ $Folder->path . DS . 'visible_folder',
+ $Folder->path . DS . 'visible_folder' . DS . '.git',
+ $Folder->path . DS . '.svn',
+ $Folder->path . DS . '.svn' . DS . 'inhiddenfolder',
+ ),
+ array(
+ $Folder->path . DS . 'not_hidden.txt',
+ $Folder->path . DS . '.hidden.txt',
+ $Folder->path . DS . '.svn' . DS . 'inhiddenfolder' . DS . 'NestedInHiddenFolder.php',
+ $Folder->path . DS . '.svn' . DS . 'InHiddenFolder.php',
+ ),
+ );
+
+ $result = $Folder->tree(null, false);
+ sort($result[0]);
+ sort($expected[0]);
+ sort($result[1]);
+ sort($expected[1]);
+ $this->assertEquals($expected, $result);
+
+ $Folder->delete();
+ }
+
+/**
+ * testWindowsPath method
+ *
+ * @return void
+ */
+ public function testWindowsPath() {
+ $this->assertFalse(Folder::isWindowsPath('0:\\cake\\is\\awesome'));
+ $this->assertTrue(Folder::isWindowsPath('C:\\cake\\is\\awesome'));
+ $this->assertTrue(Folder::isWindowsPath('d:\\cake\\is\\awesome'));
+ $this->assertTrue(Folder::isWindowsPath('\\\\vmware-host\\Shared Folders\\file'));
+ }
+
+/**
+ * testIsAbsolute method
+ *
+ * @return void
+ */
+ public function testIsAbsolute() {
+ $this->assertFalse(Folder::isAbsolute('path/to/file'));
+ $this->assertFalse(Folder::isAbsolute('cake/'));
+ $this->assertFalse(Folder::isAbsolute('path\\to\\file'));
+ $this->assertFalse(Folder::isAbsolute('0:\\path\\to\\file'));
+ $this->assertFalse(Folder::isAbsolute('\\path/to/file'));
+ $this->assertFalse(Folder::isAbsolute('\\path\\to\\file'));
+
+ $this->assertTrue(Folder::isAbsolute('/usr/local'));
+ $this->assertTrue(Folder::isAbsolute('//path/to/file'));
+ $this->assertTrue(Folder::isAbsolute('C:\\cake'));
+ $this->assertTrue(Folder::isAbsolute('C:\\path\\to\\file'));
+ $this->assertTrue(Folder::isAbsolute('d:\\path\\to\\file'));
+ $this->assertTrue(Folder::isAbsolute('\\\\vmware-host\\Shared Folders\\file'));
+ }
+
+/**
+ * testIsSlashTerm method
+ *
+ * @return void
+ */
+ public function testIsSlashTerm() {
+ $this->assertFalse(Folder::isSlashTerm('cake'));
+
+ $this->assertTrue(Folder::isSlashTerm('C:\\cake\\'));
+ $this->assertTrue(Folder::isSlashTerm('/usr/local/'));
+ }
+
+/**
+ * testStatic method
+ *
+ * @return void
+ */
+ public function testSlashTerm() {
+ $result = Folder::slashTerm('/path/to/file');
+ $this->assertEquals('/path/to/file/', $result);
+ }
+
+/**
+ * testNormalizePath method
+ *
+ * @return void
+ */
+ public function testNormalizePath() {
+ $path = '/path/to/file';
+ $result = Folder::normalizePath($path);
+ $this->assertEquals('/', $result);
+
+ $path = '\\path\\\to\\\file';
+ $result = Folder::normalizePath($path);
+ $this->assertEquals('/', $result);
+
+ $path = 'C:\\path\\to\\file';
+ $result = Folder::normalizePath($path);
+ $this->assertEquals('\\', $result);
+ }
+
+/**
+ * correctSlashFor method
+ *
+ * @return void
+ */
+ public function testCorrectSlashFor() {
+ $path = '/path/to/file';
+ $result = Folder::correctSlashFor($path);
+ $this->assertEquals('/', $result);
+
+ $path = '\\path\\to\\file';
+ $result = Folder::correctSlashFor($path);
+ $this->assertEquals('/', $result);
+
+ $path = 'C:\\path\to\\file';
+ $result = Folder::correctSlashFor($path);
+ $this->assertEquals('\\', $result);
+ }
+
+/**
+ * testInCakePath method
+ *
+ * @return void
+ */
+ public function testInCakePath() {
+ $Folder = new Folder();
+ $Folder->cd(ROOT);
+ $path = 'C:\\path\\to\\file';
+ $result = $Folder->inCakePath($path);
+ $this->assertFalse($result);
+
+ $path = ROOT;
+ $Folder->cd(ROOT);
+ $result = $Folder->inCakePath($path);
+ $this->assertFalse($result);
+
+ $path = DS . 'lib' . DS . 'Cake' . DS . 'Config';
+ $Folder->cd(ROOT . DS . 'lib' . DS . 'Cake' . DS . 'Config');
+ $result = $Folder->inCakePath($path);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testFind method
+ *
+ * @return void
+ */
+ public function testFind() {
+ $Folder = new Folder();
+ $Folder->cd(CAKE . 'Config');
+ $result = $Folder->find();
+ $expected = array('config.php');
+ $this->assertSame(array_diff($expected, $result), array());
+ $this->assertSame(array_diff($expected, $result), array());
+
+ $result = $Folder->find('.*', true);
+ $expected = array('config.php', 'routes.php');
+ $this->assertSame($expected, $result);
+
+ $result = $Folder->find('.*\.php');
+ $expected = array('config.php');
+ $this->assertSame(array_diff($expected, $result), array());
+ $this->assertSame(array_diff($expected, $result), array());
+
+ $result = $Folder->find('.*\.php', true);
+ $expected = array('config.php', 'routes.php');
+ $this->assertSame($expected, $result);
+
+ $result = $Folder->find('.*ig\.php');
+ $expected = array('config.php');
+ $this->assertSame($expected, $result);
+
+ $result = $Folder->find('config\.php');
+ $expected = array('config.php');
+ $this->assertSame($expected, $result);
+
+ $Folder->cd(TMP);
+ $File = new File($Folder->pwd() . DS . 'paths.php', true);
+ $Folder->create($Folder->pwd() . DS . 'testme');
+ $Folder->cd('testme');
+ $result = $Folder->find('paths\.php');
+ $expected = array();
+ $this->assertSame($expected, $result);
+
+ $Folder->cd($Folder->pwd() . '/..');
+ $result = $Folder->find('paths\.php');
+ $expected = array('paths.php');
+ $this->assertSame($expected, $result);
+
+ $Folder->cd(TMP);
+ $Folder->delete($Folder->pwd() . DS . 'testme');
+ $File->delete();
+ }
+
+/**
+ * testFindRecursive method
+ *
+ * @return void
+ */
+ public function testFindRecursive() {
+ $Folder = new Folder();
+ $Folder->cd(CAKE);
+ $result = $Folder->findRecursive('(config|paths)\.php');
+ $expected = array(
+ CAKE . 'Config' . DS . 'config.php'
+ );
+ $this->assertSame(array_diff($expected, $result), array());
+ $this->assertSame(array_diff($expected, $result), array());
+
+ $result = $Folder->findRecursive('(config|paths)\.php', true);
+ $expected = array(
+ CAKE . 'Config' . DS . 'config.php'
+ );
+ $this->assertSame($expected, $result);
+
+ $Folder->cd(TMP);
+ $Folder->create($Folder->pwd() . DS . 'testme');
+ $Folder->cd('testme');
+ $File = new File($Folder->pwd() . DS . 'paths.php');
+ $File->create();
+ $Folder->cd(TMP . 'sessions');
+ $result = $Folder->findRecursive('paths\.php');
+ $expected = array();
+ $this->assertSame($expected, $result);
+
+ $Folder->cd(TMP . 'testme');
+ $File = new File($Folder->pwd() . DS . 'my.php');
+ $File->create();
+ $Folder->cd($Folder->pwd() . '/../..');
+
+ $result = $Folder->findRecursive('(paths|my)\.php');
+ $expected = array(
+ TMP . 'testme' . DS . 'my.php',
+ TMP . 'testme' . DS . 'paths.php'
+ );
+ $this->assertSame(array_diff($expected, $result), array());
+ $this->assertSame(array_diff($expected, $result), array());
+
+ $result = $Folder->findRecursive('(paths|my)\.php', true);
+ $expected = array(
+ TMP . 'testme' . DS . 'my.php',
+ TMP . 'testme' . DS . 'paths.php'
+ );
+ $this->assertSame($expected, $result);
+
+ $Folder->cd(CAKE . 'Config');
+ $Folder->cd(TMP);
+ $Folder->delete($Folder->pwd() . DS . 'testme');
+ $File->delete();
+ }
+
+/**
+ * testConstructWithNonExistentPath method
+ *
+ * @return void
+ */
+ public function testConstructWithNonExistentPath() {
+ $Folder = new Folder(TMP . 'config_non_existent', true);
+ $this->assertTrue(is_dir(TMP . 'config_non_existent'));
+ $Folder->cd(TMP);
+ $Folder->delete($Folder->pwd() . 'config_non_existent');
+ }
+
+/**
+ * testDirSize method
+ *
+ * @return void
+ */
+ public function testDirSize() {
+ $Folder = new Folder(TMP . 'config_non_existent', true);
+ $this->assertEquals(0, $Folder->dirSize());
+
+ $File = new File($Folder->pwd() . DS . 'my.php', true, 0777);
+ $File->create();
+ $File->write('something here');
+ $File->close();
+ $this->assertEquals(14, $Folder->dirSize());
+
+ $Folder->cd(TMP);
+ $Folder->delete($Folder->pwd() . 'config_non_existent');
+ }
+
+/**
+ * testDelete method
+ *
+ * @return void
+ */
+ public function testDelete() {
+ $path = TMP . 'folder_delete_test';
+ mkdir($path);
+ touch($path . DS . 'file_1');
+ mkdir($path . DS . 'level_1_1');
+ touch($path . DS . 'level_1_1' . DS . 'file_1_1');
+ mkdir($path . DS . 'level_1_1' . DS . 'level_2_1');
+ touch($path . DS . 'level_1_1' . DS . 'level_2_1' . DS . 'file_2_1');
+ touch($path . DS . 'level_1_1' . DS . 'level_2_1' . DS . 'file_2_2');
+ mkdir($path . DS . 'level_1_1' . DS . 'level_2_2');
+
+ $Folder = new Folder($path, true);
+ $return = $Folder->delete();
+ $this->assertTrue($return);
+
+ $messages = $Folder->messages();
+ $errors = $Folder->errors();
+ $this->assertEquals(array(), $errors);
+
+ $expected = array(
+ $path . DS . 'file_1 removed',
+ $path . DS . 'level_1_1' . DS . 'file_1_1 removed',
+ $path . DS . 'level_1_1' . DS . 'level_2_1' . DS . 'file_2_1 removed',
+ $path . DS . 'level_1_1' . DS . 'level_2_1' . DS . 'file_2_2 removed',
+ $path . DS . 'level_1_1' . DS . 'level_2_1 removed',
+ $path . DS . 'level_1_1' . DS . 'level_2_2 removed',
+ $path . DS . 'level_1_1 removed',
+ $path . ' removed'
+ );
+ sort($expected);
+ sort($messages);
+ $this->assertEquals($expected, $messages);
+ }
+
+/**
+ * testCopy method
+ *
+ * Verify that directories and files are copied recursively
+ * even if the destination directory already exists.
+ * Subdirectories existing in both destination and source directory
+ * are skipped and not merged or overwritten.
+ *
+ * @return void
+ */
+ public function testCopy() {
+ $path = TMP . 'folder_test';
+ $folderOne = $path . DS . 'folder1';
+ $folderTwo = $folderOne . DS . 'folder2';
+ $folderThree = $path . DS . 'folder3';
+ $fileOne = $folderOne . DS . 'file1.php';
+ $fileTwo = $folderTwo . DS . 'file2.php';
+
+ new Folder($path, true);
+ new Folder($folderOne, true);
+ new Folder($folderTwo, true);
+ new Folder($folderThree, true);
+ touch($fileOne);
+ touch($fileTwo);
+
+ $Folder = new Folder($folderOne);
+ $result = $Folder->copy($folderThree);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
+ $this->assertTrue(file_exists($folderThree . DS . 'folder2' . DS . 'file2.php'));
+
+ $Folder = new Folder($folderThree);
+ $Folder->delete();
+
+ $Folder = new Folder($folderOne);
+ $result = $Folder->copy($folderThree);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
+ $this->assertTrue(file_exists($folderThree . DS . 'folder2' . DS . 'file2.php'));
+
+ $Folder = new Folder($folderThree);
+ $Folder->delete();
+
+ new Folder($folderThree, true);
+ new Folder($folderThree . DS . 'folder2', true);
+ file_put_contents($folderThree . DS . 'folder2' . DS . 'file2.php', 'untouched');
+
+ $Folder = new Folder($folderOne);
+ $result = $Folder->copy($folderThree);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
+ $this->assertEquals('untouched', file_get_contents($folderThree . DS . 'folder2' . DS . 'file2.php'));
+
+ $Folder = new Folder($path);
+ $Folder->delete();
+ }
+
+/**
+ * testMove method
+ *
+ * Verify that directories and files are moved recursively
+ * even if the destination directory already exists.
+ * Subdirectories existing in both destination and source directory
+ * are skipped and not merged or overwritten.
+ *
+ * @return void
+ */
+ public function testMove() {
+ $path = TMP . 'folder_test';
+ $folderOne = $path . DS . 'folder1';
+ $folderTwo = $folderOne . DS . 'folder2';
+ $folderThree = $path . DS . 'folder3';
+ $fileOne = $folderOne . DS . 'file1.php';
+ $fileTwo = $folderTwo . DS . 'file2.php';
+
+ new Folder($path, true);
+ new Folder($folderOne, true);
+ new Folder($folderTwo, true);
+ new Folder($folderThree, true);
+ touch($fileOne);
+ touch($fileTwo);
+
+ $Folder = new Folder($folderOne);
+ $result = $Folder->move($folderThree);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
+ $this->assertTrue(is_dir($folderThree . DS . 'folder2'));
+ $this->assertTrue(file_exists($folderThree . DS . 'folder2' . DS . 'file2.php'));
+ $this->assertFalse(file_exists($fileOne));
+ $this->assertFalse(file_exists($folderTwo));
+ $this->assertFalse(file_exists($fileTwo));
+
+ $Folder = new Folder($folderThree);
+ $Folder->delete();
+
+ new Folder($folderOne, true);
+ new Folder($folderTwo, true);
+ touch($fileOne);
+ touch($fileTwo);
+
+ $Folder = new Folder($folderOne);
+ $result = $Folder->move($folderThree);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
+ $this->assertTrue(is_dir($folderThree . DS . 'folder2'));
+ $this->assertTrue(file_exists($folderThree . DS . 'folder2' . DS . 'file2.php'));
+ $this->assertFalse(file_exists($fileOne));
+ $this->assertFalse(file_exists($folderTwo));
+ $this->assertFalse(file_exists($fileTwo));
+
+ $Folder = new Folder($folderThree);
+ $Folder->delete();
+
+ new Folder($folderOne, true);
+ new Folder($folderTwo, true);
+ new Folder($folderThree, true);
+ new Folder($folderThree . DS . 'folder2', true);
+ touch($fileOne);
+ touch($fileTwo);
+ file_put_contents($folderThree . DS . 'folder2' . DS . 'file2.php', 'untouched');
+
+ $Folder = new Folder($folderOne);
+ $result = $Folder->move($folderThree);
+ $this->assertTrue($result);
+ $this->assertTrue(file_exists($folderThree . DS . 'file1.php'));
+ $this->assertEquals('untouched', file_get_contents($folderThree . DS . 'folder2' . DS . 'file2.php'));
+ $this->assertFalse(file_exists($fileOne));
+ $this->assertFalse(file_exists($folderTwo));
+ $this->assertFalse(file_exists($fileTwo));
+
+ $Folder = new Folder($path);
+ $Folder->delete();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/HashTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/HashTest.php
new file mode 100644
index 0000000..40fcd7b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/HashTest.php
@@ -0,0 +1,2151 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Hash', 'Utility');
+
+class HashTest extends CakeTestCase {
+
+ public static function articleData() {
+ return array(
+ array(
+ 'Article' => array(
+ 'id' => '1',
+ 'user_id' => '1',
+ 'title' => 'First Article',
+ 'body' => 'First Article Body'
+ ),
+ 'User' => array(
+ 'id' => '1',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => '1',
+ 'article_id' => '1',
+ 'user_id' => '2',
+ 'comment' => 'First Comment for First Article',
+ ),
+ array(
+ 'id' => '2',
+ 'article_id' => '1',
+ 'user_id' => '4',
+ 'comment' => 'Second Comment for First Article',
+ ),
+ ),
+ 'Tag' => array(
+ array(
+ 'id' => '1',
+ 'tag' => 'tag1',
+ ),
+ array(
+ 'id' => '2',
+ 'tag' => 'tag2',
+ )
+ ),
+ 'Deep' => array(
+ 'Nesting' => array(
+ 'test' => array(
+ 1 => 'foo',
+ 2 => array(
+ 'and' => array('more' => 'stuff')
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => '2',
+ 'user_id' => '1',
+ 'title' => 'Second Article',
+ 'body' => 'Second Article Body',
+ 'published' => 'Y',
+ ),
+ 'User' => array(
+ 'id' => '2',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ ),
+ array(
+ 'Article' => array(
+ 'id' => '3',
+ 'user_id' => '1',
+ 'title' => 'Third Article',
+ 'body' => 'Third Article Body',
+ ),
+ 'User' => array(
+ 'id' => '3',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ ),
+ array(
+ 'Article' => array(
+ 'id' => '4',
+ 'user_id' => '1',
+ 'title' => 'Fourth Article',
+ 'body' => 'Fourth Article Body',
+ ),
+ 'User' => array(
+ 'id' => '4',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ ),
+ array(
+ 'Article' => array(
+ 'id' => '5',
+ 'user_id' => '1',
+ 'title' => 'Fifth Article',
+ 'body' => 'Fifth Article Body',
+ ),
+ 'User' => array(
+ 'id' => '5',
+ 'user' => 'mariano',
+ 'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+ ),
+ 'Comment' => array(),
+ 'Tag' => array()
+ )
+ );
+ }
+
+ public static function userData() {
+ return array(
+ array(
+ 'User' => array(
+ 'id' => 2,
+ 'group_id' => 1,
+ 'Data' => array(
+ 'user' => 'mariano.iglesias',
+ 'name' => 'Mariano Iglesias'
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 14,
+ 'group_id' => 2,
+ 'Data' => array(
+ 'user' => 'phpnut',
+ 'name' => 'Larry E. Masters'
+ )
+ )
+ ),
+ array(
+ 'User' => array(
+ 'id' => 25,
+ 'group_id' => 1,
+ 'Data' => array(
+ 'user' => 'gwoo',
+ 'name' => 'The Gwoo'
+ )
+ )
+ )
+ );
+ }
+
+/**
+ * Test get()
+ *
+ * return void
+ */
+ public function testGet() {
+ $data = self::articleData();
+
+ $result = Hash::get(array(), '1.Article.title');
+ $this->assertNull($result);
+
+ $result = Hash::get($data, '');
+ $this->assertNull($result);
+
+ $result = Hash::get($data, '0.Article.title');
+ $this->assertEquals('First Article', $result);
+
+ $result = Hash::get($data, '1.Article.title');
+ $this->assertEquals('Second Article', $result);
+
+ $result = Hash::get($data, '5.Article.title');
+ $this->assertNull($result);
+
+ $result = Hash::get($data, '1.Article.title.not_there');
+ $this->assertNull($result);
+
+ $result = Hash::get($data, '1.Article');
+ $this->assertEquals($data[1]['Article'], $result);
+
+ $result = Hash::get($data, array('1', 'Article'));
+ $this->assertEquals($data[1]['Article'], $result);
+ }
+
+/**
+ * Test dimensions.
+ *
+ * @return void
+ */
+ public function testDimensions() {
+ $result = Hash::dimensions(array());
+ $this->assertEquals($result, 0);
+
+ $data = array('one', '2', 'three');
+ $result = Hash::dimensions($data);
+ $this->assertEquals($result, 1);
+
+ $data = array('1' => '1.1', '2', '3');
+ $result = Hash::dimensions($data);
+ $this->assertEquals($result, 1);
+
+ $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1'));
+ $result = Hash::dimensions($data);
+ $this->assertEquals($result, 2);
+
+ $data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
+ $result = Hash::dimensions($data);
+ $this->assertEquals($result, 1);
+
+ $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Hash::dimensions($data);
+ $this->assertEquals($result, 2);
+ }
+
+/**
+ * Test maxDimensions
+ *
+ * @return void
+ */
+ public function testMaxDimensions() {
+ $data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
+ $result = Hash::maxDimensions($data);
+ $this->assertEquals($result, 2);
+
+ $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Hash::maxDimensions($data);
+ $this->assertEquals($result, 3);
+
+ $data = array(
+ '1' => array('1.1' => '1.1.1'),
+ array('2' => array('2.1' => array('2.1.1' => '2.1.1.1'))),
+ '3' => array('3.1' => array('3.1.1' => '3.1.1.1'))
+ );
+ $result = Hash::maxDimensions($data);
+ $this->assertEquals($result, 4);
+
+ $data = array(
+ '1' => array('1.1' => '1.1.1'),
+ array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1')))),
+ '3' => array('3.1' => array('3.1.1' => '3.1.1.1'))
+ );
+ $result = Hash::maxDimensions($data);
+ $this->assertEquals($result, 5);
+
+ $data = array(
+ '1' => array('1.1' => '1.1.1'),
+ array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))),
+ '3' => array('3.1' => array('3.1.1' => '3.1.1.1'))
+ );
+ $result = Hash::maxDimensions($data);
+ $this->assertEquals($result, 5);
+
+ $data = array(
+ '1' => array('1.1' => '1.1.1'),
+ array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))),
+ '3' => array('3.1' => array('3.1.1' => '3.1.1.1'))
+ );
+ $result = Hash::maxDimensions($data);
+ $this->assertEquals($result, 5);
+ }
+
+/**
+ * Tests Hash::flatten
+ *
+ * @return void
+ */
+ public function testFlatten() {
+ $data = array('Larry', 'Curly', 'Moe');
+ $result = Hash::flatten($data);
+ $this->assertEquals($result, $data);
+
+ $data[9] = 'Shemp';
+ $result = Hash::flatten($data);
+ $this->assertEquals($result, $data);
+
+ $data = array(
+ array(
+ 'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post'),
+ 'Author' => array('id' => '1', 'user' => 'nate', 'password' => 'foo'),
+ ),
+ array(
+ 'Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Second Post', 'body' => 'Second Post Body'),
+ 'Author' => array('id' => '3', 'user' => 'larry', 'password' => null),
+ )
+ );
+
+ $result = Hash::flatten($data);
+ $expected = array(
+ '0.Post.id' => '1',
+ '0.Post.author_id' => '1',
+ '0.Post.title' => 'First Post',
+ '0.Author.id' => '1',
+ '0.Author.user' => 'nate',
+ '0.Author.password' => 'foo',
+ '1.Post.id' => '2',
+ '1.Post.author_id' => '3',
+ '1.Post.title' => 'Second Post',
+ '1.Post.body' => 'Second Post Body',
+ '1.Author.id' => '3',
+ '1.Author.user' => 'larry',
+ '1.Author.password' => null
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ array('Post' => array('id' => 1)),
+ array('Post' => array('id' => 2)),
+ );
+ $result = Hash::flatten($data, '/');
+ $expected = array(
+ '0/Post/id' => '1',
+ '1/Post/id' => '2',
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test diff();
+ *
+ * @return void
+ */
+ public function testDiff() {
+ $a = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about')
+ );
+ $b = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about'),
+ 2 => array('name' => 'contact')
+ );
+
+ $result = Hash::diff($a, array());
+ $expected = $a;
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::diff(array(), $b);
+ $expected = $b;
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::diff($a, $b);
+ $expected = array(
+ 2 => array('name' => 'contact')
+ );
+ $this->assertEquals($expected, $result);
+
+ $b = array(
+ 0 => array('name' => 'me'),
+ 1 => array('name' => 'about')
+ );
+
+ $result = Hash::diff($a, $b);
+ $expected = array(
+ 0 => array('name' => 'main')
+ );
+ $this->assertEquals($expected, $result);
+
+ $a = array();
+ $b = array('name' => 'bob', 'address' => 'home');
+ $result = Hash::diff($a, $b);
+ $this->assertEquals($result, $b);
+
+ $a = array('name' => 'bob', 'address' => 'home');
+ $b = array();
+ $result = Hash::diff($a, $b);
+ $this->assertEquals($result, $a);
+
+ $a = array('key' => true, 'another' => false, 'name' => 'me');
+ $b = array('key' => 1, 'another' => 0);
+ $expected = array('name' => 'me');
+ $result = Hash::diff($a, $b);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array('key' => 'differentValue', 'another' => null);
+ $expected = array('key' => 'value', 'name' => 'me');
+ $result = Hash::diff($a, $b);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array('key' => 'differentValue', 'another' => 'value');
+ $expected = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $result = Hash::diff($a, $b);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array('key' => 'differentValue', 'another' => 'value');
+ $expected = array('key' => 'differentValue', 'another' => 'value', 'name' => 'me');
+ $result = Hash::diff($b, $a);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array(0 => 'differentValue', 1 => 'value');
+ $expected = $a + $b;
+ $result = Hash::diff($a, $b);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test merge()
+ *
+ * @return void
+ */
+ public function testMerge() {
+ $result = Hash::merge(array('foo'), array('bar'));
+ $this->assertEquals($result, array('foo', 'bar'));
+
+ $result = Hash::merge(array('foo'), array('user' => 'bob', 'no-bar'), 'bar');
+ $this->assertEquals($result, array('foo', 'user' => 'bob', 'no-bar', 'bar'));
+
+ $a = array('foo', 'foo2');
+ $b = array('bar', 'bar2');
+ $expected = array('foo', 'foo2', 'bar', 'bar2');
+ $this->assertEquals($expected, Hash::merge($a, $b));
+
+ $a = array('foo' => 'bar', 'bar' => 'foo');
+ $b = array('foo' => 'no-bar', 'bar' => 'no-foo');
+ $expected = array('foo' => 'no-bar', 'bar' => 'no-foo');
+ $this->assertEquals($expected, Hash::merge($a, $b));
+
+ $a = array('users' => array('bob', 'jim'));
+ $b = array('users' => array('lisa', 'tina'));
+ $expected = array('users' => array('bob', 'jim', 'lisa', 'tina'));
+ $this->assertEquals($expected, Hash::merge($a, $b));
+
+ $a = array('users' => array('jim', 'bob'));
+ $b = array('users' => 'none');
+ $expected = array('users' => 'none');
+ $this->assertEquals($expected, Hash::merge($a, $b));
+
+ $a = array('users' => array('lisa' => array('id' => 5, 'pw' => 'secret')), 'cakephp');
+ $b = array('users' => array('lisa' => array('pw' => 'new-pass', 'age' => 23)), 'ice-cream');
+ $expected = array(
+ 'users' => array('lisa' => array('id' => 5, 'pw' => 'new-pass', 'age' => 23)),
+ 'cakephp',
+ 'ice-cream'
+ );
+ $result = Hash::merge($a, $b);
+ $this->assertEquals($expected, $result);
+
+ $c = array(
+ 'users' => array('lisa' => array('pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog')),
+ 'chocolate'
+ );
+ $expected = array(
+ 'users' => array('lisa' => array('id' => 5, 'pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog')),
+ 'cakephp',
+ 'ice-cream',
+ 'chocolate'
+ );
+ $this->assertEquals($expected, Hash::merge($a, $b, $c));
+
+ $this->assertEquals($expected, Hash::merge($a, $b, array(), $c));
+
+ $a = array(
+ 'Tree',
+ 'CounterCache',
+ 'Upload' => array(
+ 'folder' => 'products',
+ 'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')
+ )
+ );
+ $b = array(
+ 'Cacheable' => array('enabled' => false),
+ 'Limit',
+ 'Bindable',
+ 'Validator',
+ 'Transactional'
+ );
+ $expected = array(
+ 'Tree',
+ 'CounterCache',
+ 'Upload' => array(
+ 'folder' => 'products',
+ 'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')
+ ),
+ 'Cacheable' => array('enabled' => false),
+ 'Limit',
+ 'Bindable',
+ 'Validator',
+ 'Transactional'
+ );
+ $this->assertEquals(Hash::merge($a, $b), $expected);
+ }
+
+/**
+ * test normalizing arrays
+ *
+ * @return void
+ */
+ public function testNormalize() {
+ $result = Hash::normalize(array('one', 'two', 'three'));
+ $expected = array('one' => null, 'two' => null, 'three' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::normalize(array('one', 'two', 'three'), false);
+ $expected = array('one', 'two', 'three');
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::normalize(array('one' => 1, 'two' => 2, 'three' => 3, 'four'), false);
+ $expected = array('one' => 1, 'two' => 2, 'three' => 3, 'four' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::normalize(array('one' => 1, 'two' => 2, 'three' => 3, 'four'));
+ $expected = array('one' => 1, 'two' => 2, 'three' => 3, 'four' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::normalize(array('one' => array('a', 'b', 'c' => 'cee'), 'two' => 2, 'three'));
+ $expected = array('one' => array('a', 'b', 'c' => 'cee'), 'two' => 2, 'three' => null);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testContains method
+ *
+ * @return void
+ */
+ public function testContains() {
+ $data = array('apple', 'bee', 'cyclops');
+ $this->assertTrue(Hash::contains($data, array('apple')));
+ $this->assertFalse(Hash::contains($data, array('data')));
+
+ $a = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about')
+ );
+ $b = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about'),
+ 2 => array('name' => 'contact'),
+ 'a' => 'b'
+ );
+
+ $this->assertTrue(Hash::contains($a, $a));
+ $this->assertFalse(Hash::contains($a, $b));
+ $this->assertTrue(Hash::contains($b, $a));
+
+ $a = array(
+ array('User' => array('id' => 1)),
+ array('User' => array('id' => 2)),
+ );
+ $b = array(
+ array('User' => array('id' => 1)),
+ array('User' => array('id' => 2)),
+ array('User' => array('id' => 3))
+ );
+ $this->assertTrue(Hash::contains($b, $a));
+ $this->assertFalse(Hash::contains($a, $b));
+ }
+
+/**
+ * testFilter method
+ *
+ * @return void
+ */
+ public function testFilter() {
+ $result = Hash::filter(array('0', false, true, 0, array('one thing', 'I can tell you', 'is you got to be', false)));
+ $expected = array('0', 2 => true, 3 => 0, 4 => array('one thing', 'I can tell you', 'is you got to be'));
+ $this->assertSame($expected, $result);
+
+ $result = Hash::filter(array(1, array(false)));
+ $expected = array(1);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::filter(array(1, array(false, false)));
+ $expected = array(1);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::filter(array(1, array('empty', false)));
+ $expected = array(1, array('empty'));
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::filter(array(1, array('2', false, array(3, null))));
+ $expected = array(1, array('2', 2 => array(3)));
+ $this->assertEquals($expected, $result);
+
+ $this->assertSame(array(), Hash::filter(array()));
+ }
+
+/**
+ * testNumericArrayCheck method
+ *
+ * @return void
+ */
+ public function testNumeric() {
+ $data = array('one');
+ $this->assertTrue(Hash::numeric(array_keys($data)));
+
+ $data = array(1 => 'one');
+ $this->assertFalse(Hash::numeric($data));
+
+ $data = array('one');
+ $this->assertFalse(Hash::numeric($data));
+
+ $data = array('one' => 'two');
+ $this->assertFalse(Hash::numeric($data));
+
+ $data = array('one' => 1);
+ $this->assertTrue(Hash::numeric($data));
+
+ $data = array(0);
+ $this->assertTrue(Hash::numeric($data));
+
+ $data = array('one', 'two', 'three', 'four', 'five');
+ $this->assertTrue(Hash::numeric(array_keys($data)));
+
+ $data = array(1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
+ $this->assertTrue(Hash::numeric(array_keys($data)));
+
+ $data = array('1' => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
+ $this->assertTrue(Hash::numeric(array_keys($data)));
+
+ $data = array('one', 2 => 'two', 3 => 'three', 4 => 'four', 'a' => 'five');
+ $this->assertFalse(Hash::numeric(array_keys($data)));
+ }
+
+/**
+ * Test simple paths.
+ *
+ * @return void
+ */
+ public function testExtractBasic() {
+ $data = self::articleData();
+
+ $result = Hash::extract($data, '');
+ $this->assertEquals($data, $result);
+
+ $result = Hash::extract($data, '0.Article.title');
+ $this->assertEquals(array('First Article'), $result);
+
+ $result = Hash::extract($data, '1.Article.title');
+ $this->assertEquals(array('Second Article'), $result);
+ }
+
+/**
+ * Test the {n} selector
+ *
+ * @return void
+ */
+ public function testExtractNumericKey() {
+ $data = self::articleData();
+ $result = Hash::extract($data, '{n}.Article.title');
+ $expected = array(
+ 'First Article', 'Second Article',
+ 'Third Article', 'Fourth Article',
+ 'Fifth Article'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($data, '0.Comment.{n}.user_id');
+ $expected = array(
+ '2', '4'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the {n} selector with inconsistent arrays
+ *
+ * @return void
+ */
+ public function testExtractNumericMixedKeys() {
+ $data = array(
+ 'User' => array(
+ 0 => array(
+ 'id' => 4,
+ 'name' => 'Neo'
+ ),
+ 1 => array(
+ 'id' => 5,
+ 'name' => 'Morpheus'
+ ),
+ 'stringKey' => array(
+ 'name' => 'Fail'
+ )
+ )
+ );
+ $result = Hash::extract($data, 'User.{n}.name');
+ $expected = array('Neo', 'Morpheus');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the {n} selector with non-zero based arrays
+ *
+ * @return void
+ */
+ public function testExtractNumericNonZero() {
+ $data = array(
+ 1 => array(
+ 'User' => array(
+ 'id' => 1,
+ 'name' => 'John',
+ )
+ ),
+ 2 => array(
+ 'User' => array(
+ 'id' => 2,
+ 'name' => 'Bob',
+ )
+ ),
+ 3 => array(
+ 'User' => array(
+ 'id' => 3,
+ 'name' => 'Tony',
+ )
+ )
+ );
+ $result = Hash::extract($data, '{n}.User.name');
+ $expected = array('John', 'Bob', 'Tony');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test the {s} selector.
+ *
+ * @return void
+ */
+ public function testExtractStringKey() {
+ $data = self::articleData();
+ $result = Hash::extract($data, '{n}.{s}.user');
+ $expected = array(
+ 'mariano',
+ 'mariano',
+ 'mariano',
+ 'mariano',
+ 'mariano'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($data, '{n}.{s}.Nesting.test.1');
+ $this->assertEquals(array('foo'), $result);
+ }
+
+/**
+ * Test the attribute presense selector.
+ *
+ * @return void
+ */
+ public function testExtractAttributePresence() {
+ $data = self::articleData();
+
+ $result = Hash::extract($data, '{n}.Article[published]');
+ $expected = array($data[1]['Article']);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($data, '{n}.Article[id][published]');
+ $expected = array($data[1]['Article']);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test = and != operators.
+ *
+ * @return void
+ */
+ public function testExtractAttributeEquality() {
+ $data = self::articleData();
+
+ $result = Hash::extract($data, '{n}.Article[id=3]');
+ $expected = array($data[2]['Article']);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::extract($data, '{n}.Article[id = 3]');
+ $expected = array($data[2]['Article']);
+ $this->assertEquals($expected, $result, 'Whitespace should not matter.');
+
+ $result = Hash::extract($data, '{n}.Article[id!=3]');
+ $this->assertEquals(1, $result[0]['id']);
+ $this->assertEquals(2, $result[1]['id']);
+ $this->assertEquals(4, $result[2]['id']);
+ $this->assertEquals(5, $result[3]['id']);
+ }
+
+/**
+ * Test comparison operators.
+ *
+ * @return void
+ */
+ public function testExtractAttributeComparison() {
+ $data = self::articleData();
+
+ $result = Hash::extract($data, '{n}.Comment.{n}[user_id > 2]');
+ $expected = array($data[0]['Comment'][1]);
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(4, $expected[0]['user_id']);
+
+ $result = Hash::extract($data, '{n}.Comment.{n}[user_id >= 4]');
+ $expected = array($data[0]['Comment'][1]);
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(4, $expected[0]['user_id']);
+
+ $result = Hash::extract($data, '{n}.Comment.{n}[user_id < 3]');
+ $expected = array($data[0]['Comment'][0]);
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(2, $expected[0]['user_id']);
+
+ $result = Hash::extract($data, '{n}.Comment.{n}[user_id <= 2]');
+ $expected = array($data[0]['Comment'][0]);
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(2, $expected[0]['user_id']);
+ }
+
+/**
+ * Test multiple attributes with conditions.
+ *
+ * @return void
+ */
+ public function testExtractAttributeMultiple() {
+ $data = self::articleData();
+
+ $result = Hash::extract($data, '{n}.Comment.{n}[user_id > 2][id=1]');
+ $this->assertEmpty($result);
+
+ $result = Hash::extract($data, '{n}.Comment.{n}[user_id > 2][id=2]');
+ $expected = array($data[0]['Comment'][1]);
+ $this->assertEquals($expected, $result);
+ $this->assertEquals(4, $expected[0]['user_id']);
+ }
+
+/**
+ * Test attribute pattern matching.
+ *
+ * @return void
+ */
+ public function testExtractAttributePattern() {
+ $data = self::articleData();
+
+ $result = Hash::extract($data, '{n}.Article[title=/^First/]');
+ $expected = array($data[0]['Article']);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that extract() + matching can hit null things.
+ */
+ public function testExtractMatchesNull() {
+ $data = array(
+ 'Country' => array(
+ array('name' => 'Canada'),
+ array('name' => 'Australia'),
+ array('name' => null),
+ )
+ );
+ $result = Hash::extract($data, 'Country.{n}[name=/Canada|^$/]');
+ $expected = array(
+ array(
+ 'name' => 'Canada',
+ ),
+ array(
+ 'name' => null,
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that uneven keys are handled correctly.
+ *
+ * @return void
+ */
+ public function testExtractUnevenKeys() {
+ $data = array(
+ 'Level1' => array(
+ 'Level2' => array('test1', 'test2'),
+ 'Level2bis' => array('test3', 'test4')
+ )
+ );
+ $this->assertEquals(
+ array('test1', 'test2'),
+ Hash::extract($data, 'Level1.Level2')
+ );
+ $this->assertEquals(
+ array('test3', 'test4'),
+ Hash::extract($data, 'Level1.Level2bis')
+ );
+
+ $data = array(
+ 'Level1' => array(
+ 'Level2bis' => array(
+ array('test3', 'test4'),
+ array('test5', 'test6')
+ )
+ )
+ );
+ $expected = array(
+ array('test3', 'test4'),
+ array('test5', 'test6')
+ );
+ $this->assertEquals($expected, Hash::extract($data, 'Level1.Level2bis'));
+
+ $data['Level1']['Level2'] = array('test1', 'test2');
+ $this->assertEquals($expected, Hash::extract($data, 'Level1.Level2bis'));
+ }
+
+/**
+ * testSort method
+ *
+ * @return void
+ */
+ public function testSort() {
+ $a = array(
+ 0 => array(
+ 'Person' => array('name' => 'Jeff'),
+ 'Friend' => array(array('name' => 'Nate'))
+ ),
+ 1 => array(
+ 'Person' => array('name' => 'Tracy'),
+ 'Friend' => array(array('name' => 'Lindsay'))
+ )
+ );
+ $b = array(
+ 0 => array(
+ 'Person' => array('name' => 'Tracy'),
+ 'Friend' => array(array('name' => 'Lindsay'))
+ ),
+ 1 => array(
+ 'Person' => array('name' => 'Jeff'),
+ 'Friend' => array(array('name' => 'Nate'))
+ )
+ );
+ $a = Hash::sort($a, '{n}.Friend.{n}.name', 'asc');
+ $this->assertEquals($a, $b);
+
+ $b = array(
+ 0 => array(
+ 'Person' => array('name' => 'Jeff'),
+ 'Friend' => array(array('name' => 'Nate'))
+ ),
+ 1 => array(
+ 'Person' => array('name' => 'Tracy'),
+ 'Friend' => array(array('name' => 'Lindsay'))
+ )
+ );
+ $a = array(
+ 0 => array(
+ 'Person' => array('name' => 'Tracy'),
+ 'Friend' => array(array('name' => 'Lindsay'))
+ ),
+ 1 => array(
+ 'Person' => array('name' => 'Jeff'),
+ 'Friend' => array(array('name' => 'Nate'))
+ )
+ );
+ $a = Hash::sort($a, '{n}.Friend.{n}.name', 'desc');
+ $this->assertEquals($a, $b);
+
+ $a = array(
+ 0 => array(
+ 'Person' => array('name' => 'Jeff'),
+ 'Friend' => array(array('name' => 'Nate'))
+ ),
+ 1 => array(
+ 'Person' => array('name' => 'Tracy'),
+ 'Friend' => array(array('name' => 'Lindsay'))
+ ),
+ 2 => array(
+ 'Person' => array('name' => 'Adam'),
+ 'Friend' => array(array('name' => 'Bob'))
+ )
+ );
+ $b = array(
+ 0 => array(
+ 'Person' => array('name' => 'Adam'),
+ 'Friend' => array(array('name' => 'Bob'))
+ ),
+ 1 => array(
+ 'Person' => array('name' => 'Jeff'),
+ 'Friend' => array(array('name' => 'Nate'))
+ ),
+ 2 => array(
+ 'Person' => array('name' => 'Tracy'),
+ 'Friend' => array(array('name' => 'Lindsay'))
+ )
+ );
+ $a = Hash::sort($a, '{n}.Person.name', 'asc');
+ $this->assertEquals($a, $b);
+
+ $a = array(
+ 0 => array('Person' => array('name' => 'Jeff')),
+ 1 => array('Shirt' => array('color' => 'black'))
+ );
+ $b = array(
+ 0 => array('Shirt' => array('color' => 'black')),
+ 1 => array('Person' => array('name' => 'Jeff')),
+ );
+ $a = Hash::sort($a, '{n}.Person.name', 'ASC', 'STRING');
+ $this->assertEquals($a, $b);
+
+ $names = array(
+ array('employees' => array(
+ array('name' => array('first' => 'John', 'last' => 'Doe')))
+ ),
+ array('employees' => array(
+ array('name' => array('first' => 'Jane', 'last' => 'Doe')))
+ ),
+ array('employees' => array(array('name' => array()))),
+ array('employees' => array(array('name' => array())))
+ );
+ $result = Hash::sort($names, '{n}.employees.0.name', 'asc');
+ $expected = array(
+ array('employees' => array(
+ array('name' => array('first' => 'John', 'last' => 'Doe')))
+ ),
+ array('employees' => array(
+ array('name' => array('first' => 'Jane', 'last' => 'Doe')))
+ ),
+ array('employees' => array(array('name' => array()))),
+ array('employees' => array(array('name' => array())))
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test sort() with numeric option.
+ *
+ * @return void
+ */
+ public function testSortNumeric() {
+ $items = array(
+ array('Item' => array('price' => '155,000')),
+ array('Item' => array('price' => '139,000')),
+ array('Item' => array('price' => '275,622')),
+ array('Item' => array('price' => '230,888')),
+ array('Item' => array('price' => '66,000')),
+ );
+ $result = Hash::sort($items, '{n}.Item.price', 'asc', 'numeric');
+ $expected = array(
+ array('Item' => array('price' => '66,000')),
+ array('Item' => array('price' => '139,000')),
+ array('Item' => array('price' => '155,000')),
+ array('Item' => array('price' => '230,888')),
+ array('Item' => array('price' => '275,622')),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::sort($items, '{n}.Item.price', 'desc', 'numeric');
+ $expected = array(
+ array('Item' => array('price' => '275,622')),
+ array('Item' => array('price' => '230,888')),
+ array('Item' => array('price' => '155,000')),
+ array('Item' => array('price' => '139,000')),
+ array('Item' => array('price' => '66,000')),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test natural sorting.
+ *
+ * @return void
+ */
+ public function testSortNatural() {
+ if (version_compare(PHP_VERSION, '5.4.0', '<')) {
+ $this->markTestSkipped('SORT_NATURAL is available since PHP 5.4.');
+ }
+ $items = array(
+ array('Item' => array('image' => 'img1.jpg')),
+ array('Item' => array('image' => 'img99.jpg')),
+ array('Item' => array('image' => 'img12.jpg')),
+ array('Item' => array('image' => 'img10.jpg')),
+ array('Item' => array('image' => 'img2.jpg')),
+ );
+ $result = Hash::sort($items, '{n}.Item.image', 'desc', 'natural');
+ $expected = array(
+ array('Item' => array('image' => 'img99.jpg')),
+ array('Item' => array('image' => 'img12.jpg')),
+ array('Item' => array('image' => 'img10.jpg')),
+ array('Item' => array('image' => 'img2.jpg')),
+ array('Item' => array('image' => 'img1.jpg')),
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::sort($items, '{n}.Item.image', 'asc', 'natural');
+ $expected = array(
+ array('Item' => array('image' => 'img1.jpg')),
+ array('Item' => array('image' => 'img2.jpg')),
+ array('Item' => array('image' => 'img10.jpg')),
+ array('Item' => array('image' => 'img12.jpg')),
+ array('Item' => array('image' => 'img99.jpg')),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test sorting with out of order keys.
+ *
+ * @return void
+ */
+ public function testSortWithOutOfOrderKeys() {
+ $data = array(
+ 9 => array('class' => 510, 'test2' => 2),
+ 1 => array('class' => 500, 'test2' => 1),
+ 2 => array('class' => 600, 'test2' => 2),
+ 5 => array('class' => 625, 'test2' => 4),
+ 0 => array('class' => 605, 'test2' => 3),
+ );
+ $expected = array(
+ array('class' => 500, 'test2' => 1),
+ array('class' => 510, 'test2' => 2),
+ array('class' => 600, 'test2' => 2),
+ array('class' => 605, 'test2' => 3),
+ array('class' => 625, 'test2' => 4),
+ );
+ $result = Hash::sort($data, '{n}.class', 'asc');
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::sort($data, '{n}.test2', 'asc');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test sorting with string keys.
+ *
+ * @return void
+ */
+ public function testSortString() {
+ $toSort = array(
+ 'four' => array('number' => 4, 'some' => 'foursome'),
+ 'six' => array('number' => 6, 'some' => 'sixsome'),
+ 'five' => array('number' => 5, 'some' => 'fivesome'),
+ 'two' => array('number' => 2, 'some' => 'twosome'),
+ 'three' => array('number' => 3, 'some' => 'threesome')
+ );
+ $sorted = Hash::sort($toSort, '{s}.number', 'asc');
+ $expected = array(
+ 'two' => array('number' => 2, 'some' => 'twosome'),
+ 'three' => array('number' => 3, 'some' => 'threesome'),
+ 'four' => array('number' => 4, 'some' => 'foursome'),
+ 'five' => array('number' => 5, 'some' => 'fivesome'),
+ 'six' => array('number' => 6, 'some' => 'sixsome')
+ );
+ $this->assertEquals($expected, $sorted);
+
+ $menus = array(
+ 'blogs' => array('title' => 'Blogs', 'weight' => 3),
+ 'comments' => array('title' => 'Comments', 'weight' => 2),
+ 'users' => array('title' => 'Users', 'weight' => 1),
+ );
+ $expected = array(
+ 'users' => array('title' => 'Users', 'weight' => 1),
+ 'comments' => array('title' => 'Comments', 'weight' => 2),
+ 'blogs' => array('title' => 'Blogs', 'weight' => 3),
+ );
+ $result = Hash::sort($menus, '{s}.weight', 'ASC');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test insert()
+ *
+ * @return void
+ */
+ public function testInsertSimple() {
+ $a = array(
+ 'pages' => array('name' => 'page')
+ );
+ $result = Hash::insert($a, 'files', array('name' => 'files'));
+ $expected = array(
+ 'pages' => array('name' => 'page'),
+ 'files' => array('name' => 'files')
+ );
+ $this->assertEquals($expected, $result);
+
+ $a = array(
+ 'pages' => array('name' => 'page')
+ );
+ $result = Hash::insert($a, 'pages.name', array());
+ $expected = array(
+ 'pages' => array('name' => array()),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test inserting with multiple values.
+ *
+ * @return void
+ */
+ public function testInsertMulti() {
+ $data = self::articleData();
+
+ $result = Hash::insert($data, '{n}.Article.insert', 'value');
+ $this->assertEquals('value', $result[0]['Article']['insert']);
+ $this->assertEquals('value', $result[1]['Article']['insert']);
+
+ $result = Hash::insert($data, '{n}.Comment.{n}.insert', 'value');
+ $this->assertEquals('value', $result[0]['Comment'][0]['insert']);
+ $this->assertEquals('value', $result[0]['Comment'][1]['insert']);
+ }
+
+/**
+ * Test that insert() can insert data over a string value.
+ *
+ * @return void
+ */
+ public function testInsertOverwriteStringValue() {
+ $data = array(
+ 'Some' => array(
+ 'string' => 'value'
+ )
+ );
+ $result = Hash::insert($data, 'Some.string.value', array('values'));
+ $expected = array(
+ 'Some' => array(
+ 'string' => array(
+ 'value' => array('values')
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test remove() method.
+ *
+ * @return void
+ */
+ public function testRemove() {
+ $a = array(
+ 'pages' => array('name' => 'page'),
+ 'files' => array('name' => 'files')
+ );
+
+ $result = Hash::remove($a, 'files');
+ $expected = array(
+ 'pages' => array('name' => 'page')
+ );
+ $this->assertEquals($expected, $result);
+
+ $a = array(
+ 'pages' => array(
+ 0 => array('name' => 'main'),
+ 1 => array(
+ 'name' => 'about',
+ 'vars' => array('title' => 'page title')
+ )
+ )
+ );
+
+ $result = Hash::remove($a, 'pages.1.vars');
+ $expected = array(
+ 'pages' => array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about')
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::remove($a, 'pages.2.vars');
+ $expected = $a;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test removing multiple values.
+ *
+ * @return void
+ */
+ public function testRemoveMulti() {
+ $data = self::articleData();
+
+ $result = Hash::remove($data, '{n}.Article.title');
+ $this->assertFalse(isset($result[0]['Article']['title']));
+ $this->assertFalse(isset($result[1]['Article']['title']));
+
+ $result = Hash::remove($data, '{n}.Article.{s}');
+ $this->assertFalse(isset($result[0]['Article']['id']));
+ $this->assertFalse(isset($result[0]['Article']['user_id']));
+ $this->assertFalse(isset($result[0]['Article']['title']));
+ $this->assertFalse(isset($result[0]['Article']['body']));
+ }
+
+/**
+ * testCheck method
+ *
+ * @return void
+ */
+ public function testCheck() {
+ $set = array(
+ 'My Index 1' => array('First' => 'The first item')
+ );
+ $this->assertTrue(Hash::check($set, 'My Index 1.First'));
+ $this->assertTrue(Hash::check($set, 'My Index 1'));
+
+ $set = array(
+ 'My Index 1' => array(
+ 'First' => array(
+ 'Second' => array(
+ 'Third' => array(
+ 'Fourth' => 'Heavy. Nesting.'
+ )
+ )
+ )
+ )
+ );
+ $this->assertTrue(Hash::check($set, 'My Index 1.First.Second'));
+ $this->assertTrue(Hash::check($set, 'My Index 1.First.Second.Third'));
+ $this->assertTrue(Hash::check($set, 'My Index 1.First.Second.Third.Fourth'));
+ $this->assertFalse(Hash::check($set, 'My Index 1.First.Seconds.Third.Fourth'));
+ }
+
+/**
+ * testCombine method
+ *
+ * @return void
+ */
+ public function testCombine() {
+ $result = Hash::combine(array(), '{n}.User.id', '{n}.User.Data');
+ $this->assertTrue(empty($result));
+
+ $a = self::userData();
+
+ $result = Hash::combine($a, '{n}.User.id');
+ $expected = array(2 => null, 14 => null, 25 => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine($a, '{n}.User.id', '{n}.User.non-existant');
+ $expected = array(2 => null, 14 => null, 25 => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data');
+ $expected = array(
+ 2 => array('user' => 'mariano.iglesias', 'name' => 'Mariano Iglesias'),
+ 14 => array('user' => 'phpnut', 'name' => 'Larry E. Masters'),
+ 25 => array('user' => 'gwoo', 'name' => 'The Gwoo'));
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name');
+ $expected = array(
+ 2 => 'Mariano Iglesias',
+ 14 => 'Larry E. Masters',
+ 25 => 'The Gwoo');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test combine() with a group path.
+ *
+ * @return void
+ */
+ public function testCombineWithGroupPath() {
+ $a = self::userData();
+
+ $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => array('user' => 'mariano.iglesias', 'name' => 'Mariano Iglesias'),
+ 25 => array('user' => 'gwoo', 'name' => 'The Gwoo')
+ ),
+ 2 => array(
+ 14 => array('user' => 'phpnut', 'name' => 'Larry E. Masters')
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => 'Mariano Iglesias',
+ 25 => 'The Gwoo'
+ ),
+ 2 => array(
+ 14 => 'Larry E. Masters'
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => array('user' => 'mariano.iglesias', 'name' => 'Mariano Iglesias'),
+ 25 => array('user' => 'gwoo', 'name' => 'The Gwoo')
+ ),
+ 2 => array(
+ 14 => array('user' => 'phpnut', 'name' => 'Larry E. Masters')
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => 'Mariano Iglesias',
+ 25 => 'The Gwoo'
+ ),
+ 2 => array(
+ 14 => 'Larry E. Masters'
+ )
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test combine with formatting rules.
+ *
+ * @return void
+ */
+ public function testCombineWithFormatting() {
+ $a = self::userData();
+
+ $result = Hash::combine(
+ $a,
+ '{n}.User.id',
+ array('%1$s: %2$s', '{n}.User.Data.user', '{n}.User.Data.name'),
+ '{n}.User.group_id'
+ );
+ $expected = array(
+ 1 => array(
+ 2 => 'mariano.iglesias: Mariano Iglesias',
+ 25 => 'gwoo: The Gwoo'
+ ),
+ 2 => array(
+ 14 => 'phpnut: Larry E. Masters'
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine(
+ $a,
+ array(
+ '%s: %s',
+ '{n}.User.Data.user',
+ '{n}.User.Data.name'
+ ),
+ '{n}.User.id'
+ );
+ $expected = array(
+ 'mariano.iglesias: Mariano Iglesias' => 2,
+ 'phpnut: Larry E. Masters' => 14,
+ 'gwoo: The Gwoo' => 25
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine(
+ $a,
+ array('%1$s: %2$d', '{n}.User.Data.user', '{n}.User.id'),
+ '{n}.User.Data.name'
+ );
+ $expected = array(
+ 'mariano.iglesias: 2' => 'Mariano Iglesias',
+ 'phpnut: 14' => 'Larry E. Masters',
+ 'gwoo: 25' => 'The Gwoo'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::combine(
+ $a,
+ array('%2$d: %1$s', '{n}.User.Data.user', '{n}.User.id'),
+ '{n}.User.Data.name'
+ );
+ $expected = array(
+ '2: mariano.iglesias' => 'Mariano Iglesias',
+ '14: phpnut' => 'Larry E. Masters',
+ '25: gwoo' => 'The Gwoo'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFormat method
+ *
+ * @return void
+ */
+ public function testFormat() {
+ $data = self::userData();
+
+ $result = Hash::format(
+ $data,
+ array('{n}.User.Data.user', '{n}.User.id'),
+ '%s, %s'
+ );
+ $expected = array(
+ 'mariano.iglesias, 2',
+ 'phpnut, 14',
+ 'gwoo, 25'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::format(
+ $data,
+ array('{n}.User.Data.user', '{n}.User.id'),
+ '%2$s, %1$s'
+ );
+ $expected = array(
+ '2, mariano.iglesias',
+ '14, phpnut',
+ '25, gwoo'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFormattingNullValues method
+ *
+ * @return void
+ */
+ public function testFormatNullValues() {
+ $data = array(
+ array('Person' => array(
+ 'first_name' => 'Nate', 'last_name' => 'Abele', 'city' => 'Boston', 'state' => 'MA', 'something' => '42'
+ )),
+ array('Person' => array(
+ 'first_name' => 'Larry', 'last_name' => 'Masters', 'city' => 'Boondock', 'state' => 'TN', 'something' => null
+ )),
+ array('Person' => array(
+ 'first_name' => 'Garrett', 'last_name' => 'Woodworth', 'city' => 'Venice Beach', 'state' => 'CA', 'something' => null
+ ))
+ );
+
+ $result = Hash::format($data, array('{n}.Person.something'), '%s');
+ $expected = array('42', '', '');
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::format($data, array('{n}.Person.city', '{n}.Person.something'), '%s, %s');
+ $expected = array('Boston, 42', 'Boondock, ', 'Venice Beach, ');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test map()
+ *
+ * @return void
+ */
+ public function testMap() {
+ $data = self::articleData();
+
+ $result = Hash::map($data, '{n}.Article.id', array($this, 'mapCallback'));
+ $expected = array(2, 4, 6, 8, 10);
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testApply() {
+ $data = self::articleData();
+
+ $result = Hash::apply($data, '{n}.Article.id', 'array_sum');
+ $this->assertEquals(15, $result);
+ }
+
+/**
+ * Test reduce()
+ *
+ * @return void
+ */
+ public function testReduce() {
+ $data = self::articleData();
+
+ $result = Hash::reduce($data, '{n}.Article.id', array($this, 'reduceCallback'));
+ $this->assertEquals(15, $result);
+ }
+
+/**
+ * testing method for map callbacks.
+ *
+ * @param mixed $value
+ * @return mixed.
+ */
+ public function mapCallback($value) {
+ return $value * 2;
+ }
+
+/**
+ * testing method for reduce callbacks.
+ *
+ * @param mixed $one
+ * @param mixed $two
+ * @return mixed.
+ */
+ public function reduceCallback($one, $two) {
+ return $one + $two;
+ }
+
+/**
+ * test Hash nest with a normal model result set. For kicks rely on Hash nest detecting the key names
+ * automatically
+ *
+ * @return void
+ */
+ public function testNestModel() {
+ $input = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ )
+ )
+ );
+ $expected = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ 'children' => array(
+ array(
+ 'ModelName' => array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+
+ )
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ 'children' => array(
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $result = Hash::nest($input);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Hash nest with a normal model result set, and a nominated root id
+ *
+ * @return void
+ */
+ public function testNestModelExplicitRoot() {
+ $input = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ )
+ )
+ );
+ $expected = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ 'children' => array(
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $result = Hash::nest($input, array('root' => 6));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Hash nest with a 1d array - this method should be able to handle any type of array input
+ *
+ * @return void
+ */
+ public function testNest1Dimensional() {
+ $input = array(
+ array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ array(
+ 'id' => 10,
+ 'parent_id' => 6
+ )
+ );
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'parent_id' => null,
+ 'children' => array(
+ array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 3,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 4,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 5,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+
+ )
+ ),
+ array(
+ 'id' => 6,
+ 'parent_id' => null,
+ 'children' => array(
+ array(
+ 'id' => 7,
+ 'parent_id' => 6,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 8,
+ 'parent_id' => 6,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 9,
+ 'parent_id' => 6,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 10,
+ 'parent_id' => 6,
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $result = Hash::nest($input, array('idPath' => '{n}.id', 'parentPath' => '{n}.parent_id'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Hash nest with no specified parent data.
+ *
+ * The result should be the same as the input.
+ * For an easier comparison, unset all the empty children arrays from the result
+ *
+ * @return void
+ */
+ public function testMissingParent() {
+ $input = array(
+ array(
+ 'id' => 1,
+ ),
+ array(
+ 'id' => 2,
+ ),
+ array(
+ 'id' => 3,
+ ),
+ array(
+ 'id' => 4,
+ ),
+ array(
+ 'id' => 5,
+ ),
+ array(
+ 'id' => 6,
+ ),
+ array(
+ 'id' => 7,
+ ),
+ array(
+ 'id' => 8,
+ ),
+ array(
+ 'id' => 9,
+ ),
+ array(
+ 'id' => 10,
+ )
+ );
+
+ $result = Hash::nest($input, array('idPath' => '{n}.id', 'parentPath' => '{n}.parent_id'));
+ foreach ($result as &$row) {
+ if (empty($row['children'])) {
+ unset($row['children']);
+ }
+ }
+ $this->assertEquals($input, $result);
+ }
+
+/**
+ * testMergeDiff method
+ *
+ * @return void
+ */
+ public function testMergeDiff() {
+ $first = array(
+ 'ModelOne' => array(
+ 'id' => 1001,
+ 'field_one' => 'a1.m1.f1',
+ 'field_two' => 'a1.m1.f2'
+ )
+ );
+ $second = array(
+ 'ModelTwo' => array(
+ 'id' => 1002,
+ 'field_one' => 'a2.m2.f1',
+ 'field_two' => 'a2.m2.f2'
+ )
+ );
+ $result = Hash::mergeDiff($first, $second);
+ $this->assertEquals($result, $first + $second);
+
+ $result = Hash::mergeDiff($first, array());
+ $this->assertEquals($result, $first);
+
+ $result = Hash::mergeDiff(array(), $first);
+ $this->assertEquals($result, $first);
+
+ $third = array(
+ 'ModelOne' => array(
+ 'id' => 1003,
+ 'field_one' => 'a3.m1.f1',
+ 'field_two' => 'a3.m1.f2',
+ 'field_three' => 'a3.m1.f3'
+ )
+ );
+ $result = Hash::mergeDiff($first, $third);
+ $expected = array(
+ 'ModelOne' => array(
+ 'id' => 1001,
+ 'field_one' => 'a1.m1.f1',
+ 'field_two' => 'a1.m1.f2',
+ 'field_three' => 'a3.m1.f3'
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $first = array(
+ 0 => array('ModelOne' => array('id' => 1001, 'field_one' => 's1.0.m1.f1', 'field_two' => 's1.0.m1.f2')),
+ 1 => array('ModelTwo' => array('id' => 1002, 'field_one' => 's1.1.m2.f2', 'field_two' => 's1.1.m2.f2'))
+ );
+ $second = array(
+ 0 => array('ModelOne' => array('id' => 1001, 'field_one' => 's2.0.m1.f1', 'field_two' => 's2.0.m1.f2')),
+ 1 => array('ModelTwo' => array('id' => 1002, 'field_one' => 's2.1.m2.f2', 'field_two' => 's2.1.m2.f2'))
+ );
+
+ $result = Hash::mergeDiff($first, $second);
+ $this->assertEquals($result, $first);
+
+ $third = array(
+ 0 => array(
+ 'ModelThree' => array(
+ 'id' => 1003,
+ 'field_one' => 's3.0.m3.f1',
+ 'field_two' => 's3.0.m3.f2'
+ )
+ )
+ );
+
+ $result = Hash::mergeDiff($first, $third);
+ $expected = array(
+ 0 => array(
+ 'ModelOne' => array(
+ 'id' => 1001,
+ 'field_one' => 's1.0.m1.f1',
+ 'field_two' => 's1.0.m1.f2'
+ ),
+ 'ModelThree' => array(
+ 'id' => 1003,
+ 'field_one' => 's3.0.m3.f1',
+ 'field_two' => 's3.0.m3.f2'
+ )
+ ),
+ 1 => array(
+ 'ModelTwo' => array(
+ 'id' => 1002,
+ 'field_one' => 's1.1.m2.f2',
+ 'field_two' => 's1.1.m2.f2'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Hash::mergeDiff($first, null);
+ $this->assertEquals($result, $first);
+
+ $result = Hash::mergeDiff($first, $second);
+ $this->assertEquals($result, $first + $second);
+ }
+
+/**
+ * Tests Hash::expand
+ *
+ * @return void
+ */
+ public function testExpand() {
+ $data = array('My', 'Array', 'To', 'Flatten');
+ $flat = Hash::flatten($data);
+ $result = Hash::expand($flat);
+ $this->assertEquals($data, $result);
+
+ $data = array(
+ '0.Post.id' => '1', '0.Post.author_id' => '1', '0.Post.title' => 'First Post', '0.Author.id' => '1',
+ '0.Author.user' => 'nate', '0.Author.password' => 'foo', '1.Post.id' => '2', '1.Post.author_id' => '3',
+ '1.Post.title' => 'Second Post', '1.Post.body' => 'Second Post Body', '1.Author.id' => '3',
+ '1.Author.user' => 'larry', '1.Author.password' => null
+ );
+ $result = Hash::expand($data);
+ $expected = array(
+ array(
+ 'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post'),
+ 'Author' => array('id' => '1', 'user' => 'nate', 'password' => 'foo'),
+ ),
+ array(
+ 'Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Second Post', 'body' => 'Second Post Body'),
+ 'Author' => array('id' => '3', 'user' => 'larry', 'password' => null),
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ '0/Post/id' => 1,
+ '0/Post/name' => 'test post'
+ );
+ $result = Hash::expand($data, '/');
+ $expected = array(
+ array(
+ 'Post' => array(
+ 'id' => 1,
+ 'name' => 'test post'
+ )
+ )
+ );
+ $this->assertEquals($result, $expected);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/InflectorTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/InflectorTest.php
new file mode 100644
index 0000000..cd19892
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/InflectorTest.php
@@ -0,0 +1,440 @@
+<?php
+/**
+ * InflectorTest
+ *
+ * InflectorTest is used to test cases on the Inflector class
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license Open Group Test Suite License (http://www.opensource.org/licenses/opengroup.php)
+ */
+
+/**
+ * Included libraries.
+ *
+ */
+App::uses('Inflector', 'Utility');
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class InflectorTest extends CakeTestCase {
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Inflector::reset();
+ }
+
+/**
+ * testInflectingSingulars method
+ *
+ * @return void
+ */
+ public function testInflectingSingulars() {
+ $this->assertEquals(Inflector::singularize('categorias'), 'categoria');
+ $this->assertEquals(Inflector::singularize('menus'), 'menu');
+ $this->assertEquals(Inflector::singularize('news'), 'news');
+ $this->assertEquals(Inflector::singularize('food_menus'), 'food_menu');
+ $this->assertEquals(Inflector::singularize('Menus'), 'Menu');
+ $this->assertEquals(Inflector::singularize('FoodMenus'), 'FoodMenu');
+ $this->assertEquals(Inflector::singularize('houses'), 'house');
+ $this->assertEquals(Inflector::singularize('powerhouses'), 'powerhouse');
+ $this->assertEquals(Inflector::singularize('quizzes'), 'quiz');
+ $this->assertEquals(Inflector::singularize('Buses'), 'Bus');
+ $this->assertEquals(Inflector::singularize('buses'), 'bus');
+ $this->assertEquals(Inflector::singularize('matrix_rows'), 'matrix_row');
+ $this->assertEquals(Inflector::singularize('matrices'), 'matrix');
+ $this->assertEquals(Inflector::singularize('vertices'), 'vertex');
+ $this->assertEquals(Inflector::singularize('indices'), 'index');
+ $this->assertEquals(Inflector::singularize('Aliases'), 'Alias');
+ $this->assertEquals(Inflector::singularize('Alias'), 'Alias');
+ $this->assertEquals(Inflector::singularize('Media'), 'Media');
+ $this->assertEquals(Inflector::singularize('NodeMedia'), 'NodeMedia');
+ $this->assertEquals(Inflector::singularize('alumni'), 'alumnus');
+ $this->assertEquals(Inflector::singularize('bacilli'), 'bacillus');
+ $this->assertEquals(Inflector::singularize('cacti'), 'cactus');
+ $this->assertEquals(Inflector::singularize('foci'), 'focus');
+ $this->assertEquals(Inflector::singularize('fungi'), 'fungus');
+ $this->assertEquals(Inflector::singularize('nuclei'), 'nucleus');
+ $this->assertEquals(Inflector::singularize('octopuses'), 'octopus');
+ $this->assertEquals(Inflector::singularize('radii'), 'radius');
+ $this->assertEquals(Inflector::singularize('stimuli'), 'stimulus');
+ $this->assertEquals(Inflector::singularize('syllabi'), 'syllabus');
+ $this->assertEquals(Inflector::singularize('termini'), 'terminus');
+ $this->assertEquals(Inflector::singularize('viri'), 'virus');
+ $this->assertEquals(Inflector::singularize('people'), 'person');
+ $this->assertEquals(Inflector::singularize('gloves'), 'glove');
+ $this->assertEquals(Inflector::singularize('doves'), 'dove');
+ $this->assertEquals(Inflector::singularize('lives'), 'life');
+ $this->assertEquals(Inflector::singularize('knives'), 'knife');
+ $this->assertEquals(Inflector::singularize('wolves'), 'wolf');
+ $this->assertEquals(Inflector::singularize('slaves'), 'slave');
+ $this->assertEquals(Inflector::singularize('shelves'), 'shelf');
+ $this->assertEquals(Inflector::singularize('taxis'), 'taxi');
+ $this->assertEquals(Inflector::singularize('taxes'), 'tax');
+ $this->assertEquals(Inflector::singularize('Taxes'), 'Tax');
+ $this->assertEquals(Inflector::singularize('AwesomeTaxes'), 'AwesomeTax');
+ $this->assertEquals(Inflector::singularize('faxes'), 'fax');
+ $this->assertEquals(Inflector::singularize('waxes'), 'wax');
+ $this->assertEquals(Inflector::singularize('niches'), 'niche');
+ $this->assertEquals(Inflector::singularize('waves'), 'wave');
+ $this->assertEquals(Inflector::singularize('bureaus'), 'bureau');
+ $this->assertEquals(Inflector::singularize('genetic_analyses'), 'genetic_analysis');
+ $this->assertEquals(Inflector::singularize('doctor_diagnoses'), 'doctor_diagnosis');
+ $this->assertEquals(Inflector::singularize('parantheses'), 'paranthesis');
+ $this->assertEquals(Inflector::singularize('Causes'), 'Cause');
+ $this->assertEquals(Inflector::singularize('colossuses'), 'colossus');
+ $this->assertEquals(Inflector::singularize('diagnoses'), 'diagnosis');
+ $this->assertEquals(Inflector::singularize('bases'), 'basis');
+ $this->assertEquals(Inflector::singularize('analyses'), 'analysis');
+ $this->assertEquals(Inflector::singularize('curves'), 'curve');
+ $this->assertEquals(Inflector::singularize('cafes'), 'cafe');
+ $this->assertEquals(Inflector::singularize('roofs'), 'roof');
+ $this->assertEquals(Inflector::singularize('foes'), 'foe');
+ $this->assertEquals(Inflector::singularize('databases'), 'database');
+
+ $this->assertEquals(Inflector::singularize(''), '');
+ }
+
+/**
+ * testInflectingPlurals method
+ *
+ * @return void
+ */
+ public function testInflectingPlurals() {
+ $this->assertEquals(Inflector::pluralize('categoria'), 'categorias');
+ $this->assertEquals(Inflector::pluralize('house'), 'houses');
+ $this->assertEquals(Inflector::pluralize('powerhouse'), 'powerhouses');
+ $this->assertEquals(Inflector::pluralize('Bus'), 'Buses');
+ $this->assertEquals(Inflector::pluralize('bus'), 'buses');
+ $this->assertEquals(Inflector::pluralize('menu'), 'menus');
+ $this->assertEquals(Inflector::pluralize('news'), 'news');
+ $this->assertEquals(Inflector::pluralize('food_menu'), 'food_menus');
+ $this->assertEquals(Inflector::pluralize('Menu'), 'Menus');
+ $this->assertEquals(Inflector::pluralize('FoodMenu'), 'FoodMenus');
+ $this->assertEquals(Inflector::pluralize('quiz'), 'quizzes');
+ $this->assertEquals(Inflector::pluralize('matrix_row'), 'matrix_rows');
+ $this->assertEquals(Inflector::pluralize('matrix'), 'matrices');
+ $this->assertEquals(Inflector::pluralize('vertex'), 'vertices');
+ $this->assertEquals(Inflector::pluralize('index'), 'indices');
+ $this->assertEquals(Inflector::pluralize('Alias'), 'Aliases');
+ $this->assertEquals(Inflector::pluralize('Aliases'), 'Aliases');
+ $this->assertEquals(Inflector::pluralize('Media'), 'Media');
+ $this->assertEquals(Inflector::pluralize('NodeMedia'), 'NodeMedia');
+ $this->assertEquals(Inflector::pluralize('alumnus'), 'alumni');
+ $this->assertEquals(Inflector::pluralize('bacillus'), 'bacilli');
+ $this->assertEquals(Inflector::pluralize('cactus'), 'cacti');
+ $this->assertEquals(Inflector::pluralize('focus'), 'foci');
+ $this->assertEquals(Inflector::pluralize('fungus'), 'fungi');
+ $this->assertEquals(Inflector::pluralize('nucleus'), 'nuclei');
+ $this->assertEquals(Inflector::pluralize('octopus'), 'octopuses');
+ $this->assertEquals(Inflector::pluralize('radius'), 'radii');
+ $this->assertEquals(Inflector::pluralize('stimulus'), 'stimuli');
+ $this->assertEquals(Inflector::pluralize('syllabus'), 'syllabi');
+ $this->assertEquals(Inflector::pluralize('terminus'), 'termini');
+ $this->assertEquals(Inflector::pluralize('virus'), 'viri');
+ $this->assertEquals(Inflector::pluralize('person'), 'people');
+ $this->assertEquals(Inflector::pluralize('people'), 'people');
+ $this->assertEquals(Inflector::pluralize('glove'), 'gloves');
+ $this->assertEquals(Inflector::pluralize('crisis'), 'crises');
+ $this->assertEquals(Inflector::pluralize('tax'), 'taxes');
+ $this->assertEquals(Inflector::pluralize('wave'), 'waves');
+ $this->assertEquals(Inflector::pluralize('bureau'), 'bureaus');
+ $this->assertEquals(Inflector::pluralize('cafe'), 'cafes');
+ $this->assertEquals(Inflector::pluralize('roof'), 'roofs');
+ $this->assertEquals(Inflector::pluralize('foe'), 'foes');
+ $this->assertEquals(Inflector::pluralize(''), '');
+ }
+
+/**
+ * testInflectorSlug method
+ *
+ * @return void
+ */
+ public function testInflectorSlug() {
+ $result = Inflector::slug('Foo Bar: Not just for breakfast any-more');
+ $expected = 'Foo_Bar_Not_just_for_breakfast_any_more';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('this/is/a/path');
+ $expected = 'this_is_a_path';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('Foo Bar: Not just for breakfast any-more', "-");
+ $expected = 'Foo-Bar-Not-just-for-breakfast-any-more';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('Foo Bar: Not just for breakfast any-more', "+");
+ $expected = 'Foo+Bar+Not+just+for+breakfast+any+more';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('Äpfel Über Öl grün ärgert groß öko', '-');
+ $expected = 'Aepfel-Ueber-Oel-gruen-aergert-gross-oeko';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('The truth - and- more- news', '-');
+ $expected = 'The-truth-and-more-news';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('The truth: and more news', '-');
+ $expected = 'The-truth-and-more-news';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('La langue française est un attribut de souveraineté en France', '-');
+ $expected = 'La-langue-francaise-est-un-attribut-de-souverainete-en-France';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('!@$#exciting stuff! - what !@-# was that?', '-');
+ $expected = 'exciting-stuff-what-was-that';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('20% of profits went to me!', '-');
+ $expected = '20-of-profits-went-to-me';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('#this melts your face1#2#3', '-');
+ $expected = 'this-melts-your-face1-2-3';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('controller/action/りんご/1');
+ $expected = 'controller_action_りんご_1';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('の話が出たので大丈夫かなあと');
+ $expected = 'の話が出たので大丈夫かなあと';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('posts/view/한국어/page:1/sort:asc');
+ $expected = 'posts_view_한국어_page_1_sort_asc';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testInflectorSlugWithMap method
+ *
+ * @return void
+ */
+ public function testInflectorSlugWithMap() {
+ Inflector::rules('transliteration', array('/r/' => '1'));
+ $result = Inflector::slug('replace every r');
+ $expected = '1eplace_eve1y_1';
+ $this->assertEquals($expected, $result);
+
+ $result = Inflector::slug('replace every r', '_');
+ $expected = '1eplace_eve1y_1';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testInflectorSlugWithMapOverridingDefault method
+ *
+ * @return void
+ */
+ public function testInflectorSlugWithMapOverridingDefault() {
+ Inflector::rules('transliteration', array('/å/' => 'aa', '/ø/' => 'oe'));
+ $result = Inflector::slug('Testing æ ø å', '-');
+ $expected = 'Testing-ae-oe-aa';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testInflectorUnderscore method
+ *
+ * @return void
+ */
+ public function testInflectorUnderscore() {
+ $this->assertSame(Inflector::underscore('TestThing'), 'test_thing');
+ $this->assertSame(Inflector::underscore('testThing'), 'test_thing');
+ $this->assertSame(Inflector::underscore('TestThingExtra'), 'test_thing_extra');
+ $this->assertSame(Inflector::underscore('testThingExtra'), 'test_thing_extra');
+
+ // Identical checks test the cache code path.
+ $this->assertSame(Inflector::underscore('TestThing'), 'test_thing');
+ $this->assertSame(Inflector::underscore('testThing'), 'test_thing');
+ $this->assertSame(Inflector::underscore('TestThingExtra'), 'test_thing_extra');
+ $this->assertSame(Inflector::underscore('testThingExtra'), 'test_thing_extra');
+
+ // Test stupid values
+ $this->assertSame(Inflector::underscore(''), '');
+ $this->assertSame(Inflector::underscore(0), '0');
+ $this->assertSame(Inflector::underscore(false), '');
+ }
+
+/**
+ * testVariableNaming method
+ *
+ * @return void
+ */
+ public function testVariableNaming() {
+ $this->assertEquals(Inflector::variable('test_field'), 'testField');
+ $this->assertEquals(Inflector::variable('test_fieLd'), 'testFieLd');
+ $this->assertEquals(Inflector::variable('test field'), 'testField');
+ $this->assertEquals(Inflector::variable('Test_field'), 'testField');
+ }
+
+/**
+ * testClassNaming method
+ *
+ * @return void
+ */
+ public function testClassNaming() {
+ $this->assertEquals(Inflector::classify('artists_genres'), 'ArtistsGenre');
+ $this->assertEquals(Inflector::classify('file_systems'), 'FileSystem');
+ $this->assertEquals(Inflector::classify('news'), 'News');
+ $this->assertEquals(Inflector::classify('bureaus'), 'Bureau');
+ }
+
+/**
+ * testTableNaming method
+ *
+ * @return void
+ */
+ public function testTableNaming() {
+ $this->assertEquals(Inflector::tableize('ArtistsGenre'), 'artists_genres');
+ $this->assertEquals(Inflector::tableize('FileSystem'), 'file_systems');
+ $this->assertEquals(Inflector::tableize('News'), 'news');
+ $this->assertEquals(Inflector::tableize('Bureau'), 'bureaus');
+ }
+
+/**
+ * testHumanization method
+ *
+ * @return void
+ */
+ public function testHumanization() {
+ $this->assertEquals(Inflector::humanize('posts'), 'Posts');
+ $this->assertEquals(Inflector::humanize('posts_tags'), 'Posts Tags');
+ $this->assertEquals(Inflector::humanize('file_systems'), 'File Systems');
+ }
+
+/**
+ * testCustomPluralRule method
+ *
+ * @return void
+ */
+ public function testCustomPluralRule() {
+ Inflector::rules('plural', array('/^(custom)$/i' => '\1izables'));
+ $this->assertEquals(Inflector::pluralize('custom'), 'customizables');
+
+ Inflector::rules('plural', array('uninflected' => array('uninflectable')));
+ $this->assertEquals(Inflector::pluralize('uninflectable'), 'uninflectable');
+
+ Inflector::rules('plural', array(
+ 'rules' => array('/^(alert)$/i' => '\1ables'),
+ 'uninflected' => array('noflect', 'abtuse'),
+ 'irregular' => array('amaze' => 'amazable', 'phone' => 'phonezes')
+ ));
+ $this->assertEquals(Inflector::pluralize('noflect'), 'noflect');
+ $this->assertEquals(Inflector::pluralize('abtuse'), 'abtuse');
+ $this->assertEquals(Inflector::pluralize('alert'), 'alertables');
+ $this->assertEquals(Inflector::pluralize('amaze'), 'amazable');
+ $this->assertEquals(Inflector::pluralize('phone'), 'phonezes');
+ }
+
+/**
+ * testCustomSingularRule method
+ *
+ * @return void
+ */
+ public function testCustomSingularRule() {
+ Inflector::rules('singular', array('/(eple)r$/i' => '\1', '/(jente)r$/i' => '\1'));
+
+ $this->assertEquals(Inflector::singularize('epler'), 'eple');
+ $this->assertEquals(Inflector::singularize('jenter'), 'jente');
+
+ Inflector::rules('singular', array(
+ 'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
+ 'uninflected' => array('singulars'),
+ 'irregular' => array('spins' => 'spinor')
+ ));
+
+ $this->assertEquals(Inflector::singularize('inflectors'), 'inflecta');
+ $this->assertEquals(Inflector::singularize('contributors'), 'contributa');
+ $this->assertEquals(Inflector::singularize('spins'), 'spinor');
+ $this->assertEquals(Inflector::singularize('singulars'), 'singulars');
+ }
+
+/**
+ * testCustomTransliterationRule method
+ *
+ * @return void
+ */
+ public function testCustomTransliterationRule() {
+ $this->assertEquals(Inflector::slug('Testing æ ø å'), 'Testing_ae_o_a');
+
+ Inflector::rules('transliteration', array('/å/' => 'aa', '/ø/' => 'oe'));
+ $this->assertEquals(Inflector::slug('Testing æ ø å'), 'Testing_ae_oe_aa');
+
+ Inflector::rules('transliteration', array('/ä|æ/' => 'ae', '/å/' => 'aa'), true);
+ $this->assertEquals(Inflector::slug('Testing æ ø å'), 'Testing_ae_ø_aa');
+ }
+
+/**
+ * test that setting new rules clears the inflector caches.
+ *
+ * @return void
+ */
+ public function testRulesClearsCaches() {
+ $this->assertEquals(Inflector::singularize('Bananas'), 'Banana');
+ $this->assertEquals(Inflector::tableize('Banana'), 'bananas');
+ $this->assertEquals(Inflector::pluralize('Banana'), 'Bananas');
+
+ Inflector::rules('singular', array(
+ 'rules' => array('/(.*)nas$/i' => '\1zzz')
+ ));
+ $this->assertEquals('Banazzz', Inflector::singularize('Bananas'), 'Was inflected with old rules.');
+
+ Inflector::rules('plural', array(
+ 'rules' => array('/(.*)na$/i' => '\1zzz'),
+ 'irregular' => array('corpus' => 'corpora')
+ ));
+ $this->assertEquals(Inflector::pluralize('Banana'), 'Banazzz', 'Was inflected with old rules.');
+ $this->assertEquals(Inflector::pluralize('corpus'), 'corpora', 'Was inflected with old irregular form.');
+ }
+
+/**
+ * Test resetting inflection rules.
+ *
+ * @return void
+ */
+ public function testCustomRuleWithReset() {
+ $uninflected = array('atlas', 'lapis', 'onibus', 'pires', 'virus', '.*x');
+ $pluralIrregular = array('as' => 'ases');
+
+ Inflector::rules('singular', array(
+ 'rules' => array('/^(.*)(a|e|o|u)is$/i' => '\1\2l'),
+ 'uninflected' => $uninflected,
+ ), true);
+
+ Inflector::rules('plural', array(
+ 'rules' => array(
+ '/^(.*)(a|e|o|u)l$/i' => '\1\2is',
+ ),
+ 'uninflected' => $uninflected,
+ 'irregular' => $pluralIrregular
+ ), true);
+
+ $this->assertEquals(Inflector::pluralize('Alcool'), 'Alcoois');
+ $this->assertEquals(Inflector::pluralize('Atlas'), 'Atlas');
+ $this->assertEquals(Inflector::singularize('Alcoois'), 'Alcool');
+ $this->assertEquals(Inflector::singularize('Atlas'), 'Atlas');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php
new file mode 100644
index 0000000..c8adc05
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ObjectCollectionTest.php
@@ -0,0 +1,595 @@
+<?php
+/**
+ * ObjectCollectionTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+App::uses('CakeEvent', 'Event');
+
+/**
+ * A generic object class
+ */
+class GenericObject {
+
+/**
+ * Constructor
+ *
+ * @param GenericObjectCollection $collection
+ * @param array $settings
+ */
+ public function __construct(GenericObjectCollection $collection, $settings = array()) {
+ $this->_Collection = $collection;
+ $this->settings = $settings;
+ }
+
+}
+
+/**
+ * First Extension of Generic Object
+ */
+class FirstGenericObject extends GenericObject {
+
+/**
+ * A generic callback
+ */
+ public function callback() {
+ }
+
+}
+
+/**
+ * Second Extension of Generic Object
+ */
+class SecondGenericObject extends GenericObject {
+
+ public function callback() {
+ }
+
+}
+
+/**
+ * Third Extension of Generic Object
+ */
+class ThirdGenericObject extends GenericObject {
+
+ public function callback() {
+ }
+
+}
+
+/**
+ * A collection of Generic objects
+ */
+class GenericObjectCollection extends ObjectCollection {
+
+/**
+ * Loads a generic object
+ *
+ * @param string $object Object name
+ * @param array $settings Settings array
+ * @return array List of loaded objects
+ */
+ public function load($object, $settings = array()) {
+ list($plugin, $name) = pluginSplit($object);
+ if (isset($this->_loaded[$name])) {
+ return $this->_loaded[$name];
+ }
+ $objectClass = $name . 'GenericObject';
+ $this->_loaded[$name] = new $objectClass($this, $settings);
+ $enable = isset($settings['enabled']) ? $settings['enabled'] : true;
+ if ($enable === true) {
+ $this->enable($name);
+ }
+ return $this->_loaded[$name];
+ }
+
+}
+
+class ObjectCollectionTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->Objects = new GenericObjectCollection();
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Objects);
+ }
+
+/**
+ * test triggering callbacks on loaded helpers
+ *
+ * @return void
+ */
+ public function testLoad() {
+ $result = $this->Objects->load('First');
+ $this->assertInstanceOf('FirstGenericObject', $result);
+ $this->assertInstanceOf('FirstGenericObject', $this->Objects->First);
+
+ $result = $this->Objects->attached();
+ $this->assertEquals(array('First'), $result, 'attached() results are wrong.');
+
+ $this->assertTrue($this->Objects->enabled('First'));
+
+ $result = $this->Objects->load('First');
+ $this->assertSame($result, $this->Objects->First);
+ }
+
+/**
+ * test unload()
+ *
+ * @return void
+ */
+ public function testUnload() {
+ $this->Objects->load('First');
+ $this->Objects->load('Second');
+
+ $result = $this->Objects->attached();
+ $this->assertEquals(array('First', 'Second'), $result, 'loaded objects are wrong');
+
+ $this->Objects->unload('First');
+ $this->assertFalse(isset($this->Objects->First));
+ $this->assertTrue(isset($this->Objects->Second));
+
+ $result = $this->Objects->attached();
+ $this->assertEquals(array('Second'), $result, 'loaded objects are wrong');
+
+ $result = $this->Objects->enabled();
+ $this->assertEquals(array('Second'), $result, 'enabled objects are wrong');
+ }
+
+/**
+ * Tests set()
+ *
+ * @return void
+ */
+ public function testSet() {
+ $this->Objects->load('First');
+
+ $result = $this->Objects->attached();
+ $this->assertEquals(array('First'), $result, 'loaded objects are wrong');
+
+ $result = $this->Objects->set('First', new SecondGenericObject($this->Objects));
+ $this->assertInstanceOf('SecondGenericObject', $result['First'], 'set failed');
+
+ $result = $this->Objects->set('Second', new SecondGenericObject($this->Objects));
+ $this->assertInstanceOf('SecondGenericObject', $result['Second'], 'set failed');
+
+ $this->assertEquals(2, count($result));
+ }
+
+/**
+ * creates mock classes for testing
+ *
+ * @return void
+ */
+ protected function _makeMockClasses() {
+ if (!class_exists('TriggerMockFirstGenericObject')) {
+ $this->getMock('FirstGenericObject', array(), array(), 'TriggerMockFirstGenericObject', false);
+ }
+ if (!class_exists('TriggerMockSecondGenericObject')) {
+ $this->getMock('SecondGenericObject', array(), array(), 'TriggerMockSecondGenericObject', false);
+ }
+ if (!class_exists('TriggerMockThirdGenericObject')) {
+ $this->getMock('ThirdGenericObject', array(), array(), 'TriggerMockThirdGenericObject', false);
+ }
+ }
+
+/**
+ * test triggering callbacks.
+ *
+ * @return void
+ */
+ public function testTrigger() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->will($this->returnValue(true));
+ $this->Objects->TriggerMockSecond->expects($this->once())
+ ->method('callback')
+ ->will($this->returnValue(true));
+
+ $this->assertTrue($this->Objects->trigger('callback'));
+ }
+
+/**
+ * test trigger and disabled objects
+ *
+ * @return void
+ */
+ public function testTriggerWithDisabledObjects() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->will($this->returnValue(true));
+ $this->Objects->TriggerMockSecond->expects($this->never())
+ ->method('callback')
+ ->will($this->returnValue(true));
+
+ $this->Objects->disable('TriggerMockSecond');
+
+ $this->assertTrue($this->Objects->trigger('callback', array()));
+ }
+
+/**
+ * test that the collectReturn option works.
+ *
+ * @return void
+ */
+ public function testTriggerWithCollectReturn() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->will($this->returnValue(array('one', 'two')));
+ $this->Objects->TriggerMockSecond->expects($this->once())
+ ->method('callback')
+ ->will($this->returnValue(array('three', 'four')));
+
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ array('one', 'two'),
+ array('three', 'four')
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that trigger with break & breakOn works.
+ *
+ * @return void
+ */
+ public function testTriggerWithBreak() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->will($this->returnValue(false));
+ $this->Objects->TriggerMockSecond->expects($this->never())
+ ->method('callback');
+
+ $result = $this->Objects->trigger(
+ 'callback',
+ array(),
+ array('break' => true, 'breakOn' => false)
+ );
+ $this->assertFalse($result);
+ }
+
+/**
+ * test that trigger with modParams works.
+ *
+ * @return void
+ */
+ public function testTriggerWithModParams() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->with(array('value'))
+ ->will($this->returnValue(array('new value')));
+
+ $this->Objects->TriggerMockSecond->expects($this->once())
+ ->method('callback')
+ ->with(array('new value'))
+ ->will($this->returnValue(array('newer value')));
+
+ $result = $this->Objects->trigger(
+ 'callback',
+ array(array('value')),
+ array('modParams' => 0)
+ );
+ $this->assertEquals(array('newer value'), $result);
+ }
+
+/**
+ * test that setting modParams to an index that doesn't exist doesn't cause errors.
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testTriggerModParamsInvalidIndex() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->never())
+ ->method('callback');
+
+ $this->Objects->TriggerMockSecond->expects($this->never())
+ ->method('callback');
+
+ $result = $this->Objects->trigger(
+ 'callback',
+ array(array('value')),
+ array('modParams' => 2)
+ );
+ }
+
+/**
+ * test that returning null doesn't modify parameters.
+ *
+ * @return void
+ */
+ public function testTriggerModParamsNullIgnored() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->with(array('value'))
+ ->will($this->returnValue(null));
+
+ $this->Objects->TriggerMockSecond->expects($this->once())
+ ->method('callback')
+ ->with(array('value'))
+ ->will($this->returnValue(array('new value')));
+
+ $result = $this->Objects->trigger(
+ 'callback',
+ array(array('value')),
+ array('modParams' => 0)
+ );
+ $this->assertEquals(array('new value'), $result);
+ }
+
+/**
+ * test order of callbacks triggering based on priority.
+ *
+ * @return void
+ */
+ public function testTriggerPriority() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond', array('priority' => 5));
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $this->Objects->TriggerMockFirst->expects($this->any())
+ ->method('callback')
+ ->will($this->returnValue('1st'));
+ $this->Objects->TriggerMockSecond->expects($this->any())
+ ->method('callback')
+ ->will($this->returnValue('2nd'));
+
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '1st'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->load('TriggerMockThird', array('priority' => 7));
+ $this->mockObjects[] = $this->Objects->TriggerMockThird;
+ $this->Objects->TriggerMockThird->expects($this->any())
+ ->method('callback')
+ ->will($this->returnValue('3rd'));
+
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '3rd',
+ '1st'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->disable('TriggerMockFirst');
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '3rd'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->enable('TriggerMockFirst');
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '3rd',
+ '1st'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->disable('TriggerMockThird');
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '1st'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->enable('TriggerMockThird', false);
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '1st',
+ '3rd'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->setPriority('TriggerMockThird', 1);
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '3rd',
+ '2nd',
+ '1st'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->disable('TriggerMockThird');
+ $this->Objects->setPriority('TriggerMockThird', 11);
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '1st'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->enable('TriggerMockThird');
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '1st',
+ '3rd'
+ );
+ $this->assertEquals($expected, $result);
+
+ $this->Objects->setPriority('TriggerMockThird');
+ $result = $this->Objects->trigger('callback', array(), array('collectReturn' => true));
+ $expected = array(
+ '2nd',
+ '1st',
+ '3rd'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test normalizeObjectArray
+ *
+ * @return void
+ */
+ public function testnormalizeObjectArray() {
+ $components = array(
+ 'Html',
+ 'Foo.Bar' => array('one', 'two'),
+ 'Something',
+ 'Banana.Apple' => array('foo' => 'bar')
+ );
+ $result = ObjectCollection::normalizeObjectArray($components);
+ $expected = array(
+ 'Html' => array('class' => 'Html', 'settings' => array()),
+ 'Bar' => array('class' => 'Foo.Bar', 'settings' => array('one', 'two')),
+ 'Something' => array('class' => 'Something', 'settings' => array()),
+ 'Apple' => array('class' => 'Banana.Apple', 'settings' => array('foo' => 'bar')),
+ );
+ $this->assertEquals($expected, $result);
+
+ // This is the result after Controller::_mergeVars
+ $components = array(
+ 'Html' => null,
+ 'Foo.Bar' => array('one', 'two'),
+ 'Something' => null,
+ 'Banana.Apple' => array('foo' => 'bar')
+ );
+ $result = ObjectCollection::normalizeObjectArray($components);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * tests that passing an instance of CakeEvent to trigger will prepend the subject to the list of arguments
+ *
+ * @return void
+ */
+ public function testDispatchEventWithSubject() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $subjectClass = new Object();
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->with($subjectClass, 'first argument')
+ ->will($this->returnValue(true));
+ $this->Objects->TriggerMockSecond->expects($this->once())
+ ->method('callback')
+ ->with($subjectClass, 'first argument')
+ ->will($this->returnValue(true));
+
+ $event = new CakeEvent('callback', $subjectClass, array('first argument'));
+ $this->assertTrue($this->Objects->trigger($event));
+ }
+
+/**
+ * tests that passing an instance of CakeEvent to trigger with omitSubject property
+ * will NOT prepend the subject to the list of arguments
+ *
+ * @return void
+ */
+ public function testDispatchEventNoSubject() {
+ $this->_makeMockClasses();
+ $this->Objects->load('TriggerMockFirst');
+ $this->Objects->load('TriggerMockSecond');
+
+ $this->mockObjects[] = $this->Objects->TriggerMockFirst;
+ $this->mockObjects[] = $this->Objects->TriggerMockSecond;
+
+ $subjectClass = new Object();
+ $this->Objects->TriggerMockFirst->expects($this->once())
+ ->method('callback')
+ ->with('first argument')
+ ->will($this->returnValue(true));
+ $this->Objects->TriggerMockSecond->expects($this->once())
+ ->method('callback')
+ ->with('first argument')
+ ->will($this->returnValue(true));
+
+ $event = new CakeEvent('callback', $subjectClass, array('first argument'));
+ $event->omitSubject = true;
+ $this->assertTrue($this->Objects->trigger($event));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SanitizeTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SanitizeTest.php
new file mode 100644
index 0000000..13ba63c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SanitizeTest.php
@@ -0,0 +1,462 @@
+<?php
+/**
+ * SanitizeTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.5428
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Sanitize', 'Utility');
+
+/**
+ * DataTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class SanitizeDataTest extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'SanitizeDataTest'
+ */
+ public $name = 'SanitizeDataTest';
+
+/**
+ * useTable property
+ *
+ * @var string 'data_tests'
+ */
+ public $useTable = 'data_tests';
+}
+
+/**
+ * Article class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class SanitizeArticle extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Article'
+ */
+ public $name = 'SanitizeArticle';
+
+/**
+ * useTable property
+ *
+ * @var string 'articles'
+ */
+ public $useTable = 'articles';
+}
+
+/**
+ * SanitizeTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class SanitizeTest extends CakeTestCase {
+
+/**
+ * autoFixtures property
+ *
+ * @var bool false
+ */
+ public $autoFixtures = false;
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.data_test', 'core.article');
+
+/**
+ * testEscapeAlphaNumeric method
+ *
+ * @return void
+ */
+ public function testEscapeAlphaNumeric() {
+ $resultAlpha = Sanitize::escape('abc', 'test');
+ $this->assertEquals('abc', $resultAlpha);
+
+ $resultNumeric = Sanitize::escape('123', 'test');
+ $this->assertEquals('123', $resultNumeric);
+
+ $resultNumeric = Sanitize::escape(1234, 'test');
+ $this->assertEquals(1234, $resultNumeric);
+
+ $resultNumeric = Sanitize::escape(1234.23, 'test');
+ $this->assertEquals(1234.23, $resultNumeric);
+
+ $resultNumeric = Sanitize::escape('#1234.23', 'test');
+ $this->assertEquals('#1234.23', $resultNumeric);
+
+ $resultNull = Sanitize::escape(null, 'test');
+ $this->assertEquals(null, $resultNull);
+
+ $resultNull = Sanitize::escape(false, 'test');
+ $this->assertEquals(false, $resultNull);
+
+ $resultNull = Sanitize::escape(true, 'test');
+ $this->assertEquals(true, $resultNull);
+ }
+
+/**
+ * testClean method
+ *
+ * @return void
+ */
+ public function testClean() {
+ $string = 'test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line';
+ $expected = 'test &amp; &quot;quote&quot; &#039;other&#039; ;.$ symbol.another line';
+ $result = Sanitize::clean($string, array('connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $string = 'test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line';
+ $expected = 'test & ' . Sanitize::escape('"quote"', 'test') . ' ' . Sanitize::escape('\'other\'', 'test') . ' ;.$ symbol.another line';
+ $result = Sanitize::clean($string, array('encode' => false, 'connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $string = 'test & "quote" \'other\' ;.$ \\$ symbol.' . "\r" . 'another line';
+ $expected = 'test & "quote" \'other\' ;.$ $ symbol.another line';
+ $result = Sanitize::clean($string, array('encode' => false, 'escape' => false, 'connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $string = 'test & "quote" \'other\' ;.$ \\$ symbol.' . "\r" . 'another line';
+ $expected = 'test & "quote" \'other\' ;.$ \\$ symbol.another line';
+ $result = Sanitize::clean($string, array('encode' => false, 'escape' => false, 'dollar' => false, 'connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $string = 'test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line';
+ $expected = 'test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line';
+ $result = Sanitize::clean($string, array('encode' => false, 'escape' => false, 'carriage' => false, 'connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $array = array(array('test & "quote" \'other\' ;.$ symbol.' . "\r" . 'another line'));
+ $expected = array(array('test &amp; &quot;quote&quot; &#039;other&#039; ;.$ symbol.another line'));
+ $result = Sanitize::clean($array, array('connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $array = array(array('test & "quote" \'other\' ;.$ \\$ symbol.' . "\r" . 'another line'));
+ $expected = array(array('test & "quote" \'other\' ;.$ $ symbol.another line'));
+ $result = Sanitize::clean($array, array('encode' => false, 'escape' => false, 'connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $array = array(array('test odd Ä spacesé'));
+ $expected = array(array('test odd &Auml; spaces&eacute;'));
+ $result = Sanitize::clean($array, array('odd_spaces' => false, 'escape' => false, 'connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $array = array(array('\\$', array('key' => 'test & "quote" \'other\' ;.$ \\$ symbol.' . "\r" . 'another line')));
+ $expected = array(array('$', array('key' => 'test & "quote" \'other\' ;.$ $ symbol.another line')));
+ $result = Sanitize::clean($array, array('encode' => false, 'escape' => false, 'connection' => 'test'));
+ $this->assertEquals($expected, $result);
+
+ $string = '';
+ $expected = '';
+ $result = Sanitize::clean($string, array('connection' => 'test'));
+ $this->assertEquals($expected, $string);
+
+ $data = array(
+ 'Grant' => array(
+ 'title' => '2 o clock grant',
+ 'grant_peer_review_id' => 3,
+ 'institution_id' => 5,
+ 'created_by' => 1,
+ 'modified_by' => 1,
+ 'created' => '2010-07-15 14:11:00',
+ 'modified' => '2010-07-19 10:45:41'
+ ),
+ 'GrantsMember' => array(
+ 0 => array(
+ 'id' => 68,
+ 'grant_id' => 120,
+ 'member_id' => 16,
+ 'program_id' => 29,
+ 'pi_percent_commitment' => 1
+ )
+ )
+ );
+ $result = Sanitize::clean($data, array('connection' => 'test'));
+ $this->assertEquals($data, $result);
+ }
+
+/**
+ * testHtml method
+ *
+ * @return void
+ */
+ public function testHtml() {
+ $string = '<p>This is a <em>test string</em> & so is this</p>';
+ $expected = 'This is a test string &amp; so is this';
+ $result = Sanitize::html($string, array('remove' => true));
+ $this->assertEquals($expected, $result);
+
+ $string = 'The "lazy" dog \'jumped\' & flew over the moon. If (1+1) = 2 <em>is</em> true, (2-1) = 1 is also true';
+ $expected = 'The &quot;lazy&quot; dog &#039;jumped&#039; &amp; flew over the moon. If (1+1) = 2 &lt;em&gt;is&lt;/em&gt; true, (2-1) = 1 is also true';
+ $result = Sanitize::html($string);
+ $this->assertEquals($expected, $result);
+
+ $string = 'The "lazy" dog \'jumped\'';
+ $expected = 'The &quot;lazy&quot; dog \'jumped\'';
+ $result = Sanitize::html($string, array('quotes' => ENT_COMPAT));
+ $this->assertEquals($expected, $result);
+
+ $string = 'The "lazy" dog \'jumped\'';
+ $result = Sanitize::html($string, array('quotes' => ENT_NOQUOTES));
+ $this->assertEquals($string, $result);
+
+ $string = 'The "lazy" dog \'jumped\' & flew over the moon. If (1+1) = 2 <em>is</em> true, (2-1) = 1 is also true';
+ $expected = 'The &quot;lazy&quot; dog &#039;jumped&#039; &amp; flew over the moon. If (1+1) = 2 &lt;em&gt;is&lt;/em&gt; true, (2-1) = 1 is also true';
+ $result = Sanitize::html($string);
+ $this->assertEquals($expected, $result);
+
+ $string = 'The "lazy" dog & his friend Apple&reg; conquered the world';
+ $expected = 'The &quot;lazy&quot; dog &amp; his friend Apple&amp;reg; conquered the world';
+ $result = Sanitize::html($string);
+ $this->assertEquals($expected, $result);
+
+ $string = 'The "lazy" dog & his friend Apple&reg; conquered the world';
+ $expected = 'The &quot;lazy&quot; dog &amp; his friend Apple&reg; conquered the world';
+ $result = Sanitize::html($string, array('double' => false));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStripWhitespace method
+ *
+ * @return void
+ */
+ public function testStripWhitespace() {
+ $string = "This sentence \t\t\t has lots of \n\n white\nspace \rthat \r\n needs to be \t \n trimmed.";
+ $expected = "This sentence has lots of whitespace that needs to be trimmed.";
+ $result = Sanitize::stripWhitespace($string);
+ $this->assertEquals($expected, $result);
+
+ $text = 'I love ßá†ö√ letters.';
+ $result = Sanitize::stripWhitespace($text);
+ $expected = 'I love ßá†ö√ letters.';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testParanoid method
+ *
+ * @return void
+ */
+ public function testParanoid() {
+ $string = 'I would like to !%@#% & dance & sing ^$&*()-+';
+ $expected = 'Iwouldliketodancesing';
+ $result = Sanitize::paranoid($string);
+ $this->assertEquals($expected, $result);
+
+ $string = array('This |s th% s0ng that never ends it g*es',
+ 'on and on my friends, b^ca#use it is the',
+ 'so&g th===t never ends.');
+ $expected = array('This s th% s0ng that never ends it g*es',
+ 'on and on my friends bcause it is the',
+ 'sog tht never ends.');
+ $result = Sanitize::paranoid($string, array('%', '*', '.', ' '));
+ $this->assertEquals($expected, $result);
+
+ $string = "anything' OR 1 = 1";
+ $expected = 'anythingOR11';
+ $result = Sanitize::paranoid($string);
+ $this->assertEquals($expected, $result);
+
+ $string = "x' AND email IS NULL; --";
+ $expected = 'xANDemailISNULL';
+ $result = Sanitize::paranoid($string);
+ $this->assertEquals($expected, $result);
+
+ $string = "x' AND 1=(SELECT COUNT(*) FROM users); --";
+ $expected = "xAND1SELECTCOUNTFROMusers";
+ $result = Sanitize::paranoid($string);
+ $this->assertEquals($expected, $result);
+
+ $string = "x'; DROP TABLE members; --";
+ $expected = "xDROPTABLEmembers";
+ $result = Sanitize::paranoid($string);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStripImages method
+ *
+ * @return void
+ */
+ public function testStripImages() {
+ $string = '<img src="/img/test.jpg" alt="my image" />';
+ $expected = 'my image<br />';
+ $result = Sanitize::stripImages($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<img src="javascript:alert(\'XSS\');" />';
+ $expected = '';
+ $result = Sanitize::stripImages($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<a href="http://www.badsite.com/phising"><img src="/img/test.jpg" alt="test image alt" title="test image title" id="myImage" class="image-left"/></a>';
+ $expected = '<a href="http://www.badsite.com/phising">test image alt</a><br />';
+ $result = Sanitize::stripImages($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<a onclick="medium()" href="http://example.com"><img src="foobar.png" onclick="evilFunction(); return false;"/></a>';
+ $expected = '<a onclick="medium()" href="http://example.com"></a>';
+ $result = Sanitize::stripImages($string);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStripScripts method
+ *
+ * @return void
+ */
+ public function testStripScripts() {
+ $string = '<link href="/css/styles.css" media="screen" rel="stylesheet" />';
+ $expected = '';
+ $result = Sanitize::stripScripts($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<link href="/css/styles.css" media="screen" rel="stylesheet" />' . "\n" .
+ '<link rel="icon" href="/favicon.ico" type="image/x-icon" />' . "\n" .
+ '<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />' . "\n" .
+ '<link rel="alternate" href="/feed.xml" title="RSS Feed" type="application/rss+xml" />';
+ $expected = "\n" . '<link rel="icon" href="/favicon.ico" type="image/x-icon" />' . "\n" .
+ '<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />' . "\n" .
+ '<link rel="alternate" href="/feed.xml" title="RSS Feed" type="application/rss+xml" />';
+ $result = Sanitize::stripScripts($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<script type="text/javascript"> alert("hacked!");</script>';
+ $expected = '';
+ $result = Sanitize::stripScripts($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<script> alert("hacked!");</script>';
+ $expected = '';
+ $result = Sanitize::stripScripts($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<style>#content { display:none; }</style>';
+ $expected = '';
+ $result = Sanitize::stripScripts($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<style type="text/css"><!-- #content { display:none; } --></style>';
+ $expected = '';
+ $result = Sanitize::stripScripts($string);
+ $this->assertEquals($expected, $result);
+
+ $string = <<<HTML
+text
+<style type="text/css">
+<!--
+#content { display:none; }
+-->
+</style>
+text
+HTML;
+ $expected = "text\n\ntext";
+ $result = Sanitize::stripScripts($string);
+ $this->assertTextEquals($expected, $result);
+
+ $string = <<<HTML
+text
+<script type="text/javascript">
+<!--
+alert('wooo');
+-->
+</script>
+text
+HTML;
+ $expected = "text\n\ntext";
+ $result = Sanitize::stripScripts($string);
+ $this->assertTextEquals($expected, $result);
+ }
+
+/**
+ * testStripAll method
+ *
+ * @return void
+ */
+ public function testStripAll() {
+ $string = '<img """><script>alert("xss")</script>"/>';
+ $expected = '"/>';
+ $result = Sanitize::stripAll($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>';
+ $expected = '';
+ $result = Sanitize::stripAll($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<<script>alert("XSS");//<</script>';
+ $expected = '<';
+ $result = Sanitize::stripAll($string);
+ $this->assertEquals($expected, $result);
+
+ $string = '<img src="http://google.com/images/logo.gif" onload="window.location=\'http://sam.com/\'" />' . "\n" .
+ "<p>This is ok \t\n text</p>\n" .
+ '<link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" title="my sheet" charset="utf-8">' . "\n" .
+ '<script src="xss.js" type="text/javascript" charset="utf-8"></script>';
+ $expected = '<p>This is ok text</p>';
+ $result = Sanitize::stripAll($string);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStripTags method
+ *
+ * @return void
+ */
+ public function testStripTags() {
+ $string = '<h2>Headline</h2><p><a href="http://example.com">My Link</a> could go to a bad site</p>';
+ $expected = 'Headline<p>My Link could go to a bad site</p>';
+ $result = Sanitize::stripTags($string, 'h2', 'a');
+ $this->assertEquals($expected, $result);
+
+ $string = '<script type="text/javascript" src="http://evildomain.com"> </script>';
+ $expected = ' ';
+ $result = Sanitize::stripTags($string, 'script');
+ $this->assertEquals($expected, $result);
+
+ $string = '<h2>Important</h2><p>Additional information here <a href="/about"><img src="/img/test.png" /></a>. Read even more here</p>';
+ $expected = 'Important<p>Additional information here <img src="/img/test.png" />. Read even more here</p>';
+ $result = Sanitize::stripTags($string, 'h2', 'a');
+ $this->assertEquals($expected, $result);
+
+ $string = '<h2>Important</h2><p>Additional information here <a href="/about"><img src="/img/test.png" /></a>. Read even more here</p>';
+ $expected = 'Important<p>Additional information here . Read even more here</p>';
+ $result = Sanitize::stripTags($string, 'h2', 'a', 'img');
+ $this->assertEquals($expected, $result);
+
+ $string = '<b>Important message!</b><br>This message will self destruct!';
+ $expected = 'Important message!<br>This message will self destruct!';
+ $result = Sanitize::stripTags($string, 'b');
+ $this->assertEquals($expected, $result);
+
+ $string = '<b>Important message!</b><br />This message will self destruct!';
+ $expected = 'Important message!<br />This message will self destruct!';
+ $result = Sanitize::stripTags($string, 'b');
+ $this->assertEquals($expected, $result);
+
+ $string = '<h2 onclick="alert(\'evil\'); onmouseover="badness()">Important</h2><p>Additional information here <a href="/about"><img src="/img/test.png" /></a>. Read even more here</p>';
+ $expected = 'Important<p>Additional information here . Read even more here</p>';
+ $result = Sanitize::stripTags($string, 'h2', 'a', 'img');
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SecurityTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SecurityTest.php
new file mode 100644
index 0000000..cb323d9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SecurityTest.php
@@ -0,0 +1,207 @@
+<?php
+/**
+ * SecurityTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Security', 'Utility');
+
+/**
+ * SecurityTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class SecurityTest extends CakeTestCase {
+
+/**
+ * sut property
+ *
+ * @var mixed null
+ */
+ public $sut = null;
+
+/**
+ * testInactiveMins method
+ *
+ * @return void
+ */
+ public function testInactiveMins() {
+ Configure::write('Security.level', 'high');
+ $this->assertEquals(10, Security::inactiveMins());
+
+ Configure::write('Security.level', 'medium');
+ $this->assertEquals(100, Security::inactiveMins());
+
+ Configure::write('Security.level', 'low');
+ $this->assertEquals(300, Security::inactiveMins());
+ }
+
+/**
+ * testGenerateAuthkey method
+ *
+ * @return void
+ */
+ public function testGenerateAuthkey() {
+ $this->assertEquals(strlen(Security::generateAuthKey()), 40);
+ }
+
+/**
+ * testValidateAuthKey method
+ *
+ * @return void
+ */
+ public function testValidateAuthKey() {
+ $authKey = Security::generateAuthKey();
+ $this->assertTrue(Security::validateAuthKey($authKey));
+ }
+
+/**
+ * testHash method
+ *
+ * @return void
+ */
+ public function testHash() {
+ $_hashType = Security::$hashType;
+
+ $key = 'someKey';
+ $hash = 'someHash';
+
+ $this->assertSame(strlen(Security::hash($key, null, false)), 40);
+ $this->assertSame(strlen(Security::hash($key, 'sha1', false)), 40);
+ $this->assertSame(strlen(Security::hash($key, null, true)), 40);
+ $this->assertSame(strlen(Security::hash($key, 'sha1', true)), 40);
+
+ $result = Security::hash($key, null, $hash);
+ $this->assertSame($result, 'e38fcb877dccb6a94729a81523851c931a46efb1');
+
+ $result = Security::hash($key, 'sha1', $hash);
+ $this->assertSame($result, 'e38fcb877dccb6a94729a81523851c931a46efb1');
+
+ $hashType = 'sha1';
+ Security::setHash($hashType);
+ $this->assertSame(Security::$hashType, $hashType);
+ $this->assertSame(strlen(Security::hash($key, null, true)), 40);
+ $this->assertSame(strlen(Security::hash($key, null, false)), 40);
+
+ $this->assertSame(strlen(Security::hash($key, 'md5', false)), 32);
+ $this->assertSame(strlen(Security::hash($key, 'md5', true)), 32);
+
+ $hashType = 'md5';
+ Security::setHash($hashType);
+ $this->assertSame(Security::$hashType, $hashType);
+ $this->assertSame(strlen(Security::hash($key, null, false)), 32);
+ $this->assertSame(strlen(Security::hash($key, null, true)), 32);
+
+ if (!function_exists('hash') && !function_exists('mhash')) {
+ $this->assertSame(strlen(Security::hash($key, 'sha256', false)), 32);
+ $this->assertSame(strlen(Security::hash($key, 'sha256', true)), 32);
+ } else {
+ $this->assertSame(strlen(Security::hash($key, 'sha256', false)), 64);
+ $this->assertSame(strlen(Security::hash($key, 'sha256', true)), 64);
+ }
+
+ Security::setHash($_hashType);
+ }
+
+/**
+ * testCipher method
+ *
+ * @return void
+ */
+ public function testCipher() {
+ $length = 10;
+ $txt = '';
+ for ($i = 0; $i < $length; $i++) {
+ $txt .= mt_rand(0, 255);
+ }
+ $key = 'my_key';
+ $result = Security::cipher($txt, $key);
+ $this->assertEquals($txt, Security::cipher($result, $key));
+
+ $txt = '';
+ $key = 'my_key';
+ $result = Security::cipher($txt, $key);
+ $this->assertEquals($txt, Security::cipher($result, $key));
+
+ $txt = 123456;
+ $key = 'my_key';
+ $result = Security::cipher($txt, $key);
+ $this->assertEquals($txt, Security::cipher($result, $key));
+
+ $txt = '123456';
+ $key = 'my_key';
+ $result = Security::cipher($txt, $key);
+ $this->assertEquals($txt, Security::cipher($result, $key));
+ }
+
+/**
+ * testCipherEmptyKey method
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testCipherEmptyKey() {
+ $txt = 'some_text';
+ $key = '';
+ $result = Security::cipher($txt, $key);
+ }
+
+/**
+ * testRijndael method
+ *
+ * @return void
+ */
+ public function testRijndael() {
+ $txt = 'The quick brown fox jumped over the lazy dog.';
+ $key = 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi';
+
+ $result = Security::rijndael($txt, $key, 'encrypt');
+ $this->assertEquals($txt, Security::rijndael($result, $key, 'decrypt'));
+
+ $result = Security::rijndael($key, $txt, 'encrypt');
+ $this->assertEquals($key, Security::rijndael($result, $txt, 'decrypt'));
+
+ $result = Security::rijndael('', $key, 'encrypt');
+ $this->assertEquals('', Security::rijndael($result, $key, 'decrypt'));
+
+ $result = Security::rijndael($txt, $key = 'this is my key of over 32 chars, yes it is', 'encrypt');
+ $this->assertEquals($txt, Security::rijndael($result, $key, 'decrypt'));
+ }
+
+/**
+ * testRijndaelInvalidOperation method
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testRijndaelInvalidOperation() {
+ $txt = 'The quick brown fox jumped over the lazy dog.';
+ $key = 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi';
+ $result = Security::rijndael($txt, $key, 'foo');
+ }
+
+/**
+ * testRijndaelInvalidKey method
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testRijndaelInvalidKey() {
+ $txt = 'The quick brown fox jumped over the lazy dog.';
+ $key = 'too small';
+ $result = Security::rijndael($txt, $key, 'encrypt');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SetTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SetTest.php
new file mode 100644
index 0000000..e1c18a8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/SetTest.php
@@ -0,0 +1,3542 @@
+<?php
+/**
+ * SetTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Set', 'Utility');
+App::uses('Model', 'Model');
+
+/**
+ * SetTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class SetTest extends CakeTestCase {
+
+/**
+ * testNumericKeyExtraction method
+ *
+ * @return void
+ */
+ public function testNumericKeyExtraction() {
+ $data = array('plugin' => null, 'controller' => '', 'action' => '', 1, 'whatever');
+ $this->assertEquals(array(1, 'whatever'), Set::extract($data, '{n}'));
+ $this->assertEquals(array('plugin' => null, 'controller' => '', 'action' => ''), Set::diff($data, Set::extract($data, '{n}')));
+ }
+
+/**
+ * testEnum method
+ *
+ * @return void
+ */
+ public function testEnum() {
+ $result = Set::enum(1, 'one, two');
+ $this->assertEquals('two', $result);
+ $result = Set::enum(2, 'one, two');
+ $this->assertNull($result);
+
+ $set = array('one', 'two');
+ $result = Set::enum(0, $set);
+ $this->assertEquals('one', $result);
+ $result = Set::enum(1, $set);
+ $this->assertEquals('two', $result);
+
+ $result = Set::enum(1, array('one', 'two'));
+ $this->assertEquals('two', $result);
+ $result = Set::enum(2, array('one', 'two'));
+ $this->assertNull($result);
+
+ $result = Set::enum('first', array('first' => 'one', 'second' => 'two'));
+ $this->assertEquals('one', $result);
+ $result = Set::enum('third', array('first' => 'one', 'second' => 'two'));
+ $this->assertNull($result);
+
+ $result = Set::enum('no', array('no' => 0, 'yes' => 1));
+ $this->assertEquals(0, $result);
+ $result = Set::enum('not sure', array('no' => 0, 'yes' => 1));
+ $this->assertNull($result);
+
+ $result = Set::enum(0);
+ $this->assertEquals('no', $result);
+ $result = Set::enum(1);
+ $this->assertEquals('yes', $result);
+ $result = Set::enum(2);
+ $this->assertNull($result);
+ }
+
+/**
+ * testFilter method
+ *
+ * @see Hash test cases, as Set::filter() is just a proxy.
+ * @return void
+ */
+ public function testFilter() {
+ $result = Set::filter(array('0', false, true, 0, array('one thing', 'I can tell you', 'is you got to be', false)));
+ $expected = array('0', 2 => true, 3 => 0, 4 => array('one thing', 'I can tell you', 'is you got to be'));
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testNumericArrayCheck method
+ *
+ * @see Hash test cases, as Set::numeric() is just a proxy.
+ * @return void
+ */
+ public function testNumericArrayCheck() {
+ $data = array('one');
+ $this->assertTrue(Set::numeric(array_keys($data)));
+ }
+
+/**
+ * testKeyCheck method
+ *
+ * @return void
+ */
+ public function testKeyCheck() {
+ $data = array('Multi' => array('dimensonal' => array('array')));
+ $this->assertTrue(Set::check($data, 'Multi.dimensonal'));
+ $this->assertFalse(Set::check($data, 'Multi.dimensonal.array'));
+
+ $data = array(
+ array(
+ 'Article' => array('id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ 'Comment' => array(
+ array('id' => '1', 'article_id' => '1', 'user_id' => '2', 'comment' => 'First Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'),
+ array('id' => '2', 'article_id' => '1', 'user_id' => '4', 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'),
+ ),
+ 'Tag' => array(
+ array('id' => '1', 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
+ array('id' => '2', 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31')
+ )
+ ),
+ array(
+ 'Article' => array('id' => '3', 'user_id' => '1', 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
+ 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ 'Comment' => array(),
+ 'Tag' => array()
+ )
+ );
+ $this->assertTrue(Set::check($data, '0.Article.user_id'));
+ $this->assertTrue(Set::check($data, '0.Comment.0.id'));
+ $this->assertFalse(Set::check($data, '0.Comment.0.id.0'));
+ $this->assertTrue(Set::check($data, '0.Article.user_id'));
+ $this->assertFalse(Set::check($data, '0.Article.user_id.a'));
+ }
+
+/**
+ * testMerge method
+ *
+ * @return void
+ */
+ public function testMerge() {
+ $r = Set::merge(array('foo'));
+ $this->assertEquals(array('foo'), $r);
+
+ $r = Set::merge('foo');
+ $this->assertEquals(array('foo'), $r);
+
+ $r = Set::merge('foo', 'bar');
+ $this->assertEquals(array('foo', 'bar'), $r);
+
+ $r = Set::merge('foo', array('user' => 'bob', 'no-bar'), 'bar');
+ $this->assertEquals(array('foo', 'user' => 'bob', 'no-bar', 'bar'), $r);
+
+ $a = array('foo', 'foo2');
+ $b = array('bar', 'bar2');
+ $this->assertEquals(array('foo', 'foo2', 'bar', 'bar2'), Set::merge($a, $b));
+
+ $a = array('foo' => 'bar', 'bar' => 'foo');
+ $b = array('foo' => 'no-bar', 'bar' => 'no-foo');
+ $this->assertEquals(array('foo' => 'no-bar', 'bar' => 'no-foo'), Set::merge($a, $b));
+
+ $a = array('users' => array('bob', 'jim'));
+ $b = array('users' => array('lisa', 'tina'));
+ $this->assertEquals(array('users' => array('bob', 'jim', 'lisa', 'tina')), Set::merge($a, $b));
+
+ $a = array('users' => array('jim', 'bob'));
+ $b = array('users' => 'none');
+ $this->assertEquals(array('users' => 'none'), Set::merge($a, $b));
+
+ $a = array('users' => array('lisa' => array('id' => 5, 'pw' => 'secret')), 'cakephp');
+ $b = array('users' => array('lisa' => array('pw' => 'new-pass', 'age' => 23)), 'ice-cream');
+ $this->assertEquals(array('users' => array('lisa' => array('id' => 5, 'pw' => 'new-pass', 'age' => 23)), 'cakephp', 'ice-cream'), Set::merge($a, $b));
+
+ $c = array('users' => array('lisa' => array('pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog')), 'chocolate');
+ $expected = array('users' => array('lisa' => array('id' => 5, 'pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog')), 'cakephp', 'ice-cream', 'chocolate');
+ $this->assertEquals($expected, Set::merge($a, $b, $c));
+
+ $this->assertEquals(Set::merge($a, $b, array(), $c), $expected);
+
+ $r = Set::merge($a, $b, $c);
+ $this->assertEquals($expected, $r);
+
+ $a = array('Tree', 'CounterCache',
+ 'Upload' => array('folder' => 'products',
+ 'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')));
+ $b = array('Cacheable' => array('enabled' => false),
+ 'Limit',
+ 'Bindable',
+ 'Validator',
+ 'Transactional');
+
+ $expected = array('Tree', 'CounterCache',
+ 'Upload' => array('folder' => 'products',
+ 'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')),
+ 'Cacheable' => array('enabled' => false),
+ 'Limit',
+ 'Bindable',
+ 'Validator',
+ 'Transactional');
+
+ $this->assertEquals($expected, Set::merge($a, $b));
+
+ $expected = array('Tree' => null, 'CounterCache' => null,
+ 'Upload' => array('folder' => 'products',
+ 'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')),
+ 'Cacheable' => array('enabled' => false),
+ 'Limit' => null,
+ 'Bindable' => null,
+ 'Validator' => null,
+ 'Transactional' => null);
+
+ $this->assertEquals($expected, Set::normalize(Set::merge($a, $b)));
+ }
+
+/**
+ * testSort method
+ *
+ * @return void
+ */
+ public function testSort() {
+ $a = array(
+ 0 => array('Person' => array('name' => 'Jeff'), 'Friend' => array(array('name' => 'Nate'))),
+ 1 => array('Person' => array('name' => 'Tracy'),'Friend' => array(array('name' => 'Lindsay')))
+ );
+ $b = array(
+ 0 => array('Person' => array('name' => 'Tracy'),'Friend' => array(array('name' => 'Lindsay'))),
+ 1 => array('Person' => array('name' => 'Jeff'), 'Friend' => array(array('name' => 'Nate')))
+
+ );
+ $a = Set::sort($a, '{n}.Friend.{n}.name', 'asc');
+ $this->assertEquals($a, $b);
+
+ $b = array(
+ 0 => array('Person' => array('name' => 'Jeff'), 'Friend' => array(array('name' => 'Nate'))),
+ 1 => array('Person' => array('name' => 'Tracy'),'Friend' => array(array('name' => 'Lindsay')))
+ );
+ $a = array(
+ 0 => array('Person' => array('name' => 'Tracy'),'Friend' => array(array('name' => 'Lindsay'))),
+ 1 => array('Person' => array('name' => 'Jeff'), 'Friend' => array(array('name' => 'Nate')))
+
+ );
+ $a = Set::sort($a, '{n}.Friend.{n}.name', 'desc');
+ $this->assertEquals($a, $b);
+
+ $a = array(
+ 0 => array('Person' => array('name' => 'Jeff'), 'Friend' => array(array('name' => 'Nate'))),
+ 1 => array('Person' => array('name' => 'Tracy'),'Friend' => array(array('name' => 'Lindsay'))),
+ 2 => array('Person' => array('name' => 'Adam'),'Friend' => array(array('name' => 'Bob')))
+ );
+ $b = array(
+ 0 => array('Person' => array('name' => 'Adam'),'Friend' => array(array('name' => 'Bob'))),
+ 1 => array('Person' => array('name' => 'Jeff'), 'Friend' => array(array('name' => 'Nate'))),
+ 2 => array('Person' => array('name' => 'Tracy'),'Friend' => array(array('name' => 'Lindsay')))
+ );
+ $a = Set::sort($a, '{n}.Person.name', 'asc');
+ $this->assertEquals($a, $b);
+
+ $a = array(
+ array(7,6,4),
+ array(3,4,5),
+ array(3,2,1),
+ );
+
+ $b = array(
+ array(3,2,1),
+ array(3,4,5),
+ array(7,6,4),
+ );
+
+ $a = Set::sort($a, '{n}.{n}', 'asc');
+ $this->assertEquals($a, $b);
+
+ $a = array(
+ array(7,6,4),
+ array(3,4,5),
+ array(3,2,array(1,1,1)),
+ );
+
+ $b = array(
+ array(3,2,array(1,1,1)),
+ array(3,4,5),
+ array(7,6,4),
+ );
+
+ $a = Set::sort($a, '{n}', 'asc');
+ $this->assertEquals($a, $b);
+
+ $a = array(
+ 0 => array('Person' => array('name' => 'Jeff')),
+ 1 => array('Shirt' => array('color' => 'black'))
+ );
+ $b = array(
+ 0 => array('Shirt' => array('color' => 'black')),
+ 1 => array('Person' => array('name' => 'Jeff')),
+ );
+ $a = Set::sort($a, '{n}.Person.name', 'ASC');
+ $this->assertEquals($a, $b);
+
+ $names = array(
+ array('employees' => array(array('name' => array('first' => 'John', 'last' => 'Doe')))),
+ array('employees' => array(array('name' => array('first' => 'Jane', 'last' => 'Doe')))),
+ array('employees' => array(array('name' => array()))),
+ array('employees' => array(array('name' => array())))
+ );
+ $result = Set::sort($names, '{n}.employees.0.name', 'asc', 1);
+ $expected = array(
+ array('employees' => array(array('name' => array('first' => 'John', 'last' => 'Doe')))),
+ array('employees' => array(array('name' => array('first' => 'Jane', 'last' => 'Doe')))),
+ array('employees' => array(array('name' => array()))),
+ array('employees' => array(array('name' => array())))
+ );
+ $this->assertEquals($expected, $result);
+
+ $menus = array(
+ 'blogs' => array('title' => 'Blogs', 'weight' => 3),
+ 'comments' => array('title' => 'Comments', 'weight' => 2),
+ 'users' => array('title' => 'Users', 'weight' => 1),
+ );
+ $expected = array(
+ 'users' => array('title' => 'Users', 'weight' => 1),
+ 'comments' => array('title' => 'Comments', 'weight' => 2),
+ 'blogs' => array('title' => 'Blogs', 'weight' => 3),
+ );
+ $result = Set::sort($menus, '{[a-z]+}.weight', 'ASC');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test sorting with string keys.
+ *
+ * @return void
+ */
+ public function testSortString() {
+ $toSort = array(
+ 'four' => array('number' => 4, 'some' => 'foursome'),
+ 'six' => array('number' => 6, 'some' => 'sixsome'),
+ 'five' => array('number' => 5, 'some' => 'fivesome'),
+ 'two' => array('number' => 2, 'some' => 'twosome'),
+ 'three' => array('number' => 3, 'some' => 'threesome')
+ );
+ $sorted = Set::sort($toSort, '{s}.number', 'asc');
+ $expected = array(
+ 'two' => array('number' => 2, 'some' => 'twosome'),
+ 'three' => array('number' => 3, 'some' => 'threesome'),
+ 'four' => array('number' => 4, 'some' => 'foursome'),
+ 'five' => array('number' => 5, 'some' => 'fivesome'),
+ 'six' => array('number' => 6, 'some' => 'sixsome')
+ );
+ $this->assertEquals($expected, $sorted);
+ }
+
+/**
+ * test sorting with out of order keys.
+ *
+ * @return void
+ */
+ public function testSortWithOutOfOrderKeys() {
+ $data = array(
+ 9 => array('class' => 510, 'test2' => 2),
+ 1 => array('class' => 500, 'test2' => 1),
+ 2 => array('class' => 600, 'test2' => 2),
+ 5 => array('class' => 625, 'test2' => 4),
+ 0 => array('class' => 605, 'test2' => 3),
+ );
+ $expected = array(
+ array('class' => 500, 'test2' => 1),
+ array('class' => 510, 'test2' => 2),
+ array('class' => 600, 'test2' => 2),
+ array('class' => 605, 'test2' => 3),
+ array('class' => 625, 'test2' => 4),
+ );
+ $result = Set::sort($data, '{n}.class', 'asc');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::sort($data, '{n}.test2', 'asc');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testExtract method
+ *
+ * @return void
+ */
+ public function testExtract() {
+ $a = array(
+ array(
+ 'Article' => array('id' => '1', 'user_id' => '1', 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ 'User' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ 'Comment' => array(
+ array('id' => '1', 'article_id' => '1', 'user_id' => '2', 'comment' => 'First Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'),
+ array('id' => '2', 'article_id' => '1', 'user_id' => '4', 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'),
+ ),
+ 'Tag' => array(
+ array('id' => '1', 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
+ array('id' => '2', 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31')
+ ),
+ 'Deep' => array(
+ 'Nesting' => array(
+ 'test' => array(
+ 1 => 'foo',
+ 2 => array(
+ 'and' => array('more' => 'stuff')
+ )
+ )
+ )
+ )
+ ),
+ array(
+ 'Article' => array('id' => '3', 'user_id' => '1', 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
+ 'User' => array('id' => '2', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ 'Comment' => array(),
+ 'Tag' => array()
+ ),
+ array(
+ 'Article' => array('id' => '3', 'user_id' => '1', 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
+ 'User' => array('id' => '3', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ 'Comment' => array(),
+ 'Tag' => array()
+ ),
+ array(
+ 'Article' => array('id' => '3', 'user_id' => '1', 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
+ 'User' => array('id' => '4', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ 'Comment' => array(),
+ 'Tag' => array()
+ ),
+ array(
+ 'Article' => array('id' => '3', 'user_id' => '1', 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
+ 'User' => array('id' => '5', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ 'Comment' => array(),
+ 'Tag' => array()
+ )
+ );
+ $b = array('Deep' => $a[0]['Deep']);
+ $c = array(
+ array('a' => array('I' => array('a' => 1))),
+ array(
+ 'a' => array(
+ 2
+ )
+ ),
+ array('a' => array('II' => array('a' => 3, 'III' => array('a' => array('foo' => 4))))),
+ );
+
+ $expected = array(array('a' => $c[2]['a']));
+ $r = Set::extract('/a/II[a=3]/..', $c);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(1, 2, 3, 4, 5);
+ $this->assertEquals($expected, Set::extract('/User/id', $a));
+
+ $expected = array(1, 2, 3, 4, 5);
+ $this->assertEquals($expected, Set::extract('/User/id', $a));
+
+ $expected = array(
+ array('id' => 1), array('id' => 2), array('id' => 3), array('id' => 4), array('id' => 5)
+ );
+
+ $r = Set::extract('/User/id', $a, array('flatten' => false));
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('test' => $a[0]['Deep']['Nesting']['test']));
+ $this->assertEquals($expected, Set::extract('/Deep/Nesting/test', $a));
+ $this->assertEquals($expected, Set::extract('/Deep/Nesting/test', $b));
+
+ $expected = array(array('test' => $a[0]['Deep']['Nesting']['test']));
+ $r = Set::extract('/Deep/Nesting/test/1/..', $a);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('test' => $a[0]['Deep']['Nesting']['test']));
+ $r = Set::extract('/Deep/Nesting/test/2/and/../..', $a);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('test' => $a[0]['Deep']['Nesting']['test']));
+ $r = Set::extract('/Deep/Nesting/test/2/../../../Nesting/test/2/..', $a);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(2);
+ $r = Set::extract('/User[2]/id', $a);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(4, 5);
+ $r = Set::extract('/User[id>3]/id', $a);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(2, 3);
+ $r = Set::extract('/User[id>1][id<=3]/id', $a);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('I'), array('II'));
+ $r = Set::extract('/a/@*', $c);
+ $this->assertEquals($expected, $r);
+
+ $single = array(
+ 'User' => array(
+ 'id' => 4,
+ 'name' => 'Neo',
+ )
+ );
+ $tricky = array(
+ 0 => array(
+ 'User' => array(
+ 'id' => 1,
+ 'name' => 'John',
+ )
+ ),
+ 1 => array(
+ 'User' => array(
+ 'id' => 2,
+ 'name' => 'Bob',
+ )
+ ),
+ 2 => array(
+ 'User' => array(
+ 'id' => 3,
+ 'name' => 'Tony',
+ )
+ ),
+ 'User' => array(
+ 'id' => 4,
+ 'name' => 'Neo',
+ )
+ );
+
+ $expected = array(1, 2, 3, 4);
+ $r = Set::extract('/User/id', $tricky);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(4);
+ $r = Set::extract('/User/id', $single);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(1, 3);
+ $r = Set::extract('/User[name=/n/]/id', $tricky);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(4);
+ $r = Set::extract('/User[name=/N/]/id', $tricky);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(1, 3, 4);
+ $r = Set::extract('/User[name=/N/i]/id', $tricky);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('id', 'name'), array('id', 'name'), array('id', 'name'), array('id', 'name'));
+ $r = Set::extract('/User/@*', $tricky);
+ $this->assertEquals($expected, $r);
+
+ $common = array(
+ array(
+ 'Article' => array(
+ 'id' => 1,
+ 'name' => 'Article 1',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'user_id' => 5,
+ 'article_id' => 1,
+ 'text' => 'Comment 1',
+ ),
+ array(
+ 'id' => 2,
+ 'user_id' => 23,
+ 'article_id' => 1,
+ 'text' => 'Comment 2',
+ ),
+ array(
+ 'id' => 3,
+ 'user_id' => 17,
+ 'article_id' => 1,
+ 'text' => 'Comment 3',
+ ),
+ ),
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2,
+ 'name' => 'Article 2',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 4,
+ 'user_id' => 2,
+ 'article_id' => 2,
+ 'text' => 'Comment 4',
+ 'addition' => '',
+ ),
+ array(
+ 'id' => 5,
+ 'user_id' => 23,
+ 'article_id' => 2,
+ 'text' => 'Comment 5',
+ 'addition' => 'foo',
+ ),
+ ),
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 3,
+ 'name' => 'Article 3',
+ ),
+ 'Comment' => array(),
+ )
+ );
+
+ $r = Set::extract('/Comment/id', $common);
+ $expected = array(1, 2, 3, 4, 5);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(1, 2, 4, 5);
+ $r = Set::extract('/Comment[id!=3]/id', $common);
+ $this->assertEquals($expected, $r);
+
+ $r = Set::extract('/', $common);
+ $this->assertEquals($r, $common);
+
+ $expected = array(1, 2, 4, 5);
+ $r = Set::extract($common, '/Comment[id!=3]/id');
+ $this->assertEquals($expected, $r);
+
+ $expected = array($common[0]['Comment'][2]);
+ $r = Set::extract($common, '/Comment/2');
+ $this->assertEquals($expected, $r);
+
+ $expected = array($common[0]['Comment'][0]);
+ $r = Set::extract($common, '/Comment[1]/.[id=1]');
+ $this->assertEquals($expected, $r);
+
+ $expected = array($common[1]['Comment'][1]);
+ $r = Set::extract($common, '/1/Comment/.[2]');
+ $this->assertEquals($expected, $r);
+
+ $expected = array();
+ $r = Set::extract('/User/id', array());
+ $this->assertEquals($expected, $r);
+
+ $expected = array(5);
+ $r = Set::extract('/Comment/id[:last]', $common);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(1);
+ $r = Set::extract('/Comment/id[:first]', $common);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(3);
+ $r = Set::extract('/Article[:last]/id', $common);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('Comment' => $common[1]['Comment'][0]));
+ $r = Set::extract('/Comment[addition=]', $common);
+ $this->assertEquals($expected, $r);
+
+ $habtm = array(
+ array(
+ 'Post' => array(
+ 'id' => 1,
+ 'title' => 'great post',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'text' => 'foo',
+ 'User' => array(
+ 'id' => 1,
+ 'name' => 'bob'
+ ),
+ ),
+ array(
+ 'id' => 2,
+ 'text' => 'bar',
+ 'User' => array(
+ 'id' => 2,
+ 'name' => 'tod'
+ ),
+ ),
+ ),
+ ),
+ array(
+ 'Post' => array(
+ 'id' => 2,
+ 'title' => 'fun post',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 3,
+ 'text' => '123',
+ 'User' => array(
+ 'id' => 3,
+ 'name' => 'dan'
+ ),
+ ),
+ array(
+ 'id' => 4,
+ 'text' => '987',
+ 'User' => array(
+ 'id' => 4,
+ 'name' => 'jim'
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $r = Set::extract('/Comment/User[name=/bob|dan/]/..', $habtm);
+ $this->assertEquals('bob', $r[0]['Comment']['User']['name']);
+ $this->assertEquals('dan', $r[1]['Comment']['User']['name']);
+ $this->assertEquals(2, count($r));
+
+ $r = Set::extract('/Comment/User[name=/bob|tod/]/..', $habtm);
+ $this->assertEquals('bob', $r[0]['Comment']['User']['name']);
+
+ $this->assertEquals('tod', $r[1]['Comment']['User']['name']);
+ $this->assertEquals(2, count($r));
+
+ $tree = array(
+ array(
+ 'Category' => array('name' => 'Category 1'),
+ 'children' => array(array('Category' => array('name' => 'Category 1.1')))
+ ),
+ array(
+ 'Category' => array('name' => 'Category 2'),
+ 'children' => array(
+ array('Category' => array('name' => 'Category 2.1')),
+ array('Category' => array('name' => 'Category 2.2'))
+ )
+ ),
+ array(
+ 'Category' => array('name' => 'Category 3'),
+ 'children' => array(array('Category' => array('name' => 'Category 3.1')))
+ )
+ );
+
+ $expected = array(array('Category' => $tree[1]['Category']));
+ $r = Set::extract('/Category[name=Category 2]', $tree);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(
+ array('Category' => $tree[1]['Category'], 'children' => $tree[1]['children'])
+ );
+ $r = Set::extract('/Category[name=Category 2]/..', $tree);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(
+ array('children' => $tree[1]['children'][0]),
+ array('children' => $tree[1]['children'][1])
+ );
+ $r = Set::extract('/Category[name=Category 2]/../children', $tree);
+ $this->assertEquals($expected, $r);
+
+ $habtm = array(
+ array(
+ 'Post' => array(
+ 'id' => 1,
+ 'title' => 'great post',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 1,
+ 'text' => 'foo',
+ 'User' => array(
+ 'id' => 1,
+ 'name' => 'bob'
+ ),
+ ),
+ array(
+ 'id' => 2,
+ 'text' => 'bar',
+ 'User' => array(
+ 'id' => 2,
+ 'name' => 'tod'
+ ),
+ ),
+ ),
+ ),
+ array(
+ 'Post' => array(
+ 'id' => 2,
+ 'title' => 'fun post',
+ ),
+ 'Comment' => array(
+ array(
+ 'id' => 3,
+ 'text' => '123',
+ 'User' => array(
+ 'id' => 3,
+ 'name' => 'dan'
+ ),
+ ),
+ array(
+ 'id' => 4,
+ 'text' => '987',
+ 'User' => array(
+ 'id' => 4,
+ 'name' => 'jim'
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $r = Set::extract('/Comment/User[name=/\w+/]/..', $habtm);
+ $this->assertEquals('bob', $r[0]['Comment']['User']['name']);
+ $this->assertEquals('tod', $r[1]['Comment']['User']['name']);
+ $this->assertEquals('dan', $r[2]['Comment']['User']['name']);
+ $this->assertEquals('dan', $r[3]['Comment']['User']['name']);
+ $this->assertEquals(4, count($r));
+
+ $r = Set::extract('/Comment/User[name=/[a-z]+/]/..', $habtm);
+ $this->assertEquals('bob', $r[0]['Comment']['User']['name']);
+ $this->assertEquals('tod', $r[1]['Comment']['User']['name']);
+ $this->assertEquals('dan', $r[2]['Comment']['User']['name']);
+ $this->assertEquals('dan', $r[3]['Comment']['User']['name']);
+ $this->assertEquals(4, count($r));
+
+ $r = Set::extract('/Comment/User[name=/bob|dan/]/..', $habtm);
+ $this->assertEquals('bob', $r[0]['Comment']['User']['name']);
+ $this->assertEquals('dan', $r[1]['Comment']['User']['name']);
+ $this->assertEquals(2, count($r));
+
+ $r = Set::extract('/Comment/User[name=/bob|tod/]/..', $habtm);
+ $this->assertEquals('bob', $r[0]['Comment']['User']['name']);
+ $this->assertEquals('tod', $r[1]['Comment']['User']['name']);
+ $this->assertEquals(2, count($r));
+
+ $mixedKeys = array(
+ 'User' => array(
+ 0 => array(
+ 'id' => 4,
+ 'name' => 'Neo'
+ ),
+ 1 => array(
+ 'id' => 5,
+ 'name' => 'Morpheus'
+ ),
+ 'stringKey' => array()
+ )
+ );
+ $expected = array('Neo', 'Morpheus');
+ $r = Set::extract('/User/name', $mixedKeys);
+ $this->assertEquals($expected, $r);
+
+ $f = array(
+ array(
+ 'file' => array(
+ 'name' => 'zipfile.zip',
+ 'type' => 'application/zip',
+ 'tmp_name' => '/tmp/php178.tmp',
+ 'error' => 0,
+ 'size' => '564647'
+ )
+ ),
+ array(
+ 'file' => array(
+ 'name' => 'zipfile2.zip',
+ 'type' => 'application/x-zip-compressed',
+ 'tmp_name' => '/tmp/php179.tmp',
+ 'error' => 0,
+ 'size' => '354784'
+ )
+ ),
+ array(
+ 'file' => array(
+ 'name' => 'picture.jpg',
+ 'type' => 'image/jpeg',
+ 'tmp_name' => '/tmp/php180.tmp',
+ 'error' => 0,
+ 'size' => '21324'
+ )
+ )
+ );
+ $expected = array(array('name' => 'zipfile2.zip','type' => 'application/x-zip-compressed','tmp_name' => '/tmp/php179.tmp','error' => 0,'size' => '354784'));
+ $r = Set::extract('/file/.[type=application/x-zip-compressed]', $f);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('name' => 'zipfile.zip','type' => 'application/zip','tmp_name' => '/tmp/php178.tmp','error' => 0,'size' => '564647'));
+ $r = Set::extract('/file/.[type=application/zip]', $f);
+ $this->assertEquals($expected, $r);
+
+ $f = array(
+ array(
+ 'file' => array(
+ 'name' => 'zipfile.zip',
+ 'type' => 'application/zip',
+ 'tmp_name' => '/tmp/php178.tmp',
+ 'error' => 0,
+ 'size' => '564647'
+ )
+ ),
+ array(
+ 'file' => array(
+ 'name' => 'zipfile2.zip',
+ 'type' => 'application/x zip compressed',
+ 'tmp_name' => '/tmp/php179.tmp',
+ 'error' => 0,
+ 'size' => '354784'
+ )
+ ),
+ array(
+ 'file' => array(
+ 'name' => 'picture.jpg',
+ 'type' => 'image/jpeg',
+ 'tmp_name' => '/tmp/php180.tmp',
+ 'error' => 0,
+ 'size' => '21324'
+ )
+ )
+ );
+ $expected = array(array('name' => 'zipfile2.zip','type' => 'application/x zip compressed','tmp_name' => '/tmp/php179.tmp','error' => 0,'size' => '354784'));
+ $r = Set::extract('/file/.[type=application/x zip compressed]', $f);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(
+ array('name' => 'zipfile.zip','type' => 'application/zip','tmp_name' => '/tmp/php178.tmp','error' => 0,'size' => '564647'),
+ array('name' => 'zipfile2.zip','type' => 'application/x zip compressed','tmp_name' => '/tmp/php179.tmp','error' => 0,'size' => '354784')
+ );
+ $r = Set::extract('/file/.[tmp_name=/tmp\/php17/]', $f);
+ $this->assertEquals($expected, $r);
+
+ $hasMany = array(
+ 'Node' => array(
+ 'id' => 1,
+ 'name' => 'First',
+ 'state' => 50
+ ),
+ 'ParentNode' => array(
+ 0 => array(
+ 'id' => 2,
+ 'name' => 'Second',
+ 'state' => 60,
+ )
+ )
+ );
+ $result = Set::extract('/ParentNode/name', $hasMany);
+ $expected = array('Second');
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ array(
+ 'Category' => array(
+ 'id' => 1,
+ 'name' => 'First'
+ ),
+ 0 => array(
+ 'value' => 50
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'id' => 2,
+ 'name' => 'Second'
+ ),
+ 0 => array(
+ 'value' => 60
+ )
+ )
+ );
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => 1,
+ 'name' => 'First'
+ ),
+ 0 => array(
+ 'value' => 50
+ )
+ )
+ );
+ $result = Set::extract('/Category[id=1]/..', $data);
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ array(
+ 'ChildNode' => array('id' => 1),
+ array('name' => 'Item 1')
+ ),
+ array(
+ 'ChildNode' => array('id' => 2),
+ array('name' => 'Item 2')
+ ),
+ );
+
+ $expected = array(
+ 'Item 1',
+ 'Item 2'
+ );
+ $result = Set::extract('/0/name', $data);
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ array('A1', 'B1'),
+ array('A2', 'B2')
+ );
+ $expected = array('A1', 'A2');
+ $result = Set::extract('/0', $data);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test parent selectors with extract
+ *
+ * @return void
+ */
+ public function testExtractParentSelector() {
+ $tree = array(
+ array(
+ 'Category' => array(
+ 'name' => 'Category 1'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'name' => 'Category 1.1'
+ )
+ )
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'name' => 'Category 2'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'name' => 'Category 2.1'
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'name' => 'Category 2.2'
+ )
+ ),
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'name' => 'Category 3'
+ ),
+ 'children' => array(
+ array(
+ 'Category' => array(
+ 'name' => 'Category 3.1'
+ )
+ )
+ )
+ )
+ );
+ $expected = array(array('Category' => $tree[1]['Category']));
+ $r = Set::extract('/Category[name=Category 2]', $tree);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('Category' => $tree[1]['Category'], 'children' => $tree[1]['children']));
+ $r = Set::extract('/Category[name=Category 2]/..', $tree);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(array('children' => $tree[1]['children'][0]), array('children' => $tree[1]['children'][1]));
+ $r = Set::extract('/Category[name=Category 2]/../children', $tree);
+ $this->assertEquals($expected, $r);
+
+ $single = array(
+ array(
+ 'CallType' => array(
+ 'name' => 'Internal Voice'
+ ),
+ 'x' => array(
+ 'hour' => 7
+ )
+ )
+ );
+
+ $expected = array(7);
+ $r = Set::extract('/CallType[name=Internal Voice]/../x/hour', $single);
+ $this->assertEquals($expected, $r);
+
+ $multiple = array(
+ array(
+ 'CallType' => array(
+ 'name' => 'Internal Voice'
+ ),
+ 'x' => array(
+ 'hour' => 7
+ )
+ ),
+ array(
+ 'CallType' => array(
+ 'name' => 'Internal Voice'
+ ),
+ 'x' => array(
+ 'hour' => 2
+ )
+ ),
+ array(
+ 'CallType' => array(
+ 'name' => 'Internal Voice'
+ ),
+ 'x' => array(
+ 'hour' => 1
+ )
+ )
+ );
+
+ $expected = array(7,2,1);
+ $r = Set::extract('/CallType[name=Internal Voice]/../x/hour', $multiple);
+ $this->assertEquals($expected, $r);
+
+ $a = array(
+ 'Model' => array(
+ '0' => array(
+ 'id' => 18,
+ 'SubModelsModel' => array(
+ 'id' => 1,
+ 'submodel_id' => 66,
+ 'model_id' => 18,
+ 'type' => 1
+ ),
+ ),
+ '1' => array(
+ 'id' => 0,
+ 'SubModelsModel' => array(
+ 'id' => 2,
+ 'submodel_id' => 66,
+ 'model_id' => 0,
+ 'type' => 1
+ ),
+ ),
+ '2' => array(
+ 'id' => 17,
+ 'SubModelsModel' => array(
+ 'id' => 3,
+ 'submodel_id' => 66,
+ 'model_id' => 17,
+ 'type' => 2
+ ),
+ ),
+ '3' => array(
+ 'id' => 0,
+ 'SubModelsModel' => array(
+ 'id' => 4,
+ 'submodel_id' => 66,
+ 'model_id' => 0,
+ 'type' => 2
+ )
+ )
+ )
+ );
+
+ $expected = array(
+ array(
+ 'Model' => array(
+ 'id' => 17,
+ 'SubModelsModel' => array(
+ 'id' => 3,
+ 'submodel_id' => 66,
+ 'model_id' => 17,
+ 'type' => 2
+ ),
+ )
+ ),
+ array(
+ 'Model' => array(
+ 'id' => 0,
+ 'SubModelsModel' => array(
+ 'id' => 4,
+ 'submodel_id' => 66,
+ 'model_id' => 0,
+ 'type' => 2
+ )
+ )
+ )
+ );
+ $r = Set::extract('/Model/SubModelsModel[type=2]/..', $a);
+ $this->assertEquals($expected, $r);
+ }
+
+/**
+ * test that extract() still works when arrays don't contain a 0 index.
+ *
+ * @return void
+ */
+ public function testExtractWithNonZeroArrays() {
+ $nonZero = array(
+ 1 => array(
+ 'User' => array(
+ 'id' => 1,
+ 'name' => 'John',
+ )
+ ),
+ 2 => array(
+ 'User' => array(
+ 'id' => 2,
+ 'name' => 'Bob',
+ )
+ ),
+ 3 => array(
+ 'User' => array(
+ 'id' => 3,
+ 'name' => 'Tony',
+ )
+ )
+ );
+ $expected = array(1, 2, 3);
+ $r = Set::extract('/User/id', $nonZero);
+ $this->assertEquals($expected, $r);
+
+ $expected = array(
+ array('User' => array('id' => 1, 'name' => 'John')),
+ array('User' => array('id' => 2, 'name' => 'Bob')),
+ array('User' => array('id' => 3, 'name' => 'Tony')),
+ );
+ $result = Set::extract('/User', $nonZero);
+ $this->assertEquals($expected, $result);
+
+ $nonSequential = array(
+ 'User' => array(
+ 0 => array('id' => 1),
+ 2 => array('id' => 2),
+ 6 => array('id' => 3),
+ 9 => array('id' => 4),
+ 3 => array('id' => 5),
+ ),
+ );
+
+ $nonZero = array(
+ 'User' => array(
+ 2 => array('id' => 1),
+ 4 => array('id' => 2),
+ 6 => array('id' => 3),
+ 9 => array('id' => 4),
+ 3 => array('id' => 5),
+ ),
+ );
+
+ $expected = array(1, 2, 3, 4, 5);
+ $this->assertEquals($expected, Set::extract('/User/id', $nonSequential));
+
+ $result = Set::extract('/User/id', $nonZero);
+ $this->assertEquals($expected, $result, 'Failed non zero array key extract');
+
+ $expected = array(1, 2, 3, 4, 5);
+ $this->assertEquals($expected, Set::extract('/User/id', $nonSequential));
+
+ $result = Set::extract('/User/id', $nonZero);
+ $this->assertEquals($expected, $result, 'Failed non zero array key extract');
+
+ $startingAtOne = array(
+ 'Article' => array(
+ 1 => array(
+ 'id' => 1,
+ 'approved' => 1,
+ ),
+ )
+ );
+
+ $expected = array(0 => array('Article' => array('id' => 1, 'approved' => 1)));
+ $result = Set::extract('/Article[approved=1]', $startingAtOne);
+ $this->assertEquals($expected, $result);
+
+ $items = array(
+ 240 => array(
+ 'A' => array(
+ 'field1' => 'a240',
+ 'field2' => 'a240',
+ ),
+ 'B' => array(
+ 'field1' => 'b240',
+ 'field2' => 'b240'
+ ),
+ )
+ );
+
+ $expected = array(
+ 0 => 'b240'
+ );
+
+ $result = Set::extract('/B/field1', $items);
+ $this->assertSame($expected, $result);
+ $this->assertSame($result, Set::extract('{n}.B.field1', $items));
+ }
+
+/**
+ * testExtractWithArrays method
+ *
+ * @return void
+ */
+ public function testExtractWithArrays() {
+ $data = array(
+ 'Level1' => array(
+ 'Level2' => array('test1', 'test2'),
+ 'Level2bis' => array('test3', 'test4')
+ )
+ );
+ $this->assertEquals(array(array('Level2' => array('test1', 'test2'))), Set::extract('/Level1/Level2', $data));
+ $this->assertEquals(array(array('Level2bis' => array('test3', 'test4'))), Set::extract('/Level1/Level2bis', $data));
+ }
+
+/**
+ * test extract() with elements that have non-array children.
+ *
+ * @return void
+ */
+ public function testExtractWithNonArrayElements() {
+ $data = array(
+ 'node' => array(
+ array('foo'),
+ 'bar'
+ )
+ );
+ $result = Set::extract('/node', $data);
+ $expected = array(
+ array('node' => array('foo')),
+ 'bar'
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'node' => array(
+ 'foo' => array('bar'),
+ 'bar' => array('foo')
+ )
+ );
+ $result = Set::extract('/node', $data);
+ $expected = array(
+ array('foo' => array('bar')),
+ array('bar' => array('foo')),
+ );
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ 'node' => array(
+ 'foo' => array(
+ 'bar'
+ ),
+ 'bar' => 'foo'
+ )
+ );
+ $result = Set::extract('/node', $data);
+ $expected = array(
+ array('foo' => array('bar')),
+ 'foo'
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that extract() + matching can hit null things.
+ */
+ public function testExtractMatchesNull() {
+ $data = array(
+ 'Country' => array(
+ array('name' => 'Canada'),
+ array('name' => 'Australia'),
+ array('name' => null),
+ )
+ );
+ $result = Set::extract('/Country[name=/Canada|^$/]', $data);
+ $expected = array(
+ array(
+ 'Country' => array(
+ 'name' => 'Canada',
+ ),
+ ),
+ array(
+ 'Country' => array(
+ 'name' => null,
+ ),
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMatches method
+ *
+ * @return void
+ */
+ public function testMatches() {
+ $a = array(
+ array('Article' => array('id' => 1, 'title' => 'Article 1')),
+ array('Article' => array('id' => 2, 'title' => 'Article 2')),
+ array('Article' => array('id' => 3, 'title' => 'Article 3'))
+ );
+
+ $this->assertTrue(Set::matches(array('id=2'), $a[1]['Article']));
+ $this->assertFalse(Set::matches(array('id>2'), $a[1]['Article']));
+ $this->assertTrue(Set::matches(array('id>=2'), $a[1]['Article']));
+ $this->assertFalse(Set::matches(array('id>=3'), $a[1]['Article']));
+ $this->assertTrue(Set::matches(array('id<=2'), $a[1]['Article']));
+ $this->assertFalse(Set::matches(array('id<2'), $a[1]['Article']));
+ $this->assertTrue(Set::matches(array('id>1'), $a[1]['Article']));
+ $this->assertTrue(Set::matches(array('id>1', 'id<3', 'id!=0'), $a[1]['Article']));
+
+ $this->assertTrue(Set::matches(array('3'), null, 3));
+ $this->assertTrue(Set::matches(array('5'), null, 5));
+
+ $this->assertTrue(Set::matches(array('id'), $a[1]['Article']));
+ $this->assertTrue(Set::matches(array('id', 'title'), $a[1]['Article']));
+ $this->assertFalse(Set::matches(array('non-existant'), $a[1]['Article']));
+
+ $this->assertTrue(Set::matches('/Article[id=2]', $a));
+ $this->assertFalse(Set::matches('/Article[id=4]', $a));
+ $this->assertTrue(Set::matches(array(), $a));
+
+ $r = array(
+ 'Attachment' => array(
+ 'keep' => array()
+ ),
+ 'Comment' => array(
+ 'keep' => array(
+ 'Attachment' => array(
+ 'fields' => array(
+ 0 => 'attachment',
+ ),
+ ),
+ )
+ ),
+ 'User' => array(
+ 'keep' => array()
+ ),
+ 'Article' => array(
+ 'keep' => array(
+ 'Comment' => array(
+ 'fields' => array(
+ 0 => 'comment',
+ 1 => 'published',
+ ),
+ ),
+ 'User' => array(
+ 'fields' => array(
+ 0 => 'user',
+ ),
+ ),
+ )
+ )
+ );
+
+ $this->assertTrue(Set::matches('/Article/keep/Comment', $r));
+ $this->assertEquals(array('comment', 'published'), Set::extract('/Article/keep/Comment/fields', $r));
+ $this->assertEquals(array('user'), Set::extract('/Article/keep/User/fields', $r));
+ }
+
+/**
+ * testSetExtractReturnsEmptyArray method
+ *
+ * @return void
+ */
+ public function testSetExtractReturnsEmptyArray() {
+ $this->assertEquals(Set::extract(array(), '/Post/id'), array());
+
+ $this->assertEquals(Set::extract('/Post/id', array()), array());
+
+ $this->assertEquals(Set::extract('/Post/id', array(
+ array('Post' => array('name' => 'bob')),
+ array('Post' => array('name' => 'jim'))
+ )), array());
+
+ $this->assertEquals(Set::extract(array(), 'Message.flash'), null);
+ }
+
+/**
+ * testClassicExtract method
+ *
+ * @return void
+ */
+ public function testClassicExtract() {
+ $a = array(
+ array('Article' => array('id' => 1, 'title' => 'Article 1')),
+ array('Article' => array('id' => 2, 'title' => 'Article 2')),
+ array('Article' => array('id' => 3, 'title' => 'Article 3'))
+ );
+
+ $result = Set::extract($a, '{n}.Article.id');
+ $expected = array(1, 2, 3);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{n}.Article.title');
+ $expected = array('Article 1', 'Article 2', 'Article 3');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '1.Article.title');
+ $expected = 'Article 2';
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '3.Article.title');
+ $expected = null;
+ $this->assertEquals($expected, $result);
+
+ $a = array(
+ array(
+ 'Article' => array('id' => 1, 'title' => 'Article 1',
+ 'User' => array('id' => 1, 'username' => 'mariano.iglesias'))
+ ),
+ array(
+ 'Article' => array('id' => 2, 'title' => 'Article 2',
+ 'User' => array('id' => 1, 'username' => 'mariano.iglesias'))
+ ),
+ array(
+ 'Article' => array('id' => 3, 'title' => 'Article 3',
+ 'User' => array('id' => 2, 'username' => 'phpnut'))
+ )
+ );
+
+ $result = Set::extract($a, '{n}.Article.User.username');
+ $expected = array('mariano.iglesias', 'mariano.iglesias', 'phpnut');
+ $this->assertEquals($expected, $result);
+
+ $a = array(
+ array(
+ 'Article' => array(
+ 'id' => 1, 'title' => 'Article 1',
+ 'Comment' => array(
+ array('id' => 10, 'title' => 'Comment 10'),
+ array('id' => 11, 'title' => 'Comment 11'),
+ array('id' => 12, 'title' => 'Comment 12')
+ )
+ )
+ ),
+ array(
+ 'Article' => array(
+ 'id' => 2, 'title' => 'Article 2',
+ 'Comment' => array(
+ array('id' => 13, 'title' => 'Comment 13'),
+ array('id' => 14, 'title' => 'Comment 14')
+ )
+ )
+ ),
+ array('Article' => array('id' => 3, 'title' => 'Article 3'))
+ );
+
+ $result = Set::extract($a, '{n}.Article.Comment.{n}.id');
+ $expected = array(array(10, 11, 12), array(13, 14), null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{n}.Article.Comment.{n}.title');
+ $expected = array(
+ array('Comment 10', 'Comment 11', 'Comment 12'),
+ array('Comment 13', 'Comment 14'),
+ null
+ );
+ $this->assertEquals($expected, $result);
+
+ $a = array(array('1day' => '20 sales'), array('1day' => '2 sales'));
+ $result = Set::extract($a, '{n}.1day');
+ $expected = array('20 sales', '2 sales');
+ $this->assertEquals($expected, $result);
+
+ $a = array(
+ 'pages' => array('name' => 'page'),
+ 'fruites' => array('name' => 'fruit'),
+ 0 => array('name' => 'zero')
+ );
+ $result = Set::extract($a, '{s}.name');
+ $expected = array('page','fruit');
+ $this->assertEquals($expected, $result);
+
+ $a = array(
+ 0 => array('pages' => array('name' => 'page')),
+ 1 => array('fruites' => array('name' => 'fruit')),
+ 'test' => array(array('name' => 'jippi')),
+ 'dot.test' => array(array('name' => 'jippi'))
+ );
+
+ $result = Set::extract($a, '{n}.{s}.name');
+ $expected = array(0 => array('page'), 1 => array('fruit'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{s}.{n}.name');
+ $expected = array(array('jippi'), array('jippi'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{\w+}.{\w+}.name');
+ $expected = array(
+ array('pages' => 'page'),
+ array('fruites' => 'fruit'),
+ 'test' => array('jippi'),
+ 'dot.test' => array('jippi')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{\d+}.{\w+}.name');
+ $expected = array(array('pages' => 'page'), array('fruites' => 'fruit'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{n}.{\w+}.name');
+ $expected = array(array('pages' => 'page'), array('fruites' => 'fruit'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{s}.{\d+}.name');
+ $expected = array(array('jippi'), array('jippi'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{s}');
+ $expected = array(array(array('name' => 'jippi')), array(array('name' => 'jippi')));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{[a-z]}');
+ $expected = array(
+ 'test' => array(array('name' => 'jippi')),
+ 'dot.test' => array(array('name' => 'jippi'))
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, '{dot\.test}.{n}');
+ $expected = array('dot.test' => array(array('name' => 'jippi')));
+ $this->assertEquals($expected, $result);
+
+ $a = new stdClass();
+ $a->articles = array(
+ array('Article' => array('id' => 1, 'title' => 'Article 1')),
+ array('Article' => array('id' => 2, 'title' => 'Article 2')),
+ array('Article' => array('id' => 3, 'title' => 'Article 3'))
+ );
+
+ $result = Set::extract($a, 'articles.{n}.Article.id');
+ $expected = array(1, 2, 3);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, 'articles.{n}.Article.title');
+ $expected = array('Article 1', 'Article 2', 'Article 3');
+ $this->assertEquals($expected, $result);
+
+ $a = new ArrayObject();
+ $a['articles'] = array(
+ array('Article' => array('id' => 1, 'title' => 'Article 1')),
+ array('Article' => array('id' => 2, 'title' => 'Article 2')),
+ array('Article' => array('id' => 3, 'title' => 'Article 3'))
+ );
+
+ $result = Set::extract($a, 'articles.{n}.Article.id');
+ $expected = array(1, 2, 3);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, 'articles.{n}.Article.title');
+ $expected = array('Article 1', 'Article 2', 'Article 3');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::extract($a, 'articles.0.Article.title');
+ $expected = 'Article 1';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test classicExtract with keys that exceed 32bit max int.
+ *
+ * @return void
+ */
+ public function testClassicExtractMaxInt() {
+ $data = array(
+ 'Data' => array(
+ '13376924712' => 'abc'
+ )
+ );
+ $this->assertEquals('abc', Set::classicExtract($data, 'Data.13376924712'));
+ }
+
+/**
+ * testInsert method
+ *
+ * @see Hash tests, as Set::insert() is just a proxy.
+ * @return void
+ */
+ public function testInsert() {
+ $a = array(
+ 'pages' => array('name' => 'page')
+ );
+
+ $result = Set::insert($a, 'files', array('name' => 'files'));
+ $expected = array(
+ 'pages' => array('name' => 'page'),
+ 'files' => array('name' => 'files')
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRemove method
+ *
+ * @return void
+ */
+ public function testRemove() {
+ $a = array(
+ 'pages' => array('name' => 'page'),
+ 'files' => array('name' => 'files')
+ );
+
+ $result = Set::remove($a, 'files');
+ $expected = array(
+ 'pages' => array('name' => 'page')
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCheck method
+ *
+ * @return void
+ */
+ public function testCheck() {
+ $set = array(
+ 'My Index 1' => array('First' => 'The first item')
+ );
+ $this->assertTrue(Set::check($set, 'My Index 1.First'));
+ $this->assertTrue(Set::check($set, 'My Index 1'));
+ $this->assertEquals(Set::check($set, array()), $set);
+
+ $set = array(
+ 'My Index 1' => array('First' => array('Second' => array('Third' => array('Fourth' => 'Heavy. Nesting.'))))
+ );
+ $this->assertTrue(Set::check($set, 'My Index 1.First.Second'));
+ $this->assertTrue(Set::check($set, 'My Index 1.First.Second.Third'));
+ $this->assertTrue(Set::check($set, 'My Index 1.First.Second.Third.Fourth'));
+ $this->assertFalse(Set::check($set, 'My Index 1.First.Seconds.Third.Fourth'));
+ }
+
+/**
+ * testWritingWithFunkyKeys method
+ *
+ * @return void
+ */
+ public function testWritingWithFunkyKeys() {
+ $set = Set::insert(array(), 'Session Test', "test");
+ $this->assertEquals('test', Set::extract($set, 'Session Test'));
+
+ $set = Set::remove($set, 'Session Test');
+ $this->assertFalse(Set::check($set, 'Session Test'));
+
+ $expected = array('Session Test' => array('Test Case' => 'test'));
+ $this->assertEquals(Set::insert(array(), 'Session Test.Test Case', "test"), $expected);
+ $this->assertTrue(Set::check($expected, 'Session Test.Test Case'));
+ }
+
+/**
+ * testDiff method
+ *
+ * @return void
+ */
+ public function testDiff() {
+ $a = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about')
+ );
+ $b = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about'),
+ 2 => array('name' => 'contact')
+ );
+
+ $result = Set::diff($a, $b);
+ $expected = array(
+ 2 => array('name' => 'contact')
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = Set::diff($a, array());
+ $expected = $a;
+ $this->assertEquals($expected, $result);
+
+ $result = Set::diff(array(), $b);
+ $expected = $b;
+ $this->assertEquals($expected, $result);
+
+ $b = array(
+ 0 => array('name' => 'me'),
+ 1 => array('name' => 'about')
+ );
+
+ $result = Set::diff($a, $b);
+ $expected = array(
+ 0 => array('name' => 'main')
+ );
+ $this->assertEquals($expected, $result);
+
+ $a = array();
+ $b = array('name' => 'bob', 'address' => 'home');
+ $result = Set::diff($a, $b);
+ $this->assertEquals($b, $result);
+
+ $a = array('name' => 'bob', 'address' => 'home');
+ $b = array();
+ $result = Set::diff($a, $b);
+ $this->assertEquals($a, $result);
+
+ $a = array('key' => true, 'another' => false, 'name' => 'me');
+ $b = array('key' => 1, 'another' => 0);
+ $expected = array('name' => 'me');
+ $result = Set::diff($a, $b);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array('key' => 'differentValue', 'another' => null);
+ $expected = array('key' => 'value', 'name' => 'me');
+ $result = Set::diff($a, $b);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array('key' => 'differentValue', 'another' => 'value');
+ $expected = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $result = Set::diff($a, $b);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array('key' => 'differentValue', 'another' => 'value');
+ $expected = array('key' => 'differentValue', 'another' => 'value', 'name' => 'me');
+ $result = Set::diff($b, $a);
+ $this->assertEquals($expected, $result);
+
+ $a = array('key' => 'value', 'another' => null, 'name' => 'me');
+ $b = array(0 => 'differentValue', 1 => 'value');
+ $expected = $a + $b;
+ $result = Set::diff($a, $b);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testContains method
+ *
+ * @return void
+ */
+ public function testContains() {
+ $a = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about')
+ );
+ $b = array(
+ 0 => array('name' => 'main'),
+ 1 => array('name' => 'about'),
+ 2 => array('name' => 'contact'),
+ 'a' => 'b'
+ );
+
+ $this->assertTrue(Set::contains($a, $a));
+ $this->assertFalse(Set::contains($a, $b));
+ $this->assertTrue(Set::contains($b, $a));
+ }
+
+/**
+ * testCombine method
+ *
+ * @return void
+ */
+ public function testCombine() {
+ $result = Set::combine(array(), '{n}.User.id', '{n}.User.Data');
+ $this->assertTrue(empty($result));
+ $result = Set::combine('', '{n}.User.id', '{n}.User.Data');
+ $this->assertTrue(empty($result));
+
+ $a = array(
+ array('User' => array('id' => 2, 'group_id' => 1,
+ 'Data' => array('user' => 'mariano.iglesias','name' => 'Mariano Iglesias'))),
+ array('User' => array('id' => 14, 'group_id' => 2,
+ 'Data' => array('user' => 'phpnut', 'name' => 'Larry E. Masters'))),
+ array('User' => array('id' => 25, 'group_id' => 1,
+ 'Data' => array('user' => 'gwoo','name' => 'The Gwoo'))));
+ $result = Set::combine($a, '{n}.User.id');
+ $expected = array(2 => null, 14 => null, 25 => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.non-existant');
+ $expected = array(2 => null, 14 => null, 25 => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data');
+ $expected = array(
+ 2 => array('user' => 'mariano.iglesias', 'name' => 'Mariano Iglesias'),
+ 14 => array('user' => 'phpnut', 'name' => 'Larry E. Masters'),
+ 25 => array('user' => 'gwoo', 'name' => 'The Gwoo'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name');
+ $expected = array(
+ 2 => 'Mariano Iglesias',
+ 14 => 'Larry E. Masters',
+ 25 => 'The Gwoo');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => array('user' => 'mariano.iglesias', 'name' => 'Mariano Iglesias'),
+ 25 => array('user' => 'gwoo', 'name' => 'The Gwoo')),
+ 2 => array(
+ 14 => array('user' => 'phpnut', 'name' => 'Larry E. Masters')));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => 'Mariano Iglesias',
+ 25 => 'The Gwoo'),
+ 2 => array(
+ 14 => 'Larry E. Masters'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id');
+ $expected = array(2 => null, 14 => null, 25 => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data');
+ $expected = array(
+ 2 => array('user' => 'mariano.iglesias', 'name' => 'Mariano Iglesias'),
+ 14 => array('user' => 'phpnut', 'name' => 'Larry E. Masters'),
+ 25 => array('user' => 'gwoo', 'name' => 'The Gwoo'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name');
+ $expected = array(2 => 'Mariano Iglesias', 14 => 'Larry E. Masters', 25 => 'The Gwoo');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => array('user' => 'mariano.iglesias', 'name' => 'Mariano Iglesias'),
+ 25 => array('user' => 'gwoo', 'name' => 'The Gwoo')),
+ 2 => array(
+ 14 => array('user' => 'phpnut', 'name' => 'Larry E. Masters')));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => 'Mariano Iglesias',
+ 25 => 'The Gwoo'),
+ 2 => array(
+ 14 => 'Larry E. Masters'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, '{n}.User.id', array('{0}: {1}', '{n}.User.Data.user', '{n}.User.Data.name'), '{n}.User.group_id');
+ $expected = array(
+ 1 => array(
+ 2 => 'mariano.iglesias: Mariano Iglesias',
+ 25 => 'gwoo: The Gwoo'),
+ 2 => array(14 => 'phpnut: Larry E. Masters'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, array('{0}: {1}', '{n}.User.Data.user', '{n}.User.Data.name'), '{n}.User.id');
+ $expected = array('mariano.iglesias: Mariano Iglesias' => 2, 'phpnut: Larry E. Masters' => 14, 'gwoo: The Gwoo' => 25);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, array('{1}: {0}', '{n}.User.Data.user', '{n}.User.Data.name'), '{n}.User.id');
+ $expected = array('Mariano Iglesias: mariano.iglesias' => 2, 'Larry E. Masters: phpnut' => 14, 'The Gwoo: gwoo' => 25);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, array('%1$s: %2$d', '{n}.User.Data.user', '{n}.User.id'), '{n}.User.Data.name');
+ $expected = array('mariano.iglesias: 2' => 'Mariano Iglesias', 'phpnut: 14' => 'Larry E. Masters', 'gwoo: 25' => 'The Gwoo');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, array('%2$d: %1$s', '{n}.User.Data.user', '{n}.User.id'), '{n}.User.Data.name');
+ $expected = array('2: mariano.iglesias' => 'Mariano Iglesias', '14: phpnut' => 'Larry E. Masters', '25: gwoo' => 'The Gwoo');
+ $this->assertEquals($expected, $result);
+
+ $b = new stdClass();
+ $b->users = array(
+ array('User' => array('id' => 2, 'group_id' => 1,
+ 'Data' => array('user' => 'mariano.iglesias','name' => 'Mariano Iglesias'))),
+ array('User' => array('id' => 14, 'group_id' => 2,
+ 'Data' => array('user' => 'phpnut', 'name' => 'Larry E. Masters'))),
+ array('User' => array('id' => 25, 'group_id' => 1,
+ 'Data' => array('user' => 'gwoo','name' => 'The Gwoo'))));
+ $result = Set::combine($b, 'users.{n}.User.id');
+ $expected = array(2 => null, 14 => null, 25 => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($b, 'users.{n}.User.id', 'users.{n}.User.non-existant');
+ $expected = array(2 => null, 14 => null, 25 => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::combine($a, 'fail', 'fail');
+ $this->assertEquals(array(), $result);
+ }
+
+/**
+ * testMapReverse method
+ *
+ * @return void
+ */
+ public function testMapReverse() {
+ $result = Set::reverse(null);
+ $this->assertEquals(null, $result);
+
+ $result = Set::reverse(false);
+ $this->assertEquals(false, $result);
+
+ $expected = array(
+ 'Array1' => array(
+ 'Array1Data1' => 'Array1Data1 value 1', 'Array1Data2' => 'Array1Data2 value 2'),
+ 'Array2' => array(
+ 0 => array('Array2Data1' => 1, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 1 => array('Array2Data1' => 2, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 2 => array('Array2Data1' => 3, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 3 => array('Array2Data1' => 4, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 4 => array('Array2Data1' => 5, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4')),
+ 'Array3' => array(
+ 0 => array('Array3Data1' => 1, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 1 => array('Array3Data1' => 2, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 2 => array('Array3Data1' => 3, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 3 => array('Array3Data1' => 4, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 4 => array('Array3Data1' => 5, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4')));
+ $map = Set::map($expected, true);
+ $this->assertEquals($expected['Array1']['Array1Data1'], $map->Array1->Array1Data1);
+ $this->assertEquals($expected['Array2'][0]['Array2Data1'], $map->Array2[0]->Array2Data1);
+
+ $result = Set::reverse($map);
+ $this->assertEquals($expected, $result);
+
+ $expected = array(
+ 'Post' => array('id' => 1, 'title' => 'First Post'),
+ 'Comment' => array(
+ array('id' => 1, 'title' => 'First Comment'),
+ array('id' => 2, 'title' => 'Second Comment')
+ ),
+ 'Tag' => array(
+ array('id' => 1, 'title' => 'First Tag'),
+ array('id' => 2, 'title' => 'Second Tag')
+ ),
+ );
+ $map = Set::map($expected);
+ $this->assertEquals($expected['Post']['title'], $map->title);
+ foreach ($map->Comment as $comment) {
+ $ids[] = $comment->id;
+ }
+ $this->assertEquals(array(1, 2), $ids);
+
+ $expected = array(
+ 'Array1' => array(
+ 'Array1Data1' => 'Array1Data1 value 1', 'Array1Data2' => 'Array1Data2 value 2', 'Array1Data3' => 'Array1Data3 value 3','Array1Data4' => 'Array1Data4 value 4',
+ 'Array1Data5' => 'Array1Data5 value 5', 'Array1Data6' => 'Array1Data6 value 6', 'Array1Data7' => 'Array1Data7 value 7', 'Array1Data8' => 'Array1Data8 value 8'),
+ 'string' => 1,
+ 'another' => 'string',
+ 'some' => 'thing else',
+ 'Array2' => array(
+ 0 => array('Array2Data1' => 1, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 1 => array('Array2Data1' => 2, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 2 => array('Array2Data1' => 3, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 3 => array('Array2Data1' => 4, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 4 => array('Array2Data1' => 5, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4')),
+ 'Array3' => array(
+ 0 => array('Array3Data1' => 1, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 1 => array('Array3Data1' => 2, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 2 => array('Array3Data1' => 3, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 3 => array('Array3Data1' => 4, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 4 => array('Array3Data1' => 5, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4')));
+ $map = Set::map($expected, true);
+ $result = Set::reverse($map);
+ $this->assertEquals($expected, $result);
+
+ $expected = array(
+ 'Array1' => array(
+ 'Array1Data1' => 'Array1Data1 value 1', 'Array1Data2' => 'Array1Data2 value 2', 'Array1Data3' => 'Array1Data3 value 3','Array1Data4' => 'Array1Data4 value 4',
+ 'Array1Data5' => 'Array1Data5 value 5', 'Array1Data6' => 'Array1Data6 value 6', 'Array1Data7' => 'Array1Data7 value 7', 'Array1Data8' => 'Array1Data8 value 8'),
+ 'string' => 1,
+ 'another' => 'string',
+ 'some' => 'thing else',
+ 'Array2' => array(
+ 0 => array('Array2Data1' => 1, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 1 => array('Array2Data1' => 2, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 2 => array('Array2Data1' => 3, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 3 => array('Array2Data1' => 4, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4'),
+ 4 => array('Array2Data1' => 5, 'Array2Data2' => 'Array2Data2 value 2', 'Array2Data3' => 'Array2Data3 value 2', 'Array2Data4' => 'Array2Data4 value 4')),
+ 'string2' => 1,
+ 'another2' => 'string',
+ 'some2' => 'thing else',
+ 'Array3' => array(
+ 0 => array('Array3Data1' => 1, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 1 => array('Array3Data1' => 2, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 2 => array('Array3Data1' => 3, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 3 => array('Array3Data1' => 4, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4'),
+ 4 => array('Array3Data1' => 5, 'Array3Data2' => 'Array3Data2 value 2', 'Array3Data3' => 'Array3Data3 value 2', 'Array3Data4' => 'Array3Data4 value 4')),
+ 'string3' => 1,
+ 'another3' => 'string',
+ 'some3' => 'thing else');
+ $map = Set::map($expected, true);
+ $result = Set::reverse($map);
+ $this->assertEquals($expected, $result);
+
+ $expected = array('User' => array('psword' => 'whatever', 'Icon' => array('id' => 851)));
+ $map = Set::map($expected);
+ $result = Set::reverse($map);
+ $this->assertEquals($expected, $result);
+
+ $expected = array('User' => array('psword' => 'whatever', 'Icon' => array('id' => 851)));
+ $class = new stdClass;
+ $class->User = new stdClass;
+ $class->User->psword = 'whatever';
+ $class->User->Icon = new stdClass;
+ $class->User->Icon->id = 851;
+ $result = Set::reverse($class);
+ $this->assertEquals($expected, $result);
+
+ $expected = array('User' => array('psword' => 'whatever', 'Icon' => array('id' => 851), 'Profile' => array('name' => 'Some Name', 'address' => 'Some Address')));
+ $class = new stdClass;
+ $class->User = new stdClass;
+ $class->User->psword = 'whatever';
+ $class->User->Icon = new stdClass;
+ $class->User->Icon->id = 851;
+ $class->User->Profile = new stdClass;
+ $class->User->Profile->name = 'Some Name';
+ $class->User->Profile->address = 'Some Address';
+
+ $result = Set::reverse($class);
+ $this->assertEquals($expected, $result);
+
+ $expected = array('User' => array('psword' => 'whatever',
+ 'Icon' => array('id' => 851),
+ 'Profile' => array('name' => 'Some Name', 'address' => 'Some Address'),
+ 'Comment' => array(
+ array('id' => 1, 'article_id' => 1, 'user_id' => 1, 'comment' => 'First Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'),
+ array('id' => 2, 'article_id' => 1, 'user_id' => 2, 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'))));
+
+ $class = new stdClass;
+ $class->User = new stdClass;
+ $class->User->psword = 'whatever';
+ $class->User->Icon = new stdClass;
+ $class->User->Icon->id = 851;
+ $class->User->Profile = new stdClass;
+ $class->User->Profile->name = 'Some Name';
+ $class->User->Profile->address = 'Some Address';
+ $class->User->Comment = new stdClass;
+ $class->User->Comment->{'0'} = new stdClass;
+ $class->User->Comment->{'0'}->id = 1;
+ $class->User->Comment->{'0'}->article_id = 1;
+ $class->User->Comment->{'0'}->user_id = 1;
+ $class->User->Comment->{'0'}->comment = 'First Comment for First Article';
+ $class->User->Comment->{'0'}->published = 'Y';
+ $class->User->Comment->{'0'}->created = '2007-03-18 10:47:23';
+ $class->User->Comment->{'0'}->updated = '2007-03-18 10:49:31';
+ $class->User->Comment->{'1'} = new stdClass;
+ $class->User->Comment->{'1'}->id = 2;
+ $class->User->Comment->{'1'}->article_id = 1;
+ $class->User->Comment->{'1'}->user_id = 2;
+ $class->User->Comment->{'1'}->comment = 'Second Comment for First Article';
+ $class->User->Comment->{'1'}->published = 'Y';
+ $class->User->Comment->{'1'}->created = '2007-03-18 10:47:23';
+ $class->User->Comment->{'1'}->updated = '2007-03-18 10:49:31';
+
+ $result = Set::reverse($class);
+ $this->assertEquals($expected, $result);
+
+ $expected = array('User' => array('psword' => 'whatever',
+ 'Icon' => array('id' => 851),
+ 'Profile' => array('name' => 'Some Name', 'address' => 'Some Address'),
+ 'Comment' => array(
+ array('id' => 1, 'article_id' => 1, 'user_id' => 1, 'comment' => 'First Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'),
+ array('id' => 2, 'article_id' => 1, 'user_id' => 2, 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'))));
+
+ // @codingStandardsIgnoreStart
+ $class = new stdClass;
+ $class->User = new stdClass;
+ $class->User->psword = 'whatever';
+ $class->User->Icon = new stdClass;
+ $class->User->Icon->id = 851;
+ $class->User->Profile = new stdClass;
+ $class->User->Profile->name = 'Some Name';
+ $class->User->Profile->address = 'Some Address';
+ $class->User->Comment = array();
+ $comment = new stdClass;
+ $comment->id = 1;
+ $comment->article_id = 1;
+ $comment->user_id = 1;
+ $comment->comment = 'First Comment for First Article';
+ $comment->published = 'Y';
+ $comment->created = '2007-03-18 10:47:23';
+ $comment->updated = '2007-03-18 10:49:31';
+ $comment2 = new stdClass;
+ $comment2->id = 2;
+ $comment2->article_id = 1;
+ $comment2->user_id = 2;
+ $comment2->comment = 'Second Comment for First Article';
+ $comment2->published = 'Y';
+ $comment2->created = '2007-03-18 10:47:23';
+ $comment2->updated = '2007-03-18 10:49:31';
+ // @codingStandardsIgnoreEnd
+ $class->User->Comment = array($comment, $comment2);
+ $result = Set::reverse($class);
+ $this->assertEquals($expected, $result);
+
+ $class = new stdClass;
+ $class->User = new stdClass;
+ $class->User->id = 100;
+ $class->someString = 'this is some string';
+ $class->Profile = new stdClass;
+ $class->Profile->name = 'Joe Mamma';
+
+ $result = Set::reverse($class);
+ $expected = array(
+ 'User' => array('id' => '100'),
+ 'someString' => 'this is some string',
+ 'Profile' => array('name' => 'Joe Mamma')
+ );
+ $this->assertEquals($expected, $result);
+
+ // @codingStandardsIgnoreStart
+ $class = new stdClass;
+ $class->User = new stdClass;
+ $class->User->id = 100;
+ $class->User->_name_ = 'User';
+ $class->Profile = new stdClass;
+ $class->Profile->name = 'Joe Mamma';
+ $class->Profile->_name_ = 'Profile';
+ // @codingStandardsIgnoreEnd
+
+ $result = Set::reverse($class);
+ $expected = array('User' => array('id' => '100'), 'Profile' => array('name' => 'Joe Mamma'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFormatting method
+ *
+ * @return void
+ */
+ public function testFormatting() {
+ $data = array(
+ array('Person' => array('first_name' => 'Nate', 'last_name' => 'Abele', 'city' => 'Boston', 'state' => 'MA', 'something' => '42')),
+ array('Person' => array('first_name' => 'Larry', 'last_name' => 'Masters', 'city' => 'Boondock', 'state' => 'TN', 'something' => '{0}')),
+ array('Person' => array('first_name' => 'Garrett', 'last_name' => 'Woodworth', 'city' => 'Venice Beach', 'state' => 'CA', 'something' => '{1}')));
+
+ $result = Set::format($data, '{1}, {0}', array('{n}.Person.first_name', '{n}.Person.last_name'));
+ $expected = array('Abele, Nate', 'Masters, Larry', 'Woodworth, Garrett');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '{0}, {1}', array('{n}.Person.last_name', '{n}.Person.first_name'));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '{0}, {1}', array('{n}.Person.city', '{n}.Person.state'));
+ $expected = array('Boston, MA', 'Boondock, TN', 'Venice Beach, CA');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '{{0}, {1}}', array('{n}.Person.city', '{n}.Person.state'));
+ $expected = array('{Boston, MA}', '{Boondock, TN}', '{Venice Beach, CA}');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '{{0}, {1}}', array('{n}.Person.something', '{n}.Person.something'));
+ $expected = array('{42, 42}', '{{0}, {0}}', '{{1}, {1}}');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '{%2$d, %1$s}', array('{n}.Person.something', '{n}.Person.something'));
+ $expected = array('{42, 42}', '{0, {0}}', '{0, {1}}');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '{%1$s, %1$s}', array('{n}.Person.something', '{n}.Person.something'));
+ $expected = array('{42, 42}', '{{0}, {0}}', '{{1}, {1}}');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '%2$d, %1$s', array('{n}.Person.first_name', '{n}.Person.something'));
+ $expected = array('42, Nate', '0, Larry', '0, Garrett');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '%1$s, %2$d', array('{n}.Person.first_name', '{n}.Person.something'));
+ $expected = array('Nate, 42', 'Larry, 0', 'Garrett, 0');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testFormattingNullValues method
+ *
+ * @return void
+ */
+ public function testFormattingNullValues() {
+ $data = array(
+ array('Person' => array('first_name' => 'Nate', 'last_name' => 'Abele', 'city' => 'Boston', 'state' => 'MA', 'something' => '42')),
+ array('Person' => array('first_name' => 'Larry', 'last_name' => 'Masters', 'city' => 'Boondock', 'state' => 'TN', 'something' => null)),
+ array('Person' => array('first_name' => 'Garrett', 'last_name' => 'Woodworth', 'city' => 'Venice Beach', 'state' => 'CA', 'something' => null)));
+
+ $result = Set::format($data, '%s', array('{n}.Person.something'));
+ $expected = array('42', '', '');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::format($data, '{0}, {1}', array('{n}.Person.city', '{n}.Person.something'));
+ $expected = array('Boston, 42', 'Boondock, ', 'Venice Beach, ');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testCountDim method
+ *
+ * @return void
+ */
+ public function testCountDim() {
+ $data = array('one', '2', 'three');
+ $result = Set::countDim($data);
+ $this->assertEquals(1, $result);
+
+ $data = array('1' => '1.1', '2', '3');
+ $result = Set::countDim($data);
+ $this->assertEquals(1, $result);
+
+ $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1'));
+ $result = Set::countDim($data);
+ $this->assertEquals(2, $result);
+
+ $data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
+ $result = Set::countDim($data);
+ $this->assertEquals(1, $result);
+
+ $data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
+ $result = Set::countDim($data, true);
+ $this->assertEquals(2, $result);
+
+ $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Set::countDim($data);
+ $this->assertEquals(2, $result);
+
+ $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Set::countDim($data, true);
+ $this->assertEquals(3, $result);
+
+ $data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => '2.1.1.1'))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Set::countDim($data, true);
+ $this->assertEquals(4, $result);
+
+ $data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1')))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Set::countDim($data, true);
+ $this->assertEquals(5, $result);
+
+ $data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Set::countDim($data, true);
+ $this->assertEquals(5, $result);
+
+ $set = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
+ $result = Set::countDim($set, false, 0);
+ $this->assertEquals(2, $result);
+
+ $result = Set::countDim($set, true);
+ $this->assertEquals(5, $result);
+ }
+
+/**
+ * testMapNesting method
+ *
+ * @return void
+ */
+ public function testMapNesting() {
+ $expected = array(
+ array(
+ "IndexedPage" => array(
+ "id" => 1,
+ "url" => 'http://blah.com/',
+ 'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
+ 'headers' => array(
+ 'Date' => "Wed, 14 Nov 2007 15:51:42 GMT",
+ 'Server' => "Apache",
+ 'Expires' => "Thu, 19 Nov 1981 08:52:00 GMT",
+ 'Cache-Control' => "private",
+ 'Pragma' => "no-cache",
+ 'Content-Type' => "text/html; charset=UTF-8",
+ 'X-Original-Transfer-Encoding' => "chunked",
+ 'Content-Length' => "50210",
+ ),
+ 'meta' => array(
+ 'keywords' => array('testing','tests'),
+ 'description' => 'describe me',
+ ),
+ 'get_vars' => '',
+ 'post_vars' => array(),
+ 'cookies' => array('PHPSESSID' => "dde9896ad24595998161ffaf9e0dbe2d"),
+ 'redirect' => '',
+ 'created' => "1195055503",
+ 'updated' => "1195055503",
+ )
+ ),
+ array(
+ "IndexedPage" => array(
+ "id" => 2,
+ "url" => 'http://blah.com/',
+ 'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
+ 'headers' => array(
+ 'Date' => "Wed, 14 Nov 2007 15:51:42 GMT",
+ 'Server' => "Apache",
+ 'Expires' => "Thu, 19 Nov 1981 08:52:00 GMT",
+ 'Cache-Control' => "private",
+ 'Pragma' => "no-cache",
+ 'Content-Type' => "text/html; charset=UTF-8",
+ 'X-Original-Transfer-Encoding' => "chunked",
+ 'Content-Length' => "50210",
+ ),
+ 'meta' => array(
+ 'keywords' => array('testing','tests'),
+ 'description' => 'describe me',
+ ),
+ 'get_vars' => '',
+ 'post_vars' => array(),
+ 'cookies' => array('PHPSESSID' => "dde9896ad24595998161ffaf9e0dbe2d"),
+ 'redirect' => '',
+ 'created' => "1195055503",
+ 'updated' => "1195055503",
+ ),
+ )
+ );
+
+ $mapped = Set::map($expected);
+ $ids = array();
+
+ foreach ($mapped as $object) {
+ $ids[] = $object->id;
+ }
+ $this->assertEquals(array(1, 2), $ids);
+ $this->assertEquals($expected[0]['IndexedPage']['headers'], get_object_vars($mapped[0]->headers));
+
+ $result = Set::reverse($mapped);
+ $this->assertEquals($expected, $result);
+
+ $data = array(
+ array(
+ "IndexedPage" => array(
+ "id" => 1,
+ "url" => 'http://blah.com/',
+ 'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
+ 'get_vars' => '',
+ 'redirect' => '',
+ 'created' => "1195055503",
+ 'updated' => "1195055503",
+ )
+ ),
+ array(
+ "IndexedPage" => array(
+ "id" => 2,
+ "url" => 'http://blah.com/',
+ 'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
+ 'get_vars' => '',
+ 'redirect' => '',
+ 'created' => "1195055503",
+ 'updated' => "1195055503",
+ ),
+ )
+ );
+ $mapped = Set::map($data);
+
+ // @codingStandardsIgnoreStart
+ $expected = new stdClass();
+ $expected->_name_ = 'IndexedPage';
+ $expected->id = 2;
+ $expected->url = 'http://blah.com/';
+ $expected->hash = '68a9f053b19526d08e36c6a9ad150737933816a5';
+ $expected->get_vars = '';
+ $expected->redirect = '';
+ $expected->created = "1195055503";
+ $expected->updated = "1195055503";
+ // @codingStandardsIgnoreEnd
+ $this->assertEquals($expected, $mapped[1]);
+
+ $ids = array();
+
+ foreach ($mapped as $object) {
+ $ids[] = $object->id;
+ }
+ $this->assertEquals(array(1, 2), $ids);
+
+ $result = Set::map(null);
+ $expected = null;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testNestedMappedData method
+ *
+ * @return void
+ */
+ public function testNestedMappedData() {
+ $result = Set::map(array(
+ array(
+ 'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ 'Author' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31', 'test' => 'working'),
+ )
+ , array(
+ 'Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ 'Author' => array('id' => '3', 'user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31', 'test' => 'working'),
+ )
+ ));
+
+ // @codingStandardsIgnoreStart
+ $expected = new stdClass;
+ $expected->_name_ = 'Post';
+ $expected->id = '1';
+ $expected->author_id = '1';
+ $expected->title = 'First Post';
+ $expected->body = 'First Post Body';
+ $expected->published = 'Y';
+ $expected->created = "2007-03-18 10:39:23";
+ $expected->updated = "2007-03-18 10:41:31";
+
+ $expected->Author = new stdClass;
+ $expected->Author->id = '1';
+ $expected->Author->user = 'mariano';
+ $expected->Author->password = '5f4dcc3b5aa765d61d8327deb882cf99';
+ $expected->Author->created = "2007-03-17 01:16:23";
+ $expected->Author->updated = "2007-03-17 01:18:31";
+ $expected->Author->test = "working";
+ $expected->Author->_name_ = 'Author';
+
+ $expected2 = new stdClass;
+ $expected2->_name_ = 'Post';
+ $expected2->id = '2';
+ $expected2->author_id = '3';
+ $expected2->title = 'Second Post';
+ $expected2->body = 'Second Post Body';
+ $expected2->published = 'Y';
+ $expected2->created = "2007-03-18 10:41:23";
+ $expected2->updated = "2007-03-18 10:43:31";
+
+ $expected2->Author = new stdClass;
+ $expected2->Author->id = '3';
+ $expected2->Author->user = 'larry';
+ $expected2->Author->password = '5f4dcc3b5aa765d61d8327deb882cf99';
+ $expected2->Author->created = "2007-03-17 01:20:23";
+ $expected2->Author->updated = "2007-03-17 01:22:31";
+ $expected2->Author->test = "working";
+ $expected2->Author->_name_ = 'Author';
+ // @codingStandardsIgnoreEnd
+
+ $test = array();
+ $test[0] = $expected;
+ $test[1] = $expected2;
+
+ $this->assertEquals($test, $result);
+
+ $result = Set::map(
+ array(
+ 'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ 'Author' => array('id' => '1', 'user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31', 'test' => 'working'),
+ )
+ );
+ // @codingStandardsIgnoreStart
+ $expected = new stdClass;
+ $expected->_name_ = 'Post';
+ $expected->id = '1';
+ $expected->author_id = '1';
+ $expected->title = 'First Post';
+ $expected->body = 'First Post Body';
+ $expected->published = 'Y';
+ $expected->created = "2007-03-18 10:39:23";
+ $expected->updated = "2007-03-18 10:41:31";
+
+ $expected->Author = new stdClass;
+ $expected->Author->id = '1';
+ $expected->Author->user = 'mariano';
+ $expected->Author->password = '5f4dcc3b5aa765d61d8327deb882cf99';
+ $expected->Author->created = "2007-03-17 01:16:23";
+ $expected->Author->updated = "2007-03-17 01:18:31";
+ $expected->Author->test = "working";
+ $expected->Author->_name_ = 'Author';
+ // @codingStandardsIgnoreEnd
+ $this->assertEquals($expected, $result);
+
+ //Case where extra HABTM fields come back in a result
+ $data = array(
+ 'User' => array(
+ 'id' => 1,
+ 'email' => 'user@example.com',
+ 'first_name' => 'John',
+ 'last_name' => 'Smith',
+ ),
+ 'Piece' => array(
+ array(
+ 'id' => 1,
+ 'title' => 'Moonlight Sonata',
+ 'composer' => 'Ludwig van Beethoven',
+ 'PiecesUser' => array(
+ 'id' => 1,
+ 'created' => '2008-01-01 00:00:00',
+ 'modified' => '2008-01-01 00:00:00',
+ 'piece_id' => 1,
+ 'user_id' => 2,
+ )
+ ),
+ array(
+ 'id' => 2,
+ 'title' => 'Moonlight Sonata 2',
+ 'composer' => 'Ludwig van Beethoven',
+ 'PiecesUser' => array(
+ 'id' => 2,
+ 'created' => '2008-01-01 00:00:00',
+ 'modified' => '2008-01-01 00:00:00',
+ 'piece_id' => 2,
+ 'user_id' => 2,
+ )
+ )
+ )
+ );
+
+ $result = Set::map($data);
+
+ // @codingStandardsIgnoreStart
+ $expected = new stdClass();
+ $expected->_name_ = 'User';
+ $expected->id = 1;
+ $expected->email = 'user@example.com';
+ $expected->first_name = 'John';
+ $expected->last_name = 'Smith';
+
+ $piece = new stdClass();
+ $piece->id = 1;
+ $piece->title = 'Moonlight Sonata';
+ $piece->composer = 'Ludwig van Beethoven';
+
+ $piece->PiecesUser = new stdClass();
+ $piece->PiecesUser->id = 1;
+ $piece->PiecesUser->created = '2008-01-01 00:00:00';
+ $piece->PiecesUser->modified = '2008-01-01 00:00:00';
+ $piece->PiecesUser->piece_id = 1;
+ $piece->PiecesUser->user_id = 2;
+ $piece->PiecesUser->_name_ = 'PiecesUser';
+
+ $piece->_name_ = 'Piece';
+
+ $piece2 = new stdClass();
+ $piece2->id = 2;
+ $piece2->title = 'Moonlight Sonata 2';
+ $piece2->composer = 'Ludwig van Beethoven';
+
+ $piece2->PiecesUser = new stdClass();
+ $piece2->PiecesUser->id = 2;
+ $piece2->PiecesUser->created = '2008-01-01 00:00:00';
+ $piece2->PiecesUser->modified = '2008-01-01 00:00:00';
+ $piece2->PiecesUser->piece_id = 2;
+ $piece2->PiecesUser->user_id = 2;
+ $piece2->PiecesUser->_name_ = 'PiecesUser';
+
+ $piece2->_name_ = 'Piece';
+ // @codingStandardsIgnoreEnd
+
+ $expected->Piece = array($piece, $piece2);
+
+ $this->assertEquals($expected, $result);
+
+ //Same data, but should work if _name_ has been manually defined:
+ $data = array(
+ 'User' => array(
+ 'id' => 1,
+ 'email' => 'user@example.com',
+ 'first_name' => 'John',
+ 'last_name' => 'Smith',
+ '_name_' => 'FooUser',
+ ),
+ 'Piece' => array(
+ array(
+ 'id' => 1,
+ 'title' => 'Moonlight Sonata',
+ 'composer' => 'Ludwig van Beethoven',
+ '_name_' => 'FooPiece',
+ 'PiecesUser' => array(
+ 'id' => 1,
+ 'created' => '2008-01-01 00:00:00',
+ 'modified' => '2008-01-01 00:00:00',
+ 'piece_id' => 1,
+ 'user_id' => 2,
+ '_name_' => 'FooPiecesUser',
+ )
+ ),
+ array(
+ 'id' => 2,
+ 'title' => 'Moonlight Sonata 2',
+ 'composer' => 'Ludwig van Beethoven',
+ '_name_' => 'FooPiece',
+ 'PiecesUser' => array(
+ 'id' => 2,
+ 'created' => '2008-01-01 00:00:00',
+ 'modified' => '2008-01-01 00:00:00',
+ 'piece_id' => 2,
+ 'user_id' => 2,
+ '_name_' => 'FooPiecesUser',
+ )
+ )
+ )
+ );
+
+ $result = Set::map($data);
+
+ // @codingStandardsIgnoreStart
+ $expected = new stdClass();
+ $expected->_name_ = 'FooUser';
+ $expected->id = 1;
+ $expected->email = 'user@example.com';
+ $expected->first_name = 'John';
+ $expected->last_name = 'Smith';
+
+ $piece = new stdClass();
+ $piece->id = 1;
+ $piece->title = 'Moonlight Sonata';
+ $piece->composer = 'Ludwig van Beethoven';
+ $piece->_name_ = 'FooPiece';
+ $piece->PiecesUser = new stdClass();
+ $piece->PiecesUser->id = 1;
+ $piece->PiecesUser->created = '2008-01-01 00:00:00';
+ $piece->PiecesUser->modified = '2008-01-01 00:00:00';
+ $piece->PiecesUser->piece_id = 1;
+ $piece->PiecesUser->user_id = 2;
+ $piece->PiecesUser->_name_ = 'FooPiecesUser';
+
+ $piece2 = new stdClass();
+ $piece2->id = 2;
+ $piece2->title = 'Moonlight Sonata 2';
+ $piece2->composer = 'Ludwig van Beethoven';
+ $piece2->_name_ = 'FooPiece';
+ $piece2->PiecesUser = new stdClass();
+ $piece2->PiecesUser->id = 2;
+ $piece2->PiecesUser->created = '2008-01-01 00:00:00';
+ $piece2->PiecesUser->modified = '2008-01-01 00:00:00';
+ $piece2->PiecesUser->piece_id = 2;
+ $piece2->PiecesUser->user_id = 2;
+ $piece2->PiecesUser->_name_ = 'FooPiecesUser';
+ // @codingStandardsIgnoreEnd
+
+ $expected->Piece = array($piece, $piece2);
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testPushDiff method
+ *
+ * @return void
+ */
+ public function testPushDiff() {
+ $array1 = array('ModelOne' => array('id' => 1001, 'field_one' => 'a1.m1.f1', 'field_two' => 'a1.m1.f2'));
+ $array2 = array('ModelTwo' => array('id' => 1002, 'field_one' => 'a2.m2.f1', 'field_two' => 'a2.m2.f2'));
+
+ $result = Set::pushDiff($array1, $array2);
+
+ $this->assertEquals($array1 + $array2, $result);
+
+ $array3 = array('ModelOne' => array('id' => 1003, 'field_one' => 'a3.m1.f1', 'field_two' => 'a3.m1.f2', 'field_three' => 'a3.m1.f3'));
+ $result = Set::pushDiff($array1, $array3);
+
+ $expected = array('ModelOne' => array('id' => 1001, 'field_one' => 'a1.m1.f1', 'field_two' => 'a1.m1.f2', 'field_three' => 'a3.m1.f3'));
+ $this->assertEquals($expected, $result);
+
+ $array1 = array(
+ 0 => array('ModelOne' => array('id' => 1001, 'field_one' => 's1.0.m1.f1', 'field_two' => 's1.0.m1.f2')),
+ 1 => array('ModelTwo' => array('id' => 1002, 'field_one' => 's1.1.m2.f2', 'field_two' => 's1.1.m2.f2')));
+ $array2 = array(
+ 0 => array('ModelOne' => array('id' => 1001, 'field_one' => 's2.0.m1.f1', 'field_two' => 's2.0.m1.f2')),
+ 1 => array('ModelTwo' => array('id' => 1002, 'field_one' => 's2.1.m2.f2', 'field_two' => 's2.1.m2.f2')));
+
+ $result = Set::pushDiff($array1, $array2);
+ $this->assertEquals($array1, $result);
+
+ $array3 = array(0 => array('ModelThree' => array('id' => 1003, 'field_one' => 's3.0.m3.f1', 'field_two' => 's3.0.m3.f2')));
+
+ $result = Set::pushDiff($array1, $array3);
+ $expected = array(
+ 0 => array('ModelOne' => array('id' => 1001, 'field_one' => 's1.0.m1.f1', 'field_two' => 's1.0.m1.f2'),
+ 'ModelThree' => array('id' => 1003, 'field_one' => 's3.0.m3.f1', 'field_two' => 's3.0.m3.f2')),
+ 1 => array('ModelTwo' => array('id' => 1002, 'field_one' => 's1.1.m2.f2', 'field_two' => 's1.1.m2.f2')));
+ $this->assertEquals($expected, $result);
+
+ $result = Set::pushDiff($array1, null);
+ $this->assertEquals($array1, $result);
+
+ $result = Set::pushDiff($array1, $array2);
+ $this->assertEquals($array1 + $array2, $result);
+ }
+
+/**
+ * testSetApply method
+ * @return void
+ *
+ */
+ public function testApply() {
+ $data = array(
+ array('Movie' => array('id' => 1, 'title' => 'movie 3', 'rating' => 5)),
+ array('Movie' => array('id' => 1, 'title' => 'movie 1', 'rating' => 1)),
+ array('Movie' => array('id' => 1, 'title' => 'movie 2', 'rating' => 3))
+ );
+
+ $result = Set::apply('/Movie/rating', $data, 'array_sum');
+ $expected = 9;
+ $this->assertEquals($expected, $result);
+
+ $result = Set::apply('/Movie/rating', $data, 'array_product');
+ $expected = 15;
+ $this->assertEquals($expected, $result);
+
+ $result = Set::apply('/Movie/title', $data, 'ucfirst', array('type' => 'map'));
+ $expected = array('Movie 3', 'Movie 1', 'Movie 2');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::apply('/Movie/title', $data, 'strtoupper', array('type' => 'map'));
+ $expected = array('MOVIE 3', 'MOVIE 1', 'MOVIE 2');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::apply('/Movie/rating', $data, array('SetTest', 'method'), array('type' => 'reduce'));
+ $expected = 9;
+ $this->assertEquals($expected, $result);
+
+ $result = Set::apply('/Movie/rating', $data, 'strtoupper', array('type' => 'non existing type'));
+ $expected = null;
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Helper method to test Set::apply()
+ *
+ * @return void
+ */
+ public static function method($val1, $val2) {
+ $val1 += $val2;
+ return $val1;
+ }
+
+/**
+ * testXmlSetReverse method
+ *
+ * @return void
+ */
+ public function testXmlSetReverse() {
+ App::uses('Xml', 'Utility');
+
+ $string = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <rss version="2.0">
+ <channel>
+ <title>Cake PHP Google Group</title>
+ <link>http://groups.google.com/group/cake-php</link>
+ <description>Search this group before posting anything. There are over 20,000 posts and it&amp;#39;s very likely your question was answered before. Visit the IRC channel #cakephp at irc.freenode.net for live chat with users and developers of Cake. If you post, tell us the version of Cake, PHP, and database.</description>
+ <language>en</language>
+ <item>
+ <title>constructng result array when using findall</title>
+ <link>http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f</link>
+ <description>i&#39;m using cakephp to construct a logical data model array that will be &lt;br&gt; passed to a flex app. I have the following model association: &lt;br&gt; ServiceDay-&amp;gt;(hasMany)ServiceTi me-&amp;gt;(hasMany)ServiceTimePrice. So what &lt;br&gt; the current output from my findall is something like this example: &lt;br&gt; &lt;p&gt;Array( &lt;br&gt; [0] =&amp;gt; Array(</description>
+ <guid isPermaLink="true">http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f</guid>
+ <author>bmil...@gmail.com(bpscrugs)</author>
+ <pubDate>Fri, 28 Dec 2007 00:44:14 UT</pubDate>
+ </item>
+ <item>
+ <title>Re: share views between actions?</title>
+ <link>http://groups.google.com/group/cake-php/msg/8b350d898707dad8</link>
+ <description>Then perhaps you might do us all a favour and refrain from replying to &lt;br&gt; things you do not understand. That goes especially for asinine comments. &lt;br&gt; Indeed. &lt;br&gt; To sum up: &lt;br&gt; No comment. &lt;br&gt; In my day, a simple &amp;quot;RTFM&amp;quot; would suffice. I&#39;ll keep in mind to ignore any &lt;br&gt; further responses from you. &lt;br&gt; You (and I) were referring to the *online documentation*, not other</description>
+ <guid isPermaLink="true">http://groups.google.com/group/cake-php/msg/8b350d898707dad8</guid>
+ <author>subtropolis.z...@gmail.com(subtropolis zijn)</author>
+ <pubDate>Fri, 28 Dec 2007 00:45:01 UT</pubDate>
+ </item>
+ </channel>
+ </rss>';
+ $xml = Xml::build($string);
+ $result = Set::reverse($xml);
+ $expected = array('rss' => array(
+ '@version' => '2.0',
+ 'channel' => array(
+ 'title' => 'Cake PHP Google Group',
+ 'link' => 'http://groups.google.com/group/cake-php',
+ 'description' => 'Search this group before posting anything. There are over 20,000 posts and it&#39;s very likely your question was answered before. Visit the IRC channel #cakephp at irc.freenode.net for live chat with users and developers of Cake. If you post, tell us the version of Cake, PHP, and database.',
+ 'language' => 'en',
+ 'item' => array(
+ array(
+ 'title' => 'constructng result array when using findall',
+ 'link' => 'http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f',
+ 'description' => "i'm using cakephp to construct a logical data model array that will be <br> passed to a flex app. I have the following model association: <br> ServiceDay-&gt;(hasMany)ServiceTi me-&gt;(hasMany)ServiceTimePrice. So what <br> the current output from my findall is something like this example: <br> <p>Array( <br> [0] =&gt; Array(",
+ 'guid' => array('@isPermaLink' => 'true', '@' => 'http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f'),
+ 'author' => 'bmil...@gmail.com(bpscrugs)',
+ 'pubDate' => 'Fri, 28 Dec 2007 00:44:14 UT',
+ ),
+ array(
+ 'title' => 'Re: share views between actions?',
+ 'link' => 'http://groups.google.com/group/cake-php/msg/8b350d898707dad8',
+ 'description' => 'Then perhaps you might do us all a favour and refrain from replying to <br> things you do not understand. That goes especially for asinine comments. <br> Indeed. <br> To sum up: <br> No comment. <br> In my day, a simple &quot;RTFM&quot; would suffice. I\'ll keep in mind to ignore any <br> further responses from you. <br> You (and I) were referring to the *online documentation*, not other',
+ 'guid' => array('@isPermaLink' => 'true', '@' => 'http://groups.google.com/group/cake-php/msg/8b350d898707dad8'),
+ 'author' => 'subtropolis.z...@gmail.com(subtropolis zijn)',
+ 'pubDate' => 'Fri, 28 Dec 2007 00:45:01 UT'
+ )
+ )
+ )
+ ));
+ $this->assertEquals($expected, $result);
+ $string = '<data><post title="Title of this post" description="cool"/></data>';
+
+ $xml = Xml::build($string);
+ $result = Set::reverse($xml);
+ $expected = array('data' => array('post' => array('@title' => 'Title of this post', '@description' => 'cool')));
+ $this->assertEquals($expected, $result);
+
+ $xml = Xml::build('<example><item><title>An example of a correctly reversed SimpleXMLElement</title><desc/></item></example>');
+ $result = Set::reverse($xml);
+ $expected = array('example' =>
+ array(
+ 'item' => array(
+ 'title' => 'An example of a correctly reversed SimpleXMLElement',
+ 'desc' => '',
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $xml = Xml::build('<example><item attr="123"><titles><title>title1</title><title>title2</title></titles></item></example>');
+ $result = Set::reverse($xml);
+ $expected =
+ array('example' => array(
+ 'item' => array(
+ '@attr' => '123',
+ 'titles' => array(
+ 'title' => array('title1', 'title2')
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $xml = Xml::build('<example attr="ex_attr"><item attr="123"><titles>list</titles>textforitems</item></example>');
+ $result = Set::reverse($xml);
+ $expected =
+ array('example' => array(
+ '@attr' => 'ex_attr',
+ 'item' => array(
+ '@attr' => '123',
+ 'titles' => 'list',
+ '@' => 'textforitems'
+ )
+ )
+ );
+ $this->assertEquals($expected, $result);
+
+ $string = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <rss version="2.0" xmlns:dc="http://www.cakephp.org/">
+ <channel>
+ <title>Cake PHP Google Group</title>
+ <link>http://groups.google.com/group/cake-php</link>
+ <description>Search this group before posting anything. There are over 20,000 posts and it&amp;#39;s very likely your question was answered before. Visit the IRC channel #cakephp at irc.freenode.net for live chat with users and developers of Cake. If you post, tell us the version of Cake, PHP, and database.</description>
+ <language>en</language>
+ <item>
+ <title>constructng result array when using findall</title>
+ <link>http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f</link>
+ <description>i&#39;m using cakephp to construct a logical data model array that will be &lt;br&gt; passed to a flex app. I have the following model association: &lt;br&gt; ServiceDay-&amp;gt;(hasMany)ServiceTi me-&amp;gt;(hasMany)ServiceTimePrice. So what &lt;br&gt; the current output from my findall is something like this example: &lt;br&gt; &lt;p&gt;Array( &lt;br&gt; [0] =&amp;gt; Array(</description>
+ <dc:creator>cakephp</dc:creator>
+ <category><![CDATA[cakephp]]></category>
+ <category><![CDATA[model]]></category>
+ <guid isPermaLink="true">http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f</guid>
+ <author>bmil...@gmail.com(bpscrugs)</author>
+ <pubDate>Fri, 28 Dec 2007 00:44:14 UT</pubDate>
+ </item>
+ <item>
+ <title>Re: share views between actions?</title>
+ <link>http://groups.google.com/group/cake-php/msg/8b350d898707dad8</link>
+ <description>Then perhaps you might do us all a favour and refrain from replying to &lt;br&gt; things you do not understand. That goes especially for asinine comments. &lt;br&gt; Indeed. &lt;br&gt; To sum up: &lt;br&gt; No comment. &lt;br&gt; In my day, a simple &amp;quot;RTFM&amp;quot; would suffice. I&#39;ll keep in mind to ignore any &lt;br&gt; further responses from you. &lt;br&gt; You (and I) were referring to the *online documentation*, not other</description>
+ <dc:creator>cakephp</dc:creator>
+ <category><![CDATA[cakephp]]></category>
+ <category><![CDATA[model]]></category>
+ <guid isPermaLink="true">http://groups.google.com/group/cake-php/msg/8b350d898707dad8</guid>
+ <author>subtropolis.z...@gmail.com(subtropolis zijn)</author>
+ <pubDate>Fri, 28 Dec 2007 00:45:01 UT</pubDate>
+ </item>
+ </channel>
+ </rss>';
+
+ $xml = Xml::build($string);
+ $result = Set::reverse($xml);
+
+ $expected = array('rss' => array(
+ '@version' => '2.0',
+ 'channel' => array(
+ 'title' => 'Cake PHP Google Group',
+ 'link' => 'http://groups.google.com/group/cake-php',
+ 'description' => 'Search this group before posting anything. There are over 20,000 posts and it&#39;s very likely your question was answered before. Visit the IRC channel #cakephp at irc.freenode.net for live chat with users and developers of Cake. If you post, tell us the version of Cake, PHP, and database.',
+ 'language' => 'en',
+ 'item' => array(
+ array(
+ 'title' => 'constructng result array when using findall',
+ 'link' => 'http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f',
+ 'description' => "i'm using cakephp to construct a logical data model array that will be <br> passed to a flex app. I have the following model association: <br> ServiceDay-&gt;(hasMany)ServiceTi me-&gt;(hasMany)ServiceTimePrice. So what <br> the current output from my findall is something like this example: <br> <p>Array( <br> [0] =&gt; Array(",
+ 'dc:creator' => 'cakephp',
+ 'category' => array('cakephp', 'model'),
+ 'guid' => array('@isPermaLink' => 'true', '@' => 'http://groups.google.com/group/cake-php/msg/49bc00f3bc651b4f'),
+ 'author' => 'bmil...@gmail.com(bpscrugs)',
+ 'pubDate' => 'Fri, 28 Dec 2007 00:44:14 UT',
+ ),
+ array(
+ 'title' => 'Re: share views between actions?',
+ 'link' => 'http://groups.google.com/group/cake-php/msg/8b350d898707dad8',
+ 'description' => 'Then perhaps you might do us all a favour and refrain from replying to <br> things you do not understand. That goes especially for asinine comments. <br> Indeed. <br> To sum up: <br> No comment. <br> In my day, a simple &quot;RTFM&quot; would suffice. I\'ll keep in mind to ignore any <br> further responses from you. <br> You (and I) were referring to the *online documentation*, not other',
+ 'dc:creator' => 'cakephp',
+ 'category' => array('cakephp', 'model'),
+ 'guid' => array('@isPermaLink' => 'true', '@' => 'http://groups.google.com/group/cake-php/msg/8b350d898707dad8'),
+ 'author' => 'subtropolis.z...@gmail.com(subtropolis zijn)',
+ 'pubDate' => 'Fri, 28 Dec 2007 00:45:01 UT'
+ )
+ )
+ )
+ ));
+ $this->assertEquals($expected, $result);
+
+ $text = '<?xml version="1.0" encoding="UTF-8"?>
+ <XRDS xmlns="xri://$xrds">
+ <XRD xml:id="oauth" xmlns="xri://$XRD*($v*2.0)" version="2.0">
+ <Type>xri://$xrds*simple</Type>
+ <Expires>2008-04-13T07:34:58Z</Expires>
+ <Service>
+ <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
+ <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
+ <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
+ <URI priority="10">https://ma.gnolia.com/oauth/authorize</URI>
+ <URI priority="20">http://ma.gnolia.com/oauth/authorize</URI>
+ </Service>
+ </XRD>
+ <XRD xmlns="xri://$XRD*($v*2.0)" version="2.0">
+ <Type>xri://$xrds*simple</Type>
+ <Service priority="10">
+ <Type>http://oauth.net/discovery/1.0</Type>
+ <URI>#oauth</URI>
+ </Service>
+ </XRD>
+ </XRDS>';
+
+ $xml = Xml::build($text);
+ $result = Set::reverse($xml);
+
+ $expected = array('XRDS' => array(
+ 'XRD' => array(
+ array(
+ '@xml:id' => 'oauth',
+ '@version' => '2.0',
+ 'Type' => 'xri://$xrds*simple',
+ 'Expires' => '2008-04-13T07:34:58Z',
+ 'Service' => array(
+ 'Type' => array(
+ 'http://oauth.net/core/1.0/endpoint/authorize',
+ 'http://oauth.net/core/1.0/parameters/auth-header',
+ 'http://oauth.net/core/1.0/parameters/uri-query'
+ ),
+ 'URI' => array(
+ array(
+ '@' => 'https://ma.gnolia.com/oauth/authorize',
+ '@priority' => '10',
+ ),
+ array(
+ '@' => 'http://ma.gnolia.com/oauth/authorize',
+ '@priority' => '20'
+ )
+ )
+ )
+ ),
+ array(
+ '@version' => '2.0',
+ 'Type' => 'xri://$xrds*simple',
+ 'Service' => array(
+ '@priority' => '10',
+ 'Type' => 'http://oauth.net/discovery/1.0',
+ 'URI' => '#oauth'
+ )
+ )
+ )
+ ));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStrictKeyCheck method
+ *
+ * @return void
+ */
+ public function testStrictKeyCheck() {
+ $set = array('a' => 'hi');
+ $this->assertFalse(Set::check($set, 'a.b'));
+ }
+
+/**
+ * Tests Set::flatten
+ *
+ * @return void
+ */
+ public function testFlatten() {
+ $data = array('Larry', 'Curly', 'Moe');
+ $result = Set::flatten($data);
+ $this->assertEquals($data, $result);
+
+ $data[9] = 'Shemp';
+ $result = Set::flatten($data);
+ $this->assertEquals($data, $result);
+ }
+
+/**
+ * Tests Set::expand
+ *
+ * @return void
+ */
+ public function testExpand() {
+ $data = array('My', 'Array', 'To', 'Flatten');
+ $flat = Set::flatten($data);
+ $result = Set::expand($flat);
+ $this->assertEquals($data, $result);
+ }
+
+/**
+ * test normalization
+ *
+ * @return void
+ */
+ public function testNormalizeStrings() {
+ $result = Set::normalize('one,two,three');
+ $expected = array('one' => null, 'two' => null, 'three' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::normalize('one two three', true, ' ');
+ $expected = array('one' => null, 'two' => null, 'three' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::normalize('one , two , three ', true, ',', true);
+ $expected = array('one' => null, 'two' => null, 'three' => null);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test normalizing arrays
+ *
+ * @return void
+ */
+ public function testNormalizeArrays() {
+ $result = Set::normalize(array('one', 'two', 'three'));
+ $expected = array('one' => null, 'two' => null, 'three' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::normalize(array('one', 'two', 'three'), false);
+ $expected = array('one', 'two', 'three');
+ $this->assertEquals($expected, $result);
+
+ $result = Set::normalize(array('one' => 1, 'two' => 2, 'three' => 3, 'four'), false);
+ $expected = array('one' => 1, 'two' => 2, 'three' => 3, 'four' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::normalize(array('one' => 1, 'two' => 2, 'three' => 3, 'four'));
+ $expected = array('one' => 1, 'two' => 2, 'three' => 3, 'four' => null);
+ $this->assertEquals($expected, $result);
+
+ $result = Set::normalize(array('one' => array('a', 'b', 'c' => 'cee'), 'two' => 2, 'three'));
+ $expected = array('one' => array('a', 'b', 'c' => 'cee'), 'two' => 2, 'three' => null);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Set nest with a normal model result set. For kicks rely on Set nest detecting the key names
+ * automatically
+ *
+ * @return void
+ */
+ public function testNestModel() {
+ $input = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ )
+ )
+ );
+ $expected = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ 'children' => array(
+ array(
+ 'ModelName' => array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ 'children' => array()
+ ),
+
+ )
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ 'children' => array(
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $result = Set::nest($input);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Set nest with a normal model result set, and a nominated root id
+ *
+ * @return void
+ */
+ public function testNestModelExplicitRoot() {
+ $input = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ )
+ )
+ );
+ $expected = array(
+ array(
+ 'ModelName' => array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ 'children' => array(
+ array(
+ 'ModelName' => array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ ),
+ array(
+ 'ModelName' => array(
+ 'id' => 10,
+ 'parent_id' => 6
+ ),
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $result = Set::nest($input, array('root' => 6));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Set nest with a 1d array - this method should be able to handle any type of array input
+ *
+ * @return void
+ */
+ public function testNest1Dimensional() {
+ $input = array(
+ array(
+ 'id' => 1,
+ 'parent_id' => null
+ ),
+ array(
+ 'id' => 2,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 3,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 4,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 5,
+ 'parent_id' => 1
+ ),
+ array(
+ 'id' => 6,
+ 'parent_id' => null
+ ),
+ array(
+ 'id' => 7,
+ 'parent_id' => 6
+ ),
+ array(
+ 'id' => 8,
+ 'parent_id' => 6
+ ),
+ array(
+ 'id' => 9,
+ 'parent_id' => 6
+ ),
+ array(
+ 'id' => 10,
+ 'parent_id' => 6
+ )
+ );
+ $expected = array(
+ array(
+ 'id' => 1,
+ 'parent_id' => null,
+ 'children' => array(
+ array(
+ 'id' => 2,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 3,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 4,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 5,
+ 'parent_id' => 1,
+ 'children' => array()
+ ),
+
+ )
+ ),
+ array(
+ 'id' => 6,
+ 'parent_id' => null,
+ 'children' => array(
+ array(
+ 'id' => 7,
+ 'parent_id' => 6,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 8,
+ 'parent_id' => 6,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 9,
+ 'parent_id' => 6,
+ 'children' => array()
+ ),
+ array(
+ 'id' => 10,
+ 'parent_id' => 6,
+ 'children' => array()
+ )
+ )
+ )
+ );
+ $result = Set::nest($input, array('idPath' => '/id', 'parentPath' => '/parent_id'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Set nest with no specified parent data.
+ *
+ * The result should be the same as the input.
+ * For an easier comparison, unset all the empty children arrays from the result
+ *
+ * @return void
+ */
+ public function testMissingParent() {
+ $input = array(
+ array(
+ 'id' => 1,
+ ),
+ array(
+ 'id' => 2,
+ ),
+ array(
+ 'id' => 3,
+ ),
+ array(
+ 'id' => 4,
+ ),
+ array(
+ 'id' => 5,
+ ),
+ array(
+ 'id' => 6,
+ ),
+ array(
+ 'id' => 7,
+ ),
+ array(
+ 'id' => 8,
+ ),
+ array(
+ 'id' => 9,
+ ),
+ array(
+ 'id' => 10,
+ )
+ );
+
+ $result = Set::nest($input, array('idPath' => '/id', 'parentPath' => '/parent_id'));
+ foreach ($result as &$row) {
+ if (empty($row['children'])) {
+ unset($row['children']);
+ }
+ }
+ $this->assertEquals($input, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/StringTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/StringTest.php
new file mode 100644
index 0000000..efa024b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/StringTest.php
@@ -0,0 +1,650 @@
+<?php
+/**
+ * StringTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('String', 'Utility');
+
+/**
+ * StringTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class StringTest extends CakeTestCase {
+
+ public function setUp() {
+ parent::setUp();
+ $this->Text = new String();
+ }
+
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Text);
+ }
+
+/**
+ * testUuidGeneration method
+ *
+ * @return void
+ */
+ public function testUuidGeneration() {
+ $result = String::uuid();
+ $pattern = "/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/";
+ $match = (bool)preg_match($pattern, $result);
+ $this->assertTrue($match);
+ }
+
+/**
+ * testMultipleUuidGeneration method
+ *
+ * @return void
+ */
+ public function testMultipleUuidGeneration() {
+ $check = array();
+ $count = mt_rand(10, 1000);
+ $pattern = "/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/";
+
+ for ($i = 0; $i < $count; $i++) {
+ $result = String::uuid();
+ $match = (bool)preg_match($pattern, $result);
+ $this->assertTrue($match);
+ $this->assertFalse(in_array($result, $check));
+ $check[] = $result;
+ }
+ }
+
+/**
+ * testInsert method
+ *
+ * @return void
+ */
+ public function testInsert() {
+ $string = 'some string';
+ $expected = 'some string';
+ $result = String::insert($string, array());
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = :sum. Cake is :adjective.';
+ $expected = '2 + 2 = 4. Cake is yummy.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'));
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = %sum. Cake is %adjective.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'), array('before' => '%'));
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = 2sum2. Cake is 9adjective9.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'), array('format' => '/([\d])%s\\1/'));
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = 12sum21. Cake is 23adjective45.';
+ $expected = '2 + 2 = 4. Cake is 23adjective45.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'), array('format' => '/([\d])([\d])%s\\2\\1/'));
+ $this->assertEquals($expected, $result);
+
+ $string = ':web :web_site';
+ $expected = 'www http';
+ $result = String::insert($string, array('web' => 'www', 'web_site' => 'http'));
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = <sum. Cake is <adjective>.';
+ $expected = '2 + 2 = <sum. Cake is yummy.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'), array('before' => '<', 'after' => '>'));
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = \:sum. Cake is :adjective.';
+ $expected = '2 + 2 = :sum. Cake is yummy.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'));
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = !:sum. Cake is :adjective.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'), array('escape' => '!'));
+ $this->assertEquals($expected, $result);
+
+ $string = '2 + 2 = \%sum. Cake is %adjective.';
+ $expected = '2 + 2 = %sum. Cake is yummy.';
+ $result = String::insert($string, array('sum' => '4', 'adjective' => 'yummy'), array('before' => '%'));
+ $this->assertEquals($expected, $result);
+
+ $string = ':a :b \:a :a';
+ $expected = '1 2 :a 1';
+ $result = String::insert($string, array('a' => 1, 'b' => 2));
+ $this->assertEquals($expected, $result);
+
+ $string = ':a :b :c';
+ $expected = '2 3';
+ $result = String::insert($string, array('b' => 2, 'c' => 3), array('clean' => true));
+ $this->assertEquals($expected, $result);
+
+ $string = ':a :b :c';
+ $expected = '1 3';
+ $result = String::insert($string, array('a' => 1, 'c' => 3), array('clean' => true));
+ $this->assertEquals($expected, $result);
+
+ $string = ':a :b :c';
+ $expected = '2 3';
+ $result = String::insert($string, array('b' => 2, 'c' => 3), array('clean' => true));
+ $this->assertEquals($expected, $result);
+
+ $string = ':a, :b and :c';
+ $expected = '2 and 3';
+ $result = String::insert($string, array('b' => 2, 'c' => 3), array('clean' => true));
+ $this->assertEquals($expected, $result);
+
+ $string = '":a, :b and :c"';
+ $expected = '"1, 2"';
+ $result = String::insert($string, array('a' => 1, 'b' => 2), array('clean' => true));
+ $this->assertEquals($expected, $result);
+
+ $string = '"${a}, ${b} and ${c}"';
+ $expected = '"1, 2"';
+ $result = String::insert($string, array('a' => 1, 'b' => 2), array('before' => '${', 'after' => '}', 'clean' => true));
+ $this->assertEquals($expected, $result);
+
+ $string = '<img src=":src" alt=":alt" class="foo :extra bar"/>';
+ $expected = '<img src="foo" class="foo bar"/>';
+ $result = String::insert($string, array('src' => 'foo'), array('clean' => 'html'));
+
+ $this->assertEquals($expected, $result);
+
+ $string = '<img src=":src" class=":no :extra"/>';
+ $expected = '<img src="foo"/>';
+ $result = String::insert($string, array('src' => 'foo'), array('clean' => 'html'));
+ $this->assertEquals($expected, $result);
+
+ $string = '<img src=":src" class=":no :extra"/>';
+ $expected = '<img src="foo" class="bar"/>';
+ $result = String::insert($string, array('src' => 'foo', 'extra' => 'bar'), array('clean' => 'html'));
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert("this is a ? string", "test");
+ $expected = "this is a test string";
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert("this is a ? string with a ? ? ?", array('long', 'few?', 'params', 'you know'));
+ $expected = "this is a long string with a few? params you know";
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert('update saved_urls set url = :url where id = :id', array('url' => 'http://www.testurl.com/param1:url/param2:id','id' => 1));
+ $expected = "update saved_urls set url = http://www.testurl.com/param1:url/param2:id where id = 1";
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert('update saved_urls set url = :url where id = :id', array('id' => 1, 'url' => 'http://www.testurl.com/param1:url/param2:id'));
+ $expected = "update saved_urls set url = http://www.testurl.com/param1:url/param2:id where id = 1";
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert(':me cake. :subject :verb fantastic.', array('me' => 'I :verb', 'subject' => 'cake', 'verb' => 'is'));
+ $expected = "I :verb cake. cake is fantastic.";
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert(':I.am: :not.yet: passing.', array('I.am' => 'We are'), array('before' => ':', 'after' => ':', 'clean' => array('replacement' => ' of course', 'method' => 'text')));
+ $expected = "We are of course passing.";
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert(
+ ':I.am: :not.yet: passing.',
+ array('I.am' => 'We are'),
+ array('before' => ':', 'after' => ':', 'clean' => true)
+ );
+ $expected = "We are passing.";
+ $this->assertEquals($expected, $result);
+
+ $result = String::insert('?-pended result', array('Pre'));
+ $expected = "Pre-pended result";
+ $this->assertEquals($expected, $result);
+
+ $string = 'switching :timeout / :timeout_count';
+ $expected = 'switching 5 / 10';
+ $result = String::insert($string, array('timeout' => 5, 'timeout_count' => 10));
+ $this->assertEquals($expected, $result);
+
+ $string = 'switching :timeout / :timeout_count';
+ $expected = 'switching 5 / 10';
+ $result = String::insert($string, array('timeout_count' => 10, 'timeout' => 5));
+ $this->assertEquals($expected, $result);
+
+ $string = 'switching :timeout_count by :timeout';
+ $expected = 'switching 10 by 5';
+ $result = String::insert($string, array('timeout' => 5, 'timeout_count' => 10));
+ $this->assertEquals($expected, $result);
+
+ $string = 'switching :timeout_count by :timeout';
+ $expected = 'switching 10 by 5';
+ $result = String::insert($string, array('timeout_count' => 10, 'timeout' => 5));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Clean Insert
+ *
+ * @return void
+ */
+ public function testCleanInsert() {
+ $result = String::cleanInsert(':incomplete', array(
+ 'clean' => true, 'before' => ':', 'after' => ''
+ ));
+ $this->assertEquals('', $result);
+
+ $result = String::cleanInsert(':incomplete', array(
+ 'clean' => array('method' => 'text', 'replacement' => 'complete'),
+ 'before' => ':', 'after' => '')
+ );
+ $this->assertEquals('complete', $result);
+
+ $result = String::cleanInsert(':in.complete', array(
+ 'clean' => true, 'before' => ':', 'after' => ''
+ ));
+ $this->assertEquals('', $result);
+
+ $result = String::cleanInsert(':in.complete and', array(
+ 'clean' => true, 'before' => ':', 'after' => '')
+ );
+ $this->assertEquals('', $result);
+
+ $result = String::cleanInsert(':in.complete or stuff', array(
+ 'clean' => true, 'before' => ':', 'after' => ''
+ ));
+ $this->assertEquals('stuff', $result);
+
+ $result = String::cleanInsert(
+ '<p class=":missing" id=":missing">Text here</p>',
+ array('clean' => 'html', 'before' => ':', 'after' => '')
+ );
+ $this->assertEquals('<p>Text here</p>', $result);
+ }
+
+/**
+ * Tests that non-insertable variables (i.e. arrays) are skipped when used as values in
+ * String::insert().
+ *
+ * @return void
+ */
+ public function testAutoIgnoreBadInsertData() {
+ $data = array('foo' => 'alpha', 'bar' => 'beta', 'fale' => array());
+ $result = String::insert('(:foo > :bar || :fale!)', $data, array('clean' => 'text'));
+ $this->assertEquals('(alpha > beta || !)', $result);
+ }
+
+/**
+ * testTokenize method
+ *
+ * @return void
+ */
+ public function testTokenize() {
+ $result = String::tokenize('A,(short,boring test)');
+ $expected = array('A', '(short,boring test)');
+ $this->assertEquals($expected, $result);
+
+ $result = String::tokenize('A,(short,more interesting( test)');
+ $expected = array('A', '(short,more interesting( test)');
+ $this->assertEquals($expected, $result);
+
+ $result = String::tokenize('A,(short,very interesting( test))');
+ $expected = array('A', '(short,very interesting( test))');
+ $this->assertEquals($expected, $result);
+
+ $result = String::tokenize('"single tag"', ' ', '"', '"');
+ $expected = array('"single tag"');
+ $this->assertEquals($expected, $result);
+
+ $result = String::tokenize('tagA "single tag" tagB', ' ', '"', '"');
+ $expected = array('tagA', '"single tag"', 'tagB');
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testReplaceWithQuestionMarkInString() {
+ $string = ':a, :b and :c?';
+ $expected = '2 and 3?';
+ $result = String::insert($string, array('b' => 2, 'c' => 3), array('clean' => true));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test wrap method.
+ *
+ * @return void
+ */
+ public function testWrap() {
+ $text = 'This is the song that never ends. This is the song that never ends. This is the song that never ends.';
+ $result = String::wrap($text, 33);
+ $expected = <<<TEXT
+This is the song that never ends.
+This is the song that never ends.
+This is the song that never ends.
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Text not wrapped.');
+
+ $result = String::wrap($text, array('width' => 20, 'wordWrap' => false));
+ $expected = <<<TEXT
+This is the song th
+at never ends. This
+ is the song that n
+ever ends. This is
+the song that never
+ ends.
+TEXT;
+ $this->assertTextEquals($expected, $result, 'Text not wrapped.');
+ }
+
+/**
+ * test wrap() indenting
+ *
+ * @return void
+ */
+ public function testWrapIndent() {
+ $text = 'This is the song that never ends. This is the song that never ends. This is the song that never ends.';
+ $result = String::wrap($text, array('width' => 33, 'indent' => "\t", 'indentAt' => 1));
+ $expected = <<<TEXT
+This is the song that never ends.
+ This is the song that never ends.
+ This is the song that never ends.
+TEXT;
+ $this->assertTextEquals($expected, $result);
+ }
+
+/**
+ * testTruncate method
+ *
+ * @return void
+ */
+ public function testTruncate() {
+ $text1 = 'The quick brown fox jumps over the lazy dog';
+ $text2 = 'Heiz&ouml;lr&uuml;cksto&szlig;abd&auml;mpfung';
+ $text3 = '<b>&copy; 2005-2007, Cake Software Foundation, Inc.</b><br />written by Alexander Wegener';
+ $text4 = '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But the following image tag should be conform <img src="mypic.jpg" alt="Me, myself and I" /></b><br />Great, or?';
+ $text5 = '0<b>1<i>2<span class="myclass">3</span>4<u>5</u>6</i>7</b>8<b>9</b>0';
+ $text6 = '<p><strong>Extra dates have been announced for this year\'s tour.</strong></p><p>Tickets for the new shows in</p>';
+ $text7 = 'El moño está en el lugar correcto. Eso fue lo que dijo la niña, ¿habrá dicho la verdad?';
+ $text8 = 'Vive la R' . chr(195) . chr(169) . 'publique de France';
+ $text9 = 'НОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
+ $text10 = 'http://example.com/something/foo:bar';
+
+ $this->assertSame($this->Text->truncate($text1, 15), 'The quick br...');
+ $this->assertSame($this->Text->truncate($text1, 15, array('exact' => false)), 'The quick...');
+ $this->assertSame($this->Text->truncate($text1, 100), 'The quick brown fox jumps over the lazy dog');
+ $this->assertSame($this->Text->truncate($text2, 10), 'Heiz&ou...');
+ $this->assertSame($this->Text->truncate($text2, 10, array('exact' => false)), '...');
+ $this->assertSame($this->Text->truncate($text3, 20), '<b>&copy; 2005-20...');
+ $this->assertSame($this->Text->truncate($text4, 15), '<img src="my...');
+ $this->assertSame($this->Text->truncate($text5, 6, array('ending' => '')), '0<b>1<');
+ $this->assertSame($this->Text->truncate($text1, 15, array('html' => true)), 'The quick br...');
+ $this->assertSame($this->Text->truncate($text1, 15, array('exact' => false, 'html' => true)), 'The quick...');
+ $this->assertSame($this->Text->truncate($text2, 10, array('html' => true)), 'Heiz&ouml;lr...');
+ $this->assertSame($this->Text->truncate($text2, 10, array('exact' => false, 'html' => true)), '...');
+ $this->assertSame($this->Text->truncate($text3, 20, array('html' => true)), '<b>&copy; 2005-2007, Cake...</b>');
+ $this->assertSame($this->Text->truncate($text4, 15, array('html' => true)), '<img src="mypic.jpg"> This image ...');
+ $this->assertSame($this->Text->truncate($text4, 45, array('html' => true)), '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But t...</b>');
+ $this->assertSame($this->Text->truncate($text4, 90, array('html' => true)), '<img src="mypic.jpg"> This image tag is not XHTML conform!<br><hr/><b>But the following image tag should be conform <img src="mypic.jpg" alt="Me, myself and I" /></b><br />Grea...');
+ $this->assertSame($this->Text->truncate($text5, 6, array('ending' => '', 'html' => true)), '0<b>1<i>2<span class="myclass">3</span>4<u>5</u></i></b>');
+ $this->assertSame($this->Text->truncate($text5, 20, array('ending' => '', 'html' => true)), $text5);
+ $this->assertSame($this->Text->truncate($text6, 57, array('exact' => false, 'html' => true)), "<p><strong>Extra dates have been announced for this year's...</strong></p>");
+ $this->assertSame($this->Text->truncate($text7, 255), $text7);
+ $this->assertSame($this->Text->truncate($text7, 15), 'El moño está...');
+ $this->assertSame($this->Text->truncate($text8, 15), 'Vive la R' . chr(195) . chr(169) . 'pu...');
+ $this->assertSame($this->Text->truncate($text9, 10), 'НОПРСТУ...');
+ $this->assertSame($this->Text->truncate($text10, 30), 'http://example.com/somethin...');
+
+ $text = '<p><span style="font-size: medium;"><a>Iamatestwithnospacesandhtml</a></span></p>';
+ $result = $this->Text->truncate($text, 10, array(
+ 'ending' => '...',
+ 'exact' => false,
+ 'html' => true
+ ));
+ $expected = '<p><span style="font-size: medium;"><a>...</a></span></p>';
+ $this->assertEquals($expected, $result);
+
+ $text = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
+Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
+este artículo de El País.</span></p>
+<p><span style="font-size: medium;"><span style="font-size:
+large;">Por qué Steve era distinto.</span></span></p>
+<p><span style="font-size: medium;"><a href="http://www.elpais.com/
+articulo/primer/plano/Steve/era/distinto/elpepueconeg/
+20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
+Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
+<p><span style="font-size: medium;">Ya se ha publicado la biografía de
+Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
+Isaacson</strong>", aquí os dejamos la dirección de amazon donde
+podeís adquirirla.</span></p>
+<p><span style="font-size: medium;"><a>http://www.amazon.com/Steve-
+Jobs-Walter-Isaacson/dp/1451648537</a></span></p>';
+ $result = $this->Text->truncate($text, 500, array(
+ 'ending' => '... ',
+ 'exact' => false,
+ 'html' => true
+ ));
+ $expected = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
+Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
+este artículo de El País.</span></p>
+<p><span style="font-size: medium;"><span style="font-size:
+large;">Por qué Steve era distinto.</span></span></p>
+<p><span style="font-size: medium;"><a href="http://www.elpais.com/
+articulo/primer/plano/Steve/era/distinto/elpepueconeg/
+20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
+Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
+<p><span style="font-size: medium;">Ya se ha publicado la biografía de
+Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
+Isaacson</strong>", aquí os dejamos la dirección de amazon donde
+podeís adquirirla.</span></p>
+<p><span style="font-size: medium;"><a>... </a></span></p>';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testHighlight method
+ *
+ * @return void
+ */
+ public function testHighlight() {
+ $text = 'This is a test text';
+ $phrases = array('This', 'text');
+ $result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
+ $expected = '<b>This</b> is a test <b>text</b>';
+ $this->assertEquals($expected, $result);
+
+ $phrases = array('is', 'text');
+ $result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>', 'regex' => "|\b%s\b|iu"));
+ $expected = 'This <b>is</b> a test <b>text</b>';
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a test text';
+ $phrases = null;
+ $result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
+ $this->assertEquals($text, $result);
+
+ $text = 'This is a (test) text';
+ $phrases = '(test';
+ $result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
+ $this->assertEquals('This is a <b>(test</b>) text', $result);
+
+ $text = 'Ich saß in einem Café am Übergang';
+ $expected = 'Ich <b>saß</b> in einem <b>Café</b> am <b>Übergang</b>';
+ $phrases = array('saß', 'café', 'übergang');
+ $result = $this->Text->highlight($text, $phrases, array('format' => '<b>\1</b>'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testHighlightHtml method
+ *
+ * @return void
+ */
+ public function testHighlightHtml() {
+ $text1 = '<p>strongbow isn&rsquo;t real cider</p>';
+ $text2 = '<p>strongbow <strong>isn&rsquo;t</strong> real cider</p>';
+ $text3 = '<img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
+ $text4 = 'What a strong mouse: <img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
+ $options = array('format' => '<b>\1</b>', 'html' => true);
+
+ $expected = '<p><b>strong</b>bow isn&rsquo;t real cider</p>';
+ $this->assertEquals($expected, $this->Text->highlight($text1, 'strong', $options));
+
+ $expected = '<p><b>strong</b>bow <strong>isn&rsquo;t</strong> real cider</p>';
+ $this->assertEquals($expected, $this->Text->highlight($text2, 'strong', $options));
+
+ $this->assertEquals($this->Text->highlight($text3, 'strong', $options), $text3);
+
+ $this->assertEquals($this->Text->highlight($text3, array('strong', 'what'), $options), $text3);
+
+ $expected = '<b>What</b> a <b>strong</b> mouse: <img src="what-a-strong-mouse.png" alt="What a strong mouse!" />';
+ $this->assertEquals($this->Text->highlight($text4, array('strong', 'what'), $options), $expected);
+ }
+
+/**
+ * testHighlightMulti method
+ *
+ * @return void
+ */
+ public function testHighlightMulti() {
+ $text = 'This is a test text';
+ $phrases = array('This', 'text');
+ $result = $this->Text->highlight($text, $phrases, array('format' => array('<b>\1</b>', '<em>\1</em>')));
+ $expected = '<b>This</b> is a test <em>text</em>';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testStripLinks method
+ *
+ * @return void
+ */
+ public function testStripLinks() {
+ $text = 'This is a test text';
+ $expected = 'This is a test text';
+ $result = $this->Text->stripLinks($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a <a href="#">test</a> text';
+ $expected = 'This is a test text';
+ $result = $this->Text->stripLinks($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This <strong>is</strong> a <a href="#">test</a> <a href="#">text</a>';
+ $expected = 'This <strong>is</strong> a test text';
+ $result = $this->Text->stripLinks($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This <strong>is</strong> a <a href="#">test</a> and <abbr>some</abbr> other <a href="#">text</a>';
+ $expected = 'This <strong>is</strong> a test and <abbr>some</abbr> other text';
+ $result = $this->Text->stripLinks($text);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testHighlightCaseInsensitivity method
+ *
+ * @return void
+ */
+ public function testHighlightCaseInsensitivity() {
+ $text = 'This is a Test text';
+ $expected = 'This is a <b>Test</b> text';
+
+ $result = $this->Text->highlight($text, 'test', array('format' => '<b>\1</b>'));
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Text->highlight($text, array('test'), array('format' => '<b>\1</b>'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testExcerpt method
+ *
+ * @return void
+ */
+ public function testExcerpt() {
+ $text = 'This is a phrase with test text to play with';
+
+ $expected = '...ase with test text to ...';
+ $result = $this->Text->excerpt($text, 'test', 9, '...');
+ $this->assertEquals($expected, $result);
+
+ $expected = 'This is a...';
+ $result = $this->Text->excerpt($text, 'not_found', 9, '...');
+ $this->assertEquals($expected, $result);
+
+ $expected = 'This is a phras...';
+ $result = $this->Text->excerpt($text, null, 9, '...');
+ $this->assertEquals($expected, $result);
+
+ $expected = $text;
+ $result = $this->Text->excerpt($text, null, 200, '...');
+ $this->assertEquals($expected, $result);
+
+ $expected = '...a phrase w...';
+ $result = $this->Text->excerpt($text, 'phrase', 2, '...');
+ $this->assertEquals($expected, $result);
+
+ $phrase = 'This is a phrase with test text';
+ $expected = $text;
+ $result = $this->Text->excerpt($text, $phrase, 13, '...');
+ $this->assertEquals($expected, $result);
+
+ $text = 'aaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaa';
+ $phrase = 'bbbbbbbb';
+ $result = $this->Text->excerpt($text, $phrase, 10);
+ $expected = '...aaaaaaaaaabbbbbbbbaaaaaaaaaa...';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testExcerptCaseInsensitivity method
+ *
+ * @return void
+ */
+ public function testExcerptCaseInsensitivity() {
+ $text = 'This is a phrase with test text to play with';
+
+ $expected = '...ase with test text to ...';
+ $result = $this->Text->excerpt($text, 'TEST', 9, '...');
+ $this->assertEquals($expected, $result);
+
+ $expected = 'This is a...';
+ $result = $this->Text->excerpt($text, 'NOT_FOUND', 9, '...');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testListGeneration method
+ *
+ * @return void
+ */
+ public function testListGeneration() {
+ $result = $this->Text->toList(array());
+ $this->assertEquals('', $result);
+
+ $result = $this->Text->toList(array('One'));
+ $this->assertEquals('One', $result);
+
+ $result = $this->Text->toList(array('Larry', 'Curly', 'Moe'));
+ $this->assertEquals('Larry, Curly and Moe', $result);
+
+ $result = $this->Text->toList(array('Dusty', 'Lucky', 'Ned'), 'y');
+ $this->assertEquals('Dusty, Lucky y Ned', $result);
+
+ $result = $this->Text->toList(array(1 => 'Dusty', 2 => 'Lucky', 3 => 'Ned'), 'y');
+ $this->assertEquals('Dusty, Lucky y Ned', $result);
+
+ $result = $this->Text->toList(array(1 => 'Dusty', 2 => 'Lucky', 3 => 'Ned'), 'and', ' + ');
+ $this->assertEquals('Dusty + Lucky and Ned', $result);
+
+ $result = $this->Text->toList(array('name1' => 'Dusty', 'name2' => 'Lucky'));
+ $this->assertEquals('Dusty and Lucky', $result);
+
+ $result = $this->Text->toList(array('test_0' => 'banana', 'test_1' => 'apple', 'test_2' => 'lemon'));
+ $this->assertEquals('banana, apple and lemon', $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ValidationTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ValidationTest.php
new file mode 100644
index 0000000..a3f98f9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/ValidationTest.php
@@ -0,0 +1,2217 @@
+<?php
+/**
+ * ValidationTest file
+ *
+ * PHP Version 5.x
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Validation', 'Utility');
+
+/**
+ * CustomValidator class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class CustomValidator {
+
+/**
+ * Makes sure that a given $email address is valid and unique
+ *
+ * @param string $email
+ * @return boolean
+ */
+ public static function customValidate($check) {
+ return (bool)preg_match('/^[0-9]{3}$/', $check);
+ }
+
+}
+
+/**
+ * TestNlValidation class
+ *
+ * Used to test pass through of Validation
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class TestNlValidation {
+
+/**
+ * postal function, for testing postal pass through.
+ *
+ * @param string $check
+ * @return void
+ */
+ public static function postal($check) {
+ return true;
+ }
+
+/**
+ * ssn function for testing ssn pass through
+ *
+ * @return void
+ */
+ public static function ssn($check) {
+ return true;
+ }
+
+}
+
+/**
+ * TestDeValidation class
+ *
+ * Used to test pass through of Validation
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class TestDeValidation {
+
+/**
+ * phone function, for testing phone pass through.
+ *
+ * @param string $check
+ * @return void
+ */
+ public static function phone($check) {
+ return true;
+ }
+
+}
+
+/**
+ * Test Case for Validation Class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class ValidationTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->_appEncoding = Configure::read('App.encoding');
+ $this->_appLocale = array();
+ foreach (array(LC_MONETARY, LC_NUMERIC, LC_TIME) as $category) {
+ $this->_appLocale[$category] = setlocale($category, 0);
+ setlocale($category, 'en_US');
+ }
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('App.encoding', $this->_appEncoding);
+ foreach ($this->_appLocale as $category => $locale) {
+ setlocale($category, $locale);
+ }
+ }
+
+/**
+ * testNotEmpty method
+ *
+ * @return void
+ */
+ public function testNotEmpty() {
+ $this->assertTrue(Validation::notEmpty('abcdefg'));
+ $this->assertTrue(Validation::notEmpty('fasdf '));
+ $this->assertTrue(Validation::notEmpty('fooo' . chr(243) . 'blabla'));
+ $this->assertTrue(Validation::notEmpty('abçďĕʑʘπй'));
+ $this->assertTrue(Validation::notEmpty('José'));
+ $this->assertTrue(Validation::notEmpty('é'));
+ $this->assertTrue(Validation::notEmpty('π'));
+ $this->assertFalse(Validation::notEmpty("\t "));
+ $this->assertFalse(Validation::notEmpty(""));
+ }
+
+/**
+ * testNotEmptyISO88591Encoding method
+ *
+ * @return void
+ */
+ public function testNotEmptyISO88591AppEncoding() {
+ Configure::write('App.encoding', 'ISO-8859-1');
+ $this->assertTrue(Validation::notEmpty('abcdefg'));
+ $this->assertTrue(Validation::notEmpty('fasdf '));
+ $this->assertTrue(Validation::notEmpty('fooo' . chr(243) . 'blabla'));
+ $this->assertTrue(Validation::notEmpty('abçďĕʑʘπй'));
+ $this->assertTrue(Validation::notEmpty('José'));
+ $this->assertTrue(Validation::notEmpty(utf8_decode('José')));
+ $this->assertFalse(Validation::notEmpty("\t "));
+ $this->assertFalse(Validation::notEmpty(""));
+ }
+
+/**
+ * testAlphaNumeric method
+ *
+ * @return void
+ */
+ public function testAlphaNumeric() {
+ $this->assertTrue(Validation::alphaNumeric('frferrf'));
+ $this->assertTrue(Validation::alphaNumeric('12234'));
+ $this->assertTrue(Validation::alphaNumeric('1w2e2r3t4y'));
+ $this->assertTrue(Validation::alphaNumeric('0'));
+ $this->assertTrue(Validation::alphaNumeric('abçďĕʑʘπй'));
+ $this->assertTrue(Validation::alphaNumeric('ˇˆๆゞ'));
+ $this->assertTrue(Validation::alphaNumeric('אกあアꀀ豈'));
+ $this->assertTrue(Validation::alphaNumeric('Džᾈᾨ'));
+ $this->assertTrue(Validation::alphaNumeric('ÆΔΩЖÇ'));
+
+ $this->assertFalse(Validation::alphaNumeric('12 234'));
+ $this->assertFalse(Validation::alphaNumeric('dfd 234'));
+ $this->assertFalse(Validation::alphaNumeric("\n"));
+ $this->assertFalse(Validation::alphaNumeric("\t"));
+ $this->assertFalse(Validation::alphaNumeric("\r"));
+ $this->assertFalse(Validation::alphaNumeric(' '));
+ $this->assertFalse(Validation::alphaNumeric(''));
+ }
+
+/**
+ * testAlphaNumericPassedAsArray method
+ *
+ * @return void
+ */
+ public function testAlphaNumericPassedAsArray() {
+ $this->assertTrue(Validation::alphaNumeric(array('check' => 'frferrf')));
+ $this->assertTrue(Validation::alphaNumeric(array('check' => '12234')));
+ $this->assertTrue(Validation::alphaNumeric(array('check' => '1w2e2r3t4y')));
+ $this->assertTrue(Validation::alphaNumeric(array('check' => '0')));
+ $this->assertFalse(Validation::alphaNumeric(array('check' => '12 234')));
+ $this->assertFalse(Validation::alphaNumeric(array('check' => 'dfd 234')));
+ $this->assertFalse(Validation::alphaNumeric(array('check' => "\n")));
+ $this->assertFalse(Validation::alphaNumeric(array('check' => "\t")));
+ $this->assertFalse(Validation::alphaNumeric(array('check' => "\r")));
+ $this->assertFalse(Validation::alphaNumeric(array('check' => ' ')));
+ $this->assertFalse(Validation::alphaNumeric(array('check' => '')));
+ }
+
+/**
+ * testBetween method
+ *
+ * @return void
+ */
+ public function testBetween() {
+ $this->assertTrue(Validation::between('abcdefg', 1, 7));
+ $this->assertTrue(Validation::between('', 0, 7));
+ $this->assertTrue(Validation::between('אกあアꀀ豈', 1, 7));
+
+ $this->assertFalse(Validation::between('abcdefg', 1, 6));
+ $this->assertFalse(Validation::between('ÆΔΩЖÇ', 1, 3));
+ }
+
+/**
+ * testBlank method
+ *
+ * @return void
+ */
+ public function testBlank() {
+ $this->assertTrue(Validation::blank(''));
+ $this->assertTrue(Validation::blank(' '));
+ $this->assertTrue(Validation::blank("\n"));
+ $this->assertTrue(Validation::blank("\t"));
+ $this->assertTrue(Validation::blank("\r"));
+ $this->assertFalse(Validation::blank(' Blank'));
+ $this->assertFalse(Validation::blank('Blank'));
+ }
+
+/**
+ * testBlankAsArray method
+ *
+ * @return void
+ */
+ public function testBlankAsArray() {
+ $this->assertTrue(Validation::blank(array('check' => '')));
+ $this->assertTrue(Validation::blank(array('check' => ' ')));
+ $this->assertTrue(Validation::blank(array('check' => "\n")));
+ $this->assertTrue(Validation::blank(array('check' => "\t")));
+ $this->assertTrue(Validation::blank(array('check' => "\r")));
+ $this->assertFalse(Validation::blank(array('check' => ' Blank')));
+ $this->assertFalse(Validation::blank(array('check' => 'Blank')));
+ }
+
+/**
+ * testcc method
+ *
+ * @return void
+ */
+ public function testCc() {
+ //American Express
+ $this->assertTrue(Validation::cc('370482756063980', array('amex')));
+ $this->assertTrue(Validation::cc('349106433773483', array('amex')));
+ $this->assertTrue(Validation::cc('344671486204764', array('amex')));
+ $this->assertTrue(Validation::cc('344042544509943', array('amex')));
+ $this->assertTrue(Validation::cc('377147515754475', array('amex')));
+ $this->assertTrue(Validation::cc('375239372816422', array('amex')));
+ $this->assertTrue(Validation::cc('376294341957707', array('amex')));
+ $this->assertTrue(Validation::cc('341779292230411', array('amex')));
+ $this->assertTrue(Validation::cc('341646919853372', array('amex')));
+ $this->assertTrue(Validation::cc('348498616319346', array('amex')));
+ //BankCard
+ $this->assertTrue(Validation::cc('5610745867413420', array('bankcard')));
+ $this->assertTrue(Validation::cc('5610376649499352', array('bankcard')));
+ $this->assertTrue(Validation::cc('5610091936000694', array('bankcard')));
+ $this->assertTrue(Validation::cc('5602248780118788', array('bankcard')));
+ $this->assertTrue(Validation::cc('5610631567676765', array('bankcard')));
+ $this->assertTrue(Validation::cc('5602238211270795', array('bankcard')));
+ $this->assertTrue(Validation::cc('5610173951215470', array('bankcard')));
+ $this->assertTrue(Validation::cc('5610139705753702', array('bankcard')));
+ $this->assertTrue(Validation::cc('5602226032150551', array('bankcard')));
+ $this->assertTrue(Validation::cc('5602223993735777', array('bankcard')));
+ //Diners Club 14
+ $this->assertTrue(Validation::cc('30155483651028', array('diners')));
+ $this->assertTrue(Validation::cc('36371312803821', array('diners')));
+ $this->assertTrue(Validation::cc('38801277489875', array('diners')));
+ $this->assertTrue(Validation::cc('30348560464296', array('diners')));
+ $this->assertTrue(Validation::cc('30349040317708', array('diners')));
+ $this->assertTrue(Validation::cc('36567413559978', array('diners')));
+ $this->assertTrue(Validation::cc('36051554732702', array('diners')));
+ $this->assertTrue(Validation::cc('30391842198191', array('diners')));
+ $this->assertTrue(Validation::cc('30172682197745', array('diners')));
+ $this->assertTrue(Validation::cc('30162056566641', array('diners')));
+ $this->assertTrue(Validation::cc('30085066927745', array('diners')));
+ $this->assertTrue(Validation::cc('36519025221976', array('diners')));
+ $this->assertTrue(Validation::cc('30372679371044', array('diners')));
+ $this->assertTrue(Validation::cc('38913939150124', array('diners')));
+ $this->assertTrue(Validation::cc('36852899094637', array('diners')));
+ $this->assertTrue(Validation::cc('30138041971120', array('diners')));
+ $this->assertTrue(Validation::cc('36184047836838', array('diners')));
+ $this->assertTrue(Validation::cc('30057460264462', array('diners')));
+ $this->assertTrue(Validation::cc('38980165212050', array('diners')));
+ $this->assertTrue(Validation::cc('30356516881240', array('diners')));
+ $this->assertTrue(Validation::cc('38744810033182', array('diners')));
+ $this->assertTrue(Validation::cc('30173638706621', array('diners')));
+ $this->assertTrue(Validation::cc('30158334709185', array('diners')));
+ $this->assertTrue(Validation::cc('30195413721186', array('diners')));
+ $this->assertTrue(Validation::cc('38863347694793', array('diners')));
+ $this->assertTrue(Validation::cc('30275627009113', array('diners')));
+ $this->assertTrue(Validation::cc('30242860404971', array('diners')));
+ $this->assertTrue(Validation::cc('30081877595151', array('diners')));
+ $this->assertTrue(Validation::cc('38053196067461', array('diners')));
+ $this->assertTrue(Validation::cc('36520379984870', array('diners')));
+ //2004 MasterCard/Diners Club Alliance International 14
+ $this->assertTrue(Validation::cc('36747701998969', array('diners')));
+ $this->assertTrue(Validation::cc('36427861123159', array('diners')));
+ $this->assertTrue(Validation::cc('36150537602386', array('diners')));
+ $this->assertTrue(Validation::cc('36582388820610', array('diners')));
+ $this->assertTrue(Validation::cc('36729045250216', array('diners')));
+ //2004 MasterCard/Diners Club Alliance US & Canada 16
+ $this->assertTrue(Validation::cc('5597511346169950', array('diners')));
+ $this->assertTrue(Validation::cc('5526443162217562', array('diners')));
+ $this->assertTrue(Validation::cc('5577265786122391', array('diners')));
+ $this->assertTrue(Validation::cc('5534061404676989', array('diners')));
+ $this->assertTrue(Validation::cc('5545313588374502', array('diners')));
+ //Discover
+ $this->assertTrue(Validation::cc('6011802876467237', array('disc')));
+ $this->assertTrue(Validation::cc('6506432777720955', array('disc')));
+ $this->assertTrue(Validation::cc('6011126265283942', array('disc')));
+ $this->assertTrue(Validation::cc('6502187151579252', array('disc')));
+ $this->assertTrue(Validation::cc('6506600836002298', array('disc')));
+ $this->assertTrue(Validation::cc('6504376463615189', array('disc')));
+ $this->assertTrue(Validation::cc('6011440907005377', array('disc')));
+ $this->assertTrue(Validation::cc('6509735979634270', array('disc')));
+ $this->assertTrue(Validation::cc('6011422366775856', array('disc')));
+ $this->assertTrue(Validation::cc('6500976374623323', array('disc')));
+ //enRoute
+ $this->assertTrue(Validation::cc('201496944158937', array('enroute')));
+ $this->assertTrue(Validation::cc('214945833739665', array('enroute')));
+ $this->assertTrue(Validation::cc('214982692491187', array('enroute')));
+ $this->assertTrue(Validation::cc('214901395949424', array('enroute')));
+ $this->assertTrue(Validation::cc('201480676269187', array('enroute')));
+ $this->assertTrue(Validation::cc('214911922887807', array('enroute')));
+ $this->assertTrue(Validation::cc('201485025457250', array('enroute')));
+ $this->assertTrue(Validation::cc('201402662758866', array('enroute')));
+ $this->assertTrue(Validation::cc('214981579370225', array('enroute')));
+ $this->assertTrue(Validation::cc('201447595859877', array('enroute')));
+ //JCB 15 digit
+ $this->assertTrue(Validation::cc('210034762247893', array('jcb')));
+ $this->assertTrue(Validation::cc('180078671678892', array('jcb')));
+ $this->assertTrue(Validation::cc('180010559353736', array('jcb')));
+ $this->assertTrue(Validation::cc('210095474464258', array('jcb')));
+ $this->assertTrue(Validation::cc('210006675562188', array('jcb')));
+ $this->assertTrue(Validation::cc('210063299662662', array('jcb')));
+ $this->assertTrue(Validation::cc('180032506857825', array('jcb')));
+ $this->assertTrue(Validation::cc('210057919192738', array('jcb')));
+ $this->assertTrue(Validation::cc('180031358949367', array('jcb')));
+ $this->assertTrue(Validation::cc('180033802147846', array('jcb')));
+ //JCB 16 digit
+ $this->assertTrue(Validation::cc('3096806857839939', array('jcb')));
+ $this->assertTrue(Validation::cc('3158699503187091', array('jcb')));
+ $this->assertTrue(Validation::cc('3112549607186579', array('jcb')));
+ $this->assertTrue(Validation::cc('3112332922425604', array('jcb')));
+ $this->assertTrue(Validation::cc('3112001541159239', array('jcb')));
+ $this->assertTrue(Validation::cc('3112162495317841', array('jcb')));
+ $this->assertTrue(Validation::cc('3337562627732768', array('jcb')));
+ $this->assertTrue(Validation::cc('3337107161330775', array('jcb')));
+ $this->assertTrue(Validation::cc('3528053736003621', array('jcb')));
+ $this->assertTrue(Validation::cc('3528915255020360', array('jcb')));
+ $this->assertTrue(Validation::cc('3096786059660921', array('jcb')));
+ $this->assertTrue(Validation::cc('3528264799292320', array('jcb')));
+ $this->assertTrue(Validation::cc('3096469164130136', array('jcb')));
+ $this->assertTrue(Validation::cc('3112127443822853', array('jcb')));
+ $this->assertTrue(Validation::cc('3096849995802328', array('jcb')));
+ $this->assertTrue(Validation::cc('3528090735127407', array('jcb')));
+ $this->assertTrue(Validation::cc('3112101006819234', array('jcb')));
+ $this->assertTrue(Validation::cc('3337444428040784', array('jcb')));
+ $this->assertTrue(Validation::cc('3088043154151061', array('jcb')));
+ $this->assertTrue(Validation::cc('3088295969414866', array('jcb')));
+ $this->assertTrue(Validation::cc('3158748843158575', array('jcb')));
+ $this->assertTrue(Validation::cc('3158709206148538', array('jcb')));
+ $this->assertTrue(Validation::cc('3158365159575324', array('jcb')));
+ $this->assertTrue(Validation::cc('3158671691305165', array('jcb')));
+ $this->assertTrue(Validation::cc('3528523028771093', array('jcb')));
+ $this->assertTrue(Validation::cc('3096057126267870', array('jcb')));
+ $this->assertTrue(Validation::cc('3158514047166834', array('jcb')));
+ $this->assertTrue(Validation::cc('3528274546125962', array('jcb')));
+ $this->assertTrue(Validation::cc('3528890967705733', array('jcb')));
+ $this->assertTrue(Validation::cc('3337198811307545', array('jcb')));
+ //Maestro (debit card)
+ $this->assertTrue(Validation::cc('5020147409985219', array('maestro')));
+ $this->assertTrue(Validation::cc('5020931809905616', array('maestro')));
+ $this->assertTrue(Validation::cc('5020412965470224', array('maestro')));
+ $this->assertTrue(Validation::cc('5020129740944022', array('maestro')));
+ $this->assertTrue(Validation::cc('5020024696747943', array('maestro')));
+ $this->assertTrue(Validation::cc('5020581514636509', array('maestro')));
+ $this->assertTrue(Validation::cc('5020695008411987', array('maestro')));
+ $this->assertTrue(Validation::cc('5020565359718977', array('maestro')));
+ $this->assertTrue(Validation::cc('6339931536544062', array('maestro')));
+ $this->assertTrue(Validation::cc('6465028615704406', array('maestro')));
+ //Mastercard
+ $this->assertTrue(Validation::cc('5580424361774366', array('mc')));
+ $this->assertTrue(Validation::cc('5589563059318282', array('mc')));
+ $this->assertTrue(Validation::cc('5387558333690047', array('mc')));
+ $this->assertTrue(Validation::cc('5163919215247175', array('mc')));
+ $this->assertTrue(Validation::cc('5386742685055055', array('mc')));
+ $this->assertTrue(Validation::cc('5102303335960674', array('mc')));
+ $this->assertTrue(Validation::cc('5526543403964565', array('mc')));
+ $this->assertTrue(Validation::cc('5538725892618432', array('mc')));
+ $this->assertTrue(Validation::cc('5119543573129778', array('mc')));
+ $this->assertTrue(Validation::cc('5391174753915767', array('mc')));
+ $this->assertTrue(Validation::cc('5510994113980714', array('mc')));
+ $this->assertTrue(Validation::cc('5183720260418091', array('mc')));
+ $this->assertTrue(Validation::cc('5488082196086704', array('mc')));
+ $this->assertTrue(Validation::cc('5484645164161834', array('mc')));
+ $this->assertTrue(Validation::cc('5171254350337031', array('mc')));
+ $this->assertTrue(Validation::cc('5526987528136452', array('mc')));
+ $this->assertTrue(Validation::cc('5504148941409358', array('mc')));
+ $this->assertTrue(Validation::cc('5240793507243615', array('mc')));
+ $this->assertTrue(Validation::cc('5162114693017107', array('mc')));
+ $this->assertTrue(Validation::cc('5163104807404753', array('mc')));
+ $this->assertTrue(Validation::cc('5590136167248365', array('mc')));
+ $this->assertTrue(Validation::cc('5565816281038948', array('mc')));
+ $this->assertTrue(Validation::cc('5467639122779531', array('mc')));
+ $this->assertTrue(Validation::cc('5297350261550024', array('mc')));
+ $this->assertTrue(Validation::cc('5162739131368058', array('mc')));
+ //Solo 16
+ $this->assertTrue(Validation::cc('6767432107064987', array('solo')));
+ $this->assertTrue(Validation::cc('6334667758225411', array('solo')));
+ $this->assertTrue(Validation::cc('6767037421954068', array('solo')));
+ $this->assertTrue(Validation::cc('6767823306394854', array('solo')));
+ $this->assertTrue(Validation::cc('6334768185398134', array('solo')));
+ $this->assertTrue(Validation::cc('6767286729498589', array('solo')));
+ $this->assertTrue(Validation::cc('6334972104431261', array('solo')));
+ $this->assertTrue(Validation::cc('6334843427400616', array('solo')));
+ $this->assertTrue(Validation::cc('6767493947881311', array('solo')));
+ $this->assertTrue(Validation::cc('6767194235798817', array('solo')));
+ //Solo 18
+ $this->assertTrue(Validation::cc('676714834398858593', array('solo')));
+ $this->assertTrue(Validation::cc('676751666435130857', array('solo')));
+ $this->assertTrue(Validation::cc('676781908573924236', array('solo')));
+ $this->assertTrue(Validation::cc('633488724644003240', array('solo')));
+ $this->assertTrue(Validation::cc('676732252338067316', array('solo')));
+ $this->assertTrue(Validation::cc('676747520084495821', array('solo')));
+ $this->assertTrue(Validation::cc('633465488901381957', array('solo')));
+ $this->assertTrue(Validation::cc('633487484858610484', array('solo')));
+ $this->assertTrue(Validation::cc('633453764680740694', array('solo')));
+ $this->assertTrue(Validation::cc('676768613295414451', array('solo')));
+ //Solo 19
+ $this->assertTrue(Validation::cc('6767838565218340113', array('solo')));
+ $this->assertTrue(Validation::cc('6767760119829705181', array('solo')));
+ $this->assertTrue(Validation::cc('6767265917091593668', array('solo')));
+ $this->assertTrue(Validation::cc('6767938856947440111', array('solo')));
+ $this->assertTrue(Validation::cc('6767501945697390076', array('solo')));
+ $this->assertTrue(Validation::cc('6334902868716257379', array('solo')));
+ $this->assertTrue(Validation::cc('6334922127686425532', array('solo')));
+ $this->assertTrue(Validation::cc('6334933119080706440', array('solo')));
+ $this->assertTrue(Validation::cc('6334647959628261714', array('solo')));
+ $this->assertTrue(Validation::cc('6334527312384101382', array('solo')));
+ //Switch 16
+ $this->assertTrue(Validation::cc('5641829171515733', array('switch')));
+ $this->assertTrue(Validation::cc('5641824852820809', array('switch')));
+ $this->assertTrue(Validation::cc('6759129648956909', array('switch')));
+ $this->assertTrue(Validation::cc('6759626072268156', array('switch')));
+ $this->assertTrue(Validation::cc('5641822698388957', array('switch')));
+ $this->assertTrue(Validation::cc('5641827123105470', array('switch')));
+ $this->assertTrue(Validation::cc('5641823755819553', array('switch')));
+ $this->assertTrue(Validation::cc('5641821939587682', array('switch')));
+ $this->assertTrue(Validation::cc('4936097148079186', array('switch')));
+ $this->assertTrue(Validation::cc('5641829739125009', array('switch')));
+ $this->assertTrue(Validation::cc('5641822860725507', array('switch')));
+ $this->assertTrue(Validation::cc('4936717688865831', array('switch')));
+ $this->assertTrue(Validation::cc('6759487613615441', array('switch')));
+ $this->assertTrue(Validation::cc('5641821346840617', array('switch')));
+ $this->assertTrue(Validation::cc('5641825793417126', array('switch')));
+ $this->assertTrue(Validation::cc('5641821302759595', array('switch')));
+ $this->assertTrue(Validation::cc('6759784969918837', array('switch')));
+ $this->assertTrue(Validation::cc('5641824910667036', array('switch')));
+ $this->assertTrue(Validation::cc('6759139909636173', array('switch')));
+ $this->assertTrue(Validation::cc('6333425070638022', array('switch')));
+ $this->assertTrue(Validation::cc('5641823910382067', array('switch')));
+ $this->assertTrue(Validation::cc('4936295218139423', array('switch')));
+ $this->assertTrue(Validation::cc('6333031811316199', array('switch')));
+ $this->assertTrue(Validation::cc('4936912044763198', array('switch')));
+ $this->assertTrue(Validation::cc('4936387053303824', array('switch')));
+ $this->assertTrue(Validation::cc('6759535838760523', array('switch')));
+ $this->assertTrue(Validation::cc('6333427174594051', array('switch')));
+ $this->assertTrue(Validation::cc('5641829037102700', array('switch')));
+ $this->assertTrue(Validation::cc('5641826495463046', array('switch')));
+ $this->assertTrue(Validation::cc('6333480852979946', array('switch')));
+ $this->assertTrue(Validation::cc('5641827761302876', array('switch')));
+ $this->assertTrue(Validation::cc('5641825083505317', array('switch')));
+ $this->assertTrue(Validation::cc('6759298096003991', array('switch')));
+ $this->assertTrue(Validation::cc('4936119165483420', array('switch')));
+ $this->assertTrue(Validation::cc('4936190990500993', array('switch')));
+ $this->assertTrue(Validation::cc('4903356467384927', array('switch')));
+ $this->assertTrue(Validation::cc('6333372765092554', array('switch')));
+ $this->assertTrue(Validation::cc('5641821330950570', array('switch')));
+ $this->assertTrue(Validation::cc('6759841558826118', array('switch')));
+ $this->assertTrue(Validation::cc('4936164540922452', array('switch')));
+ //Switch 18
+ $this->assertTrue(Validation::cc('493622764224625174', array('switch')));
+ $this->assertTrue(Validation::cc('564182823396913535', array('switch')));
+ $this->assertTrue(Validation::cc('675917308304801234', array('switch')));
+ $this->assertTrue(Validation::cc('675919890024220298', array('switch')));
+ $this->assertTrue(Validation::cc('633308376862556751', array('switch')));
+ $this->assertTrue(Validation::cc('564182377633208779', array('switch')));
+ $this->assertTrue(Validation::cc('564182870014926787', array('switch')));
+ $this->assertTrue(Validation::cc('675979788553829819', array('switch')));
+ $this->assertTrue(Validation::cc('493668394358130935', array('switch')));
+ $this->assertTrue(Validation::cc('493637431790930965', array('switch')));
+ $this->assertTrue(Validation::cc('633321438601941513', array('switch')));
+ $this->assertTrue(Validation::cc('675913800898840986', array('switch')));
+ $this->assertTrue(Validation::cc('564182592016841547', array('switch')));
+ $this->assertTrue(Validation::cc('564182428380440899', array('switch')));
+ $this->assertTrue(Validation::cc('493696376827623463', array('switch')));
+ $this->assertTrue(Validation::cc('675977939286485757', array('switch')));
+ $this->assertTrue(Validation::cc('490302699502091579', array('switch')));
+ $this->assertTrue(Validation::cc('564182085013662230', array('switch')));
+ $this->assertTrue(Validation::cc('493693054263310167', array('switch')));
+ $this->assertTrue(Validation::cc('633321755966697525', array('switch')));
+ $this->assertTrue(Validation::cc('675996851719732811', array('switch')));
+ $this->assertTrue(Validation::cc('493699211208281028', array('switch')));
+ $this->assertTrue(Validation::cc('493697817378356614', array('switch')));
+ $this->assertTrue(Validation::cc('675968224161768150', array('switch')));
+ $this->assertTrue(Validation::cc('493669416873337627', array('switch')));
+ $this->assertTrue(Validation::cc('564182439172549714', array('switch')));
+ $this->assertTrue(Validation::cc('675926914467673598', array('switch')));
+ $this->assertTrue(Validation::cc('564182565231977809', array('switch')));
+ $this->assertTrue(Validation::cc('675966282607849002', array('switch')));
+ $this->assertTrue(Validation::cc('493691609704348548', array('switch')));
+ $this->assertTrue(Validation::cc('675933118546065120', array('switch')));
+ $this->assertTrue(Validation::cc('493631116677238592', array('switch')));
+ $this->assertTrue(Validation::cc('675921142812825938', array('switch')));
+ $this->assertTrue(Validation::cc('633338311815675113', array('switch')));
+ $this->assertTrue(Validation::cc('633323539867338621', array('switch')));
+ $this->assertTrue(Validation::cc('675964912740845663', array('switch')));
+ $this->assertTrue(Validation::cc('633334008833727504', array('switch')));
+ $this->assertTrue(Validation::cc('493631941273687169', array('switch')));
+ $this->assertTrue(Validation::cc('564182971729706785', array('switch')));
+ $this->assertTrue(Validation::cc('633303461188963496', array('switch')));
+ //Switch 19
+ $this->assertTrue(Validation::cc('6759603460617628716', array('switch')));
+ $this->assertTrue(Validation::cc('4936705825268647681', array('switch')));
+ $this->assertTrue(Validation::cc('5641829846600479183', array('switch')));
+ $this->assertTrue(Validation::cc('6759389846573792530', array('switch')));
+ $this->assertTrue(Validation::cc('4936189558712637603', array('switch')));
+ $this->assertTrue(Validation::cc('5641822217393868189', array('switch')));
+ $this->assertTrue(Validation::cc('4903075563780057152', array('switch')));
+ $this->assertTrue(Validation::cc('4936510653566569547', array('switch')));
+ $this->assertTrue(Validation::cc('4936503083627303364', array('switch')));
+ $this->assertTrue(Validation::cc('4936777334398116272', array('switch')));
+ $this->assertTrue(Validation::cc('5641823876900554860', array('switch')));
+ $this->assertTrue(Validation::cc('6759619236903407276', array('switch')));
+ $this->assertTrue(Validation::cc('6759011470269978117', array('switch')));
+ $this->assertTrue(Validation::cc('6333175833997062502', array('switch')));
+ $this->assertTrue(Validation::cc('6759498728789080439', array('switch')));
+ $this->assertTrue(Validation::cc('4903020404168157841', array('switch')));
+ $this->assertTrue(Validation::cc('6759354334874804313', array('switch')));
+ $this->assertTrue(Validation::cc('6759900856420875115', array('switch')));
+ $this->assertTrue(Validation::cc('5641827269346868860', array('switch')));
+ $this->assertTrue(Validation::cc('5641828995047453870', array('switch')));
+ $this->assertTrue(Validation::cc('6333321884754806543', array('switch')));
+ $this->assertTrue(Validation::cc('6333108246283715901', array('switch')));
+ $this->assertTrue(Validation::cc('6759572372800700102', array('switch')));
+ $this->assertTrue(Validation::cc('4903095096797974933', array('switch')));
+ $this->assertTrue(Validation::cc('6333354315797920215', array('switch')));
+ $this->assertTrue(Validation::cc('6759163746089433755', array('switch')));
+ $this->assertTrue(Validation::cc('6759871666634807647', array('switch')));
+ $this->assertTrue(Validation::cc('5641827883728575248', array('switch')));
+ $this->assertTrue(Validation::cc('4936527975051407847', array('switch')));
+ $this->assertTrue(Validation::cc('5641823318396882141', array('switch')));
+ $this->assertTrue(Validation::cc('6759123772311123708', array('switch')));
+ $this->assertTrue(Validation::cc('4903054736148271088', array('switch')));
+ $this->assertTrue(Validation::cc('4936477526808883952', array('switch')));
+ $this->assertTrue(Validation::cc('4936433964890967966', array('switch')));
+ $this->assertTrue(Validation::cc('6333245128906049344', array('switch')));
+ $this->assertTrue(Validation::cc('4936321036970553134', array('switch')));
+ $this->assertTrue(Validation::cc('4936111816358702773', array('switch')));
+ $this->assertTrue(Validation::cc('4936196077254804290', array('switch')));
+ $this->assertTrue(Validation::cc('6759558831206830183', array('switch')));
+ $this->assertTrue(Validation::cc('5641827998830403137', array('switch')));
+ //VISA 13 digit
+ $this->assertTrue(Validation::cc('4024007174754', array('visa')));
+ $this->assertTrue(Validation::cc('4104816460717', array('visa')));
+ $this->assertTrue(Validation::cc('4716229700437', array('visa')));
+ $this->assertTrue(Validation::cc('4539305400213', array('visa')));
+ $this->assertTrue(Validation::cc('4728260558665', array('visa')));
+ $this->assertTrue(Validation::cc('4929100131792', array('visa')));
+ $this->assertTrue(Validation::cc('4024007117308', array('visa')));
+ $this->assertTrue(Validation::cc('4539915491024', array('visa')));
+ $this->assertTrue(Validation::cc('4539790901139', array('visa')));
+ $this->assertTrue(Validation::cc('4485284914909', array('visa')));
+ $this->assertTrue(Validation::cc('4782793022350', array('visa')));
+ $this->assertTrue(Validation::cc('4556899290685', array('visa')));
+ $this->assertTrue(Validation::cc('4024007134774', array('visa')));
+ $this->assertTrue(Validation::cc('4333412341316', array('visa')));
+ $this->assertTrue(Validation::cc('4539534204543', array('visa')));
+ $this->assertTrue(Validation::cc('4485640373626', array('visa')));
+ $this->assertTrue(Validation::cc('4929911445746', array('visa')));
+ $this->assertTrue(Validation::cc('4539292550806', array('visa')));
+ $this->assertTrue(Validation::cc('4716523014030', array('visa')));
+ $this->assertTrue(Validation::cc('4024007125152', array('visa')));
+ $this->assertTrue(Validation::cc('4539758883311', array('visa')));
+ $this->assertTrue(Validation::cc('4024007103258', array('visa')));
+ $this->assertTrue(Validation::cc('4916933155767', array('visa')));
+ $this->assertTrue(Validation::cc('4024007159672', array('visa')));
+ $this->assertTrue(Validation::cc('4716935544871', array('visa')));
+ $this->assertTrue(Validation::cc('4929415177779', array('visa')));
+ $this->assertTrue(Validation::cc('4929748547896', array('visa')));
+ $this->assertTrue(Validation::cc('4929153468612', array('visa')));
+ $this->assertTrue(Validation::cc('4539397132104', array('visa')));
+ $this->assertTrue(Validation::cc('4485293435540', array('visa')));
+ $this->assertTrue(Validation::cc('4485799412720', array('visa')));
+ $this->assertTrue(Validation::cc('4916744757686', array('visa')));
+ $this->assertTrue(Validation::cc('4556475655426', array('visa')));
+ $this->assertTrue(Validation::cc('4539400441625', array('visa')));
+ $this->assertTrue(Validation::cc('4485437129173', array('visa')));
+ $this->assertTrue(Validation::cc('4716253605320', array('visa')));
+ $this->assertTrue(Validation::cc('4539366156589', array('visa')));
+ $this->assertTrue(Validation::cc('4916498061392', array('visa')));
+ $this->assertTrue(Validation::cc('4716127163779', array('visa')));
+ $this->assertTrue(Validation::cc('4024007183078', array('visa')));
+ $this->assertTrue(Validation::cc('4041553279654', array('visa')));
+ $this->assertTrue(Validation::cc('4532380121960', array('visa')));
+ $this->assertTrue(Validation::cc('4485906062491', array('visa')));
+ $this->assertTrue(Validation::cc('4539365115149', array('visa')));
+ $this->assertTrue(Validation::cc('4485146516702', array('visa')));
+ //VISA 16 digit
+ $this->assertTrue(Validation::cc('4916375389940009', array('visa')));
+ $this->assertTrue(Validation::cc('4929167481032610', array('visa')));
+ $this->assertTrue(Validation::cc('4485029969061519', array('visa')));
+ $this->assertTrue(Validation::cc('4485573845281759', array('visa')));
+ $this->assertTrue(Validation::cc('4485669810383529', array('visa')));
+ $this->assertTrue(Validation::cc('4929615806560327', array('visa')));
+ $this->assertTrue(Validation::cc('4556807505609535', array('visa')));
+ $this->assertTrue(Validation::cc('4532611336232890', array('visa')));
+ $this->assertTrue(Validation::cc('4532201952422387', array('visa')));
+ $this->assertTrue(Validation::cc('4485073797976290', array('visa')));
+ $this->assertTrue(Validation::cc('4024007157580969', array('visa')));
+ $this->assertTrue(Validation::cc('4053740470212274', array('visa')));
+ $this->assertTrue(Validation::cc('4716265831525676', array('visa')));
+ $this->assertTrue(Validation::cc('4024007100222966', array('visa')));
+ $this->assertTrue(Validation::cc('4539556148303244', array('visa')));
+ $this->assertTrue(Validation::cc('4532449879689709', array('visa')));
+ $this->assertTrue(Validation::cc('4916805467840986', array('visa')));
+ $this->assertTrue(Validation::cc('4532155644440233', array('visa')));
+ $this->assertTrue(Validation::cc('4467977802223781', array('visa')));
+ $this->assertTrue(Validation::cc('4539224637000686', array('visa')));
+ $this->assertTrue(Validation::cc('4556629187064965', array('visa')));
+ $this->assertTrue(Validation::cc('4532970205932943', array('visa')));
+ $this->assertTrue(Validation::cc('4821470132041850', array('visa')));
+ $this->assertTrue(Validation::cc('4916214267894485', array('visa')));
+ $this->assertTrue(Validation::cc('4024007169073284', array('visa')));
+ $this->assertTrue(Validation::cc('4716783351296122', array('visa')));
+ $this->assertTrue(Validation::cc('4556480171913795', array('visa')));
+ $this->assertTrue(Validation::cc('4929678411034997', array('visa')));
+ $this->assertTrue(Validation::cc('4682061913519392', array('visa')));
+ $this->assertTrue(Validation::cc('4916495481746474', array('visa')));
+ $this->assertTrue(Validation::cc('4929007108460499', array('visa')));
+ $this->assertTrue(Validation::cc('4539951357838586', array('visa')));
+ $this->assertTrue(Validation::cc('4716482691051558', array('visa')));
+ $this->assertTrue(Validation::cc('4916385069917516', array('visa')));
+ $this->assertTrue(Validation::cc('4929020289494641', array('visa')));
+ $this->assertTrue(Validation::cc('4532176245263774', array('visa')));
+ $this->assertTrue(Validation::cc('4556242273553949', array('visa')));
+ $this->assertTrue(Validation::cc('4481007485188614', array('visa')));
+ $this->assertTrue(Validation::cc('4716533372139623', array('visa')));
+ $this->assertTrue(Validation::cc('4929152038152632', array('visa')));
+ $this->assertTrue(Validation::cc('4539404037310550', array('visa')));
+ $this->assertTrue(Validation::cc('4532800925229140', array('visa')));
+ $this->assertTrue(Validation::cc('4916845885268360', array('visa')));
+ $this->assertTrue(Validation::cc('4394514669078434', array('visa')));
+ $this->assertTrue(Validation::cc('4485611378115042', array('visa')));
+ //Visa Electron
+ $this->assertTrue(Validation::cc('4175003346287100', array('electron')));
+ $this->assertTrue(Validation::cc('4913042516577228', array('electron')));
+ $this->assertTrue(Validation::cc('4917592325659381', array('electron')));
+ $this->assertTrue(Validation::cc('4917084924450511', array('electron')));
+ $this->assertTrue(Validation::cc('4917994610643999', array('electron')));
+ $this->assertTrue(Validation::cc('4175005933743585', array('electron')));
+ $this->assertTrue(Validation::cc('4175008373425044', array('electron')));
+ $this->assertTrue(Validation::cc('4913119763664154', array('electron')));
+ $this->assertTrue(Validation::cc('4913189017481812', array('electron')));
+ $this->assertTrue(Validation::cc('4913085104968622', array('electron')));
+ $this->assertTrue(Validation::cc('4175008803122021', array('electron')));
+ $this->assertTrue(Validation::cc('4913294453962489', array('electron')));
+ $this->assertTrue(Validation::cc('4175009797419290', array('electron')));
+ $this->assertTrue(Validation::cc('4175005028142917', array('electron')));
+ $this->assertTrue(Validation::cc('4913940802385364', array('electron')));
+ //Voyager
+ $this->assertTrue(Validation::cc('869940697287073', array('voyager')));
+ $this->assertTrue(Validation::cc('869934523596112', array('voyager')));
+ $this->assertTrue(Validation::cc('869958670174621', array('voyager')));
+ $this->assertTrue(Validation::cc('869921250068209', array('voyager')));
+ $this->assertTrue(Validation::cc('869972521242198', array('voyager')));
+ }
+
+/**
+ * testLuhn method
+ *
+ * @return void
+ */
+ public function testLuhn() {
+ //American Express
+ $this->assertTrue(Validation::luhn('370482756063980', true));
+ //BankCard
+ $this->assertTrue(Validation::luhn('5610745867413420', true));
+ //Diners Club 14
+ $this->assertTrue(Validation::luhn('30155483651028', true));
+ //2004 MasterCard/Diners Club Alliance International 14
+ $this->assertTrue(Validation::luhn('36747701998969', true));
+ //2004 MasterCard/Diners Club Alliance US & Canada 16
+ $this->assertTrue(Validation::luhn('5597511346169950', true));
+ //Discover
+ $this->assertTrue(Validation::luhn('6011802876467237', true));
+ //enRoute
+ $this->assertTrue(Validation::luhn('201496944158937', true));
+ //JCB 15 digit
+ $this->assertTrue(Validation::luhn('210034762247893', true));
+ //JCB 16 digit
+ $this->assertTrue(Validation::luhn('3096806857839939', true));
+ //Maestro (debit card)
+ $this->assertTrue(Validation::luhn('5020147409985219', true));
+ //Mastercard
+ $this->assertTrue(Validation::luhn('5580424361774366', true));
+ //Solo 16
+ $this->assertTrue(Validation::luhn('6767432107064987', true));
+ //Solo 18
+ $this->assertTrue(Validation::luhn('676714834398858593', true));
+ //Solo 19
+ $this->assertTrue(Validation::luhn('6767838565218340113', true));
+ //Switch 16
+ $this->assertTrue(Validation::luhn('5641829171515733', true));
+ //Switch 18
+ $this->assertTrue(Validation::luhn('493622764224625174', true));
+ //Switch 19
+ $this->assertTrue(Validation::luhn('6759603460617628716', true));
+ //VISA 13 digit
+ $this->assertTrue(Validation::luhn('4024007174754', true));
+ //VISA 16 digit
+ $this->assertTrue(Validation::luhn('4916375389940009', true));
+ //Visa Electron
+ $this->assertTrue(Validation::luhn('4175003346287100', true));
+ //Voyager
+ $this->assertTrue(Validation::luhn('869940697287073', true));
+
+ $this->assertFalse(Validation::luhn('0000000000000000', true));
+
+ $this->assertFalse(Validation::luhn('869940697287173', true));
+ }
+
+/**
+ * testCustomRegexForCc method
+ *
+ * @return void
+ */
+ public function testCustomRegexForCc() {
+ $this->assertTrue(Validation::cc('12332105933743585', null, null, '/123321\\d{11}/'));
+ $this->assertFalse(Validation::cc('1233210593374358', null, null, '/123321\\d{11}/'));
+ $this->assertFalse(Validation::cc('12312305933743585', null, null, '/123321\\d{11}/'));
+ }
+
+/**
+ * testCustomRegexForCcWithLuhnCheck method
+ *
+ * @return void
+ */
+ public function testCustomRegexForCcWithLuhnCheck() {
+ $this->assertTrue(Validation::cc('12332110426226941', null, true, '/123321\\d{11}/'));
+ $this->assertFalse(Validation::cc('12332105933743585', null, true, '/123321\\d{11}/'));
+ $this->assertFalse(Validation::cc('12332105933743587', null, true, '/123321\\d{11}/'));
+ $this->assertFalse(Validation::cc('12312305933743585', null, true, '/123321\\d{11}/'));
+ }
+
+/**
+ * testFastCc method
+ *
+ * @return void
+ */
+ public function testFastCc() {
+ // too short
+ $this->assertFalse(Validation::cc('123456789012'));
+ //American Express
+ $this->assertTrue(Validation::cc('370482756063980'));
+ //Diners Club 14
+ $this->assertTrue(Validation::cc('30155483651028'));
+ //2004 MasterCard/Diners Club Alliance International 14
+ $this->assertTrue(Validation::cc('36747701998969'));
+ //2004 MasterCard/Diners Club Alliance US & Canada 16
+ $this->assertTrue(Validation::cc('5597511346169950'));
+ //Discover
+ $this->assertTrue(Validation::cc('6011802876467237'));
+ //Mastercard
+ $this->assertTrue(Validation::cc('5580424361774366'));
+ //VISA 13 digit
+ $this->assertTrue(Validation::cc('4024007174754'));
+ //VISA 16 digit
+ $this->assertTrue(Validation::cc('4916375389940009'));
+ //Visa Electron
+ $this->assertTrue(Validation::cc('4175003346287100'));
+ }
+
+/**
+ * testAllCc method
+ *
+ * @return void
+ */
+ public function testAllCc() {
+ //American Express
+ $this->assertTrue(Validation::cc('370482756063980', 'all'));
+ //BankCard
+ $this->assertTrue(Validation::cc('5610745867413420', 'all'));
+ //Diners Club 14
+ $this->assertTrue(Validation::cc('30155483651028', 'all'));
+ //2004 MasterCard/Diners Club Alliance International 14
+ $this->assertTrue(Validation::cc('36747701998969', 'all'));
+ //2004 MasterCard/Diners Club Alliance US & Canada 16
+ $this->assertTrue(Validation::cc('5597511346169950', 'all'));
+ //Discover
+ $this->assertTrue(Validation::cc('6011802876467237', 'all'));
+ //enRoute
+ $this->assertTrue(Validation::cc('201496944158937', 'all'));
+ //JCB 15 digit
+ $this->assertTrue(Validation::cc('210034762247893', 'all'));
+ //JCB 16 digit
+ $this->assertTrue(Validation::cc('3096806857839939', 'all'));
+ //Maestro (debit card)
+ $this->assertTrue(Validation::cc('5020147409985219', 'all'));
+ //Mastercard
+ $this->assertTrue(Validation::cc('5580424361774366', 'all'));
+ //Solo 16
+ $this->assertTrue(Validation::cc('6767432107064987', 'all'));
+ //Solo 18
+ $this->assertTrue(Validation::cc('676714834398858593', 'all'));
+ //Solo 19
+ $this->assertTrue(Validation::cc('6767838565218340113', 'all'));
+ //Switch 16
+ $this->assertTrue(Validation::cc('5641829171515733', 'all'));
+ //Switch 18
+ $this->assertTrue(Validation::cc('493622764224625174', 'all'));
+ //Switch 19
+ $this->assertTrue(Validation::cc('6759603460617628716', 'all'));
+ //VISA 13 digit
+ $this->assertTrue(Validation::cc('4024007174754', 'all'));
+ //VISA 16 digit
+ $this->assertTrue(Validation::cc('4916375389940009', 'all'));
+ //Visa Electron
+ $this->assertTrue(Validation::cc('4175003346287100', 'all'));
+ //Voyager
+ $this->assertTrue(Validation::cc('869940697287073', 'all'));
+ }
+
+/**
+ * testAllCcDeep method
+ *
+ * @return void
+ */
+ public function testAllCcDeep() {
+ //American Express
+ $this->assertTrue(Validation::cc('370482756063980', 'all', true));
+ //BankCard
+ $this->assertTrue(Validation::cc('5610745867413420', 'all', true));
+ //Diners Club 14
+ $this->assertTrue(Validation::cc('30155483651028', 'all', true));
+ //2004 MasterCard/Diners Club Alliance International 14
+ $this->assertTrue(Validation::cc('36747701998969', 'all', true));
+ //2004 MasterCard/Diners Club Alliance US & Canada 16
+ $this->assertTrue(Validation::cc('5597511346169950', 'all', true));
+ //Discover
+ $this->assertTrue(Validation::cc('6011802876467237', 'all', true));
+ //enRoute
+ $this->assertTrue(Validation::cc('201496944158937', 'all', true));
+ //JCB 15 digit
+ $this->assertTrue(Validation::cc('210034762247893', 'all', true));
+ //JCB 16 digit
+ $this->assertTrue(Validation::cc('3096806857839939', 'all', true));
+ //Maestro (debit card)
+ $this->assertTrue(Validation::cc('5020147409985219', 'all', true));
+ //Mastercard
+ $this->assertTrue(Validation::cc('5580424361774366', 'all', true));
+ //Solo 16
+ $this->assertTrue(Validation::cc('6767432107064987', 'all', true));
+ //Solo 18
+ $this->assertTrue(Validation::cc('676714834398858593', 'all', true));
+ //Solo 19
+ $this->assertTrue(Validation::cc('6767838565218340113', 'all', true));
+ //Switch 16
+ $this->assertTrue(Validation::cc('5641829171515733', 'all', true));
+ //Switch 18
+ $this->assertTrue(Validation::cc('493622764224625174', 'all', true));
+ //Switch 19
+ $this->assertTrue(Validation::cc('6759603460617628716', 'all', true));
+ //VISA 13 digit
+ $this->assertTrue(Validation::cc('4024007174754', 'all', true));
+ //VISA 16 digit
+ $this->assertTrue(Validation::cc('4916375389940009', 'all', true));
+ //Visa Electron
+ $this->assertTrue(Validation::cc('4175003346287100', 'all', true));
+ //Voyager
+ $this->assertTrue(Validation::cc('869940697287073', 'all', true));
+ }
+
+/**
+ * testComparison method
+ *
+ * @return void
+ */
+ public function testComparison() {
+ $this->assertFalse(Validation::comparison(7, null, 6));
+ $this->assertTrue(Validation::comparison(7, 'is greater', 6));
+ $this->assertTrue(Validation::comparison(7, '>', 6));
+ $this->assertTrue(Validation::comparison(6, 'is less', 7));
+ $this->assertTrue(Validation::comparison(6, '<', 7));
+ $this->assertTrue(Validation::comparison(7, 'greater or equal', 7));
+ $this->assertTrue(Validation::comparison(7, '>=', 7));
+ $this->assertTrue(Validation::comparison(7, 'greater or equal', 6));
+ $this->assertTrue(Validation::comparison(7, '>=', 6));
+ $this->assertTrue(Validation::comparison(6, 'less or equal', 7));
+ $this->assertTrue(Validation::comparison(6, '<=', 7));
+ $this->assertTrue(Validation::comparison(7, 'equal to', 7));
+ $this->assertTrue(Validation::comparison(7, '==', 7));
+ $this->assertTrue(Validation::comparison(7, 'not equal', 6));
+ $this->assertTrue(Validation::comparison(7, '!=', 6));
+ $this->assertFalse(Validation::comparison(6, 'is greater', 7));
+ $this->assertFalse(Validation::comparison(6, '>', 7));
+ $this->assertFalse(Validation::comparison(7, 'is less', 6));
+ $this->assertFalse(Validation::comparison(7, '<', 6));
+ $this->assertFalse(Validation::comparison(6, 'greater or equal', 7));
+ $this->assertFalse(Validation::comparison(6, '>=', 7));
+ $this->assertFalse(Validation::comparison(6, 'greater or equal', 7));
+ $this->assertFalse(Validation::comparison(6, '>=', 7));
+ $this->assertFalse(Validation::comparison(7, 'less or equal', 6));
+ $this->assertFalse(Validation::comparison(7, '<=', 6));
+ $this->assertFalse(Validation::comparison(7, 'equal to', 6));
+ $this->assertFalse(Validation::comparison(7, '==', 6));
+ $this->assertFalse(Validation::comparison(7, 'not equal', 7));
+ $this->assertFalse(Validation::comparison(7, '!=', 7));
+ }
+
+/**
+ * testComparisonAsArray method
+ *
+ * @return void
+ */
+ public function testComparisonAsArray() {
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => 'is greater', 'check2' => 6)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => '>', 'check2' => 6)));
+ $this->assertTrue(Validation::comparison(array('check1' => 6, 'operator' => 'is less', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 6, 'operator' => '<', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => 'greater or equal', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => '>=', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => 'greater or equal','check2' => 6)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => '>=', 'check2' => 6)));
+ $this->assertTrue(Validation::comparison(array('check1' => 6, 'operator' => 'less or equal', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 6, 'operator' => '<=', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => 'equal to', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => '==', 'check2' => 7)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => 'not equal', 'check2' => 6)));
+ $this->assertTrue(Validation::comparison(array('check1' => 7, 'operator' => '!=', 'check2' => 6)));
+ $this->assertFalse(Validation::comparison(array('check1' => 6, 'operator' => 'is greater', 'check2' => 7)));
+ $this->assertFalse(Validation::comparison(array('check1' => 6, 'operator' => '>', 'check2' => 7)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => 'is less', 'check2' => 6)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => '<', 'check2' => 6)));
+ $this->assertFalse(Validation::comparison(array('check1' => 6, 'operator' => 'greater or equal', 'check2' => 7)));
+ $this->assertFalse(Validation::comparison(array('check1' => 6, 'operator' => '>=', 'check2' => 7)));
+ $this->assertFalse(Validation::comparison(array('check1' => 6, 'operator' => 'greater or equal', 'check2' => 7)));
+ $this->assertFalse(Validation::comparison(array('check1' => 6, 'operator' => '>=', 'check2' => 7)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => 'less or equal', 'check2' => 6)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => '<=', 'check2' => 6)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => 'equal to', 'check2' => 6)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => '==','check2' => 6)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => 'not equal', 'check2' => 7)));
+ $this->assertFalse(Validation::comparison(array('check1' => 7, 'operator' => '!=', 'check2' => 7)));
+ }
+
+/**
+ * testCustom method
+ *
+ * @return void
+ */
+ public function testCustom() {
+ $this->assertTrue(Validation::custom('12345', '/(?<!\\S)\\d++(?!\\S)/'));
+ $this->assertFalse(Validation::custom('Text', '/(?<!\\S)\\d++(?!\\S)/'));
+ $this->assertFalse(Validation::custom('123.45', '/(?<!\\S)\\d++(?!\\S)/'));
+ $this->assertFalse(Validation::custom('missing regex'));
+ }
+
+/**
+ * testCustomAsArray method
+ *
+ * @return void
+ */
+ public function testCustomAsArray() {
+ $this->assertTrue(Validation::custom(array('check' => '12345', 'regex' => '/(?<!\\S)\\d++(?!\\S)/')));
+ $this->assertFalse(Validation::custom(array('check' => 'Text', 'regex' => '/(?<!\\S)\\d++(?!\\S)/')));
+ $this->assertFalse(Validation::custom(array('check' => '123.45', 'regex' => '/(?<!\\S)\\d++(?!\\S)/')));
+ }
+
+/**
+ * testDateDdmmyyyy method
+ *
+ * @return void
+ */
+ public function testDateDdmmyyyy() {
+ $this->assertTrue(Validation::date('27-12-2006', array('dmy')));
+ $this->assertTrue(Validation::date('27.12.2006', array('dmy')));
+ $this->assertTrue(Validation::date('27/12/2006', array('dmy')));
+ $this->assertTrue(Validation::date('27 12 2006', array('dmy')));
+ $this->assertFalse(Validation::date('00-00-0000', array('dmy')));
+ $this->assertFalse(Validation::date('00.00.0000', array('dmy')));
+ $this->assertFalse(Validation::date('00/00/0000', array('dmy')));
+ $this->assertFalse(Validation::date('00 00 0000', array('dmy')));
+ $this->assertFalse(Validation::date('31-11-2006', array('dmy')));
+ $this->assertFalse(Validation::date('31.11.2006', array('dmy')));
+ $this->assertFalse(Validation::date('31/11/2006', array('dmy')));
+ $this->assertFalse(Validation::date('31 11 2006', array('dmy')));
+ }
+
+/**
+ * testDateDdmmyyyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateDdmmyyyyLeapYear() {
+ $this->assertTrue(Validation::date('29-02-2004', array('dmy')));
+ $this->assertTrue(Validation::date('29.02.2004', array('dmy')));
+ $this->assertTrue(Validation::date('29/02/2004', array('dmy')));
+ $this->assertTrue(Validation::date('29 02 2004', array('dmy')));
+ $this->assertFalse(Validation::date('29-02-2006', array('dmy')));
+ $this->assertFalse(Validation::date('29.02.2006', array('dmy')));
+ $this->assertFalse(Validation::date('29/02/2006', array('dmy')));
+ $this->assertFalse(Validation::date('29 02 2006', array('dmy')));
+ }
+
+/**
+ * testDateDdmmyy method
+ *
+ * @return void
+ */
+ public function testDateDdmmyy() {
+ $this->assertTrue(Validation::date('27-12-06', array('dmy')));
+ $this->assertTrue(Validation::date('27.12.06', array('dmy')));
+ $this->assertTrue(Validation::date('27/12/06', array('dmy')));
+ $this->assertTrue(Validation::date('27 12 06', array('dmy')));
+ $this->assertFalse(Validation::date('00-00-00', array('dmy')));
+ $this->assertFalse(Validation::date('00.00.00', array('dmy')));
+ $this->assertFalse(Validation::date('00/00/00', array('dmy')));
+ $this->assertFalse(Validation::date('00 00 00', array('dmy')));
+ $this->assertFalse(Validation::date('31-11-06', array('dmy')));
+ $this->assertFalse(Validation::date('31.11.06', array('dmy')));
+ $this->assertFalse(Validation::date('31/11/06', array('dmy')));
+ $this->assertFalse(Validation::date('31 11 06', array('dmy')));
+ }
+
+/**
+ * testDateDdmmyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateDdmmyyLeapYear() {
+ $this->assertTrue(Validation::date('29-02-04', array('dmy')));
+ $this->assertTrue(Validation::date('29.02.04', array('dmy')));
+ $this->assertTrue(Validation::date('29/02/04', array('dmy')));
+ $this->assertTrue(Validation::date('29 02 04', array('dmy')));
+ $this->assertFalse(Validation::date('29-02-06', array('dmy')));
+ $this->assertFalse(Validation::date('29.02.06', array('dmy')));
+ $this->assertFalse(Validation::date('29/02/06', array('dmy')));
+ $this->assertFalse(Validation::date('29 02 06', array('dmy')));
+ }
+
+/**
+ * testDateDmyy method
+ *
+ * @return void
+ */
+ public function testDateDmyy() {
+ $this->assertTrue(Validation::date('7-2-06', array('dmy')));
+ $this->assertTrue(Validation::date('7.2.06', array('dmy')));
+ $this->assertTrue(Validation::date('7/2/06', array('dmy')));
+ $this->assertTrue(Validation::date('7 2 06', array('dmy')));
+ $this->assertFalse(Validation::date('0-0-00', array('dmy')));
+ $this->assertFalse(Validation::date('0.0.00', array('dmy')));
+ $this->assertFalse(Validation::date('0/0/00', array('dmy')));
+ $this->assertFalse(Validation::date('0 0 00', array('dmy')));
+ $this->assertFalse(Validation::date('32-2-06', array('dmy')));
+ $this->assertFalse(Validation::date('32.2.06', array('dmy')));
+ $this->assertFalse(Validation::date('32/2/06', array('dmy')));
+ $this->assertFalse(Validation::date('32 2 06', array('dmy')));
+ }
+
+/**
+ * testDateDmyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateDmyyLeapYear() {
+ $this->assertTrue(Validation::date('29-2-04', array('dmy')));
+ $this->assertTrue(Validation::date('29.2.04', array('dmy')));
+ $this->assertTrue(Validation::date('29/2/04', array('dmy')));
+ $this->assertTrue(Validation::date('29 2 04', array('dmy')));
+ $this->assertFalse(Validation::date('29-2-06', array('dmy')));
+ $this->assertFalse(Validation::date('29.2.06', array('dmy')));
+ $this->assertFalse(Validation::date('29/2/06', array('dmy')));
+ $this->assertFalse(Validation::date('29 2 06', array('dmy')));
+ }
+
+/**
+ * testDateDmyyyy method
+ *
+ * @return void
+ */
+ public function testDateDmyyyy() {
+ $this->assertTrue(Validation::date('7-2-2006', array('dmy')));
+ $this->assertTrue(Validation::date('7.2.2006', array('dmy')));
+ $this->assertTrue(Validation::date('7/2/2006', array('dmy')));
+ $this->assertTrue(Validation::date('7 2 2006', array('dmy')));
+ $this->assertFalse(Validation::date('0-0-0000', array('dmy')));
+ $this->assertFalse(Validation::date('0.0.0000', array('dmy')));
+ $this->assertFalse(Validation::date('0/0/0000', array('dmy')));
+ $this->assertFalse(Validation::date('0 0 0000', array('dmy')));
+ $this->assertFalse(Validation::date('32-2-2006', array('dmy')));
+ $this->assertFalse(Validation::date('32.2.2006', array('dmy')));
+ $this->assertFalse(Validation::date('32/2/2006', array('dmy')));
+ $this->assertFalse(Validation::date('32 2 2006', array('dmy')));
+ }
+
+/**
+ * testDateDmyyyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateDmyyyyLeapYear() {
+ $this->assertTrue(Validation::date('29-2-2004', array('dmy')));
+ $this->assertTrue(Validation::date('29.2.2004', array('dmy')));
+ $this->assertTrue(Validation::date('29/2/2004', array('dmy')));
+ $this->assertTrue(Validation::date('29 2 2004', array('dmy')));
+ $this->assertFalse(Validation::date('29-2-2006', array('dmy')));
+ $this->assertFalse(Validation::date('29.2.2006', array('dmy')));
+ $this->assertFalse(Validation::date('29/2/2006', array('dmy')));
+ $this->assertFalse(Validation::date('29 2 2006', array('dmy')));
+ }
+
+/**
+ * testDateMmddyyyy method
+ *
+ * @return void
+ */
+ public function testDateMmddyyyy() {
+ $this->assertTrue(Validation::date('12-27-2006', array('mdy')));
+ $this->assertTrue(Validation::date('12.27.2006', array('mdy')));
+ $this->assertTrue(Validation::date('12/27/2006', array('mdy')));
+ $this->assertTrue(Validation::date('12 27 2006', array('mdy')));
+ $this->assertFalse(Validation::date('00-00-0000', array('mdy')));
+ $this->assertFalse(Validation::date('00.00.0000', array('mdy')));
+ $this->assertFalse(Validation::date('00/00/0000', array('mdy')));
+ $this->assertFalse(Validation::date('00 00 0000', array('mdy')));
+ $this->assertFalse(Validation::date('11-31-2006', array('mdy')));
+ $this->assertFalse(Validation::date('11.31.2006', array('mdy')));
+ $this->assertFalse(Validation::date('11/31/2006', array('mdy')));
+ $this->assertFalse(Validation::date('11 31 2006', array('mdy')));
+ }
+
+/**
+ * testDateMmddyyyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateMmddyyyyLeapYear() {
+ $this->assertTrue(Validation::date('02-29-2004', array('mdy')));
+ $this->assertTrue(Validation::date('02.29.2004', array('mdy')));
+ $this->assertTrue(Validation::date('02/29/2004', array('mdy')));
+ $this->assertTrue(Validation::date('02 29 2004', array('mdy')));
+ $this->assertFalse(Validation::date('02-29-2006', array('mdy')));
+ $this->assertFalse(Validation::date('02.29.2006', array('mdy')));
+ $this->assertFalse(Validation::date('02/29/2006', array('mdy')));
+ $this->assertFalse(Validation::date('02 29 2006', array('mdy')));
+ }
+
+/**
+ * testDateMmddyy method
+ *
+ * @return void
+ */
+ public function testDateMmddyy() {
+ $this->assertTrue(Validation::date('12-27-06', array('mdy')));
+ $this->assertTrue(Validation::date('12.27.06', array('mdy')));
+ $this->assertTrue(Validation::date('12/27/06', array('mdy')));
+ $this->assertTrue(Validation::date('12 27 06', array('mdy')));
+ $this->assertFalse(Validation::date('00-00-00', array('mdy')));
+ $this->assertFalse(Validation::date('00.00.00', array('mdy')));
+ $this->assertFalse(Validation::date('00/00/00', array('mdy')));
+ $this->assertFalse(Validation::date('00 00 00', array('mdy')));
+ $this->assertFalse(Validation::date('11-31-06', array('mdy')));
+ $this->assertFalse(Validation::date('11.31.06', array('mdy')));
+ $this->assertFalse(Validation::date('11/31/06', array('mdy')));
+ $this->assertFalse(Validation::date('11 31 06', array('mdy')));
+ }
+
+/**
+ * testDateMmddyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateMmddyyLeapYear() {
+ $this->assertTrue(Validation::date('02-29-04', array('mdy')));
+ $this->assertTrue(Validation::date('02.29.04', array('mdy')));
+ $this->assertTrue(Validation::date('02/29/04', array('mdy')));
+ $this->assertTrue(Validation::date('02 29 04', array('mdy')));
+ $this->assertFalse(Validation::date('02-29-06', array('mdy')));
+ $this->assertFalse(Validation::date('02.29.06', array('mdy')));
+ $this->assertFalse(Validation::date('02/29/06', array('mdy')));
+ $this->assertFalse(Validation::date('02 29 06', array('mdy')));
+ }
+
+/**
+ * testDateMdyy method
+ *
+ * @return void
+ */
+ public function testDateMdyy() {
+ $this->assertTrue(Validation::date('2-7-06', array('mdy')));
+ $this->assertTrue(Validation::date('2.7.06', array('mdy')));
+ $this->assertTrue(Validation::date('2/7/06', array('mdy')));
+ $this->assertTrue(Validation::date('2 7 06', array('mdy')));
+ $this->assertFalse(Validation::date('0-0-00', array('mdy')));
+ $this->assertFalse(Validation::date('0.0.00', array('mdy')));
+ $this->assertFalse(Validation::date('0/0/00', array('mdy')));
+ $this->assertFalse(Validation::date('0 0 00', array('mdy')));
+ $this->assertFalse(Validation::date('2-32-06', array('mdy')));
+ $this->assertFalse(Validation::date('2.32.06', array('mdy')));
+ $this->assertFalse(Validation::date('2/32/06', array('mdy')));
+ $this->assertFalse(Validation::date('2 32 06', array('mdy')));
+ }
+
+/**
+ * testDateMdyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateMdyyLeapYear() {
+ $this->assertTrue(Validation::date('2-29-04', array('mdy')));
+ $this->assertTrue(Validation::date('2.29.04', array('mdy')));
+ $this->assertTrue(Validation::date('2/29/04', array('mdy')));
+ $this->assertTrue(Validation::date('2 29 04', array('mdy')));
+ $this->assertFalse(Validation::date('2-29-06', array('mdy')));
+ $this->assertFalse(Validation::date('2.29.06', array('mdy')));
+ $this->assertFalse(Validation::date('2/29/06', array('mdy')));
+ $this->assertFalse(Validation::date('2 29 06', array('mdy')));
+ }
+
+/**
+ * testDateMdyyyy method
+ *
+ * @return void
+ */
+ public function testDateMdyyyy() {
+ $this->assertTrue(Validation::date('2-7-2006', array('mdy')));
+ $this->assertTrue(Validation::date('2.7.2006', array('mdy')));
+ $this->assertTrue(Validation::date('2/7/2006', array('mdy')));
+ $this->assertTrue(Validation::date('2 7 2006', array('mdy')));
+ $this->assertFalse(Validation::date('0-0-0000', array('mdy')));
+ $this->assertFalse(Validation::date('0.0.0000', array('mdy')));
+ $this->assertFalse(Validation::date('0/0/0000', array('mdy')));
+ $this->assertFalse(Validation::date('0 0 0000', array('mdy')));
+ $this->assertFalse(Validation::date('2-32-2006', array('mdy')));
+ $this->assertFalse(Validation::date('2.32.2006', array('mdy')));
+ $this->assertFalse(Validation::date('2/32/2006', array('mdy')));
+ $this->assertFalse(Validation::date('2 32 2006', array('mdy')));
+ }
+
+/**
+ * testDateMdyyyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateMdyyyyLeapYear() {
+ $this->assertTrue(Validation::date('2-29-2004', array('mdy')));
+ $this->assertTrue(Validation::date('2.29.2004', array('mdy')));
+ $this->assertTrue(Validation::date('2/29/2004', array('mdy')));
+ $this->assertTrue(Validation::date('2 29 2004', array('mdy')));
+ $this->assertFalse(Validation::date('2-29-2006', array('mdy')));
+ $this->assertFalse(Validation::date('2.29.2006', array('mdy')));
+ $this->assertFalse(Validation::date('2/29/2006', array('mdy')));
+ $this->assertFalse(Validation::date('2 29 2006', array('mdy')));
+ }
+
+/**
+ * testDateYyyymmdd method
+ *
+ * @return void
+ */
+ public function testDateYyyymmdd() {
+ $this->assertTrue(Validation::date('2006-12-27', array('ymd')));
+ $this->assertTrue(Validation::date('2006.12.27', array('ymd')));
+ $this->assertTrue(Validation::date('2006/12/27', array('ymd')));
+ $this->assertTrue(Validation::date('2006 12 27', array('ymd')));
+ $this->assertFalse(Validation::date('2006-11-31', array('ymd')));
+ $this->assertFalse(Validation::date('2006.11.31', array('ymd')));
+ $this->assertFalse(Validation::date('2006/11/31', array('ymd')));
+ $this->assertFalse(Validation::date('2006 11 31', array('ymd')));
+ }
+
+/**
+ * testDateYyyymmddLeapYear method
+ *
+ * @return void
+ */
+ public function testDateYyyymmddLeapYear() {
+ $this->assertTrue(Validation::date('2004-02-29', array('ymd')));
+ $this->assertTrue(Validation::date('2004.02.29', array('ymd')));
+ $this->assertTrue(Validation::date('2004/02/29', array('ymd')));
+ $this->assertTrue(Validation::date('2004 02 29', array('ymd')));
+ $this->assertFalse(Validation::date('2006-02-29', array('ymd')));
+ $this->assertFalse(Validation::date('2006.02.29', array('ymd')));
+ $this->assertFalse(Validation::date('2006/02/29', array('ymd')));
+ $this->assertFalse(Validation::date('2006 02 29', array('ymd')));
+ }
+
+/**
+ * testDateYymmdd method
+ *
+ * @return void
+ */
+ public function testDateYymmdd() {
+ $this->assertTrue(Validation::date('06-12-27', array('ymd')));
+ $this->assertTrue(Validation::date('06.12.27', array('ymd')));
+ $this->assertTrue(Validation::date('06/12/27', array('ymd')));
+ $this->assertTrue(Validation::date('06 12 27', array('ymd')));
+ $this->assertFalse(Validation::date('12/27/2600', array('ymd')));
+ $this->assertFalse(Validation::date('12.27.2600', array('ymd')));
+ $this->assertFalse(Validation::date('12/27/2600', array('ymd')));
+ $this->assertFalse(Validation::date('12 27 2600', array('ymd')));
+ $this->assertFalse(Validation::date('06-11-31', array('ymd')));
+ $this->assertFalse(Validation::date('06.11.31', array('ymd')));
+ $this->assertFalse(Validation::date('06/11/31', array('ymd')));
+ $this->assertFalse(Validation::date('06 11 31', array('ymd')));
+ }
+
+/**
+ * testDateYymmddLeapYear method
+ *
+ * @return void
+ */
+ public function testDateYymmddLeapYear() {
+ $this->assertTrue(Validation::date('2004-02-29', array('ymd')));
+ $this->assertTrue(Validation::date('2004.02.29', array('ymd')));
+ $this->assertTrue(Validation::date('2004/02/29', array('ymd')));
+ $this->assertTrue(Validation::date('2004 02 29', array('ymd')));
+ $this->assertFalse(Validation::date('2006-02-29', array('ymd')));
+ $this->assertFalse(Validation::date('2006.02.29', array('ymd')));
+ $this->assertFalse(Validation::date('2006/02/29', array('ymd')));
+ $this->assertFalse(Validation::date('2006 02 29', array('ymd')));
+ }
+
+/**
+ * testDateDdMMMMyyyy method
+ *
+ * @return void
+ */
+ public function testDateDdMMMMyyyy() {
+ $this->assertTrue(Validation::date('27 December 2006', array('dMy')));
+ $this->assertTrue(Validation::date('27 Dec 2006', array('dMy')));
+ $this->assertFalse(Validation::date('2006 Dec 27', array('dMy')));
+ $this->assertFalse(Validation::date('2006 December 27', array('dMy')));
+ }
+
+/**
+ * testDateDdMMMMyyyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateDdMMMMyyyyLeapYear() {
+ $this->assertTrue(Validation::date('29 February 2004', array('dMy')));
+ $this->assertFalse(Validation::date('29 February 2006', array('dMy')));
+ }
+
+/**
+ * testDateMmmmDdyyyy method
+ *
+ * @return void
+ */
+ public function testDateMmmmDdyyyy() {
+ $this->assertTrue(Validation::date('December 27, 2006', array('Mdy')));
+ $this->assertTrue(Validation::date('Dec 27, 2006', array('Mdy')));
+ $this->assertTrue(Validation::date('December 27 2006', array('Mdy')));
+ $this->assertTrue(Validation::date('Dec 27 2006', array('Mdy')));
+ $this->assertFalse(Validation::date('27 Dec 2006', array('Mdy')));
+ $this->assertFalse(Validation::date('2006 December 27', array('Mdy')));
+ $this->assertTrue(Validation::date('Sep 12, 2011', array('Mdy')));
+ }
+
+/**
+ * testDateMmmmDdyyyyLeapYear method
+ *
+ * @return void
+ */
+ public function testDateMmmmDdyyyyLeapYear() {
+ $this->assertTrue(Validation::date('February 29, 2004', array('Mdy')));
+ $this->assertTrue(Validation::date('Feb 29, 2004', array('Mdy')));
+ $this->assertTrue(Validation::date('February 29 2004', array('Mdy')));
+ $this->assertTrue(Validation::date('Feb 29 2004', array('Mdy')));
+ $this->assertFalse(Validation::date('February 29, 2006', array('Mdy')));
+ }
+
+/**
+ * testDateMy method
+ *
+ * @return void
+ */
+ public function testDateMy() {
+ $this->assertTrue(Validation::date('December 2006', array('My')));
+ $this->assertTrue(Validation::date('Dec 2006', array('My')));
+ $this->assertTrue(Validation::date('December/2006', array('My')));
+ $this->assertTrue(Validation::date('Dec/2006', array('My')));
+ }
+
+/**
+ * testDateMyNumeric method
+ *
+ * @return void
+ */
+ public function testDateMyNumeric() {
+ $this->assertTrue(Validation::date('12/2006', array('my')));
+ $this->assertTrue(Validation::date('12-2006', array('my')));
+ $this->assertTrue(Validation::date('12.2006', array('my')));
+ $this->assertTrue(Validation::date('12 2006', array('my')));
+ $this->assertFalse(Validation::date('12/06', array('my')));
+ $this->assertFalse(Validation::date('12-06', array('my')));
+ $this->assertFalse(Validation::date('12.06', array('my')));
+ $this->assertFalse(Validation::date('12 06', array('my')));
+ }
+
+/**
+ * Test validating dates with multiple formats
+ *
+ * @return void
+ */
+ public function testDateMultiple() {
+ $this->assertTrue(Validation::date('2011-12-31', array('ymd', 'dmy')));
+ $this->assertTrue(Validation::date('31-12-2011', array('ymd', 'dmy')));
+ }
+
+/**
+ * testTime method
+ *
+ * @return void
+ */
+ public function testTime() {
+ $this->assertTrue(Validation::time('00:00'));
+ $this->assertTrue(Validation::time('23:59'));
+ $this->assertFalse(Validation::time('24:00'));
+ $this->assertTrue(Validation::time('12:00'));
+ $this->assertTrue(Validation::time('12:01'));
+ $this->assertTrue(Validation::time('12:01am'));
+ $this->assertTrue(Validation::time('12:01pm'));
+ $this->assertTrue(Validation::time('1pm'));
+ $this->assertTrue(Validation::time('1 pm'));
+ $this->assertTrue(Validation::time('1 PM'));
+ $this->assertTrue(Validation::time('01:00'));
+ $this->assertFalse(Validation::time('1:00'));
+ $this->assertTrue(Validation::time('1:00pm'));
+ $this->assertFalse(Validation::time('13:00pm'));
+ $this->assertFalse(Validation::time('9:00'));
+ }
+
+/**
+ * testBoolean method
+ *
+ * @return void
+ */
+ public function testBoolean() {
+ $this->assertTrue(Validation::boolean('0'));
+ $this->assertTrue(Validation::boolean('1'));
+ $this->assertTrue(Validation::boolean(0));
+ $this->assertTrue(Validation::boolean(1));
+ $this->assertTrue(Validation::boolean(true));
+ $this->assertTrue(Validation::boolean(false));
+ $this->assertFalse(Validation::boolean('true'));
+ $this->assertFalse(Validation::boolean('false'));
+ $this->assertFalse(Validation::boolean('-1'));
+ $this->assertFalse(Validation::boolean('2'));
+ $this->assertFalse(Validation::boolean('Boo!'));
+ }
+
+/**
+ * testDateCustomRegx method
+ *
+ * @return void
+ */
+ public function testDateCustomRegx() {
+ $this->assertTrue(Validation::date('2006-12-27', null, '%^(19|20)[0-9]{2}[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$%'));
+ $this->assertFalse(Validation::date('12-27-2006', null, '%^(19|20)[0-9]{2}[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$%'));
+ }
+
+/**
+ * testDecimal method
+ *
+ * @return void
+ */
+ public function testDecimal() {
+ $this->assertTrue(Validation::decimal('+1234.54321'));
+ $this->assertTrue(Validation::decimal('-1234.54321'));
+ $this->assertTrue(Validation::decimal('1234.54321'));
+ $this->assertTrue(Validation::decimal('+0123.45e6'));
+ $this->assertTrue(Validation::decimal('-0123.45e6'));
+ $this->assertTrue(Validation::decimal('0123.45e6'));
+ $this->assertTrue(Validation::decimal('1234'));
+ $this->assertTrue(Validation::decimal('-1234'));
+ $this->assertTrue(Validation::decimal('+1234'));
+ $this->assertTrue(Validation::decimal(1234.56));
+ $this->assertTrue(Validation::decimal(1234.00));
+ $this->assertTrue(Validation::decimal(.0));
+ $this->assertTrue(Validation::decimal(.00));
+ $this->assertTrue(Validation::decimal(.01));
+
+ $this->assertFalse(Validation::decimal('string'));
+ }
+
+/**
+ * testDecimalWithPlaces method
+ *
+ * @return void
+ */
+ public function testDecimalWithPlaces() {
+ $this->assertTrue(Validation::decimal('.27', '2'));
+ $this->assertTrue(Validation::decimal(0.27, 2));
+ $this->assertTrue(Validation::decimal(-0.27, 2));
+ $this->assertTrue(Validation::decimal(0.27, 2));
+ $this->assertTrue(Validation::decimal('0.277', '3'));
+ $this->assertTrue(Validation::decimal(0.277, 3));
+ $this->assertTrue(Validation::decimal(-0.277, 3));
+ $this->assertTrue(Validation::decimal(0.277, 3));
+ $this->assertTrue(Validation::decimal('1234.5678', '4'));
+ $this->assertTrue(Validation::decimal(1234.5678, 4));
+ $this->assertTrue(Validation::decimal(-1234.5678, 4));
+ $this->assertTrue(Validation::decimal(1234.5678, 4));
+ $this->assertFalse(Validation::decimal('1234.5678', '3'));
+ $this->assertFalse(Validation::decimal(1234.5678, 3));
+ $this->assertFalse(Validation::decimal(-1234.5678, 3));
+ $this->assertFalse(Validation::decimal(1234.5678, 3));
+ }
+
+/**
+ * testDecimalCustomRegex method
+ *
+ * @return void
+ */
+ public function testDecimalCustomRegex() {
+ $this->assertTrue(Validation::decimal('1.54321', null, '/^[-+]?[0-9]+(\\.[0-9]+)?$/s'));
+ $this->assertFalse(Validation::decimal('.54321', null, '/^[-+]?[0-9]+(\\.[0-9]+)?$/s'));
+ }
+
+/**
+ * testEmail method
+ *
+ * @return void
+ */
+ public function testEmail() {
+ $this->assertTrue(Validation::email('abc.efg@domain.com'));
+ $this->assertTrue(Validation::email('efg@domain.com'));
+ $this->assertTrue(Validation::email('abc-efg@domain.com'));
+ $this->assertTrue(Validation::email('abc_efg@domain.com'));
+ $this->assertTrue(Validation::email('raw@test.ra.ru'));
+ $this->assertTrue(Validation::email('abc-efg@domain-hyphened.com'));
+ $this->assertTrue(Validation::email("p.o'malley@domain.com"));
+ $this->assertTrue(Validation::email('abc+efg@domain.com'));
+ $this->assertTrue(Validation::email('abc&efg@domain.com'));
+ $this->assertTrue(Validation::email('abc.efg@12345.com'));
+ $this->assertTrue(Validation::email('abc.efg@12345.co.jp'));
+ $this->assertTrue(Validation::email('abc@g.cn'));
+ $this->assertTrue(Validation::email('abc@x.com'));
+ $this->assertTrue(Validation::email('henrik@sbcglobal.net'));
+ $this->assertTrue(Validation::email('sani@sbcglobal.net'));
+
+ // all ICANN TLDs
+ $this->assertTrue(Validation::email('abc@example.aero'));
+ $this->assertTrue(Validation::email('abc@example.asia'));
+ $this->assertTrue(Validation::email('abc@example.biz'));
+ $this->assertTrue(Validation::email('abc@example.cat'));
+ $this->assertTrue(Validation::email('abc@example.com'));
+ $this->assertTrue(Validation::email('abc@example.coop'));
+ $this->assertTrue(Validation::email('abc@example.edu'));
+ $this->assertTrue(Validation::email('abc@example.gov'));
+ $this->assertTrue(Validation::email('abc@example.info'));
+ $this->assertTrue(Validation::email('abc@example.int'));
+ $this->assertTrue(Validation::email('abc@example.jobs'));
+ $this->assertTrue(Validation::email('abc@example.mil'));
+ $this->assertTrue(Validation::email('abc@example.mobi'));
+ $this->assertTrue(Validation::email('abc@example.museum'));
+ $this->assertTrue(Validation::email('abc@example.name'));
+ $this->assertTrue(Validation::email('abc@example.net'));
+ $this->assertTrue(Validation::email('abc@example.org'));
+ $this->assertTrue(Validation::email('abc@example.pro'));
+ $this->assertTrue(Validation::email('abc@example.tel'));
+ $this->assertTrue(Validation::email('abc@example.travel'));
+ $this->assertTrue(Validation::email('someone@st.t-com.hr'));
+
+ // strange, but technically valid email addresses
+ $this->assertTrue(Validation::email('S=postmaster/OU=rz/P=uni-frankfurt/A=d400/C=de@gateway.d400.de'));
+ $this->assertTrue(Validation::email('customer/department=shipping@example.com'));
+ $this->assertTrue(Validation::email('$A12345@example.com'));
+ $this->assertTrue(Validation::email('!def!xyz%abc@example.com'));
+ $this->assertTrue(Validation::email('_somename@example.com'));
+
+ // invalid addresses
+ $this->assertFalse(Validation::email('abc@example'));
+ $this->assertFalse(Validation::email('abc@example.c'));
+ $this->assertFalse(Validation::email('abc@example.com.'));
+ $this->assertFalse(Validation::email('abc.@example.com'));
+ $this->assertFalse(Validation::email('abc@example..com'));
+ $this->assertFalse(Validation::email('abc@example.com.a'));
+ $this->assertFalse(Validation::email('abc@example.toolong'));
+ $this->assertFalse(Validation::email('abc;@example.com'));
+ $this->assertFalse(Validation::email('abc@example.com;'));
+ $this->assertFalse(Validation::email('abc@efg@example.com'));
+ $this->assertFalse(Validation::email('abc@@example.com'));
+ $this->assertFalse(Validation::email('abc efg@example.com'));
+ $this->assertFalse(Validation::email('abc,efg@example.com'));
+ $this->assertFalse(Validation::email('abc@sub,example.com'));
+ $this->assertFalse(Validation::email("abc@sub'example.com"));
+ $this->assertFalse(Validation::email('abc@sub/example.com'));
+ $this->assertFalse(Validation::email('abc@yahoo!.com'));
+ $this->assertFalse(Validation::email("Nyrée.surname@example.com"));
+ $this->assertFalse(Validation::email('abc@example_underscored.com'));
+ $this->assertFalse(Validation::email('raw@test.ra.ru....com'));
+ }
+
+/**
+ * testEmailDeep method
+ *
+ * @return void
+ */
+ public function testEmailDeep() {
+ $this->skipIf(gethostbynamel('example.abcd'), 'Your DNS service responds for non-existant domains, skipping deep email checks.');
+
+ $this->assertTrue(Validation::email('abc.efg@cakephp.org', true));
+ $this->assertFalse(Validation::email('abc.efg@caphpkeinvalid.com', true));
+ $this->assertFalse(Validation::email('abc@example.abcd', true));
+ }
+
+/**
+ * testEmailCustomRegex method
+ *
+ * @return void
+ */
+ public function testEmailCustomRegex() {
+ $this->assertTrue(Validation::email('abc.efg@cakephp.org', null, '/^[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i'));
+ $this->assertFalse(Validation::email('abc.efg@com.caphpkeinvalid', null, '/^[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i'));
+ }
+
+/**
+ * testEqualTo method
+ *
+ * @return void
+ */
+ public function testEqualTo() {
+ $this->assertTrue(Validation::equalTo("1", "1"));
+ $this->assertFalse(Validation::equalTo(1, "1"));
+ $this->assertFalse(Validation::equalTo("", null));
+ $this->assertFalse(Validation::equalTo("", false));
+ $this->assertFalse(Validation::equalTo(0, false));
+ $this->assertFalse(Validation::equalTo(null, false));
+ }
+
+/**
+ * testIpV4 method
+ *
+ * @return void
+ */
+ public function testIpV4() {
+ $this->assertTrue(Validation::ip('0.0.0.0', 'ipv4'));
+ $this->assertTrue(Validation::ip('192.168.1.156'));
+ $this->assertTrue(Validation::ip('255.255.255.255'));
+ $this->assertFalse(Validation::ip('127.0.0'));
+ $this->assertFalse(Validation::ip('127.0.0.a'));
+ $this->assertFalse(Validation::ip('127.0.0.256'));
+ $this->assertFalse(Validation::ip('2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'ipv4'), 'IPv6 is not valid IPv4');
+ }
+
+/**
+ * testIp v6
+ *
+ * @return void
+ */
+ public function testIpv6() {
+ $this->assertTrue(Validation::ip('2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:db8:85a3:0:0:8a2e:370:7334', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:db8:85a3::8a2e:370:7334', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:0db8:0000:0000:0000:0000:1428:57ab', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:0db8:0000:0000:0000::1428:57ab', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:0db8:0:0:0:0:1428:57ab', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:0db8:0:0::1428:57ab', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:0db8::1428:57ab', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:db8::1428:57ab', 'IPv6'));
+ $this->assertTrue(Validation::ip('0000:0000:0000:0000:0000:0000:0000:0001', 'IPv6'));
+ $this->assertTrue(Validation::ip('::1', 'IPv6'));
+ $this->assertTrue(Validation::ip('::ffff:12.34.56.78', 'IPv6'));
+ $this->assertTrue(Validation::ip('::ffff:0c22:384e', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:0db8:1234:0000:0000:0000:0000:0000', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:0db8:1234:ffff:ffff:ffff:ffff:ffff', 'IPv6'));
+ $this->assertTrue(Validation::ip('2001:db8:a::123', 'IPv6'));
+ $this->assertTrue(Validation::ip('fe80::', 'IPv6'));
+ $this->assertTrue(Validation::ip('::ffff:192.0.2.128', 'IPv6'));
+ $this->assertTrue(Validation::ip('::ffff:c000:280', 'IPv6'));
+
+ $this->assertFalse(Validation::ip('123', 'IPv6'));
+ $this->assertFalse(Validation::ip('ldkfj', 'IPv6'));
+ $this->assertFalse(Validation::ip('2001::FFD3::57ab', 'IPv6'));
+ $this->assertFalse(Validation::ip('2001:db8:85a3::8a2e:37023:7334', 'IPv6'));
+ $this->assertFalse(Validation::ip('2001:db8:85a3::8a2e:370k:7334', 'IPv6'));
+ $this->assertFalse(Validation::ip('1:2:3:4:5:6:7:8:9', 'IPv6'));
+ $this->assertFalse(Validation::ip('1::2::3', 'IPv6'));
+ $this->assertFalse(Validation::ip('1:::3:4:5', 'IPv6'));
+ $this->assertFalse(Validation::ip('1:2:3::4:5:6:7:8:9', 'IPv6'));
+ $this->assertFalse(Validation::ip('::ffff:2.3.4', 'IPv6'));
+ $this->assertFalse(Validation::ip('::ffff:257.1.2.3', 'IPv6'));
+ $this->assertFalse(Validation::ip('255.255.255.255', 'ipv6'), 'IPv4 is not valid IPv6');
+ }
+
+/**
+ * testMaxLength method
+ *
+ * @return void
+ */
+ public function testMaxLength() {
+ $this->assertTrue(Validation::maxLength('ab', 3));
+ $this->assertTrue(Validation::maxLength('abc', 3));
+ $this->assertTrue(Validation::maxLength('ÆΔΩЖÇ', 10));
+
+ $this->assertFalse(Validation::maxLength('abcd', 3));
+ $this->assertFalse(Validation::maxLength('ÆΔΩЖÇ', 3));
+ }
+
+/**
+ * testMinLength method
+ *
+ * @return void
+ */
+ public function testMinLength() {
+ $this->assertFalse(Validation::minLength('ab', 3));
+ $this->assertFalse(Validation::minLength('ÆΔΩЖÇ', 10));
+
+ $this->assertTrue(Validation::minLength('abc', 3));
+ $this->assertTrue(Validation::minLength('abcd', 3));
+ $this->assertTrue(Validation::minLength('ÆΔΩЖÇ', 2));
+ }
+
+/**
+ * testUrl method
+ *
+ * @return void
+ */
+ public function testUrl() {
+ $this->assertTrue(Validation::url('http://www.cakephp.org'));
+ $this->assertTrue(Validation::url('http://cakephp.org'));
+ $this->assertTrue(Validation::url('http://www.cakephp.org/somewhere#anchor'));
+ $this->assertTrue(Validation::url('http://192.168.0.1'));
+ $this->assertTrue(Validation::url('https://www.cakephp.org'));
+ $this->assertTrue(Validation::url('https://cakephp.org'));
+ $this->assertTrue(Validation::url('https://www.cakephp.org/somewhere#anchor'));
+ $this->assertTrue(Validation::url('https://192.168.0.1'));
+ $this->assertTrue(Validation::url('ftps://www.cakephp.org/pub/cake'));
+ $this->assertTrue(Validation::url('ftps://cakephp.org/pub/cake'));
+ $this->assertTrue(Validation::url('ftps://192.168.0.1/pub/cake'));
+ $this->assertTrue(Validation::url('ftp://www.cakephp.org/pub/cake'));
+ $this->assertTrue(Validation::url('ftp://cakephp.org/pub/cake'));
+ $this->assertTrue(Validation::url('ftp://192.168.0.1/pub/cake'));
+ $this->assertTrue(Validation::url('sftp://192.168.0.1/pub/cake'));
+ $this->assertFalse(Validation::url('ftps://256.168.0.1/pub/cake'));
+ $this->assertFalse(Validation::url('ftp://256.168.0.1/pub/cake'));
+ $this->assertTrue(Validation::url('https://my.domain.com/gizmo/app?class=MySip;proc=start'));
+ $this->assertTrue(Validation::url('www.domain.tld'));
+ $this->assertFalse(Validation::url('http://w_w.domain.co_m'));
+ $this->assertFalse(Validation::url('http://www.domain.12com'));
+ $this->assertFalse(Validation::url('http://www.domain.longttldnotallowed'));
+ $this->assertFalse(Validation::url('http://www.-invaliddomain.tld'));
+ $this->assertFalse(Validation::url('http://www.domain.-invalidtld'));
+ $this->assertTrue(Validation::url('http://123456789112345678921234567893123456789412345678951234567896123.com'));
+ $this->assertFalse(Validation::url('http://this-domain-is-too-loooooong-by-icann-rules-maximum-length-is-63.com'));
+ $this->assertTrue(Validation::url('http://www.domain.com/blogs/index.php?blog=6&tempskin=_rss2'));
+ $this->assertTrue(Validation::url('http://www.domain.com/blogs/parenth()eses.php'));
+ $this->assertTrue(Validation::url('http://www.domain.com/index.php?get=params&amp;get2=params'));
+ $this->assertTrue(Validation::url('http://www.domain.com/ndex.php?get=params&amp;get2=params#anchor'));
+ $this->assertFalse(Validation::url('http://www.domain.com/fakeenco%ode'));
+ $this->assertTrue(Validation::url('http://www.domain.com/real%20url%20encodeing'));
+ $this->assertTrue(Validation::url('http://en.wikipedia.org/wiki/Architectural_pattern_(computer_science)'));
+ $this->assertFalse(Validation::url('http://en.(wikipedia).org/'));
+ $this->assertFalse(Validation::url('www.cakephp.org', true));
+ $this->assertTrue(Validation::url('http://www.cakephp.org', true));
+ $this->assertTrue(Validation::url('http://example.com/~userdir/'));
+
+ $this->assertTrue(Validation::url('http://example.com/~userdir/subdir/index.html'));
+ $this->assertTrue(Validation::url('http://www.zwischenraume.de'));
+ $this->assertTrue(Validation::url('http://www.zwischenraume.cz'));
+ $this->assertTrue(Validation::url('http://www.last.fm/music/浜崎あゆみ'), 'utf8 path failed');
+ $this->assertTrue(Validation::url('http://www.electrohome.ro/images/239537750-284232-215_300[1].jpg'));
+
+ $this->assertTrue(Validation::url('http://cakephp.org:80'));
+ $this->assertTrue(Validation::url('http://cakephp.org:443'));
+ $this->assertTrue(Validation::url('http://cakephp.org:2000'));
+ $this->assertTrue(Validation::url('http://cakephp.org:27000'));
+ $this->assertTrue(Validation::url('http://cakephp.org:65000'));
+
+ $this->assertTrue(Validation::url('[2001:0db8::1428:57ab]'));
+ $this->assertTrue(Validation::url('[::1]'));
+ $this->assertTrue(Validation::url('[2001:0db8::1428:57ab]:80'));
+ $this->assertTrue(Validation::url('[::1]:80'));
+ $this->assertTrue(Validation::url('http://[2001:0db8::1428:57ab]'));
+ $this->assertTrue(Validation::url('http://[::1]'));
+ $this->assertTrue(Validation::url('http://[2001:0db8::1428:57ab]:80'));
+ $this->assertTrue(Validation::url('http://[::1]:80'));
+
+ $this->assertFalse(Validation::url('[1::2::3]'));
+ }
+
+ public function testUuid() {
+ $this->assertTrue(Validation::uuid('550e8400-e29b-11d4-a716-446655440000'));
+ $this->assertFalse(Validation::uuid('BRAP-e29b-11d4-a716-446655440000'));
+ $this->assertTrue(Validation::uuid('550E8400-e29b-11D4-A716-446655440000'));
+ $this->assertFalse(Validation::uuid('550e8400-e29b11d4-a716-446655440000'));
+ $this->assertFalse(Validation::uuid('550e8400-e29b-11d4-a716-4466440000'));
+ $this->assertFalse(Validation::uuid('550e8400-e29b-11d4-a71-446655440000'));
+ $this->assertFalse(Validation::uuid('550e8400-e29b-11d-a716-446655440000'));
+ $this->assertFalse(Validation::uuid('550e8400-e29-11d4-a716-446655440000'));
+ }
+
+/**
+ * testInList method
+ *
+ * @return void
+ */
+ public function testInList() {
+ $this->assertTrue(Validation::inList('one', array('one', 'two')));
+ $this->assertTrue(Validation::inList('two', array('one', 'two')));
+ $this->assertFalse(Validation::inList('three', array('one', 'two')));
+ $this->assertFalse(Validation::inList('1one', array(0, 1, 2, 3)));
+ $this->assertFalse(Validation::inList('one', array(0, 1, 2, 3)));
+ $this->assertFalse(Validation::inList('2', array(1, 2, 3)));
+ $this->assertTrue(Validation::inList('2', array(1, 2, 3), false));
+ }
+
+/**
+ * testRange method
+ *
+ * @return void
+ */
+ public function testRange() {
+ $this->assertFalse(Validation::range(20, 100, 1));
+ $this->assertTrue(Validation::range(20, 1, 100));
+ $this->assertFalse(Validation::range(.5, 1, 100));
+ $this->assertTrue(Validation::range(.5, 0, 100));
+ $this->assertTrue(Validation::range(5));
+ $this->assertTrue(Validation::range(-5, -10, 1));
+ $this->assertFalse(Validation::range('word'));
+ }
+
+/**
+ * testExtension method
+ *
+ * @return void
+ */
+ public function testExtension() {
+ $this->assertTrue(Validation::extension('extension.jpeg'));
+ $this->assertTrue(Validation::extension('extension.JPEG'));
+ $this->assertTrue(Validation::extension('extension.gif'));
+ $this->assertTrue(Validation::extension('extension.GIF'));
+ $this->assertTrue(Validation::extension('extension.png'));
+ $this->assertTrue(Validation::extension('extension.jpg'));
+ $this->assertTrue(Validation::extension('extension.JPG'));
+ $this->assertFalse(Validation::extension('noextension'));
+ $this->assertTrue(Validation::extension('extension.pdf', array('PDF')));
+ $this->assertFalse(Validation::extension('extension.jpg', array('GIF')));
+ $this->assertTrue(Validation::extension(array('extension.JPG', 'extension.gif', 'extension.png')));
+ $this->assertTrue(Validation::extension(array('file' => array('name' => 'file.jpg'))));
+ $this->assertTrue(Validation::extension(array('file1' => array('name' => 'file.jpg'),
+ 'file2' => array('name' => 'file.jpg'),
+ 'file3' => array('name' => 'file.jpg'))));
+ $this->assertFalse(Validation::extension(array('file1' => array('name' => 'file.jpg'),
+ 'file2' => array('name' => 'file.jpg'),
+ 'file3' => array('name' => 'file.jpg')), array('gif')));
+
+ $this->assertFalse(Validation::extension(array('noextension', 'extension.JPG', 'extension.gif', 'extension.png')));
+ $this->assertFalse(Validation::extension(array('extension.pdf', 'extension.JPG', 'extension.gif', 'extension.png')));
+ }
+
+/**
+ * testMoney method
+ *
+ * @return void
+ */
+ public function testMoney() {
+ $this->assertTrue(Validation::money('$100'));
+ $this->assertTrue(Validation::money('$100.11'));
+ $this->assertTrue(Validation::money('$100.112'));
+ $this->assertFalse(Validation::money('$100.1'));
+ $this->assertFalse(Validation::money('$100.1111'));
+ $this->assertFalse(Validation::money('text'));
+
+ $this->assertTrue(Validation::money('100', 'right'));
+ $this->assertTrue(Validation::money('100.11$', 'right'));
+ $this->assertTrue(Validation::money('100.112$', 'right'));
+ $this->assertFalse(Validation::money('100.1$', 'right'));
+ $this->assertFalse(Validation::money('100.1111$', 'right'));
+
+ $this->assertTrue(Validation::money('€100'));
+ $this->assertTrue(Validation::money('€100.11'));
+ $this->assertTrue(Validation::money('€100.112'));
+ $this->assertFalse(Validation::money('€100.1'));
+ $this->assertFalse(Validation::money('€100.1111'));
+
+ $this->assertTrue(Validation::money('100', 'right'));
+ $this->assertTrue(Validation::money('100.11€', 'right'));
+ $this->assertTrue(Validation::money('100.112€', 'right'));
+ $this->assertFalse(Validation::money('100.1€', 'right'));
+ $this->assertFalse(Validation::money('100.1111€', 'right'));
+ }
+
+/**
+ * Test Multiple Select Validation
+ *
+ * @return void
+ */
+ public function testMultiple() {
+ $this->assertTrue(Validation::multiple(array(0, 1, 2, 3)));
+ $this->assertTrue(Validation::multiple(array(50, 32, 22, 0)));
+ $this->assertTrue(Validation::multiple(array('str', 'var', 'enum', 0)));
+ $this->assertFalse(Validation::multiple(''));
+ $this->assertFalse(Validation::multiple(null));
+ $this->assertFalse(Validation::multiple(array()));
+ $this->assertFalse(Validation::multiple(array(0)));
+ $this->assertFalse(Validation::multiple(array('0')));
+
+ $this->assertTrue(Validation::multiple(array(0, 3, 4, 5), array('in' => range(0, 10))));
+ $this->assertFalse(Validation::multiple(array(0, 15, 20, 5), array('in' => range(0, 10))));
+ $this->assertFalse(Validation::multiple(array(0, 5, 10, 11), array('in' => range(0, 10))));
+ $this->assertFalse(Validation::multiple(array('boo', 'foo', 'bar'), array('in' => array('foo', 'bar', 'baz'))));
+ $this->assertFalse(Validation::multiple(array('foo', '1bar'), array('in' => range(0, 10))));
+
+ $this->assertTrue(Validation::multiple(array(0, 5, 10, 11), array('max' => 3)));
+ $this->assertFalse(Validation::multiple(array(0, 5, 10, 11, 55), array('max' => 3)));
+ $this->assertTrue(Validation::multiple(array('foo', 'bar', 'baz'), array('max' => 3)));
+ $this->assertFalse(Validation::multiple(array('foo', 'bar', 'baz', 'squirrel'), array('max' => 3)));
+
+ $this->assertTrue(Validation::multiple(array(0, 5, 10, 11), array('min' => 3)));
+ $this->assertTrue(Validation::multiple(array(0, 5, 10, 11, 55), array('min' => 3)));
+ $this->assertFalse(Validation::multiple(array('foo', 'bar', 'baz'), array('min' => 5)));
+ $this->assertFalse(Validation::multiple(array('foo', 'bar', 'baz', 'squirrel'), array('min' => 10)));
+
+ $this->assertTrue(Validation::multiple(array(0, 5, 9), array('in' => range(0, 10), 'max' => 5)));
+ $this->assertFalse(Validation::multiple(array('0', '5', '9'), array('in' => range(0, 10), 'max' => 5)));
+ $this->assertTrue(Validation::multiple(array('0', '5', '9'), array('in' => range(0, 10), 'max' => 5), false));
+ $this->assertFalse(Validation::multiple(array(0, 5, 9, 8, 6, 2, 1), array('in' => range(0, 10), 'max' => 5)));
+ $this->assertFalse(Validation::multiple(array(0, 5, 9, 8, 11), array('in' => range(0, 10), 'max' => 5)));
+
+ $this->assertFalse(Validation::multiple(array(0, 5, 9), array('in' => range(0, 10), 'max' => 5, 'min' => 3)));
+ $this->assertFalse(Validation::multiple(array(0, 5, 9, 8, 6, 2, 1), array('in' => range(0, 10), 'max' => 5, 'min' => 2)));
+ $this->assertFalse(Validation::multiple(array(0, 5, 9, 8, 11), array('in' => range(0, 10), 'max' => 5, 'min' => 2)));
+ }
+
+/**
+ * testNumeric method
+ *
+ * @return void
+ */
+ public function testNumeric() {
+ $this->assertFalse(Validation::numeric('teststring'));
+ $this->assertFalse(Validation::numeric('1.1test'));
+ $this->assertFalse(Validation::numeric('2test'));
+
+ $this->assertTrue(Validation::numeric('2'));
+ $this->assertTrue(Validation::numeric(2));
+ $this->assertTrue(Validation::numeric(2.2));
+ $this->assertTrue(Validation::numeric('2.2'));
+ }
+
+/**
+ * testNaturalNumber method
+ *
+ * @return void
+ */
+ public function testNaturalNumber() {
+ $this->assertFalse(Validation::naturalNumber('teststring'));
+ $this->assertFalse(Validation::naturalNumber('5.4'));
+ $this->assertFalse(Validation::naturalNumber(99.004));
+ $this->assertFalse(Validation::naturalNumber('0,05'));
+ $this->assertFalse(Validation::naturalNumber('-2'));
+ $this->assertFalse(Validation::naturalNumber(-2));
+ $this->assertFalse(Validation::naturalNumber('0'));
+ $this->assertFalse(Validation::naturalNumber('050'));
+
+ $this->assertTrue(Validation::naturalNumber('2'));
+ $this->assertTrue(Validation::naturalNumber(49));
+ $this->assertTrue(Validation::naturalNumber('0', true));
+ $this->assertTrue(Validation::naturalNumber(0, true));
+ }
+
+/**
+ * testPhone method
+ *
+ * @return void
+ */
+ public function testPhone() {
+ $this->assertFalse(Validation::phone('teststring'));
+ $this->assertFalse(Validation::phone('1-(33)-(333)-(4444)'));
+ $this->assertFalse(Validation::phone('1-(33)-3333-4444'));
+ $this->assertFalse(Validation::phone('1-(33)-33-4444'));
+ $this->assertFalse(Validation::phone('1-(33)-3-44444'));
+ $this->assertFalse(Validation::phone('1-(33)-3-444'));
+ $this->assertFalse(Validation::phone('1-(33)-3-44'));
+
+ $this->assertFalse(Validation::phone('(055) 999-9999'));
+ $this->assertFalse(Validation::phone('(155) 999-9999'));
+ $this->assertFalse(Validation::phone('(595) 999-9999'));
+ $this->assertFalse(Validation::phone('(555) 099-9999'));
+ $this->assertFalse(Validation::phone('(555) 199-9999'));
+
+ $this->assertTrue(Validation::phone('1 (222) 333 4444'));
+ $this->assertTrue(Validation::phone('+1 (222) 333 4444'));
+ $this->assertTrue(Validation::phone('(222) 333 4444'));
+
+ $this->assertTrue(Validation::phone('1-(333)-333-4444'));
+ $this->assertTrue(Validation::phone('1.(333)-333-4444'));
+ $this->assertTrue(Validation::phone('1.(333).333-4444'));
+ $this->assertTrue(Validation::phone('1.(333).333.4444'));
+ $this->assertTrue(Validation::phone('1-333-333-4444'));
+ }
+
+/**
+ * testPostal method
+ *
+ * @return void
+ */
+ public function testPostal() {
+ $this->assertFalse(Validation::postal('111', null, 'de'));
+ $this->assertFalse(Validation::postal('1111', null, 'de'));
+ $this->assertTrue(Validation::postal('13089', null, 'de'));
+
+ $this->assertFalse(Validation::postal('111', null, 'be'));
+ $this->assertFalse(Validation::postal('0123', null, 'be'));
+ $this->assertTrue(Validation::postal('1204', null, 'be'));
+
+ $this->assertFalse(Validation::postal('111', null, 'it'));
+ $this->assertFalse(Validation::postal('1111', null, 'it'));
+ $this->assertTrue(Validation::postal('13089', null, 'it'));
+
+ $this->assertFalse(Validation::postal('111', null, 'uk'));
+ $this->assertFalse(Validation::postal('1111', null, 'uk'));
+ $this->assertFalse(Validation::postal('AZA 0AB', null, 'uk'));
+ $this->assertFalse(Validation::postal('X0A 0ABC', null, 'uk'));
+ $this->assertTrue(Validation::postal('X0A 0AB', null, 'uk'));
+ $this->assertTrue(Validation::postal('AZ0A 0AA', null, 'uk'));
+ $this->assertTrue(Validation::postal('A89 2DD', null, 'uk'));
+
+ $this->assertFalse(Validation::postal('111', null, 'ca'));
+ $this->assertFalse(Validation::postal('1111', null, 'ca'));
+ $this->assertFalse(Validation::postal('D2A 0A0', null, 'ca'));
+ $this->assertFalse(Validation::postal('BAA 0ABC', null, 'ca'));
+ $this->assertFalse(Validation::postal('B2A AABC', null, 'ca'));
+ $this->assertFalse(Validation::postal('B2A 2AB', null, 'ca'));
+ $this->assertTrue(Validation::postal('X0A 0A2', null, 'ca'));
+ $this->assertTrue(Validation::postal('G4V 4C3', null, 'ca'));
+
+ $this->assertFalse(Validation::postal('111', null, 'us'));
+ $this->assertFalse(Validation::postal('1111', null, 'us'));
+ $this->assertFalse(Validation::postal('130896', null, 'us'));
+ $this->assertFalse(Validation::postal('13089-33333', null, 'us'));
+ $this->assertFalse(Validation::postal('13089-333', null, 'us'));
+ $this->assertFalse(Validation::postal('13A89-4333', null, 'us'));
+ $this->assertTrue(Validation::postal('13089-3333', null, 'us'));
+
+ $this->assertFalse(Validation::postal('111'));
+ $this->assertFalse(Validation::postal('1111'));
+ $this->assertFalse(Validation::postal('130896'));
+ $this->assertFalse(Validation::postal('13089-33333'));
+ $this->assertFalse(Validation::postal('13089-333'));
+ $this->assertFalse(Validation::postal('13A89-4333'));
+ $this->assertTrue(Validation::postal('13089-3333'));
+ }
+
+/**
+ * test that phone and postal pass to other classes.
+ *
+ * @return void
+ */
+ public function testPhonePostalSsnPass() {
+ $this->assertTrue(Validation::postal('text', null, 'testNl'));
+ $this->assertTrue(Validation::phone('text', null, 'testDe'));
+ $this->assertTrue(Validation::ssn('text', null, 'testNl'));
+ }
+
+/**
+ * test pass through failure on postal
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ */
+ public function testPassThroughMethodFailure() {
+ Validation::phone('text', null, 'testNl');
+ }
+
+/**
+ * test the pass through calling of an alternate locale with postal()
+ *
+ * @expectedException PHPUnit_Framework_Error
+ * @return void
+ **/
+ public function testPassThroughClassFailure() {
+ Validation::postal('text', null, 'AUTOFAIL');
+ }
+
+/**
+ * test pass through method
+ *
+ * @return void
+ */
+ public function testPassThroughMethod() {
+ $this->assertTrue(Validation::postal('text', null, 'testNl'));
+ }
+
+/**
+ * testSsn method
+ *
+ * @return void
+ */
+ public function testSsn() {
+ $this->assertFalse(Validation::ssn('111-333', null, 'dk'));
+ $this->assertFalse(Validation::ssn('111111-333', null, 'dk'));
+ $this->assertTrue(Validation::ssn('111111-3334', null, 'dk'));
+
+ $this->assertFalse(Validation::ssn('1118333', null, 'nl'));
+ $this->assertFalse(Validation::ssn('1234567890', null, 'nl'));
+ $this->assertFalse(Validation::ssn('12345A789', null, 'nl'));
+ $this->assertTrue(Validation::ssn('123456789', null, 'nl'));
+
+ $this->assertFalse(Validation::ssn('11-33-4333', null, 'us'));
+ $this->assertFalse(Validation::ssn('113-3-4333', null, 'us'));
+ $this->assertFalse(Validation::ssn('111-33-333', null, 'us'));
+ $this->assertTrue(Validation::ssn('111-33-4333', null, 'us'));
+ }
+
+/**
+ * testUserDefined method
+ *
+ * @return void
+ */
+ public function testUserDefined() {
+ $validator = new CustomValidator;
+ $this->assertFalse(Validation::userDefined('33', $validator, 'customValidate'));
+ $this->assertFalse(Validation::userDefined('3333', $validator, 'customValidate'));
+ $this->assertTrue(Validation::userDefined('333', $validator, 'customValidate'));
+ }
+
+/**
+ * testDatetime method
+ *
+ * @return void
+ */
+ public function testDatetime() {
+ $this->assertTrue(Validation::datetime('27-12-2006 01:00', 'dmy'));
+ $this->assertTrue(Validation::datetime('27-12-2006 01:00', array('dmy')));
+ $this->assertFalse(Validation::datetime('27-12-2006 1:00', 'dmy'));
+
+ $this->assertTrue(Validation::datetime('27.12.2006 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('27.12.2006 13:00pm', 'dmy'));
+
+ $this->assertTrue(Validation::datetime('27/12/2006 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('27/12/2006 9:00', 'dmy'));
+
+ $this->assertTrue(Validation::datetime('27 12 2006 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('27 12 2006 24:00', 'dmy'));
+
+ $this->assertFalse(Validation::datetime('00-00-0000 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('00.00.0000 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('00/00/0000 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('00 00 0000 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('31-11-2006 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('31.11.2006 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('31/11/2006 1:00pm', 'dmy'));
+ $this->assertFalse(Validation::datetime('31 11 2006 1:00pm', 'dmy'));
+ }
+
+/**
+ * testMimeType method
+ *
+ * @return void
+ */
+ public function testMimeType() {
+ $image = CORE_PATH . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'webroot' . DS . 'img' . DS . 'cake.power.gif';
+ $File = new File($image, false);
+ $this->skipIf(!$File->mime(), 'Cannot determine mimeType');
+ $this->assertTrue(Validation::mimeType($image, array('image/gif')));
+ $this->assertTrue(Validation::mimeType(array('tmp_name' => $image), array('image/gif')));
+
+ $this->assertFalse(Validation::mimeType($image, array('image/png')));
+ $this->assertFalse(Validation::mimeType(array('tmp_name' => $image), array('image/png')));
+ }
+
+/**
+ * testMimeTypeFalse method
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testMimeTypeFalse() {
+ $image = CORE_PATH . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'webroot' . DS . 'img' . DS . 'cake.power.gif';
+ $File = new File($image, false);
+ $this->skipIf($File->mime(), 'mimeType can be determined, no Exception will be thrown');
+ Validation::mimeType($image, array('image/gif'));
+ }
+
+/**
+ * testMimeType method
+ *
+ * @return void
+ */
+ public function testUploadError() {
+ $this->assertTrue(Validation::uploadError(0));
+ $this->assertTrue(Validation::uploadError(array('error' => 0)));
+
+ $this->assertFalse(Validation::uploadError(2));
+ $this->assertFalse(Validation::uploadError(array('error' => 2)));
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/XmlTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/XmlTest.php
new file mode 100644
index 0000000..7108d75
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/Utility/XmlTest.php
@@ -0,0 +1,1064 @@
+<?php
+/**
+ * XmlTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Utility
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Xml', 'Utility');
+App::uses('CakeTestModel', 'TestSuite/Fixture');
+
+/**
+ * Article class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class XmlArticle extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'Article'
+ */
+ public $name = 'Article';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array(
+ 'User' => array(
+ 'className' => 'XmlUser',
+ 'foreignKey' => 'user_id'
+ )
+ );
+}
+
+/**
+ * User class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class XmlUser extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'User'
+ */
+ public $name = 'User';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'Article' => array(
+ 'className' => 'XmlArticle'
+ )
+ );
+}
+
+/**
+ * XmlTest class
+ *
+ * @package Cake.Test.Case.Utility
+ */
+class XmlTest extends CakeTestCase {
+
+/**
+ * autoFixtures property
+ *
+ * @var bool false
+ */
+ public $autoFixtures = false;
+
+/**
+ * fixtures property
+ * @var array
+ */
+ public $fixtures = array(
+ 'core.article', 'core.user'
+ );
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->_appEncoding = Configure::read('App.encoding');
+ Configure::write('App.encoding', 'UTF-8');
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::write('App.encoding', $this->_appEncoding);
+ }
+
+/**
+ * testBuild method
+ *
+ * @return void
+ */
+ public function testBuild() {
+ $xml = '<tag>value</tag>';
+ $obj = Xml::build($xml);
+ $this->assertTrue($obj instanceof SimpleXMLElement);
+ $this->assertEquals('tag', (string)$obj->getName());
+ $this->assertEquals('value', (string)$obj);
+
+ $xml = '<?xml version="1.0" encoding="UTF-8"?><tag>value</tag>';
+ $this->assertEquals($obj, Xml::build($xml));
+
+ $obj = Xml::build($xml, array('return' => 'domdocument'));
+ $this->assertTrue($obj instanceof DOMDocument);
+ $this->assertEquals('tag', $obj->firstChild->nodeName);
+ $this->assertEquals('value', $obj->firstChild->nodeValue);
+
+ $xml = CAKE . 'Test' . DS . 'Fixture' . DS . 'sample.xml';
+ $obj = Xml::build($xml);
+ $this->assertEquals('tags', $obj->getName());
+ $this->assertEquals(2, count($obj));
+
+ $this->assertEquals(Xml::build($xml), Xml::build(file_get_contents($xml)));
+
+ $obj = Xml::build($xml, array('return' => 'domdocument'));
+ $this->assertEquals('tags', $obj->firstChild->nodeName);
+
+ $this->assertEquals(
+ Xml::build($xml, array('return' => 'domdocument')),
+ Xml::build(file_get_contents($xml), array('return' => 'domdocument'))
+ );
+ $this->assertEquals(
+ Xml::build($xml, array('return' => 'simplexml')),
+ Xml::build($xml, 'simplexml')
+ );
+
+ $xml = array('tag' => 'value');
+ $obj = Xml::build($xml);
+ $this->assertEquals('tag', $obj->getName());
+ $this->assertEquals('value', (string)$obj);
+
+ $obj = Xml::build($xml, array('return' => 'domdocument'));
+ $this->assertEquals('tag', $obj->firstChild->nodeName);
+ $this->assertEquals('value', $obj->firstChild->nodeValue);
+
+ $obj = Xml::build($xml, array('return' => 'domdocument', 'encoding' => null));
+ $this->assertNotRegExp('/encoding/', $obj->saveXML());
+ }
+
+/**
+ * data provider function for testBuildInvalidData
+ *
+ * @return array
+ */
+ public static function invalidDataProvider() {
+ return array(
+ array(null),
+ array(false),
+ array(''),
+ );
+ }
+
+/**
+ * testBuildInvalidData
+ *
+ * @dataProvider invalidDataProvider
+ * @expectedException XmlException
+ * return void
+ */
+ public function testBuildInvalidData($value) {
+ Xml::build($value);
+ }
+
+/**
+ * test build with a single empty tag
+ *
+ * return void
+ */
+ public function testBuildEmptyTag() {
+ try {
+ Xml::build('<tag>');
+ $this->fail('No exception');
+ } catch (Exception $e) {
+ $this->assertTrue(true, 'An exception was raised');
+ }
+ }
+
+/**
+ * testFromArray method
+ *
+ * @return void
+ */
+ public function testFromArray() {
+ $xml = array('tag' => 'value');
+ $obj = Xml::fromArray($xml);
+ $this->assertEquals('tag', $obj->getName());
+ $this->assertEquals('value', (string)$obj);
+
+ $xml = array('tag' => null);
+ $obj = Xml::fromArray($xml);
+ $this->assertEquals('tag', $obj->getName());
+ $this->assertEquals('', (string)$obj);
+
+ $xml = array('tag' => array('@' => 'value'));
+ $obj = Xml::fromArray($xml);
+ $this->assertEquals('tag', $obj->getName());
+ $this->assertEquals('value', (string)$obj);
+
+ $xml = array(
+ 'tags' => array(
+ 'tag' => array(
+ array(
+ 'id' => '1',
+ 'name' => 'defect'
+ ),
+ array(
+ 'id' => '2',
+ 'name' => 'enhancement'
+ )
+ )
+ )
+ );
+ $obj = Xml::fromArray($xml, 'attributes');
+ $this->assertTrue($obj instanceof SimpleXMLElement);
+ $this->assertEquals('tags', $obj->getName());
+ $this->assertEquals(2, count($obj));
+ $xmlText = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<tags>
+ <tag id="1" name="defect"/>
+ <tag id="2" name="enhancement"/>
+</tags>
+XML;
+ $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
+
+ $obj = Xml::fromArray($xml);
+ $this->assertTrue($obj instanceof SimpleXMLElement);
+ $this->assertEquals('tags', $obj->getName());
+ $this->assertEquals(2, count($obj));
+ $xmlText = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<tags>
+ <tag>
+ <id>1</id>
+ <name>defect</name>
+ </tag>
+ <tag>
+ <id>2</id>
+ <name>enhancement</name>
+ </tag>
+</tags>
+XML;
+ $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
+
+ $xml = array(
+ 'tags' => array(
+ )
+ );
+ $obj = Xml::fromArray($xml);
+ $this->assertEquals('tags', $obj->getName());
+ $this->assertEquals('', (string)$obj);
+
+ $xml = array(
+ 'tags' => array(
+ 'bool' => true,
+ 'int' => 1,
+ 'float' => 10.2,
+ 'string' => 'ok',
+ 'null' => null,
+ 'array' => array()
+ )
+ );
+ $obj = Xml::fromArray($xml, 'tags');
+ $this->assertEquals(6, count($obj));
+ $this->assertSame((string)$obj->bool, '1');
+ $this->assertSame((string)$obj->int, '1');
+ $this->assertSame((string)$obj->float, '10.2');
+ $this->assertSame((string)$obj->string, 'ok');
+ $this->assertSame((string)$obj->null, '');
+ $this->assertSame((string)$obj->array, '');
+
+ $xml = array(
+ 'tags' => array(
+ 'tag' => array(
+ array(
+ '@id' => '1',
+ 'name' => 'defect'
+ ),
+ array(
+ '@id' => '2',
+ 'name' => 'enhancement'
+ )
+ )
+ )
+ );
+ $obj = Xml::fromArray($xml, 'tags');
+ $xmlText = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<tags>
+ <tag id="1">
+ <name>defect</name>
+ </tag>
+ <tag id="2">
+ <name>enhancement</name>
+ </tag>
+</tags>
+XML;
+ $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
+
+ $xml = array(
+ 'tags' => array(
+ 'tag' => array(
+ array(
+ '@id' => '1',
+ 'name' => 'defect',
+ '@' => 'Tag 1'
+ ),
+ array(
+ '@id' => '2',
+ 'name' => 'enhancement'
+ ),
+ ),
+ '@' => 'All tags'
+ )
+ );
+ $obj = Xml::fromArray($xml, 'tags');
+ $xmlText = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<tags>All tags<tag id="1">Tag 1<name>defect</name></tag><tag id="2"><name>enhancement</name></tag></tags>
+XML;
+ $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
+
+ $xml = array(
+ 'tags' => array(
+ 'tag' => array(
+ 'id' => 1,
+ '@' => 'defect'
+ )
+ )
+ );
+ $obj = Xml::fromArray($xml, 'attributes');
+ $xmlText = '<' . '?xml version="1.0" encoding="UTF-8"?><tags><tag id="1">defect</tag></tags>';
+ $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
+ }
+
+/**
+ * Test non-sequential keys in list types.
+ *
+ * @return void
+ */
+ public function testFromArrayNonSequentialKeys() {
+ $xmlArray = array(
+ 'Event' => array(
+ array(
+ 'id' => '235',
+ 'Attribute' => array(
+ 0 => array(
+ 'id' => '9646',
+ ),
+ 2 => array(
+ 'id' => '9647',
+ )
+ )
+ )
+ )
+ );
+ $obj = Xml::fromArray($xmlArray);
+ $expected = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<Event>
+ <id>235</id>
+ <Attribute>
+ <id>9646</id>
+ </Attribute>
+ <Attribute>
+ <id>9647</id>
+ </Attribute>
+</Event>
+XML;
+ $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
+ }
+
+/**
+ * data provider for fromArray() failures
+ *
+ * @return array
+ */
+ public static function invalidArrayDataProvider() {
+ return array(
+ array(''),
+ array(null),
+ array(false),
+ array(array()),
+ array(array('numeric key as root')),
+ array(array('item1' => '', 'item2' => '')),
+ array(array('items' => array('item1', 'item2'))),
+ array(array(
+ 'tags' => array(
+ 'tag' => array(
+ array(
+ array(
+ 'string'
+ )
+ )
+ )
+ )
+ )),
+ array(array(
+ 'tags' => array(
+ '@tag' => array(
+ array(
+ '@id' => '1',
+ 'name' => 'defect'
+ ),
+ array(
+ '@id' => '2',
+ 'name' => 'enhancement'
+ )
+ )
+ )
+ )),
+ array(new DateTime())
+ );
+ }
+
+/**
+ * testFromArrayFail method
+ *
+ * @dataProvider invalidArrayDataProvider
+ */
+ public function testFromArrayFail($value) {
+ try {
+ Xml::fromArray($value);
+ $this->fail('No exception.');
+ } catch (Exception $e) {
+ $this->assertTrue(true, 'Caught exception.');
+ }
+ }
+
+/**
+ * testToArray method
+ *
+ * @return void
+ */
+ public function testToArray() {
+ $xml = '<tag>name</tag>';
+ $obj = Xml::build($xml);
+ $this->assertEquals(array('tag' => 'name'), Xml::toArray($obj));
+
+ $xml = CAKE . 'Test' . DS . 'Fixture' . DS . 'sample.xml';
+ $obj = Xml::build($xml);
+ $expected = array(
+ 'tags' => array(
+ 'tag' => array(
+ array(
+ '@id' => '1',
+ 'name' => 'defect'
+ ),
+ array(
+ '@id' => '2',
+ 'name' => 'enhancement'
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($obj));
+
+ $array = array(
+ 'tags' => array(
+ 'tag' => array(
+ array(
+ 'id' => '1',
+ 'name' => 'defect'
+ ),
+ array(
+ 'id' => '2',
+ 'name' => 'enhancement'
+ )
+ )
+ )
+ );
+ $this->assertEquals(Xml::toArray(Xml::fromArray($array, 'tags')), $array);
+
+ $expected = array(
+ 'tags' => array(
+ 'tag' => array(
+ array(
+ '@id' => '1',
+ '@name' => 'defect'
+ ),
+ array(
+ '@id' => '2',
+ '@name' => 'enhancement'
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, 'attributes')));
+ $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, array('return' => 'domdocument', 'format' => 'attributes'))));
+ $this->assertEquals(Xml::toArray(Xml::fromArray($array)), $array);
+ $this->assertEquals(Xml::toArray(Xml::fromArray($array, array('return' => 'domdocument'))), $array);
+
+ $array = array(
+ 'tags' => array(
+ 'tag' => array(
+ 'id' => '1',
+ 'posts' => array(
+ array('id' => '1'),
+ array('id' => '2')
+ )
+ ),
+ 'tagOther' => array(
+ 'subtag' => array(
+ 'id' => '1'
+ )
+ )
+ )
+ );
+ $expected = array(
+ 'tags' => array(
+ 'tag' => array(
+ '@id' => '1',
+ 'posts' => array(
+ array('@id' => '1'),
+ array('@id' => '2')
+ )
+ ),
+ 'tagOther' => array(
+ 'subtag' => array(
+ '@id' => '1'
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, 'attributes')));
+ $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, array('format' => 'attributes', 'return' => 'domdocument'))));
+
+ $xml = <<<XML
+<root>
+<tag id="1">defect</tag>
+</root>
+XML;
+ $obj = Xml::build($xml);
+
+ $expected = array(
+ 'root' => array(
+ 'tag' => array(
+ '@id' => 1,
+ '@' => 'defect'
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($obj));
+
+ $xml = <<<XML
+<root>
+ <table xmlns="http://www.w3.org/TR/html4/"><tr><td>Apples</td><td>Bananas</td></tr></table>
+ <table xmlns="http://www.cakephp.org"><name>CakePHP</name><license>MIT</license></table>
+ <table>The book is on the table.</table>
+</root>
+XML;
+ $obj = Xml::build($xml);
+
+ $expected = array(
+ 'root' => array(
+ 'table' => array(
+ array('tr' => array('td' => array('Apples', 'Bananas'))),
+ array('name' => 'CakePHP', 'license' => 'MIT'),
+ 'The book is on the table.'
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($obj));
+
+ $xml = <<<XML
+<root xmlns:cake="http://www.cakephp.org/">
+<tag>defect</tag>
+<cake:bug>1</cake:bug>
+</root>
+XML;
+ $obj = Xml::build($xml);
+
+ $expected = array(
+ 'root' => array(
+ 'tag' => 'defect',
+ 'cake:bug' => 1
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($obj));
+ }
+
+/**
+ * testRss
+ *
+ * @return void
+ */
+ public function testRss() {
+ $rss = file_get_contents(CAKE . 'Test' . DS . 'Fixture' . DS . 'rss.xml');
+ $rssAsArray = Xml::toArray(Xml::build($rss));
+ $this->assertEquals('2.0', $rssAsArray['rss']['@version']);
+ $this->assertEquals(2, count($rssAsArray['rss']['channel']['item']));
+
+ $atomLink = array('@href' => 'http://bakery.cakephp.org/articles/rss', '@rel' => 'self', '@type' => 'application/rss+xml');
+ $this->assertEquals($rssAsArray['rss']['channel']['atom:link'], $atomLink);
+ $this->assertEquals('http://bakery.cakephp.org/', $rssAsArray['rss']['channel']['link']);
+
+ $expected = array(
+ 'title' => 'Alertpay automated sales via IPN',
+ 'link' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn',
+ 'description' => 'I\'m going to show you how I implemented a payment module via the Alertpay payment processor.',
+ 'pubDate' => 'Tue, 31 Aug 2010 01:42:00 -0500',
+ 'guid' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn'
+ );
+ $this->assertSame($rssAsArray['rss']['channel']['item'][1], $expected);
+
+ $rss = array(
+ 'rss' => array(
+ 'xmlns:atom' => 'http://www.w3.org/2005/Atom',
+ '@version' => '2.0',
+ 'channel' => array(
+ 'atom:link' => array(
+ '@href' => 'http://bakery.cakephp.org/articles/rss',
+ '@rel' => 'self',
+ '@type' => 'application/rss+xml'
+ ),
+ 'title' => 'The Bakery: ',
+ 'link' => 'http://bakery.cakephp.org/',
+ 'description' => 'Recent Articles at The Bakery.',
+ 'pubDate' => 'Sun, 12 Sep 2010 04:18:26 -0500',
+ 'item' => array(
+ array(
+ 'title' => 'CakePHP 1.3.4 released',
+ 'link' => 'http://bakery.cakephp.org/articles/view/cakephp-1-3-4-released'
+ ),
+ array(
+ 'title' => 'Wizard Component 1.2 Tutorial',
+ 'link' => 'http://bakery.cakephp.org/articles/view/wizard-component-1-2-tutorial'
+ )
+ )
+ )
+ )
+ );
+ $rssAsSimpleXML = Xml::fromArray($rss);
+ $xmlText = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
+<channel>
+ <atom:link href="http://bakery.cakephp.org/articles/rss" rel="self" type="application/rss+xml"/>
+ <title>The Bakery: </title>
+ <link>http://bakery.cakephp.org/</link>
+ <description>Recent Articles at The Bakery.</description>
+ <pubDate>Sun, 12 Sep 2010 04:18:26 -0500</pubDate>
+ <item>
+ <title>CakePHP 1.3.4 released</title>
+ <link>http://bakery.cakephp.org/articles/view/cakephp-1-3-4-released</link>
+ </item>
+ <item>
+ <title>Wizard Component 1.2 Tutorial</title>
+ <link>http://bakery.cakephp.org/articles/view/wizard-component-1-2-tutorial</link>
+ </item>
+</channel>
+</rss>
+XML;
+ $this->assertXmlStringEqualsXmlString($xmlText, $rssAsSimpleXML->asXML());
+ }
+
+/**
+ * testXmlRpc
+ *
+ * @return void
+ */
+ public function testXmlRpc() {
+ $xml = Xml::build('<methodCall><methodName>test</methodName><params /></methodCall>');
+ $expected = array(
+ 'methodCall' => array(
+ 'methodName' => 'test',
+ 'params' => ''
+ )
+ );
+ $this->assertSame(Xml::toArray($xml), $expected);
+
+ $xml = Xml::build('<methodCall><methodName>test</methodName><params><param><value><array><data><value><int>12</int></value><value><string>Egypt</string></value><value><boolean>0</boolean></value><value><int>-31</int></value></data></array></value></param></params></methodCall>');
+ $expected = array(
+ 'methodCall' => array(
+ 'methodName' => 'test',
+ 'params' => array(
+ 'param' => array(
+ 'value' => array(
+ 'array' => array(
+ 'data' => array(
+ 'value' => array(
+ array('int' => '12'),
+ array('string' => 'Egypt'),
+ array('boolean' => '0'),
+ array('int' => '-31')
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ );
+ $this->assertSame(Xml::toArray($xml), $expected);
+
+ $xmlText = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<methodResponse>
+ <params>
+ <param>
+ <value>
+ <array>
+ <data>
+ <value>
+ <int>1</int>
+ </value>
+ <value>
+ <string>testing</string>
+ </value>
+ </data>
+ </array>
+ </value>
+ </param>
+ </params>
+</methodResponse>
+XML;
+ $xml = Xml::build($xmlText);
+ $expected = array(
+ 'methodResponse' => array(
+ 'params' => array(
+ 'param' => array(
+ 'value' => array(
+ 'array' => array(
+ 'data' => array(
+ 'value' => array(
+ array('int' => '1'),
+ array('string' => 'testing')
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ );
+ $this->assertSame(Xml::toArray($xml), $expected);
+
+ $xml = Xml::fromArray($expected, 'tags');
+ $this->assertXmlStringEqualsXmlString($xmlText, $xml->asXML());
+ }
+
+/**
+ * testSoap
+ *
+ * @return void
+ */
+ public function testSoap() {
+ $xmlRequest = Xml::build(CAKE . 'Test' . DS . 'Fixture' . DS . 'soap_request.xml');
+ $expected = array(
+ 'Envelope' => array(
+ '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
+ 'soap:Body' => array(
+ 'm:GetStockPrice' => array(
+ 'm:StockName' => 'IBM'
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($xmlRequest));
+
+ $xmlResponse = Xml::build(CAKE . 'Test' . DS . 'Fixture' . DS . 'soap_response.xml');
+ $expected = array(
+ 'Envelope' => array(
+ '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
+ 'soap:Body' => array(
+ 'm:GetStockPriceResponse' => array(
+ 'm:Price' => '34.5'
+ )
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($xmlResponse));
+
+ $xml = array(
+ 'soap:Envelope' => array(
+ 'xmlns:soap' => 'http://www.w3.org/2001/12/soap-envelope',
+ '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
+ 'soap:Body' => array(
+ 'xmlns:m' => 'http://www.example.org/stock',
+ 'm:GetStockPrice' => array(
+ 'm:StockName' => 'IBM'
+ )
+ )
+ )
+ );
+ $xmlRequest = Xml::fromArray($xml, array('encoding' => null));
+ $xmlText = <<<XML
+<?xml version="1.0"?>
+<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
+ <soap:Body xmlns:m="http://www.example.org/stock">
+ <m:GetStockPrice><m:StockName>IBM</m:StockName></m:GetStockPrice>
+ </soap:Body>
+</soap:Envelope>
+XML;
+ $this->assertXmlStringEqualsXmlString($xmlText, $xmlRequest->asXML());
+ }
+
+/**
+ * testNamespace
+ *
+ * @return void
+ */
+ public function testNamespace() {
+ $xml = <<<XML
+<root xmlns:ns="http://cakephp.org">
+ <ns:tag id="1">
+ <child>good</child>
+ <otherchild>bad</otherchild>
+ </ns:tag>
+ <tag>Tag without ns</tag>
+</root>
+XML;
+ $xmlResponse = Xml::build($xml);
+ $expected = array(
+ 'root' => array(
+ 'ns:tag' => array(
+ '@id' => '1',
+ 'child' => 'good',
+ 'otherchild' => 'bad'
+ ),
+ 'tag' => 'Tag without ns'
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($xmlResponse));
+
+ $xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:tag id="1" /><tag><id>1</id></tag></root>');
+ $expected = array(
+ 'root' => array(
+ 'ns:tag' => array(
+ '@id' => '1'
+ ),
+ 'tag' => array(
+ 'id' => '1'
+ )
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($xmlResponse));
+
+ $xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:attr>1</ns:attr></root>');
+ $expected = array(
+ 'root' => array(
+ 'ns:attr' => '1'
+ )
+ );
+ $this->assertEquals($expected, Xml::toArray($xmlResponse));
+
+ $xmlResponse = Xml::build('<root><ns:attr xmlns:ns="http://cakephp.org">1</ns:attr></root>');
+ $this->assertEquals($expected, Xml::toArray($xmlResponse));
+
+ $xml = array(
+ 'root' => array(
+ 'ns:attr' => array(
+ 'xmlns:ns' => 'http://cakephp.org',
+ '@' => 1
+ )
+ )
+ );
+ $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root><ns:attr xmlns:ns="http://cakephp.org">1</ns:attr></root>';
+ $xmlResponse = Xml::fromArray($xml);
+ $this->assertEquals(str_replace(array("\r", "\n"), '', $xmlResponse->asXML()), $expected);
+
+ $xml = array(
+ 'root' => array(
+ 'tag' => array(
+ 'xmlns:pref' => 'http://cakephp.org',
+ 'pref:item' => array(
+ 'item 1',
+ 'item 2'
+ )
+ )
+ )
+ );
+ $expected = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <tag xmlns:pref="http://cakephp.org">
+ <pref:item>item 1</pref:item>
+ <pref:item>item 2</pref:item>
+ </tag>
+</root>
+XML;
+ $xmlResponse = Xml::fromArray($xml);
+ $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
+
+ $xml = array(
+ 'root' => array(
+ 'tag' => array(
+ 'xmlns:' => 'http://cakephp.org'
+ )
+ )
+ );
+ $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root><tag xmlns="http://cakephp.org"/></root>';
+ $xmlResponse = Xml::fromArray($xml);
+ $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
+
+ $xml = array(
+ 'root' => array(
+ 'xmlns:' => 'http://cakephp.org'
+ )
+ );
+ $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root xmlns="http://cakephp.org"/>';
+ $xmlResponse = Xml::fromArray($xml);
+ $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
+
+ $xml = array(
+ 'root' => array(
+ 'xmlns:ns' => 'http://cakephp.org'
+ )
+ );
+ $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root xmlns:ns="http://cakephp.org"/>';
+ $xmlResponse = Xml::fromArray($xml);
+ $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
+ }
+
+/**
+ * test that CDATA blocks don't get screwed up by SimpleXml
+ *
+ * @return void
+ */
+ public function testCdata() {
+ $xml = '<' . '?xml version="1.0" encoding="UTF-8"?>' .
+ '<people><name><![CDATA[ Mark ]]></name></people>';
+
+ $result = Xml::build($xml);
+ $this->assertEquals(' Mark ', (string)$result->name);
+ }
+
+/**
+ * data provider for toArray() failures
+ *
+ * @return array
+ */
+ public static function invalidToArrayDataProvider() {
+ return array(
+ array(new DateTime()),
+ array(array())
+ );
+ }
+
+/**
+ * testToArrayFail method
+ *
+ * @dataProvider invalidToArrayDataProvider
+ * @expectedException XmlException
+ */
+ public function testToArrayFail($value) {
+ Xml::toArray($value);
+ }
+
+/**
+ * testWithModel method
+ *
+ * @return void
+ */
+ public function testWithModel() {
+ $this->loadFixtures('User', 'Article');
+
+ $user = new XmlUser();
+ $data = $user->read(null, 1);
+
+ $obj = Xml::build(compact('data'));
+ $expected = <<<XML
+<?xml version="1.0" encoding="UTF-8"?><data>
+<User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
+<created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
+<Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
+<published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
+<Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
+<published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
+</data>
+XML;
+ $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
+
+ //multiple model results - without a records key it would fatal error
+ $data = $user->find('all', array('limit' => 2));
+ $data = array('records' => $data);
+ $obj = Xml::build(compact('data'));
+ $expected = <<<XML
+<?xml version="1.0" encoding="UTF-8"?><data>
+<records>
+<User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
+<created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
+<Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
+<published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
+<Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
+<published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
+</records><records><User><id>2</id><user>nate</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
+<created>2007-03-17 01:18:23</created><updated>2007-03-17 01:20:31</updated></User><Article/>
+</records>
+</data>
+XML;
+ $result = $obj->asXML();
+ $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
+ }
+
+/**
+ * Test ampersand in text elements.
+ *
+ * @return void
+ */
+ public function testAmpInText() {
+ $data = array(
+ 'outer' => array(
+ 'inner' => array('name' => 'mark & mark')
+ )
+ );
+ $obj = Xml::build($data);
+ $result = $obj->asXml();
+ $this->assertContains('mark &amp; mark', $result);
+ }
+
+/**
+ * Test that entity loading is disabled by default.
+ *
+ * @return void
+ */
+ public function testNoEntityLoading() {
+ $file = CAKE . 'VERSION.txt';
+ $xml = <<<XML
+<!DOCTYPE cakephp [
+ <!ENTITY payload SYSTEM "file://$file" >]>
+<request>
+ <xxe>&payload;</xxe>
+</request>
+XML;
+ try {
+ $result = Xml::build($xml);
+ $this->assertEquals('', (string)$result->xxe);
+ } catch (Exception $e) {
+ $this->assertTrue(true, 'A warning was raised meaning external entities were not loaded');
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php
new file mode 100644
index 0000000..f6e04b6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/CacheHelperTest.php
@@ -0,0 +1,650 @@
+<?php
+/**
+ * CacheHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('Model', 'Model');
+App::uses('View', 'View');
+App::uses('CacheHelper', 'View/Helper');
+
+/**
+ * CacheTestController class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class CacheTestController extends Controller {
+
+/**
+ * helpers property
+ *
+ * @var array
+ */
+ public $helpers = array('Html', 'Cache');
+
+/**
+ * cache_parsing method
+ *
+ * @return void
+ */
+ public function cache_parsing() {
+ $this->viewPath = 'Posts';
+ $this->layout = 'cache_layout';
+ $this->set('variable', 'variableValue');
+ $this->set('superman', 'clark kent');
+ $this->set('batman', 'bruce wayne');
+ $this->set('spiderman', 'peter parker');
+ }
+
+}
+
+/**
+ * CacheHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class CacheHelperTest extends CakeTestCase {
+
+/**
+ * Checks if TMP/views is writable, and skips the case if it is not.
+ *
+ * @return void
+ */
+ public function skip() {
+ if (!is_writable(TMP . 'cache' . DS . 'views' . DS)) {
+ $this->markTestSkipped('TMP/views is not writable %s');
+ }
+ }
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $_GET = array();
+ $request = new CakeRequest();
+ $this->Controller = new CacheTestController($request);
+ $View = new View($this->Controller);
+ $this->Cache = new CacheHelper($View);
+ Configure::write('Cache.check', true);
+ Configure::write('Cache.disable', false);
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), App::RESET);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ clearCache();
+ unset($this->Cache);
+ parent::tearDown();
+ }
+
+/**
+ * test cache parsing with no cake:nocache tags in view file.
+ *
+ * @return void
+ */
+ public function testLayoutCacheParsingNoTagsInView() {
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = 21600;
+ $this->Controller->request->here = '/cacheTest/cache_parsing';
+ $this->Controller->request->action = 'cache_parsing';
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+
+ $contents = file_get_contents($filename);
+ $this->assertRegExp('/php echo \$variable/', $contents);
+ $this->assertRegExp('/php echo microtime()/', $contents);
+ $this->assertRegExp('/clark kent/', $result);
+
+ @unlink($filename);
+ }
+
+/**
+ * test cache parsing with non-latin characters in current route
+ *
+ * @return void
+ */
+ public function testCacheNonLatinCharactersInRoute() {
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array('風街ろまん'),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = 21600;
+ $this->Controller->request->here = '/posts/view/風街ろまん';
+ $this->Controller->action = 'view';
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $filename = CACHE . 'views' . DS . 'posts_view_風街ろまん.php';
+ $this->assertTrue(file_exists($filename));
+
+ @unlink($filename);
+ }
+
+/**
+ * Test cache parsing with cake:nocache tags in view file.
+ *
+ * @return void
+ */
+ public function testLayoutCacheParsingWithTagsInView() {
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = 21600;
+ $this->Controller->request->here = '/cacheTest/cache_parsing';
+ $this->Controller->action = 'cache_parsing';
+
+ $View = new View($this->Controller);
+ $result = $View->render('test_nocache_tags');
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+
+ $contents = file_get_contents($filename);
+ $this->assertRegExp('/if \(is_writable\(TMP\)\)\:/', $contents);
+ $this->assertRegExp('/php echo \$variable/', $contents);
+ $this->assertRegExp('/php echo microtime()/', $contents);
+ $this->assertNotRegExp('/cake:nocache/', $contents);
+
+ @unlink($filename);
+ }
+
+/**
+ * test that multiple <!--nocache--> tags function with multiple nocache tags in the layout.
+ *
+ * @return void
+ */
+ public function testMultipleNoCacheTagsInViewfile() {
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = 21600;
+ $this->Controller->request->here = '/cacheTest/cache_parsing';
+ $this->Controller->action = 'cache_parsing';
+
+ $View = new View($this->Controller);
+ $result = $View->render('multiple_nocache');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+
+ $contents = file_get_contents($filename);
+ $this->assertNotRegExp('/cake:nocache/', $contents);
+ @unlink($filename);
+ }
+
+/**
+ * testComplexNoCache method
+ *
+ * @return void
+ */
+ public function testComplexNoCache() {
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_complex',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = array('cache_complex' => 21600);
+ $this->Controller->request->here = '/cacheTest/cache_complex';
+ $this->Controller->action = 'cache_complex';
+ $this->Controller->layout = 'multi_cache';
+ $this->Controller->viewPath = 'Posts';
+
+ $View = new View($this->Controller);
+ $result = $View->render('sequencial_nocache');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+ $this->assertRegExp('/A\. Layout Before Content/', $result);
+ $this->assertRegExp('/B\. In Plain Element/', $result);
+ $this->assertRegExp('/C\. Layout After Test Element/', $result);
+ $this->assertRegExp('/D\. In View File/', $result);
+ $this->assertRegExp('/E\. Layout After Content/', $result);
+ $this->assertRegExp('/F\. In Element With No Cache Tags/', $result);
+ $this->assertRegExp('/G\. Layout After Content And After Element With No Cache Tags/', $result);
+ $this->assertNotRegExp('/1\. layout before content/', $result);
+ $this->assertNotRegExp('/2\. in plain element/', $result);
+ $this->assertNotRegExp('/3\. layout after test element/', $result);
+ $this->assertNotRegExp('/4\. in view file/', $result);
+ $this->assertNotRegExp('/5\. layout after content/', $result);
+ $this->assertNotRegExp('/6\. in element with no cache tags/', $result);
+ $this->assertNotRegExp('/7\. layout after content and after element with no cache tags/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_complex.php';
+ $this->assertTrue(file_exists($filename));
+ $contents = file_get_contents($filename);
+ @unlink($filename);
+
+ $this->assertRegExp('/A\. Layout Before Content/', $contents);
+ $this->assertNotRegExp('/B\. In Plain Element/', $contents);
+ $this->assertRegExp('/C\. Layout After Test Element/', $contents);
+ $this->assertRegExp('/D\. In View File/', $contents);
+ $this->assertRegExp('/E\. Layout After Content/', $contents);
+ $this->assertRegExp('/F\. In Element With No Cache Tags/', $contents);
+ $this->assertRegExp('/G\. Layout After Content And After Element With No Cache Tags/', $contents);
+ $this->assertRegExp('/1\. layout before content/', $contents);
+ $this->assertNotRegExp('/2\. in plain element/', $contents);
+ $this->assertRegExp('/3\. layout after test element/', $contents);
+ $this->assertRegExp('/4\. in view file/', $contents);
+ $this->assertRegExp('/5\. layout after content/', $contents);
+ $this->assertRegExp('/6\. in element with no cache tags/', $contents);
+ $this->assertRegExp('/7\. layout after content and after element with no cache tags/', $contents);
+ }
+
+/**
+ * test cache of view vars
+ *
+ * @return void
+ */
+ public function testCacheViewVars() {
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->request->here = '/cacheTest/cache_parsing';
+ $this->Controller->cacheAction = 21600;
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+
+ $contents = file_get_contents($filename);
+ $this->assertRegExp('/\$this\-\>viewVars/', $contents);
+ $this->assertRegExp('/extract\(\$this\-\>viewVars, EXTR_SKIP\);/', $contents);
+ $this->assertRegExp('/php echo \$variable/', $contents);
+
+ @unlink($filename);
+ }
+
+/**
+ * Test that callback code is generated correctly.
+ *
+ * @return void
+ */
+ public function testCacheCallbacks() {
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = array(
+ 'cache_parsing' => array(
+ 'duration' => 21600,
+ 'callbacks' => true
+ )
+ );
+ $this->Controller->request->here = '/cacheTest/cache_parsing';
+ $this->Controller->cache_parsing();
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+
+ $contents = file_get_contents($filename);
+
+ $this->assertRegExp('/\$controller->startupProcess\(\);/', $contents);
+
+ @unlink($filename);
+ }
+
+/**
+ * test cacheAction set to a boolean
+ *
+ * @return void
+ */
+ public function testCacheActionArray() {
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->request->here = '/cache_test/cache_parsing';
+ $this->Controller->cacheAction = array(
+ 'cache_parsing' => 21600
+ );
+
+ $this->Controller->cache_parsing();
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cache_test_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+ @unlink($filename);
+ }
+
+/**
+ * Test that cacheAction works with camelcased controller names.
+ *
+ * @return void
+ */
+ public function testCacheActionArrayCamelCase() {
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = array(
+ 'cache_parsing' => 21600
+ );
+ $this->Controller->request->here = '/cacheTest/cache_parsing';
+ $this->Controller->cache_parsing();
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+ @unlink($filename);
+ }
+
+/**
+ * test with named and pass args.
+ *
+ * @return void
+ */
+ public function testCacheWithNamedAndPassedArgs() {
+ Router::reload();
+
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(1, 2),
+ 'named' => array(
+ 'name' => 'mark',
+ 'ice' => 'cream'
+ )
+ ));
+ $this->Controller->cacheAction = array(
+ 'cache_parsing' => 21600
+ );
+ $this->Controller->request->here = '/cache_test/cache_parsing/1/2/name:mark/ice:cream';
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cache_test_cache_parsing_1_2_name_mark_ice_cream.php';
+ $this->assertTrue(file_exists($filename));
+ @unlink($filename);
+ }
+
+/**
+ * Test that query string parameters are included in the cache filename.
+ *
+ * @return void
+ */
+ public function testCacheWithQueryStringParams() {
+ Router::reload();
+
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->request->query = array('q' => 'cakephp');
+ $this->Controller->cacheAction = array(
+ 'cache_parsing' => 21600
+ );
+ $this->Controller->request->here = '/cache_test/cache_parsing';
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cache_test_cache_parsing_q_cakephp.php';
+ $this->assertTrue(file_exists($filename), 'Missing cache file ' . $filename);
+ @unlink($filename);
+ }
+
+/**
+ * test that custom routes are respected when generating cache files.
+ *
+ * @return void
+ */
+ public function testCacheWithCustomRoutes() {
+ Router::reload();
+ Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
+
+ $this->Controller->cache_parsing();
+ $this->Controller->request->addParams(array(
+ 'lang' => 'en',
+ 'controller' => 'cache_test',
+ 'action' => 'cache_parsing',
+ 'pass' => array(),
+ 'named' => array()
+ ));
+ $this->Controller->cacheAction = array(
+ 'cache_parsing' => 21600
+ );
+ $this->Controller->request->here = '/en/cache_test/cache_parsing';
+ $this->Controller->action = 'cache_parsing';
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'en_cache_test_cache_parsing.php';
+ $this->assertTrue(file_exists($filename));
+ @unlink($filename);
+ }
+
+/**
+ * test ControllerName contains AppName
+ *
+ * This test verifies view cache is created correctly when the app name is contained in part of the controller name.
+ * (webapp Name) base name is 'cache' controller is 'cacheTest' action is 'cache_name'
+ * apps url would look something like http://localhost/cache/cacheTest/cache_name
+ *
+ * @return void
+ **/
+ public function testCacheBaseNameControllerName() {
+ $this->Controller->cache_parsing();
+ $this->Controller->cacheAction = array(
+ 'cache_name' => 21600
+ );
+ $this->Controller->params = array(
+ 'controller' => 'cacheTest',
+ 'action' => 'cache_name',
+ 'pass' => array(),
+ 'named' => array()
+ );
+ $this->Controller->here = '/cache/cacheTest/cache_name';
+ $this->Controller->action = 'cache_name';
+ $this->Controller->base = '/cache';
+
+ $View = new View($this->Controller);
+ $result = $View->render('index');
+
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+
+ $filename = CACHE . 'views' . DS . 'cache_cachetest_cache_name.php';
+ $this->assertTrue(file_exists($filename));
+ @unlink($filename);
+ }
+
+/**
+ * test that afterRender checks the conditions correctly.
+ *
+ * @return void
+ */
+ public function testAfterRenderConditions() {
+ Configure::write('Cache.check', true);
+ $View = new View($this->Controller);
+ $View->cacheAction = '+1 day';
+ $View->output = 'test';
+
+ $Cache = $this->getMock('CacheHelper', array('_parseContent'), array($View));
+ $Cache->expects($this->once())
+ ->method('_parseContent')
+ ->with('posts/index', 'content')
+ ->will($this->returnValue(''));
+
+ $Cache->afterRenderFile('posts/index', 'content');
+
+ Configure::write('Cache.check', false);
+ $Cache->afterRender('posts/index');
+
+ Configure::write('Cache.check', true);
+ $View->cacheAction = false;
+ $Cache->afterRender('posts/index');
+ }
+
+/**
+ * test that afterRender checks the conditions correctly.
+ *
+ * @return void
+ */
+ public function testAfterLayoutConditions() {
+ Configure::write('Cache.check', true);
+ $View = new View($this->Controller);
+ $View->cacheAction = '+1 day';
+ $View->output = 'test';
+
+ $Cache = $this->getMock('CacheHelper', array('cache'), array($View));
+ $Cache->expects($this->once())
+ ->method('cache')
+ ->with('posts/index', $View->output)
+ ->will($this->returnValue(''));
+
+ $Cache->afterLayout('posts/index');
+
+ Configure::write('Cache.check', false);
+ $Cache->afterLayout('posts/index');
+
+ Configure::write('Cache.check', true);
+ $View->cacheAction = false;
+ $Cache->afterLayout('posts/index');
+ }
+
+/**
+ * testCacheEmptySections method
+ *
+ * This test must be uncommented/fixed in next release (1.2+)
+ *
+ * @return void
+ */
+ public function testCacheEmptySections() {
+ $this->Controller->cache_parsing();
+ $this->Controller->params = array(
+ 'controller' => 'cacheTest',
+ 'action' => 'cache_empty_sections',
+ 'pass' => array(),
+ 'named' => array()
+ );
+ $this->Controller->cacheAction = array('cache_empty_sections' => 21600);
+ $this->Controller->here = '/cacheTest/cache_empty_sections';
+ $this->Controller->action = 'cache_empty_sections';
+ $this->Controller->layout = 'cache_empty_sections';
+ $this->Controller->viewPath = 'Posts';
+
+ $View = new View($this->Controller);
+ $result = $View->render('cache_empty_sections');
+ $this->assertNotRegExp('/nocache/', $result);
+ $this->assertNotRegExp('/php echo/', $result);
+ $this->assertRegExp(
+ '@</title>\s*</head>\s*' .
+ '<body>\s*' .
+ 'View Content\s*' .
+ 'cached count is: 3\s*' .
+ '</body>@', $result);
+
+ $filename = CACHE . 'views' . DS . 'cachetest_cache_empty_sections.php';
+ $this->assertTrue(file_exists($filename));
+ $contents = file_get_contents($filename);
+ $this->assertNotRegExp('/nocache/', $contents);
+ $this->assertRegExp(
+ '@<head>\s*<title>Posts</title>\s*' .
+ '<\?php \$x \= 1; \?>\s*' .
+ '</head>\s*' .
+ '<body>\s*' .
+ '<\?php \$x\+\+; \?>\s*' .
+ '<\?php \$x\+\+; \?>\s*' .
+ 'View Content\s*' .
+ '<\?php \$y = 1; \?>\s*' .
+ '<\?php echo \'cached count is: \' . \$x; \?>\s*' .
+ '@', $contents);
+ @unlink($filename);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/FormHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/FormHelperTest.php
new file mode 100644
index 0000000..e523024
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/FormHelperTest.php
@@ -0,0 +1,8004 @@
+<?php
+/**
+ * FormHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ClassRegistry', 'Utility');
+App::uses('Controller', 'Controller');
+App::uses('View', 'View');
+App::uses('Model', 'Model');
+App::uses('Security', 'Utility');
+App::uses('CakeRequest', 'Network');
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('FormHelper', 'View/Helper');
+App::uses('Router', 'Routing');
+
+/**
+ * ContactTestController class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class ContactTestController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'ContactTest'
+ */
+ public $name = 'ContactTest';
+
+/**
+ * uses property
+ *
+ * @var mixed null
+ */
+ public $uses = null;
+}
+
+/**
+ * Contact class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class Contact extends CakeTestModel {
+
+/**
+ * primaryKey property
+ *
+ * @var string 'id'
+ */
+ public $primaryKey = 'id';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'Contact'
+ */
+ public $name = 'Contact';
+
+/**
+ * Default schema
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'phone' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'password' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null),
+ 'age' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => null)
+ );
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array(
+ 'non_existing' => array(),
+ 'idontexist' => array(),
+ 'imrequired' => array('rule' => array('between', 5, 30), 'allowEmpty' => false),
+ 'imrequiredonupdate' => array('notEmpty' => array('rule' => 'alphaNumeric', 'on' => 'update')),
+ 'imrequiredoncreate' => array('required' => array('rule' => 'alphaNumeric', 'on' => 'create')),
+ 'imrequiredonboth' => array(
+ 'required' => array('rule' => 'alphaNumeric', 'allowEmpty' => true),
+ 'check' => array('rule' => 'alphaNumeric')
+ ),
+ 'string_required' => 'notEmpty',
+ 'imalsorequired' => array('rule' => 'alphaNumeric', 'allowEmpty' => false),
+ 'imrequiredtoo' => array('rule' => 'notEmpty'),
+ 'required_one' => array('required' => array('rule' => array('notEmpty'))),
+ 'imnotrequired' => array('required' => false, 'rule' => 'alphaNumeric', 'allowEmpty' => true),
+ 'imalsonotrequired' => array(
+ 'alpha' => array('rule' => 'alphaNumeric', 'allowEmpty' => true),
+ 'between' => array('rule' => array('between', 5, 30), 'allowEmpty' => true),
+ ),
+ 'imnotrequiredeither' => array('required' => true, 'rule' => array('between', 5, 30), 'allowEmpty' => true),
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function setSchema($schema) {
+ $this->_schema = $schema;
+ }
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('ContactTag' => array('with' => 'ContactTagsContact'));
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $belongsTo = array('User' => array('className' => 'UserForm'));
+}
+
+/**
+ * ContactTagsContact class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class ContactTagsContact extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'Contact'
+ */
+ public $name = 'ContactTagsContact';
+
+/**
+ * Default schema
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'contact_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'contact_tag_id' => array(
+ 'type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'
+ )
+ );
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function setSchema($schema) {
+ $this->_schema = $schema;
+ }
+
+}
+
+/**
+ * ContactNonStandardPk class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class ContactNonStandardPk extends Contact {
+
+/**
+ * primaryKey property
+ *
+ * @var string 'pk'
+ */
+ public $primaryKey = 'pk';
+
+/**
+ * name property
+ *
+ * @var string 'ContactNonStandardPk'
+ */
+ public $name = 'ContactNonStandardPk';
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ $this->_schema = parent::schema();
+ $this->_schema['pk'] = $this->_schema['id'];
+ unset($this->_schema['id']);
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * ContactTag class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class ContactTag extends Model {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema definition
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => true, 'default' => '', 'length' => ''),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null)
+ );
+}
+
+/**
+ * UserForm class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class UserForm extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * primaryKey property
+ *
+ * @var string 'id'
+ */
+ public $primaryKey = 'id';
+
+/**
+ * name property
+ *
+ * @var string 'UserForm'
+ */
+ public $name = 'UserForm';
+
+/**
+ * hasMany property
+ *
+ * @var array
+ */
+ public $hasMany = array(
+ 'OpenidUrl' => array('className' => 'OpenidUrl', 'foreignKey' => 'user_form_id'
+ ));
+
+/**
+ * schema definition
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
+ 'other' => array('type' => 'text', 'null' => true, 'default' => null, 'length' => null),
+ 'stuff' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 10),
+ 'something' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 255),
+ 'active' => array('type' => 'boolean', 'null' => false, 'default' => false),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+}
+
+/**
+ * OpenidUrl class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class OpenidUrl extends CakeTestModel {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * primaryKey property
+ *
+ * @var string 'id'
+ */
+ public $primaryKey = 'id';
+
+/**
+ * name property
+ *
+ * @var string 'OpenidUrl'
+ */
+ public $name = 'OpenidUrl';
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('UserForm' => array(
+ 'className' => 'UserForm', 'foreignKey' => 'user_form_id'
+ ));
+
+/**
+ * validate property
+ *
+ * @var array
+ */
+ public $validate = array('openid_not_registered' => array());
+
+/**
+ * schema method
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'user_form_id' => array(
+ 'type' => 'user_form_id', 'null' => '', 'default' => '', 'length' => '8'
+ ),
+ 'url' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ );
+
+/**
+ * beforeValidate method
+ *
+ * @return void
+ */
+ public function beforeValidate($options = array()) {
+ $this->invalidate('openid_not_registered');
+ return true;
+ }
+
+}
+
+/**
+ * ValidateUser class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class ValidateUser extends CakeTestModel {
+
+/**
+ * primaryKey property
+ *
+ * @var string 'id'
+ */
+ public $primaryKey = 'id';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'ValidateUser'
+ */
+ public $name = 'ValidateUser';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('ValidateProfile' => array(
+ 'className' => 'ValidateProfile', 'foreignKey' => 'user_id'
+ ));
+
+/**
+ * schema method
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'balance' => array('type' => 'float', 'null' => false, 'length' => '5,2'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+
+/**
+ * beforeValidate method
+ *
+ * @return void
+ */
+ public function beforeValidate($options = array()) {
+ $this->invalidate('email');
+ return false;
+ }
+
+}
+
+/**
+ * ValidateProfile class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class ValidateProfile extends CakeTestModel {
+
+/**
+ * primaryKey property
+ *
+ * @var string 'id'
+ */
+ public $primaryKey = 'id';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'user_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'full_name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'city' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+
+/**
+ * name property
+ *
+ * @var string 'ValidateProfile'
+ */
+ public $name = 'ValidateProfile';
+
+/**
+ * hasOne property
+ *
+ * @var array
+ */
+ public $hasOne = array('ValidateItem' => array(
+ 'className' => 'ValidateItem', 'foreignKey' => 'profile_id'
+ ));
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('ValidateUser' => array(
+ 'className' => 'ValidateUser', 'foreignKey' => 'user_id'
+ ));
+
+/**
+ * beforeValidate method
+ *
+ * @return void
+ */
+ public function beforeValidate($options = array()) {
+ $this->invalidate('full_name');
+ $this->invalidate('city');
+ return false;
+ }
+
+}
+
+/**
+ * ValidateItem class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class ValidateItem extends CakeTestModel {
+
+/**
+ * primaryKey property
+ *
+ * @var string 'id'
+ */
+ public $primaryKey = 'id';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'ValidateItem'
+ */
+ public $name = 'ValidateItem';
+
+/**
+ * schema property
+ *
+ * @var array
+ */
+ protected $_schema = array(
+ 'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'profile_id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'text', 'null' => '', 'default' => '', 'length' => '255'),
+ 'description' => array(
+ 'type' => 'string', 'null' => '', 'default' => '', 'length' => '255'
+ ),
+ 'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
+ 'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
+ );
+
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('ValidateProfile' => array('foreignKey' => 'profile_id'));
+
+/**
+ * beforeValidate method
+ *
+ * @return void
+ */
+ public function beforeValidate($options = array()) {
+ $this->invalidate('description');
+ return false;
+ }
+
+}
+
+/**
+ * TestMail class
+ *
+ * @package cake
+ * @package Cake.Test.Case.View.Helper
+ */
+class TestMail extends CakeTestModel {
+
+/**
+ * primaryKey property
+ *
+ * @var string 'id'
+ */
+ public $primaryKey = 'id';
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * name property
+ *
+ * @var string 'TestMail'
+ */
+ public $name = 'TestMail';
+}
+
+/**
+ * FormHelperTest class
+ *
+ * @package cake
+ * @subpackage Cake.Test.Case.View.Helper
+ * @property FormHelper $Form
+ */
+class FormHelperTest extends CakeTestCase {
+
+/**
+ * Fixtures to be used
+ *
+ * @var array
+ */
+ public $fixtures = array('core.post');
+
+/**
+ * Do not load the fixtures by default
+ *
+ * @var boolean
+ */
+ public $autoFixtures = false;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ Configure::write('App.base', '');
+ $this->Controller = new ContactTestController();
+ $this->View = new View($this->Controller);
+
+ $this->Form = new FormHelper($this->View);
+ $this->Form->Html = new HtmlHelper($this->View);
+ $this->Form->request = new CakeRequest('contacts/add', false);
+ $this->Form->request->here = '/contacts/add';
+ $this->Form->request['action'] = 'add';
+ $this->Form->request->webroot = '';
+ $this->Form->request->base = '';
+
+ ClassRegistry::addObject('Contact', new Contact());
+ ClassRegistry::addObject('ContactNonStandardPk', new ContactNonStandardPk());
+ ClassRegistry::addObject('OpenidUrl', new OpenidUrl());
+ ClassRegistry::addObject('User', new UserForm());
+ ClassRegistry::addObject('ValidateItem', new ValidateItem());
+ ClassRegistry::addObject('ValidateUser', new ValidateUser());
+ ClassRegistry::addObject('ValidateProfile', new ValidateProfile());
+
+ $this->oldSalt = Configure::read('Security.salt');
+
+ $this->dateRegex = array(
+ 'daysRegex' => 'preg:/(?:<option value="0?([\d]+)">\\1<\/option>[\r\n]*)*/',
+ 'monthsRegex' => 'preg:/(?:<option value="[\d]+">[\w]+<\/option>[\r\n]*)*/',
+ 'yearsRegex' => 'preg:/(?:<option value="([\d]+)">\\1<\/option>[\r\n]*)*/',
+ 'hoursRegex' => 'preg:/(?:<option value="0?([\d]+)">\\1<\/option>[\r\n]*)*/',
+ 'minutesRegex' => 'preg:/(?:<option value="([\d]+)">0?\\1<\/option>[\r\n]*)*/',
+ 'meridianRegex' => 'preg:/(?:<option value="(am|pm)">\\1<\/option>[\r\n]*)*/',
+ );
+
+ Configure::write('Security.salt', 'foo!');
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Form->Html, $this->Form, $this->Controller, $this->View);
+ Configure::write('Security.salt', $this->oldSalt);
+ }
+
+/**
+ * testFormCreateWithSecurity method
+ *
+ * Test form->create() with security key.
+ *
+ * @return void
+ */
+ public function testCreateWithSecurity() {
+ $this->Form->request['_Token'] = array('key' => 'testKey');
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $result = $this->Form->create('Contact', array('url' => '/contacts/add'));
+ $expected = array(
+ 'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testKey', 'id'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('Contact', array('url' => '/contacts/add', 'id' => 'MyForm'));
+ $expected['form']['id'] = 'MyForm';
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that create() clears the fields property so it starts fresh
+ *
+ * @return void
+ */
+ public function testCreateClearingFields() {
+ $this->Form->fields = array('model_id');
+ $this->Form->create('Contact');
+ $this->assertEquals(array(), $this->Form->fields);
+ }
+
+/**
+ * Tests form hash generation with model-less data
+ *
+ * @return void
+ */
+ public function testValidateHashNoModel() {
+ $this->Form->request['_Token'] = array('key' => 'foo');
+ $result = $this->Form->secure(array('anything'));
+ $this->assertRegExp('/540ac9c60d323c22bafe997b72c0790f39a8bdef/', $result);
+ }
+
+/**
+ * Tests that models with identical field names get resolved properly
+ *
+ * @return void
+ */
+ public function testDuplicateFieldNameResolution() {
+ $result = $this->Form->create('ValidateUser');
+ $this->assertEquals(array('ValidateUser'), $this->Form->entity());
+
+ $result = $this->Form->input('ValidateItem.name');
+ $this->assertEquals(array('ValidateItem', 'name'), $this->Form->entity());
+
+ $result = $this->Form->input('ValidateUser.name');
+ $this->assertEquals(array('ValidateUser', 'name'), $this->Form->entity());
+ $this->assertRegExp('/name="data\[ValidateUser\]\[name\]"/', $result);
+ $this->assertRegExp('/type="text"/', $result);
+
+ $result = $this->Form->input('ValidateItem.name');
+ $this->assertEquals(array('ValidateItem', 'name'), $this->Form->entity());
+ $this->assertRegExp('/name="data\[ValidateItem\]\[name\]"/', $result);
+ $this->assertRegExp('/<textarea/', $result);
+
+ $result = $this->Form->input('name');
+ $this->assertEquals(array('ValidateUser', 'name'), $this->Form->entity());
+ $this->assertRegExp('/name="data\[ValidateUser\]\[name\]"/', $result);
+ $this->assertRegExp('/type="text"/', $result);
+ }
+
+/**
+ * Tests that hidden fields generated for checkboxes don't get locked
+ *
+ * @return void
+ */
+ public function testNoCheckboxLocking() {
+ $this->Form->request['_Token'] = array('key' => 'foo');
+ $this->assertSame(array(), $this->Form->fields);
+
+ $this->Form->checkbox('check', array('value' => '1'));
+ $this->assertSame($this->Form->fields, array('check'));
+ }
+
+/**
+ * testFormSecurityFields method
+ *
+ * Test generation of secure form hash generation.
+ *
+ * @return void
+ */
+ public function testFormSecurityFields() {
+ $key = 'testKey';
+ $fields = array('Model.password', 'Model.username', 'Model.valid' => '0');
+
+ $this->Form->request['_Token'] = array('key' => $key);
+ $result = $this->Form->secure($fields);
+
+ $expected = Security::hash(serialize($fields) . Configure::read('Security.salt'));
+ $expected .= ':' . 'Model.valid';
+
+ $expected = array(
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][fields]',
+ 'value' => urlencode($expected), 'id' => 'preg:/TokenFields\d+/'
+ )),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
+ 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Tests correct generation of number fields for double and float fields
+ *
+ * @return void
+ */
+ public function testTextFieldGenerationForFloats() {
+ $model = ClassRegistry::getObject('Contact');
+ $model->setSchema(array('foo' => array(
+ 'type' => 'float',
+ 'null' => false,
+ 'default' => null,
+ 'length' => null
+ )));
+
+ $this->Form->create('Contact');
+ $result = $this->Form->input('foo');
+ $expected = array(
+ 'div' => array('class' => 'input number'),
+ 'label' => array('for' => 'ContactFoo'),
+ 'Foo',
+ '/label',
+ array('input' => array(
+ 'type' => 'number',
+ 'name' => 'data[Contact][foo]',
+ 'id' => 'ContactFoo',
+ 'step' => 'any'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('foo', array('step' => 0.5));
+ $expected = array(
+ 'div' => array('class' => 'input number'),
+ 'label' => array('for' => 'ContactFoo'),
+ 'Foo',
+ '/label',
+ array('input' => array(
+ 'type' => 'number',
+ 'name' => 'data[Contact][foo]',
+ 'id' => 'ContactFoo',
+ 'step' => '0.5'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Tests correct generation of number fields for integer fields
+ *
+ * @access public
+ * @return void
+ */
+ public function testTextFieldTypeNumberGenerationForIntegers() {
+ $model = ClassRegistry::getObject('Contact');
+ $model->setSchema(array('foo' => array(
+ 'type' => 'integer',
+ 'null' => false,
+ 'default' => null,
+ 'length' => null
+ )));
+
+ $this->Form->create('Contact');
+ $result = $this->Form->input('foo');
+ $expected = array(
+ 'div' => array('class' => 'input number'),
+ 'label' => array('for' => 'ContactFoo'),
+ 'Foo',
+ '/label',
+ array('input' => array(
+ 'type' => 'number', 'name' => 'data[Contact][foo]',
+ 'id' => 'ContactFoo'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormSecurityMultipleFields method
+ *
+ * Test secure() with multiple row form. Ensure hash is correct.
+ *
+ * @return void
+ */
+ public function testFormSecurityMultipleFields() {
+ $key = 'testKey';
+
+ $fields = array(
+ 'Model.0.password', 'Model.0.username', 'Model.0.hidden' => 'value',
+ 'Model.0.valid' => '0', 'Model.1.password', 'Model.1.username',
+ 'Model.1.hidden' => 'value', 'Model.1.valid' => '0'
+ );
+ $this->Form->request['_Token'] = array('key' => $key);
+ $result = $this->Form->secure($fields);
+
+ $hash = '51e3b55a6edd82020b3f29c9ae200e14bbeb7ee5%3AModel.0.hidden%7CModel.0.valid';
+ $hash .= '%7CModel.1.hidden%7CModel.1.valid';
+
+ $expected = array(
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][fields]',
+ 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
+ )),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
+ 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormSecurityMultipleSubmitButtons
+ *
+ * test form submit generation and ensure that _Token is only created on end()
+ *
+ * @return void
+ */
+ public function testFormSecurityMultipleSubmitButtons() {
+ $key = 'testKey';
+ $this->Form->request['_Token'] = array('key' => $key);
+
+ $this->Form->create('Addresses');
+ $this->Form->input('Address.title');
+ $this->Form->input('Address.first_name');
+
+ $result = $this->Form->submit('Save', array('name' => 'save'));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'name' => 'save', 'value' => 'Save'),
+ '/div',
+ );
+ $this->assertTags($result, $expected);
+ $result = $this->Form->submit('Cancel', array('name' => 'cancel'));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'name' => 'cancel', 'value' => 'Cancel'),
+ '/div',
+ );
+ $this->assertTags($result, $expected);
+ $result = $this->Form->end(null);
+
+ $expected = array(
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][fields]',
+ 'value' => 'preg:/.+/', 'id' => 'preg:/TokenFields\d+/'
+ )),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
+ 'value' => 'cancel%7Csave', 'id' => 'preg:/TokenUnlocked\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test that buttons created with foo[bar] name attributes are unlocked correctly.
+ *
+ * @return void
+ */
+ public function testSecurityButtonNestedNamed() {
+ $key = 'testKey';
+ $this->Form->request['_Token'] = array('key' => $key);
+
+ $this->Form->create('Addresses');
+ $this->Form->button('Test', array('type' => 'submit', 'name' => 'Address[button]'));
+ $result = $this->Form->unlockField();
+ $this->assertEquals(array('Address.button'), $result);
+ }
+
+/**
+ * Test that submit inputs created with foo[bar] name attributes are unlocked correctly.
+ *
+ * @return void
+ */
+ public function testSecuritySubmitNestedNamed() {
+ $key = 'testKey';
+ $this->Form->request['_Token'] = array('key' => $key);
+
+ $this->Form->create('Addresses');
+ $this->Form->submit('Test', array('type' => 'submit', 'name' => 'Address[button]'));
+ $result = $this->Form->unlockField();
+ $this->assertEquals(array('Address.button'), $result);
+ }
+
+/**
+ * Test that the correct fields are unlocked for image submits with no names.
+ *
+ * @return void
+ */
+ public function testSecuritySubmitImageNoName() {
+ $key = 'testKey';
+ $this->Form->request['_Token'] = array('key' => $key);
+
+ $this->Form->create('User');
+ $result = $this->Form->submit('save.png');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'image', 'src' => 'img/save.png'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ $this->assertEquals(array('x', 'y'), $this->Form->unlockField());
+ }
+
+/**
+ * Test that the correct fields are unlocked for image submits with names.
+ *
+ * @return void
+ */
+ public function testSecuritySubmitImageName() {
+ $key = 'testKey';
+ $this->Form->request['_Token'] = array('key' => $key);
+
+ $this->Form->create('User');
+ $result = $this->Form->submit('save.png', array('name' => 'test'));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'image', 'name' => 'test', 'src' => 'img/save.png'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ $this->assertEquals(array('test', 'test_x', 'test_y'), $this->Form->unlockField());
+ }
+
+/**
+ * testFormSecurityMultipleInputFields method
+ *
+ * Test secure form creation with multiple row creation. Checks hidden, text, checkbox field types
+ *
+ * @return void
+ */
+ public function testFormSecurityMultipleInputFields() {
+ $key = 'testKey';
+
+ $this->Form->request['_Token'] = array('key' => $key);
+ $this->Form->create('Addresses');
+
+ $this->Form->hidden('Addresses.0.id', array('value' => '123456'));
+ $this->Form->input('Addresses.0.title');
+ $this->Form->input('Addresses.0.first_name');
+ $this->Form->input('Addresses.0.last_name');
+ $this->Form->input('Addresses.0.address');
+ $this->Form->input('Addresses.0.city');
+ $this->Form->input('Addresses.0.phone');
+ $this->Form->input('Addresses.0.primary', array('type' => 'checkbox'));
+
+ $this->Form->hidden('Addresses.1.id', array('value' => '654321'));
+ $this->Form->input('Addresses.1.title');
+ $this->Form->input('Addresses.1.first_name');
+ $this->Form->input('Addresses.1.last_name');
+ $this->Form->input('Addresses.1.address');
+ $this->Form->input('Addresses.1.city');
+ $this->Form->input('Addresses.1.phone');
+ $this->Form->input('Addresses.1.primary', array('type' => 'checkbox'));
+
+ $result = $this->Form->secure($this->Form->fields);
+
+ $hash = 'c9118120e680a7201b543f562e5301006ccfcbe2%3AAddresses.0.id%7CAddresses.1.id';
+
+ $expected = array(
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][fields]',
+ 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
+ )),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
+ 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test form security with Model.field.0 style inputs
+ *
+ * @return void
+ */
+ public function testFormSecurityArrayFields() {
+ $key = 'testKey';
+
+ $this->Form->request->params['_Token']['key'] = $key;
+ $this->Form->create('Address');
+ $this->Form->input('Address.primary.1');
+ $this->assertEquals('Address.primary', $this->Form->fields[0]);
+
+ $this->Form->input('Address.secondary.1.0');
+ $this->assertEquals('Address.secondary', $this->Form->fields[1]);
+ }
+
+/**
+ * testFormSecurityMultipleInputDisabledFields method
+ *
+ * test secure form generation with multiple records and disabled fields.
+ *
+ * @return void
+ */
+ public function testFormSecurityMultipleInputDisabledFields() {
+ $key = 'testKey';
+ $this->Form->request->params['_Token'] = array(
+ 'key' => $key,
+ 'unlockedFields' => array('first_name', 'address')
+ );
+ $this->Form->create();
+
+ $this->Form->hidden('Addresses.0.id', array('value' => '123456'));
+ $this->Form->input('Addresses.0.title');
+ $this->Form->input('Addresses.0.first_name');
+ $this->Form->input('Addresses.0.last_name');
+ $this->Form->input('Addresses.0.address');
+ $this->Form->input('Addresses.0.city');
+ $this->Form->input('Addresses.0.phone');
+ $this->Form->hidden('Addresses.1.id', array('value' => '654321'));
+ $this->Form->input('Addresses.1.title');
+ $this->Form->input('Addresses.1.first_name');
+ $this->Form->input('Addresses.1.last_name');
+ $this->Form->input('Addresses.1.address');
+ $this->Form->input('Addresses.1.city');
+ $this->Form->input('Addresses.1.phone');
+
+ $result = $this->Form->secure($this->Form->fields);
+ $hash = '629b6536dcece48aa41a117045628ce602ccbbb2%3AAddresses.0.id%7CAddresses.1.id';
+
+ $expected = array(
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][fields]',
+ 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
+ )),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
+ 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormSecurityInputDisabledFields method
+ *
+ * Test single record form with disabled fields.
+ *
+ * @return void
+ */
+ public function testFormSecurityInputUnlockedFields() {
+ $key = 'testKey';
+ $this->Form->request['_Token'] = array(
+ 'key' => $key,
+ 'unlockedFields' => array('first_name', 'address')
+ );
+ $this->Form->create();
+ $this->assertEquals($this->Form->request['_Token']['unlockedFields'], $this->Form->unlockField());
+
+ $this->Form->hidden('Addresses.id', array('value' => '123456'));
+ $this->Form->input('Addresses.title');
+ $this->Form->input('Addresses.first_name');
+ $this->Form->input('Addresses.last_name');
+ $this->Form->input('Addresses.address');
+ $this->Form->input('Addresses.city');
+ $this->Form->input('Addresses.phone');
+
+ $result = $this->Form->fields;
+ $expected = array(
+ 'Addresses.id' => '123456', 'Addresses.title', 'Addresses.last_name',
+ 'Addresses.city', 'Addresses.phone'
+ );
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Form->secure($expected);
+
+ $hash = '2981c38990f3f6ba935e6561dc77277966fabd6d%3AAddresses.id';
+ $expected = array(
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][fields]',
+ 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
+ )),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
+ 'value' => 'address%7Cfirst_name', 'id' => 'preg:/TokenUnlocked\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test securing inputs with custom name attributes.
+ *
+ * @return void
+ */
+ public function testFormSecureWithCustomNameAttribute() {
+ $this->Form->request->params['_Token']['key'] = 'testKey';
+
+ $this->Form->text('UserForm.published', array('name' => 'data[User][custom]'));
+ $this->assertEquals('User.custom', $this->Form->fields[0]);
+
+ $this->Form->text('UserForm.published', array('name' => 'data[User][custom][another][value]'));
+ $this->assertEquals('User.custom.another.value', $this->Form->fields[1]);
+ }
+
+/**
+ * testFormSecuredInput method
+ *
+ * Test generation of entire secure form, assertions made on input() output.
+ *
+ * @return void
+ */
+ public function testFormSecuredInput() {
+ $this->Form->request['_Token'] = array('key' => 'testKey');
+
+ $result = $this->Form->create('Contact', array('url' => '/contacts/add'));
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $expected = array(
+ 'form' => array('method' => 'post', 'action' => '/contacts/add', 'accept-charset' => $encoding, 'id' => 'ContactAddForm'),
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][key]',
+ 'value' => 'testKey', 'id' => 'preg:/Token\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('UserForm.published', array('type' => 'text'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'UserFormPublished'),
+ 'Published',
+ '/label',
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[UserForm][published]',
+ 'id' => 'UserFormPublished'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('UserForm.other', array('type' => 'text'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'UserFormOther'),
+ 'Other',
+ '/label',
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[UserForm][other]',
+ 'id' => 'UserFormOther'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->hidden('UserForm.stuff');
+ $expected = array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[UserForm][stuff]',
+ 'id' => 'UserFormStuff'
+ ));
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->hidden('UserForm.hidden', array('value' => '0'));
+ $expected = array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[UserForm][hidden]',
+ 'value' => '0', 'id' => 'UserFormHidden'
+ ));
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('UserForm.something', array('type' => 'checkbox'));
+ $expected = array(
+ 'div' => array('class' => 'input checkbox'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[UserForm][something]',
+ 'value' => '0', 'id' => 'UserFormSomething_'
+ )),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[UserForm][something]',
+ 'value' => '1', 'id' => 'UserFormSomething'
+ )),
+ 'label' => array('for' => 'UserFormSomething'),
+ 'Something',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->fields;
+ $expected = array(
+ 'UserForm.published', 'UserForm.other', 'UserForm.stuff' => '',
+ 'UserForm.hidden' => '0', 'UserForm.something'
+ );
+ $this->assertEquals($expected, $result);
+
+ $hash = 'bd7c4a654e5361f9a433a43f488ff9a1065d0aaf%3AUserForm.hidden%7CUserForm.stuff';
+
+ $result = $this->Form->secure($this->Form->fields);
+ $expected = array(
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][fields]',
+ 'value' => $hash, 'id' => 'preg:/TokenFields\d+/'
+ )),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[_Token][unlocked]',
+ 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Tests that the correct keys are added to the field hash index
+ *
+ * @return void
+ */
+ public function testFormSecuredFileInput() {
+ $this->Form->request['_Token'] = array('key' => 'testKey');
+ $this->assertEquals(array(), $this->Form->fields);
+
+ $result = $this->Form->file('Attachment.file');
+ $expected = array(
+ 'Attachment.file.name', 'Attachment.file.type', 'Attachment.file.tmp_name',
+ 'Attachment.file.error', 'Attachment.file.size'
+ );
+ $this->assertEquals($expected, $this->Form->fields);
+ }
+
+/**
+ * test that multiple selects keys are added to field hash
+ *
+ * @return void
+ */
+ public function testFormSecuredMultipleSelect() {
+ $this->Form->request['_Token'] = array('key' => 'testKey');
+ $this->assertEquals(array(), $this->Form->fields);
+ $options = array('1' => 'one', '2' => 'two');
+
+ $this->Form->select('Model.select', $options);
+ $expected = array('Model.select');
+ $this->assertEquals($expected, $this->Form->fields);
+
+ $this->Form->fields = array();
+ $this->Form->select('Model.select', $options, array('multiple' => true));
+ $this->assertEquals($expected, $this->Form->fields);
+ }
+
+/**
+ * testFormSecuredRadio method
+ *
+ * @return void
+ */
+ public function testFormSecuredRadio() {
+ $this->Form->request['_Token'] = array('key' => 'testKey');
+ $this->assertEquals(array(), $this->Form->fields);
+ $options = array('1' => 'option1', '2' => 'option2');
+
+ $this->Form->radio('Test.test', $options);
+ $expected = array('Test.test');
+ $this->assertEquals($expected, $this->Form->fields);
+ }
+
+/**
+ * test that forms with disabled inputs + secured forms leave off the inputs from the form
+ * hashing.
+ *
+ * @return void
+ */
+ public function testFormSecuredAndDisabled() {
+ $this->Form->request['_Token'] = array('key' => 'testKey');
+
+ $this->Form->checkbox('Model.checkbox', array('disabled' => true));
+ $this->Form->text('Model.text', array('disabled' => true));
+ $this->Form->password('Model.text', array('disabled' => true));
+ $this->Form->textarea('Model.textarea', array('disabled' => true));
+ $this->Form->select('Model.select', array(1, 2), array('disabled' => true));
+ $this->Form->radio('Model.radio', array(1, 2), array('disabled' => array(1, 2)));
+ $this->Form->year('Model.year', null, null, array('disabled' => true));
+ $this->Form->month('Model.month', array('disabled' => true));
+ $this->Form->day('Model.day', array('disabled' => true));
+ $this->Form->hour('Model.hour', false, array('disabled' => true));
+ $this->Form->minute('Model.minute', array('disabled' => true));
+ $this->Form->meridian('Model.meridian', array('disabled' => true));
+
+ $expected = array(
+ 'Model.radio' => ''
+ );
+ $this->assertEquals($expected, $this->Form->fields);
+ }
+
+/**
+ * testDisableSecurityUsingForm method
+ *
+ * @return void
+ */
+ public function testDisableSecurityUsingForm() {
+ $this->Form->request['_Token'] = array(
+ 'key' => 'testKey',
+ 'disabledFields' => array()
+ );
+ $this->Form->create();
+
+ $this->Form->hidden('Addresses.id', array('value' => '123456'));
+ $this->Form->input('Addresses.title');
+ $this->Form->input('Addresses.first_name', array('secure' => false));
+ $this->Form->input('Addresses.city', array('type' => 'textarea', 'secure' => false));
+ $this->Form->input('Addresses.zip', array(
+ 'type' => 'select', 'options' => array(1,2), 'secure' => false
+ ));
+
+ $result = $this->Form->fields;
+ $expected = array(
+ 'Addresses.id' => '123456', 'Addresses.title',
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test disableField
+ *
+ * @return void
+ */
+ public function testUnlockFieldAddsToList() {
+ $this->Form->request['_Token'] = array(
+ 'key' => 'testKey',
+ 'unlockedFields' => array()
+ );
+ $this->Form->create('Contact');
+ $this->Form->unlockField('Contact.name');
+ $this->Form->text('Contact.name');
+
+ $this->assertEquals(array('Contact.name'), $this->Form->unlockField());
+ $this->assertEquals(array(), $this->Form->fields);
+ }
+
+/**
+ * test unlockField removing from fields array.
+ *
+ * @return void
+ */
+ public function testUnlockFieldRemovingFromFields() {
+ $this->Form->request['_Token'] = array(
+ 'key' => 'testKey',
+ 'unlockedFields' => array()
+ );
+ $this->Form->create('Contact');
+ $this->Form->hidden('Contact.id', array('value' => 1));
+ $this->Form->text('Contact.name');
+
+ $this->assertEquals(1, $this->Form->fields['Contact.id'], 'Hidden input should be secured.');
+ $this->assertTrue(in_array('Contact.name', $this->Form->fields), 'Field should be secured.');
+
+ $this->Form->unlockField('Contact.name');
+ $this->Form->unlockField('Contact.id');
+ $this->assertEquals(array(), $this->Form->fields);
+ }
+
+/**
+ * testTagIsInvalid method
+ *
+ * @return void
+ */
+ public function testTagIsInvalid() {
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors[0]['email'] = array('Please provide an email');
+
+ $this->Form->setEntity('Contact.0.email');
+ $result = $this->Form->tagIsInvalid();
+ $expected = array('Please provide an email');
+ $this->assertEquals($expected, $result);
+
+ $this->Form->setEntity('Contact.1.email');
+ $result = $this->Form->tagIsInvalid();
+ $expected = false;
+ $this->assertSame($expected, $result);
+
+ $this->Form->setEntity('Contact.0.name');
+ $result = $this->Form->tagIsInvalid();
+ $expected = false;
+ $this->assertSame($expected, $result);
+ }
+
+/**
+ * testPasswordValidation method
+ *
+ * test validation errors on password input.
+ *
+ * @return void
+ */
+ public function testPasswordValidation() {
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors['password'] = array('Please provide a password');
+
+ $result = $this->Form->input('Contact.password');
+ $expected = array(
+ 'div' => array('class' => 'input password error'),
+ 'label' => array('for' => 'ContactPassword'),
+ 'Password',
+ '/label',
+ 'input' => array(
+ 'type' => 'password', 'name' => 'data[Contact][password]',
+ 'id' => 'ContactPassword', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error-message')),
+ 'Please provide a password',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testEmptyErrorValidation method
+ *
+ * test validation error div when validation message is an empty string
+ *
+ * @access public
+ * @return void
+ */
+ public function testEmptyErrorValidation() {
+ $this->Form->validationErrors['Contact']['password'] = '';
+ $result = $this->Form->input('Contact.password');
+ $expected = array(
+ 'div' => array('class' => 'input password error'),
+ 'label' => array('for' => 'ContactPassword'),
+ 'Password',
+ '/label',
+ 'input' => array(
+ 'type' => 'password', 'name' => 'data[Contact][password]',
+ 'id' => 'ContactPassword', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error-message')),
+ array(),
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testEmptyInputErrorValidation method
+ *
+ * test validation error div when validation message is overridden by an empty string when calling input()
+ *
+ * @access public
+ * @return void
+ */
+ public function testEmptyInputErrorValidation() {
+ $this->Form->validationErrors['Contact']['password'] = 'Please provide a password';
+ $result = $this->Form->input('Contact.password', array('error' => ''));
+ $expected = array(
+ 'div' => array('class' => 'input password error'),
+ 'label' => array('for' => 'ContactPassword'),
+ 'Password',
+ '/label',
+ 'input' => array(
+ 'type' => 'password', 'name' => 'data[Contact][password]',
+ 'id' => 'ContactPassword', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error-message')),
+ array(),
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormValidationAssociated method
+ *
+ * test display of form errors in conjunction with model::validates.
+ *
+ * @return void
+ */
+ public function testFormValidationAssociated() {
+ $this->UserForm = ClassRegistry::getObject('UserForm');
+ $this->UserForm->OpenidUrl = ClassRegistry::getObject('OpenidUrl');
+
+ $data = array(
+ 'UserForm' => array('name' => 'user'),
+ 'OpenidUrl' => array('url' => 'http://www.cakephp.org')
+ );
+
+ $result = $this->UserForm->OpenidUrl->create($data);
+ $this->assertFalse(empty($result));
+ $this->assertFalse($this->UserForm->OpenidUrl->validates());
+
+ $result = $this->Form->create('UserForm', array('type' => 'post', 'action' => 'login'));
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $expected = array(
+ 'form' => array(
+ 'method' => 'post', 'action' => '/user_forms/login', 'id' => 'UserFormLoginForm',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->error(
+ 'OpenidUrl.openid_not_registered', 'Error, not registered', array('wrap' => false)
+ );
+ $this->assertEquals('Error, not registered', $result);
+
+ unset($this->UserForm->OpenidUrl, $this->UserForm);
+ }
+
+/**
+ * testFormValidationAssociatedFirstLevel method
+ *
+ * test form error display with associated model.
+ *
+ * @return void
+ */
+ public function testFormValidationAssociatedFirstLevel() {
+ $this->ValidateUser = ClassRegistry::getObject('ValidateUser');
+ $this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
+
+ $data = array(
+ 'ValidateUser' => array('name' => 'mariano'),
+ 'ValidateProfile' => array('full_name' => 'Mariano Iglesias')
+ );
+
+ $result = $this->ValidateUser->create($data);
+ $this->assertFalse(empty($result));
+ $this->assertFalse($this->ValidateUser->validates());
+ $this->assertFalse($this->ValidateUser->ValidateProfile->validates());
+
+ $result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $expected = array(
+ 'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id','accept-charset' => $encoding),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->error(
+ 'ValidateUser.email', 'Invalid email', array('wrap' => false)
+ );
+ $this->assertEquals('Invalid email', $result);
+
+ $result = $this->Form->error(
+ 'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
+ );
+ $this->assertEquals('Invalid name', $result);
+
+ $result = $this->Form->error(
+ 'ValidateProfile.city', 'Invalid city', array('wrap' => false)
+ );
+ $this->assertEquals('Invalid city', $result);
+
+ unset($this->ValidateUser->ValidateProfile);
+ unset($this->ValidateUser);
+ }
+
+/**
+ * testFormValidationAssociatedSecondLevel method
+ *
+ * test form error display with associated model.
+ *
+ * @return void
+ */
+ public function testFormValidationAssociatedSecondLevel() {
+ $this->ValidateUser = ClassRegistry::getObject('ValidateUser');
+ $this->ValidateUser->ValidateProfile = ClassRegistry::getObject('ValidateProfile');
+ $this->ValidateUser->ValidateProfile->ValidateItem = ClassRegistry::getObject('ValidateItem');
+
+ $data = array(
+ 'ValidateUser' => array('name' => 'mariano'),
+ 'ValidateProfile' => array('full_name' => 'Mariano Iglesias'),
+ 'ValidateItem' => array('name' => 'Item')
+ );
+
+ $result = $this->ValidateUser->create($data);
+ $this->assertFalse(empty($result));
+ $this->assertFalse($this->ValidateUser->validates());
+ $this->assertFalse($this->ValidateUser->ValidateProfile->validates());
+ $this->assertFalse($this->ValidateUser->ValidateProfile->ValidateItem->validates());
+
+ $result = $this->Form->create('ValidateUser', array('type' => 'post', 'action' => 'add'));
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $expected = array(
+ 'form' => array('method' => 'post', 'action' => '/validate_users/add', 'id','accept-charset' => $encoding),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->error(
+ 'ValidateUser.email', 'Invalid email', array('wrap' => false)
+ );
+ $this->assertEquals('Invalid email', $result);
+
+ $result = $this->Form->error(
+ 'ValidateProfile.full_name', 'Invalid name', array('wrap' => false)
+ );
+ $this->assertEquals('Invalid name', $result);
+
+ $result = $this->Form->error(
+ 'ValidateProfile.city', 'Invalid city', array('wrap' => false)
+ );
+
+ $result = $this->Form->error(
+ 'ValidateItem.description', 'Invalid description', array('wrap' => false)
+ );
+ $this->assertEquals('Invalid description', $result);
+
+ unset($this->ValidateUser->ValidateProfile->ValidateItem);
+ unset($this->ValidateUser->ValidateProfile);
+ unset($this->ValidateUser);
+ }
+
+/**
+ * testFormValidationMultiRecord method
+ *
+ * test form error display with multiple records.
+ *
+ * @return void
+ */
+ public function testFormValidationMultiRecord() {
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors[2] = array(
+ 'name' => array('This field cannot be left blank')
+ );
+ $result = $this->Form->input('Contact.2.name');
+ $expected = array(
+ 'div' => array('class' => 'input text error'),
+ 'label' => array('for' => 'Contact2Name'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][2][name]', 'id' => 'Contact2Name',
+ 'class' => 'form-error', 'maxlength' => 255
+ ),
+ array('div' => array('class' => 'error-message')),
+ 'This field cannot be left blank',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testMultipleInputValidation method
+ *
+ * test multiple record form validation error display.
+ *
+ * @return void
+ */
+ public function testMultipleInputValidation() {
+ $Address = ClassRegistry::init(array('class' => 'Address', 'table' => false, 'ds' => 'test'));
+ $Address->validationErrors[0] = array(
+ 'title' => array('This field cannot be empty'),
+ 'first_name' => array('This field cannot be empty')
+ );
+ $Address->validationErrors[1] = array(
+ 'last_name' => array('You must have a last name')
+ );
+ $this->Form->create();
+
+ $result = $this->Form->input('Address.0.title');
+ $expected = array(
+ 'div' => array('class'),
+ 'label' => array('for'),
+ 'preg:/[^<]+/',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name', 'id', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error-message')),
+ 'This field cannot be empty',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Address.0.first_name');
+ $expected = array(
+ 'div' => array('class'),
+ 'label' => array('for'),
+ 'preg:/[^<]+/',
+ '/label',
+ 'input' => array('type' => 'text', 'name', 'id', 'class' => 'form-error'),
+ array('div' => array('class' => 'error-message')),
+ 'This field cannot be empty',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Address.0.last_name');
+ $expected = array(
+ 'div' => array('class'),
+ 'label' => array('for'),
+ 'preg:/[^<]+/',
+ '/label',
+ 'input' => array('type' => 'text', 'name', 'id'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Address.1.last_name');
+ $expected = array(
+ 'div' => array('class'),
+ 'label' => array('for'),
+ 'preg:/[^<]+/',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'preg:/[^<]+/',
+ 'id' => 'preg:/[^<]+/', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error-message')),
+ 'You must have a last name',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testInput method
+ *
+ * Test various incarnations of input().
+ *
+ * @return void
+ */
+ public function testInput() {
+ $result = $this->Form->input('ValidateUser.balance');
+ $expected = array(
+ 'div' => array('class'),
+ 'label' => array('for'),
+ 'Balance',
+ '/label',
+ 'input' => array('name', 'type' => 'number', 'maxlength' => 8, 'id'),
+ '/div',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.email', array('id' => 'custom'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'custom'),
+ 'Email',
+ '/label',
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][email]',
+ 'id' => 'custom', 'maxlength' => 255
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.email', array('div' => array('class' => false)));
+ $expected = array(
+ '<div',
+ 'label' => array('for' => 'ContactEmail'),
+ 'Email',
+ '/label',
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][email]',
+ 'id' => 'ContactEmail', 'maxlength' => 255
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->hidden('Contact.idontexist');
+ $expected = array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[Contact][idontexist]',
+ 'id' => 'ContactIdontexist'
+ ));
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.email', array('type' => 'text'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactEmail'),
+ 'Email',
+ '/label',
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][email]',
+ 'id' => 'ContactEmail'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.5.email', array('type' => 'text'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'Contact5Email'),
+ 'Email',
+ '/label',
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][5][email]',
+ 'id' => 'Contact5Email'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.password');
+ $expected = array(
+ 'div' => array('class' => 'input password'),
+ 'label' => array('for' => 'ContactPassword'),
+ 'Password',
+ '/label',
+ array('input' => array(
+ 'type' => 'password', 'name' => 'data[Contact][password]',
+ 'id' => 'ContactPassword'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.email', array(
+ 'type' => 'file', 'class' => 'textbox'
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input file'),
+ 'label' => array('for' => 'ContactEmail'),
+ 'Email',
+ '/label',
+ array('input' => array(
+ 'type' => 'file', 'name' => 'data[Contact][email]', 'class' => 'textbox',
+ 'id' => 'ContactEmail'
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array('Contact' => array('phone' => 'Hello & World > weird chars'));
+ $result = $this->Form->input('Contact.phone');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactPhone'),
+ 'Phone',
+ '/label',
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][phone]',
+ 'value' => 'Hello &amp; World &gt; weird chars',
+ 'id' => 'ContactPhone', 'maxlength' => 255
+ )),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['0']['OtherModel']['field'] = 'My value';
+ $result = $this->Form->input('Model.0.OtherModel.field', array('id' => 'myId'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'myId'),
+ 'Field',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Model][0][OtherModel][field]',
+ 'value' => 'My value', 'id' => 'myId'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ unset($this->Form->request->data);
+
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors['field'] = array('Badness!');
+ $result = $this->Form->input('Contact.field');
+ $expected = array(
+ 'div' => array('class' => 'input text error'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field]',
+ 'id' => 'ContactField', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error-message')),
+ 'Badness!',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.field', array(
+ 'div' => false, 'error' => array('attributes' => array('wrap' => 'span'))
+ ));
+ $expected = array(
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field]',
+ 'id' => 'ContactField', 'class' => 'form-error'
+ ),
+ array('span' => array('class' => 'error-message')),
+ 'Badness!',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.field', array(
+ 'type' => 'text', 'error' => array('attributes' => array('class' => 'error'))
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text error'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field]',
+ 'id' => 'ContactField', 'class' => 'form-error'
+ ),
+ array('div' => array('class' => 'error')),
+ 'Badness!',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.field', array(
+ 'div' => array('tag' => 'span'), 'error' => array('attributes' => array('wrap' => false))
+ ));
+ $expected = array(
+ 'span' => array('class' => 'input text error'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field]',
+ 'id' => 'ContactField', 'class' => 'form-error'
+ ),
+ 'Badness!',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.field', array('after' => 'A message to you, Rudy'));
+ $expected = array(
+ 'div' => array('class' => 'input text error'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field]',
+ 'id' => 'ContactField', 'class' => 'form-error'
+ ),
+ 'A message to you, Rudy',
+ array('div' => array('class' => 'error-message')),
+ 'Badness!',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->setEntity(null);
+ $this->Form->setEntity('Contact.field');
+ $result = $this->Form->input('Contact.field', array(
+ 'after' => 'A message to you, Rudy', 'error' => false
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array('type' => 'text', 'name' => 'data[Contact][field]', 'id' => 'ContactField', 'class' => 'form-error'),
+ 'A message to you, Rudy',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Object.field', array('after' => 'A message to you, Rudy'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ObjectField'),
+ 'Field',
+ '/label',
+ 'input' => array('type' => 'text', 'name' => 'data[Object][field]', 'id' => 'ObjectField'),
+ 'A message to you, Rudy',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $Contact->validationErrors['field'] = array('minLength');
+ $result = $this->Form->input('Contact.field', array(
+ 'error' => array(
+ 'minLength' => 'Le login doit contenir au moins 2 caractères',
+ 'maxLength' => 'login too large'
+ )
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text error'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array('type' => 'text', 'name' => 'data[Contact][field]', 'id' => 'ContactField', 'class' => 'form-error'),
+ array('div' => array('class' => 'error-message')),
+ 'Le login doit contenir au moins 2 caractères',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $Contact->validationErrors['field'] = array('maxLength');
+ $result = $this->Form->input('Contact.field', array(
+ 'error' => array(
+ 'attributes' => array('wrap' => 'span', 'rel' => 'fake'),
+ 'minLength' => 'Le login doit contenir au moins 2 caractères',
+ 'maxLength' => 'login too large',
+ )
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text error'),
+ 'label' => array('for' => 'ContactField'),
+ 'Field',
+ '/label',
+ 'input' => array('type' => 'text', 'name' => 'data[Contact][field]', 'id' => 'ContactField', 'class' => 'form-error'),
+ array('span' => array('class' => 'error-message', 'rel' => 'fake')),
+ 'login too large',
+ '/span',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test input() with checkbox creation
+ *
+ * @return void
+ */
+ public function testInputCheckbox() {
+ $result = $this->Form->input('User.active', array('label' => false, 'checked' => true));
+ $expected = array(
+ 'div' => array('class' => 'input checkbox'),
+ 'input' => array('type' => 'hidden', 'name' => 'data[User][active]', 'value' => '0', 'id' => 'UserActive_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[User][active]', 'value' => '1', 'id' => 'UserActive', 'checked' => 'checked')),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('User.active', array('label' => false, 'checked' => 1));
+ $expected = array(
+ 'div' => array('class' => 'input checkbox'),
+ 'input' => array('type' => 'hidden', 'name' => 'data[User][active]', 'value' => '0', 'id' => 'UserActive_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[User][active]', 'value' => '1', 'id' => 'UserActive', 'checked' => 'checked')),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('User.active', array('label' => false, 'checked' => '1'));
+ $expected = array(
+ 'div' => array('class' => 'input checkbox'),
+ 'input' => array('type' => 'hidden', 'name' => 'data[User][active]', 'value' => '0', 'id' => 'UserActive_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[User][active]', 'value' => '1', 'id' => 'UserActive', 'checked' => 'checked')),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test form->input() with time types.
+ *
+ */
+ public function testInputTime() {
+ extract($this->dateRegex);
+ $result = $this->Form->input('Contact.created', array('type' => 'time', 'timeFormat' => 24));
+ $result = explode(':', $result);
+ $this->assertRegExp('/option value="23"/', $result[0]);
+ $this->assertNotRegExp('/option value="24"/', $result[0]);
+
+ $result = $this->Form->input('Contact.created', array('type' => 'time', 'timeFormat' => 24));
+ $result = explode(':', $result);
+ $this->assertRegExp('/option value="23"/', $result[0]);
+ $this->assertNotRegExp('/option value="24"/', $result[0]);
+
+ $result = $this->Form->input('Model.field', array(
+ 'type' => 'time', 'timeFormat' => 24, 'interval' => 15
+ ));
+ $result = explode(':', $result);
+ $this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
+ $this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
+ $this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
+
+ $result = $this->Form->input('Model.field', array(
+ 'type' => 'time', 'timeFormat' => 12, 'interval' => 15
+ ));
+ $result = explode(':', $result);
+ $this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
+ $this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
+ $this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
+
+ $result = $this->Form->input('prueba', array(
+ 'type' => 'time', 'timeFormat' => 24 , 'dateFormat' => 'DMY' , 'minYear' => 2008,
+ 'maxYear' => date('Y') + 1 ,'interval' => 15
+ ));
+ $result = explode(':', $result);
+ $this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
+ $this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
+ $this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
+ $this->assertRegExp('#<option value="30"[^>]*>30</option>#', $result[1]);
+
+ $result = $this->Form->input('Random.start_time', array(
+ 'type' => 'time',
+ 'selected' => '18:15'
+ ));
+ $this->assertRegExp('#<option value="06"[^>]*>6</option>#', $result);
+ $this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result);
+ $this->assertRegExp('#<option value="pm"[^>]*>pm</option>#', $result);
+ }
+
+/**
+ * test form->input() with datetime, date and time types
+ *
+ * @return void
+ */
+ public function testInputDatetime() {
+ extract($this->dateRegex);
+ $result = $this->Form->input('prueba', array(
+ 'type' => 'datetime', 'timeFormat' => 24, 'dateFormat' => 'DMY', 'minYear' => 2008,
+ 'maxYear' => date('Y') + 1, 'interval' => 15
+ ));
+ $result = explode(':', $result);
+ $this->assertNotRegExp('#<option value="12"[^>]*>12</option>#', $result[1]);
+ $this->assertNotRegExp('#<option value="50"[^>]*>50</option>#', $result[1]);
+ $this->assertRegExp('#<option value="15"[^>]*>15</option>#', $result[1]);
+ $this->assertRegExp('#<option value="30"[^>]*>30</option>#', $result[1]);
+
+ //related to ticket #5013
+ $result = $this->Form->input('Contact.date', array(
+ 'type' => 'date', 'class' => 'customClass', 'onChange' => 'function(){}'
+ ));
+ $this->assertRegExp('/class="customClass"/', $result);
+ $this->assertRegExp('/onChange="function\(\)\{\}"/', $result);
+
+ $result = $this->Form->input('Contact.date', array(
+ 'type' => 'date', 'id' => 'customId', 'onChange' => 'function(){}'
+ ));
+ $this->assertRegExp('/id="customIdDay"/', $result);
+ $this->assertRegExp('/id="customIdMonth"/', $result);
+ $this->assertRegExp('/onChange="function\(\)\{\}"/', $result);
+
+ $result = $this->Form->input('Model.field', array(
+ 'type' => 'datetime', 'timeFormat' => 24, 'id' => 'customID'
+ ));
+ $this->assertRegExp('/id="customIDDay"/', $result);
+ $this->assertRegExp('/id="customIDHour"/', $result);
+ $result = explode('</select><select', $result);
+ $result = explode(':', $result[1]);
+ $this->assertRegExp('/option value="23"/', $result[0]);
+ $this->assertNotRegExp('/option value="24"/', $result[0]);
+
+ $result = $this->Form->input('Model.field', array(
+ 'type' => 'datetime', 'timeFormat' => 12
+ ));
+ $result = explode('</select><select', $result);
+ $result = explode(':', $result[1]);
+ $this->assertRegExp('/option value="12"/', $result[0]);
+ $this->assertNotRegExp('/option value="13"/', $result[0]);
+
+ $this->Form->request->data = array('Contact' => array('created' => null));
+ $result = $this->Form->input('Contact.created', array('empty' => 'Date Unknown'));
+ $expected = array(
+ 'div' => array('class' => 'input date'),
+ 'label' => array('for' => 'ContactCreatedMonth'),
+ 'Created',
+ '/label',
+ array('select' => array('name' => 'data[Contact][created][month]', 'id' => 'ContactCreatedMonth')),
+ array('option' => array('value' => '')), 'Date Unknown', '/option',
+ $monthsRegex,
+ '/select', '-',
+ array('select' => array('name' => 'data[Contact][created][day]', 'id' => 'ContactCreatedDay')),
+ array('option' => array('value' => '')), 'Date Unknown', '/option',
+ $daysRegex,
+ '/select', '-',
+ array('select' => array('name' => 'data[Contact][created][year]', 'id' => 'ContactCreatedYear')),
+ array('option' => array('value' => '')), 'Date Unknown', '/option',
+ $yearsRegex,
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array('Contact' => array('created' => null));
+ $result = $this->Form->input('Contact.created', array('type' => 'datetime', 'dateFormat' => 'NONE'));
+ $this->assertRegExp('/for\="ContactCreatedHour"/', $result);
+
+ $this->Form->request->data = array('Contact' => array('created' => null));
+ $result = $this->Form->input('Contact.created', array('type' => 'datetime', 'timeFormat' => 'NONE'));
+ $this->assertRegExp('/for\="ContactCreatedMonth"/', $result);
+
+ $result = $this->Form->input('Contact.created', array(
+ 'type' => 'date',
+ 'id' => array('day' => 'created-day', 'month' => 'created-month', 'year' => 'created-year'),
+ 'timeFormat' => 'NONE'
+ ));
+ $this->assertRegExp('/for\="created-month"/', $result);
+ }
+
+/**
+ * Test generating checkboxes in a loop.
+ *
+ * @return void
+ */
+ public function testInputCheckboxesInLoop() {
+ for ($i = 1; $i < 5; $i++) {
+ $result = $this->Form->input("Contact.{$i}.email", array('type' => 'checkbox', 'value' => $i));
+ $expected = array(
+ 'div' => array('class' => 'input checkbox'),
+ 'input' => array('type' => 'hidden', 'name' => "data[Contact][{$i}][email]", 'value' => '0', 'id' => "Contact{$i}Email_"),
+ array('input' => array('type' => 'checkbox', 'name' => "data[Contact][{$i}][email]", 'value' => $i, 'id' => "Contact{$i}Email")),
+ 'label' => array('for' => "Contact{$i}Email"),
+ 'Email',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+ }
+
+/**
+ * test input name with leading integer, ensure attributes are generated correctly.
+ *
+ * @return void
+ */
+ public function testInputWithLeadingInteger() {
+ $result = $this->Form->text('0.Node.title');
+ $expected = array(
+ 'input' => array('name' => 'data[0][Node][title]', 'id' => '0NodeTitle', 'type' => 'text')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test form->input() with select type inputs.
+ *
+ * @return void
+ */
+ public function testInputSelectType() {
+ $result = $this->Form->input('email', array(
+ 'options' => array('è' => 'Firést', 'é' => 'Secoènd'), 'empty' => true)
+ );
+ $expected = array(
+ 'div' => array('class' => 'input select'),
+ 'label' => array('for' => 'email'),
+ 'Email',
+ '/label',
+ array('select' => array('name' => 'data[email]', 'id' => 'email')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => 'è')),
+ 'Firést',
+ '/option',
+ array('option' => array('value' => 'é')),
+ 'Secoènd',
+ '/option',
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('email', array(
+ 'options' => array('First', 'Second'), 'empty' => true)
+ );
+ $expected = array(
+ 'div' => array('class' => 'input select'),
+ 'label' => array('for' => 'email'),
+ 'Email',
+ '/label',
+ array('select' => array('name' => 'data[email]', 'id' => 'email')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '0')),
+ 'First',
+ '/option',
+ array('option' => array('value' => '1')),
+ 'Second',
+ '/option',
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
+ $this->Form->request->data = array('Model' => array('user_id' => 'value'));
+
+ $result = $this->Form->input('Model.user_id', array('empty' => true));
+ $expected = array(
+ 'div' => array('class' => 'input select'),
+ 'label' => array('for' => 'ModelUserId'),
+ 'User',
+ '/label',
+ 'select' => array('name' => 'data[Model][user_id]', 'id' => 'ModelUserId'),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => 'value', 'selected' => 'selected')),
+ 'good',
+ '/option',
+ array('option' => array('value' => 'other')),
+ 'bad',
+ '/option',
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
+ $this->Form->request->data = array('Thing' => array('user_id' => null));
+ $result = $this->Form->input('Thing.user_id', array('empty' => 'Some Empty'));
+ $expected = array(
+ 'div' => array('class' => 'input select'),
+ 'label' => array('for' => 'ThingUserId'),
+ 'User',
+ '/label',
+ 'select' => array('name' => 'data[Thing][user_id]', 'id' => 'ThingUserId'),
+ array('option' => array('value' => '')),
+ 'Some Empty',
+ '/option',
+ array('option' => array('value' => 'value')),
+ 'good',
+ '/option',
+ array('option' => array('value' => 'other')),
+ 'bad',
+ '/option',
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
+ $this->Form->request->data = array('Thing' => array('user_id' => 'value'));
+ $result = $this->Form->input('Thing.user_id', array('empty' => 'Some Empty'));
+ $expected = array(
+ 'div' => array('class' => 'input select'),
+ 'label' => array('for' => 'ThingUserId'),
+ 'User',
+ '/label',
+ 'select' => array('name' => 'data[Thing][user_id]', 'id' => 'ThingUserId'),
+ array('option' => array('value' => '')),
+ 'Some Empty',
+ '/option',
+ array('option' => array('value' => 'value', 'selected' => 'selected')),
+ 'good',
+ '/option',
+ array('option' => array('value' => 'other')),
+ 'bad',
+ '/option',
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
+ $this->Form->request->data = array('User' => array('User' => array('value')));
+ $result = $this->Form->input('User.User', array('empty' => true));
+ $expected = array(
+ 'div' => array('class' => 'input select'),
+ 'label' => array('for' => 'UserUser'),
+ 'User',
+ '/label',
+ 'input' => array('type' => 'hidden', 'name' => 'data[User][User]', 'value' => '', 'id' => 'UserUser_'),
+ 'select' => array('name' => 'data[User][User][]', 'id' => 'UserUser', 'multiple' => 'multiple'),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => 'value', 'selected' => 'selected')),
+ 'good',
+ '/option',
+ array('option' => array('value' => 'other')),
+ 'bad',
+ '/option',
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->data = array();
+ $result = $this->Form->input('Publisher.id', array(
+ 'label' => 'Publisher',
+ 'type' => 'select',
+ 'multiple' => 'checkbox',
+ 'options' => array('Value 1' => 'Label 1', 'Value 2' => 'Label 2')
+ ));
+ $expected = array(
+ array('div' => array('class' => 'input select')),
+ array('label' => array('for' => 'PublisherId')),
+ 'Publisher',
+ '/label',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Publisher][id]', 'value' => '', 'id' => 'PublisherId'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Publisher][id][]', 'value' => 'Value 1', 'id' => 'PublisherIdValue1')),
+ array('label' => array('for' => 'PublisherIdValue1')),
+ 'Label 1',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Publisher][id][]', 'value' => 'Value 2', 'id' => 'PublisherIdValue2')),
+ array('label' => array('for' => 'PublisherIdValue2')),
+ 'Label 2',
+ '/label',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that input() and a non standard primary key makes a hidden input by default.
+ *
+ * @return void
+ */
+ public function testInputWithNonStandardPrimaryKeyMakesHidden() {
+ $this->Form->create('User');
+ $this->Form->fieldset = array(
+ 'User' => array(
+ 'fields' => array(
+ 'model_id' => array('type' => 'integer')
+ ),
+ 'validates' => array(),
+ 'key' => 'model_id'
+ )
+ );
+ $result = $this->Form->input('model_id');
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[User][model_id]', 'id' => 'UserModelId'),
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that overriding the magic select type widget is possible
+ *
+ * @return void
+ */
+ public function testInputOverridingMagicSelectType() {
+ $this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
+ $result = $this->Form->input('Model.user_id', array('type' => 'text'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ModelUserId'), 'User', '/label',
+ 'input' => array('name' => 'data[Model][user_id]', 'type' => 'text', 'id' => 'ModelUserId'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ //Check that magic types still work for plural/singular vars
+ $this->View->viewVars['types'] = array('value' => 'good', 'other' => 'bad');
+ $result = $this->Form->input('Model.type');
+ $expected = array(
+ 'div' => array('class' => 'input select'),
+ 'label' => array('for' => 'ModelType'), 'Type', '/label',
+ 'select' => array('name' => 'data[Model][type]', 'id' => 'ModelType'),
+ array('option' => array('value' => 'value')), 'good', '/option',
+ array('option' => array('value' => 'other')), 'bad', '/option',
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test that magic input() selects can easily be converted into radio types without error.
+ *
+ * @return void
+ */
+ public function testInputMagicSelectChangeToRadio() {
+ $this->View->viewVars['users'] = array('value' => 'good', 'other' => 'bad');
+ $result = $this->Form->input('Model.user_id', array('type' => 'radio'));
+ $this->assertRegExp('/input type="radio"/', $result);
+ }
+
+/**
+ * fields with the same name as the model should work.
+ *
+ * @return void
+ */
+ public function testInputWithMatchingFieldAndModelName() {
+ $this->Form->create('User');
+ $this->Form->fieldset = array(
+ 'User' => array(
+ 'fields' => array(
+ 'User' => array('type' => 'text')
+ ),
+ 'validates' => array(),
+ 'key' => 'id'
+ )
+ );
+ $this->Form->request->data['User']['User'] = 'ABC, Inc.';
+ $result = $this->Form->input('User', array('type' => 'text'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'UserUser'), 'User', '/label',
+ 'input' => array('name' => 'data[User][User]', 'type' => 'text', 'id' => 'UserUser', 'value' => 'ABC, Inc.'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormInputs method
+ *
+ * test correct results from form::inputs().
+ *
+ * @return void
+ */
+ public function testFormInputs() {
+ $this->Form->create('Contact');
+ $result = $this->Form->inputs('The Legend');
+ $expected = array(
+ '<fieldset',
+ '<legend',
+ 'The Legend',
+ '/legend',
+ '*/fieldset',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->inputs(array('legend' => 'Field of Dreams', 'fieldset' => 'classy-stuff'));
+ $expected = array(
+ 'fieldset' => array('class' => 'classy-stuff'),
+ '<legend',
+ 'Field of Dreams',
+ '/legend',
+ '*/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $this->Form->request['prefix'] = 'admin';
+ $this->Form->request['action'] = 'admin_edit';
+ $result = $this->Form->inputs();
+ $expected = array(
+ '<fieldset',
+ '<legend',
+ 'Edit Contact',
+ '/legend',
+ '*/fieldset',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->inputs(false);
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input password')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input datetime')),
+ '*/div',
+ array('div' => array('class' => 'input number')),
+ '*/div',
+ array('div' => array('class' => 'input select')),
+ '*/div',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->inputs(array('fieldset' => false, 'legend' => false));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input password')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input datetime')),
+ '*/div',
+ array('div' => array('class' => 'input number')),
+ '*/div',
+ array('div' => array('class' => 'input select')),
+ '*/div',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->inputs(array('fieldset' => true, 'legend' => false));
+ $expected = array(
+ 'fieldset' => array(),
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input password')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input datetime')),
+ '*/div',
+ array('div' => array('class' => 'input number')),
+ '*/div',
+ array('div' => array('class' => 'input select')),
+ '*/div',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->inputs(array('fieldset' => false, 'legend' => 'Hello'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input password')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input datetime')),
+ '*/div',
+ array('div' => array('class' => 'input number')),
+ '*/div',
+ array('div' => array('class' => 'input select')),
+ '*/div',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->inputs('Hello');
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Hello',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input password')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input datetime')),
+ '*/div',
+ array('div' => array('class' => 'input number')),
+ '*/div',
+ array('div' => array('class' => 'input select')),
+ '*/div',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->inputs(array('legend' => 'Hello'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Hello',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][id]', 'id' => 'ContactId'),
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input text')),
+ '*/div',
+ array('div' => array('class' => 'input password')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input date')),
+ '*/div',
+ array('div' => array('class' => 'input datetime')),
+ '*/div',
+ array('div' => array('class' => 'input number')),
+ '*/div',
+ array('div' => array('class' => 'input select')),
+ '*/div',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSelectAsCheckbox method
+ *
+ * test multi-select widget with checkbox formatting.
+ *
+ * @return void
+ */
+ public function testSelectAsCheckbox() {
+ $result = $this->Form->select('Model.multi_field', array('first', 'second', 'third'), array('multiple' => 'checkbox', 'value' => array(0, 1)));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'checked' => 'checked', 'value' => '0', 'id' => 'ModelMultiField0')),
+ array('label' => array('for' => 'ModelMultiField0', 'class' => 'selected')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'checked' => 'checked', 'value' => '1', 'id' => 'ModelMultiField1')),
+ array('label' => array('for' => 'ModelMultiField1', 'class' => 'selected')),
+ 'second',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '2', 'id' => 'ModelMultiField2')),
+ array('label' => array('for' => 'ModelMultiField2')),
+ 'third',
+ '/label',
+ '/div',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select('Model.multi_field', array('1/2' => 'half'), array('multiple' => 'checkbox'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1/2', 'id' => 'ModelMultiField12')),
+ array('label' => array('for' => 'ModelMultiField12')),
+ 'half',
+ '/label',
+ '/div',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testLabel method
+ *
+ * test label generation.
+ *
+ * @return void
+ */
+ public function testLabel() {
+ $this->Form->text('Person.name');
+ $result = $this->Form->label();
+ $this->assertTags($result, array('label' => array('for' => 'PersonName'), 'Name', '/label'));
+
+ $this->Form->text('Person.name');
+ $result = $this->Form->label();
+ $this->assertTags($result, array('label' => array('for' => 'PersonName'), 'Name', '/label'));
+
+ $result = $this->Form->label('Person.first_name');
+ $this->assertTags($result, array('label' => array('for' => 'PersonFirstName'), 'First Name', '/label'));
+
+ $result = $this->Form->label('Person.first_name', 'Your first name');
+ $this->assertTags($result, array('label' => array('for' => 'PersonFirstName'), 'Your first name', '/label'));
+
+ $result = $this->Form->label('Person.first_name', 'Your first name', array('class' => 'my-class'));
+ $this->assertTags($result, array('label' => array('for' => 'PersonFirstName', 'class' => 'my-class'), 'Your first name', '/label'));
+
+ $result = $this->Form->label('Person.first_name', 'Your first name', array('class' => 'my-class', 'id' => 'LabelID'));
+ $this->assertTags($result, array('label' => array('for' => 'PersonFirstName', 'class' => 'my-class', 'id' => 'LabelID'), 'Your first name', '/label'));
+
+ $result = $this->Form->label('Person.first_name', '');
+ $this->assertTags($result, array('label' => array('for' => 'PersonFirstName'), '/label'));
+
+ $result = $this->Form->label('Person.2.name', '');
+ $this->assertTags($result, array('label' => array('for' => 'Person2Name'), '/label'));
+ }
+
+/**
+ * testTextbox method
+ *
+ * test textbox element generation
+ *
+ * @return void
+ */
+ public function testTextbox() {
+ $result = $this->Form->text('Model.field');
+ $this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'id' => 'ModelField')));
+
+ $result = $this->Form->text('Model.field', array('type' => 'password'));
+ $this->assertTags($result, array('input' => array('type' => 'password', 'name' => 'data[Model][field]', 'id' => 'ModelField')));
+
+ $result = $this->Form->text('Model.field', array('id' => 'theID'));
+ $this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'id' => 'theID')));
+
+ $this->Form->request->data['Model']['text'] = 'test <strong>HTML</strong> values';
+ $result = $this->Form->text('Model.text');
+ $this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][text]', 'value' => 'test &lt;strong&gt;HTML&lt;/strong&gt; values', 'id' => 'ModelText')));
+
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors['text'] = array(true);
+ $this->Form->request->data['Contact']['text'] = 'test';
+ $result = $this->Form->text('Contact.text', array('id' => 'theID'));
+ $this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Contact][text]', 'value' => 'test', 'id' => 'theID', 'class' => 'form-error')));
+
+ $this->Form->request->data['Model']['0']['OtherModel']['field'] = 'My value';
+ $result = $this->Form->text('Model.0.OtherModel.field', array('id' => 'myId'));
+ $expected = array(
+ 'input' => array('type' => 'text', 'name' => 'data[Model][0][OtherModel][field]', 'value' => 'My value', 'id' => 'myId')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testDefaultValue method
+ *
+ * Test default value setting
+ *
+ * @return void
+ */
+ public function testDefaultValue() {
+ $this->Form->request->data['Model']['field'] = 'test';
+ $result = $this->Form->text('Model.field', array('default' => 'default value'));
+ $this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'value' => 'test', 'id' => 'ModelField')));
+
+ unset($this->Form->request->data['Model']['field']);
+ $result = $this->Form->text('Model.field', array('default' => 'default value'));
+ $this->assertTags($result, array('input' => array('type' => 'text', 'name' => 'data[Model][field]', 'value' => 'default value', 'id' => 'ModelField')));
+ }
+
+/**
+ * testCheckboxDefaultValue method
+ *
+ * Test default value setting on checkbox() method
+ *
+ * @return void
+ */
+ public function testCheckboxDefaultValue() {
+ $this->Form->request->data['Model']['field'] = false;
+ $result = $this->Form->checkbox('Model.field', array('default' => true, 'hiddenField' => false));
+ $this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField')));
+
+ unset($this->Form->request->data['Model']['field']);
+ $result = $this->Form->checkbox('Model.field', array('default' => true, 'hiddenField' => false));
+ $this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked')));
+
+ $this->Form->request->data['Model']['field'] = true;
+ $result = $this->Form->checkbox('Model.field', array('default' => false, 'hiddenField' => false));
+ $this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked')));
+
+ unset($this->Form->request->data['Model']['field']);
+ $result = $this->Form->checkbox('Model.field', array('default' => false, 'hiddenField' => false));
+ $this->assertTags($result, array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField')));
+ }
+
+/**
+ * testError method
+ *
+ * Test field error generation
+ *
+ * @return void
+ */
+ public function testError() {
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors['field'] = array(1);
+ $result = $this->Form->error('Contact.field');
+ $this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field Field', '/div'));
+
+ $result = $this->Form->error('Contact.field', null, array('wrap' => false));
+ $this->assertEquals('Error in field Field', $result);
+
+ $Contact->validationErrors['field'] = array("This field contains invalid input");
+ $result = $this->Form->error('Contact.field', null, array('wrap' => false));
+ $this->assertEquals('This field contains invalid input', $result);
+
+ $Contact->validationErrors['field'] = array("This field contains invalid input");
+ $result = $this->Form->error('Contact.field', null, array('wrap' => 'span'));
+ $this->assertTags($result, array('span' => array('class' => 'error-message'), 'This field contains invalid input', '/span'));
+
+ $result = $this->Form->error('Contact.field', 'There is an error fool!', array('wrap' => 'span'));
+ $this->assertTags($result, array('span' => array('class' => 'error-message'), 'There is an error fool!', '/span'));
+
+ $result = $this->Form->error('Contact.field', "<strong>Badness!</strong>", array('wrap' => false));
+ $this->assertEquals('&lt;strong&gt;Badness!&lt;/strong&gt;', $result);
+
+ $result = $this->Form->error('Contact.field', "<strong>Badness!</strong>", array('wrap' => false, 'escape' => true));
+ $this->assertEquals('&lt;strong&gt;Badness!&lt;/strong&gt;', $result);
+
+ $result = $this->Form->error('Contact.field', "<strong>Badness!</strong>", array('wrap' => false, 'escape' => false));
+ $this->assertEquals('<strong>Badness!</strong>', $result);
+
+ $Contact->validationErrors['field'] = array("email");
+ $result = $this->Form->error('Contact.field', array('attributes' => array('class' => 'field-error'), 'email' => 'No good!'));
+ $expected = array(
+ 'div' => array('class' => 'field-error'),
+ 'No good!',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $Contact->validationErrors['field'] = array('notEmpty', 'email', 'Something else');
+ $result = $this->Form->error('Contact.field', array(
+ 'notEmpty' => 'Cannot be empty',
+ 'email' => 'No good!'
+ ));
+ $expected = array(
+ 'div' => array('class' => 'error-message'),
+ 'ul' => array(),
+ '<li', 'Cannot be empty', '/li',
+ '<li', 'No good!', '/li',
+ '<li', 'Something else', '/li',
+ '/ul',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ /** Testing error messages list options **/
+ $Contact->validationErrors['field'] = array('notEmpty', 'email');
+
+ $result = $this->Form->error('Contact.field', null, array('listOptions' => 'ol'));
+ $expected = array(
+ 'div' => array('class' => 'error-message'),
+ 'ol' => array(),
+ '<li', 'notEmpty', '/li',
+ '<li', 'email', '/li',
+ '/ol',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->error('Contact.field', null, array('listOptions' => array('tag' => 'ol')));
+ $expected = array(
+ 'div' => array('class' => 'error-message'),
+ 'ol' => array(),
+ '<li', 'notEmpty', '/li',
+ '<li', 'email', '/li',
+ '/ol',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->error('Contact.field', null, array(
+ 'listOptions' => array(
+ 'class' => 'ul-class',
+ 'itemOptions' => array(
+ 'class' => 'li-class'
+ )
+ )
+ ));
+ $expected = array(
+ 'div' => array('class' => 'error-message'),
+ 'ul' => array('class' => 'ul-class'),
+ array('li' => array('class' => 'li-class')), 'notEmpty', '/li',
+ array('li' => array('class' => 'li-class')), 'email', '/li',
+ '/ul',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test error options when using form->input();
+ *
+ * @return void
+ */
+ public function testInputErrorEscape() {
+ $this->Form->create('ValidateProfile');
+ $ValidateProfile = ClassRegistry::getObject('ValidateProfile');
+ $ValidateProfile->validationErrors['city'] = array('required<br>');
+ $result = $this->Form->input('city',array('error' => array('attributes' => array('escape' => true))));
+ $this->assertRegExp('/required&lt;br&gt;/', $result);
+
+ $result = $this->Form->input('city',array('error' => array('attributes' => array('escape' => false))));
+ $this->assertRegExp('/required<br>/', $result);
+ }
+
+/**
+ * testPassword method
+ *
+ * Test password element generation
+ *
+ * @return void
+ */
+ public function testPassword() {
+ $Contact = ClassRegistry::getObject('Contact');
+ $result = $this->Form->password('Contact.field');
+ $this->assertTags($result, array('input' => array('type' => 'password', 'name' => 'data[Contact][field]', 'id' => 'ContactField')));
+
+ $Contact->validationErrors['passwd'] = 1;
+ $this->Form->request->data['Contact']['passwd'] = 'test';
+ $result = $this->Form->password('Contact.passwd', array('id' => 'theID'));
+ $this->assertTags($result, array('input' => array('type' => 'password', 'name' => 'data[Contact][passwd]', 'value' => 'test', 'id' => 'theID', 'class' => 'form-error')));
+ }
+
+/**
+ * testRadio method
+ *
+ * Test radio element set generation
+ *
+ * @return void
+ */
+ public function testRadio() {
+ $result = $this->Form->radio('Model.field', array('option A'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
+ 'label' => array('for' => 'ModelField0'),
+ 'option A',
+ '/label'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('1/2' => 'half'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1/2', 'id' => 'ModelField12')),
+ 'label' => array('for' => 'ModelField12'),
+ 'half',
+ '/label'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('option A', 'option B'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
+ array('label' => array('for' => 'ModelField0')),
+ 'option A',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
+ array('label' => array('for' => 'ModelField1')),
+ 'option B',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('option A', 'option B'), array('separator' => '<br/>'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
+ array('label' => array('for' => 'ModelField0')),
+ 'option A',
+ '/label',
+ 'br' => array(),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
+ array('label' => array('for' => 'ModelField1')),
+ 'option B',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => '1'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1', 'checked' => 'checked')),
+ array('label' => array('for' => 'ModelField1')),
+ 'Yes',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
+ array('label' => array('for' => 'ModelField0')),
+ 'No',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => '0'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
+ array('label' => array('for' => 'ModelField1')),
+ 'Yes',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'checked' => 'checked')),
+ array('label' => array('for' => 'ModelField0')),
+ 'No',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => null));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
+ array('label' => array('for' => 'ModelField1')),
+ 'Yes',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
+ array('label' => array('for' => 'ModelField0')),
+ 'No',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
+ array('label' => array('for' => 'ModelField1')),
+ 'Yes',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0')),
+ array('label' => array('for' => 'ModelField0')),
+ 'No',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Newsletter.subscribe', array('legend' => 'Legend title', 'type' => 'radio', 'options' => array('0' => 'Unsubscribe', '1' => 'Subscribe')));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Legend title',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Newsletter][subscribe]', 'value' => '', 'id' => 'NewsletterSubscribe_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '0', 'id' => 'NewsletterSubscribe0')),
+ array('label' => array('for' => 'NewsletterSubscribe0')),
+ 'Unsubscribe',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '1', 'id' => 'NewsletterSubscribe1')),
+ array('label' => array('for' => 'NewsletterSubscribe1')),
+ 'Subscribe',
+ '/label',
+ '/fieldset',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Newsletter.subscribe', array('legend' => false, 'type' => 'radio', 'options' => array('0' => 'Unsubscribe', '1' => 'Subscribe')));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'input' => array('type' => 'hidden', 'name' => 'data[Newsletter][subscribe]', 'value' => '', 'id' => 'NewsletterSubscribe_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '0', 'id' => 'NewsletterSubscribe0')),
+ array('label' => array('for' => 'NewsletterSubscribe0')),
+ 'Unsubscribe',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '1', 'id' => 'NewsletterSubscribe1')),
+ array('label' => array('for' => 'NewsletterSubscribe1')),
+ 'Subscribe',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Newsletter.subscribe', array('legend' => 'Legend title', 'label' => false, 'type' => 'radio', 'options' => array('0' => 'Unsubscribe', '1' => 'Subscribe')));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Legend title',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Newsletter][subscribe]', 'value' => '', 'id' => 'NewsletterSubscribe_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '0', 'id' => 'NewsletterSubscribe0')),
+ 'Unsubscribe',
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '1', 'id' => 'NewsletterSubscribe1')),
+ 'Subscribe',
+ '/fieldset',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Newsletter.subscribe', array('legend' => false, 'label' => false, 'type' => 'radio', 'options' => array('0' => 'Unsubscribe', '1' => 'Subscribe')));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'input' => array('type' => 'hidden', 'name' => 'data[Newsletter][subscribe]', 'value' => '', 'id' => 'NewsletterSubscribe_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '0', 'id' => 'NewsletterSubscribe0')),
+ 'Unsubscribe',
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '1', 'id' => 'NewsletterSubscribe1')),
+ 'Subscribe',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Newsletter.subscribe', array('legend' => false, 'label' => false, 'type' => 'radio', 'value' => '1', 'options' => array('0' => 'Unsubscribe', '1' => 'Subscribe')));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '0', 'id' => 'NewsletterSubscribe0')),
+ 'Unsubscribe',
+ array('input' => array('type' => 'radio', 'name' => 'data[Newsletter][subscribe]', 'value' => '1', 'id' => 'NewsletterSubscribe1', 'checked' => 'checked')),
+ 'Subscribe',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Employee.gender', array('male' => 'Male', 'female' => 'Female'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Gender',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Employee][gender]', 'value' => '', 'id' => 'EmployeeGender_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Employee][gender]', 'value' => 'male', 'id' => 'EmployeeGenderMale')),
+ array('label' => array('for' => 'EmployeeGenderMale')),
+ 'Male',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Employee][gender]', 'value' => 'female', 'id' => 'EmployeeGenderFemale')),
+ array('label' => array('for' => 'EmployeeGenderFemale')),
+ 'Female',
+ '/label',
+ '/fieldset',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Officer.gender', array('male' => 'Male', 'female' => 'Female'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Gender',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Officer][gender]', 'value' => '', 'id' => 'OfficerGender_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Officer][gender]', 'value' => 'male', 'id' => 'OfficerGenderMale')),
+ array('label' => array('for' => 'OfficerGenderMale')),
+ 'Male',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Officer][gender]', 'value' => 'female', 'id' => 'OfficerGenderFemale')),
+ array('label' => array('for' => 'OfficerGenderFemale')),
+ 'Female',
+ '/label',
+ '/fieldset',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Contact.1.imrequired', array('option A'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][1][imrequired]', 'value' => '', 'id' => 'Contact1Imrequired_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Contact][1][imrequired]', 'value' => '0', 'id' => 'Contact1Imrequired0')),
+ 'label' => array('for' => 'Contact1Imrequired0'),
+ 'option A',
+ '/label'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.1.field', array('option A'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][1][field]', 'value' => '', 'id' => 'Model1Field_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0')),
+ 'label' => array('for' => 'Model1Field0'),
+ 'option A',
+ '/label'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.field', array('option A', 'option B'), array('name' => 'data[Model][custom]'));
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][custom]', 'value' => '', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][custom]', 'value' => '0', 'id' => 'ModelField0')),
+ array('label' => array('for' => 'ModelField0')),
+ 'option A',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][custom]', 'value' => '1', 'id' => 'ModelField1')),
+ array('label' => array('for' => 'ModelField1')),
+ 'option B',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio(
+ 'Model.field',
+ array('option A', 'option B'),
+ array('between' => 'I am between')
+ );
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ 'I am between',
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][field]',
+ 'value' => '', 'id' => 'ModelField_'
+ ),
+ array('input' => array(
+ 'type' => 'radio', 'name' => 'data[Model][field]',
+ 'value' => '0', 'id' => 'ModelField0'
+ )),
+ array('label' => array('for' => 'ModelField0')),
+ 'option A',
+ '/label',
+ array('input' => array(
+ 'type' => 'radio', 'name' => 'data[Model][field]',
+ 'value' => '1', 'id' => 'ModelField1'
+ )),
+ array('label' => array('for' => 'ModelField1')),
+ 'option B',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test disabled radio options
+ *
+ * @return void
+ */
+ public function testRadioDisabled() {
+ $result = $this->Form->radio(
+ 'Model.field',
+ array('option A', 'option B'),
+ array('disabled' => array('option A'), 'value' => 'option A')
+ );
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'disabled' => 'disabled', 'checked' => 'checked')),
+ array('label' => array('for' => 'ModelField0')),
+ 'option A',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1')),
+ array('label' => array('for' => 'ModelField1')),
+ 'option B',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio(
+ 'Model.field',
+ array('option A', 'option B'),
+ array('disabled' => true, 'value' => 'option A')
+ );
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'disabled' => 'disabled', 'checked' => 'checked')),
+ array('label' => array('for' => 'ModelField0')),
+ 'option A',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1', 'disabled' => 'disabled')),
+ array('label' => array('for' => 'ModelField1')),
+ 'option B',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio(
+ 'Model.field',
+ array('option A', 'option B'),
+ array('disabled' => 'disabled', 'value' => 'option A')
+ );
+ $expected = array(
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField0', 'disabled' => 'disabled', 'checked' => 'checked')),
+ array('label' => array('for' => 'ModelField0')),
+ 'option A',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField1', 'disabled' => 'disabled')),
+ array('label' => array('for' => 'ModelField1')),
+ 'option B',
+ '/label',
+ '/fieldset'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test disabling the hidden input for radio buttons
+ *
+ * @return void
+ */
+ public function testRadioHiddenInputDisabling() {
+ $result = $this->Form->input('Model.1.field', array(
+ 'type' => 'radio',
+ 'options' => array('option A'),
+ 'hiddenField' => false
+ )
+ );
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0'),
+ 'label' => array('for' => 'Model1Field0'),
+ 'option A',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->radio('Model.1.field', array('option A'), array('hiddenField' => false));
+ $expected = array(
+ 'input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0'),
+ 'label' => array('for' => 'Model1Field0'),
+ 'option A',
+ '/label'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test adding an empty option for radio buttons
+ *
+ * @return void
+ */
+ public function testRadioAddEmptyOption() {
+ $result = $this->Form->input('Model.1.field', array(
+ 'type' => 'radio',
+ 'options' => array('option A'),
+ 'empty' => true,
+ 'hiddenField' => false
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '', 'id' => 'Model1Field')),
+ array('label' => array('for' => 'Model1Field')),
+ __('empty'),
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0')),
+ array('label' => array('for' => 'Model1Field0')),
+ 'option A',
+ '/label',
+ '/fieldset',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.1.field', array(
+ 'type' => 'radio',
+ 'options' => array('option A'),
+ 'empty' => 'CustomEmptyLabel',
+ 'hiddenField' => false
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Field',
+ '/legend',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '', 'id' => 'Model1Field')),
+ array('label' => array('for' => 'Model1Field')),
+ 'CustomEmptyLabel',
+ '/label',
+ array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0')),
+ array('label' => array('for' => 'Model1Field0')),
+ 'option A',
+ '/label',
+ '/fieldset',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.1.field', array(
+ 'type' => 'radio',
+ 'options' => array('option A'),
+ 'empty' => false,
+ 'hiddenField' => false
+ ));
+ $this->assertTextNotContains('"Model1Field"', $result);
+ }
+
+/**
+ * testSelect method
+ *
+ * Test select element generation.
+ *
+ * @return void
+ */
+ public function testSelect() {
+ $result = $this->Form->select('Model.field', array());
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => '')),
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array('Model' => array('field' => 'value'));
+ $result = $this->Form->select('Model.field', array('value' => 'good', 'other' => 'bad'));
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => 'value', 'selected' => 'selected')),
+ 'good',
+ '/option',
+ array('option' => array('value' => 'other')),
+ 'bad',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array();
+ $result = $this->Form->select('Model.field', array('value' => 'good', 'other' => 'bad'));
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => 'value')),
+ 'good',
+ '/option',
+ array('option' => array('value' => 'other')),
+ 'bad',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.field', array('first' => 'first "html" <chars>', 'second' => 'value'),
+ array('empty' => false)
+ );
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => 'first')),
+ 'first &quot;html&quot; &lt;chars&gt;',
+ '/option',
+ array('option' => array('value' => 'second')),
+ 'value',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.field',
+ array('first' => 'first "html" <chars>', 'second' => 'value'),
+ array('escape' => false, 'empty' => false)
+ );
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => 'first')),
+ 'first "html" <chars>',
+ '/option',
+ array('option' => array('value' => 'second')),
+ 'value',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $options = array(
+ array('value' => 'first', 'name' => 'First'),
+ array('value' => 'first', 'name' => 'Another First'),
+ );
+ $result = $this->Form->select(
+ 'Model.field',
+ $options,
+ array('escape' => false, 'empty' => false)
+ );
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => 'first')),
+ 'First',
+ '/option',
+ array('option' => array('value' => 'first')),
+ 'Another First',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array('Model' => array('contact_id' => 228));
+ $result = $this->Form->select(
+ 'Model.contact_id',
+ array('228' => '228 value', '228-1' => '228-1 value', '228-2' => '228-2 value'),
+ array('escape' => false, 'empty' => 'pick something')
+ );
+
+ $expected = array(
+ 'select' => array('name' => 'data[Model][contact_id]', 'id' => 'ModelContactId'),
+ array('option' => array('value' => '')), 'pick something', '/option',
+ array('option' => array('value' => '228', 'selected' => 'selected')), '228 value', '/option',
+ array('option' => array('value' => '228-1')), '228-1 value', '/option',
+ array('option' => array('value' => '228-2')), '228-2 value', '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = 0;
+ $result = $this->Form->select('Model.field', array('0' => 'No', '1' => 'Yes'));
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => '')), '/option',
+ array('option' => array('value' => '0', 'selected' => 'selected')), 'No', '/option',
+ array('option' => array('value' => '1')), 'Yes', '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that select() with optiongroups listens to the escape param.
+ *
+ * @return void
+ */
+ public function testSelectOptionGroupEscaping() {
+ $options = array(
+ '>< Key' => array(
+ 1 => 'One',
+ 2 => 'Two'
+ )
+ );
+ $result = $this->Form->select('Model.field', $options, array('empty' => false));
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ 'optgroup' => array('label' => '&gt;&lt; Key'),
+ array('option' => array('value' => '1')), 'One', '/option',
+ array('option' => array('value' => '2')), 'Two', '/option',
+ '/optgroup',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $options = array(
+ '>< Key' => array(
+ 1 => 'One',
+ 2 => 'Two'
+ )
+ );
+ $result = $this->Form->select('Model.field', $options, array('empty' => false, 'escape' => false));
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ 'optgroup' => array('label' => '>< Key'),
+ array('option' => array('value' => '1')), 'One', '/option',
+ array('option' => array('value' => '2')), 'Two', '/option',
+ '/optgroup',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Tests that FormHelper::select() allows null to be passed in the $attributes parameter
+ *
+ * @return void
+ */
+ public function testSelectWithNullAttributes() {
+ $result = $this->Form->select('Model.field', array('first', 'second'), array('empty' => false));
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => '0')),
+ 'first',
+ '/option',
+ array('option' => array('value' => '1')),
+ 'second',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testNestedSelect method
+ *
+ * test select element generation with optgroups
+ *
+ * @return void
+ */
+ public function testNestedSelect() {
+ $result = $this->Form->select(
+ 'Model.field',
+ array(1 => 'One', 2 => 'Two', 'Three' => array(
+ 3 => 'Three', 4 => 'Four', 5 => 'Five'
+ )), array('empty' => false)
+ );
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]',
+ 'id' => 'ModelField'),
+ array('option' => array('value' => 1)),
+ 'One',
+ '/option',
+ array('option' => array('value' => 2)),
+ 'Two',
+ '/option',
+ array('optgroup' => array('label' => 'Three')),
+ array('option' => array('value' => 4)),
+ 'Four',
+ '/option',
+ array('option' => array('value' => 5)),
+ 'Five',
+ '/option',
+ '/optgroup',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.field',
+ array(1 => 'One', 2 => 'Two', 'Three' => array(3 => 'Three', 4 => 'Four')),
+ array('showParents' => true, 'empty' => false)
+ );
+
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => 1)),
+ 'One',
+ '/option',
+ array('option' => array('value' => 2)),
+ 'Two',
+ '/option',
+ array('optgroup' => array('label' => 'Three')),
+ array('option' => array('value' => 3)),
+ 'Three',
+ '/option',
+ array('option' => array('value' => 4)),
+ 'Four',
+ '/option',
+ '/optgroup',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSelectMultiple method
+ *
+ * test generation of multiple select elements
+ *
+ * @return void
+ */
+ public function testSelectMultiple() {
+ $options = array('first', 'second', 'third');
+ $result = $this->Form->select(
+ 'Model.multi_field', $options, array('multiple' => true)
+ );
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField_'
+ ),
+ 'select' => array(
+ 'name' => 'data[Model][multi_field][]',
+ 'id' => 'ModelMultiField', 'multiple' => 'multiple'
+ ),
+ array('option' => array('value' => '0')),
+ 'first',
+ '/option',
+ array('option' => array('value' => '1')),
+ 'second',
+ '/option',
+ array('option' => array('value' => '2')),
+ 'third',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.multi_field', $options, array('multiple' => 'multiple')
+ );
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField_'
+ ),
+ 'select' => array(
+ 'name' => 'data[Model][multi_field][]',
+ 'id' => 'ModelMultiField', 'multiple' => 'multiple'
+ ),
+ array('option' => array('value' => '0')),
+ 'first',
+ '/option',
+ array('option' => array('value' => '1')),
+ 'second',
+ '/option',
+ array('option' => array('value' => '2')),
+ 'third',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.multi_field', $options, array('multiple' => true, 'value' => array(0, 1))
+ );
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField_'
+ ),
+ 'select' => array(
+ 'name' => 'data[Model][multi_field][]', 'id' => 'ModelMultiField',
+ 'multiple' => 'multiple'
+ ),
+ array('option' => array('value' => '0', 'selected' => 'selected')),
+ 'first',
+ '/option',
+ array('option' => array('value' => '1', 'selected' => 'selected')),
+ 'second',
+ '/option',
+ array('option' => array('value' => '2')),
+ 'third',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.multi_field', $options, array('multiple' => false, 'value' => array(0, 1))
+ );
+ $expected = array(
+ 'select' => array(
+ 'name' => 'data[Model][multi_field]', 'id' => 'ModelMultiField'
+ ),
+ array('option' => array('value' => '0', 'selected' => 'selected')),
+ 'first',
+ '/option',
+ array('option' => array('value' => '1', 'selected' => 'selected')),
+ 'second',
+ '/option',
+ array('option' => array('value' => '2')),
+ 'third',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test generation of habtm select boxes.
+ *
+ * @return void
+ */
+ public function testHabtmSelectBox() {
+ $this->View->viewVars['contactTags'] = array(
+ 1 => 'blue',
+ 2 => 'red',
+ 3 => 'green'
+ );
+ $this->Form->request->data = array(
+ 'Contact' => array(),
+ 'ContactTag' => array(
+ array(
+ 'id' => 1,
+ 'name' => 'blue'
+ ),
+ array(
+ 'id' => 3,
+ 'name' => 'green'
+ )
+ )
+ );
+ $this->Form->create('Contact');
+ $result = $this->Form->input('ContactTag', array('div' => false, 'label' => false));
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[ContactTag][ContactTag]', 'value' => '', 'id' => 'ContactTagContactTag_'
+ ),
+ 'select' => array(
+ 'name' => 'data[ContactTag][ContactTag][]', 'id' => 'ContactTagContactTag',
+ 'multiple' => 'multiple'
+ ),
+ array('option' => array('value' => '1', 'selected' => 'selected')),
+ 'blue',
+ '/option',
+ array('option' => array('value' => '2')),
+ 'red',
+ '/option',
+ array('option' => array('value' => '3', 'selected' => 'selected')),
+ 'green',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test generation of multi select elements in checkbox format
+ *
+ * @return void
+ */
+ public function testSelectMultipleCheckboxes() {
+ $result = $this->Form->select(
+ 'Model.multi_field',
+ array('first', 'second', 'third'),
+ array('multiple' => 'checkbox')
+ );
+
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
+ ),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => '0', 'id' => 'ModelMultiField0'
+ )),
+ array('label' => array('for' => 'ModelMultiField0')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => '1', 'id' => 'ModelMultiField1'
+ )),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'second',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => '2', 'id' => 'ModelMultiField2'
+ )),
+ array('label' => array('for' => 'ModelMultiField2')),
+ 'third',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.multi_field',
+ array('a' => 'first', 'b' => 'second', 'c' => 'third'),
+ array('multiple' => 'checkbox')
+ );
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
+ ),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => 'a', 'id' => 'ModelMultiFieldA'
+ )),
+ array('label' => array('for' => 'ModelMultiFieldA')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => 'b', 'id' => 'ModelMultiFieldB'
+ )),
+ array('label' => array('for' => 'ModelMultiFieldB')),
+ 'second',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => 'c', 'id' => 'ModelMultiFieldC'
+ )),
+ array('label' => array('for' => 'ModelMultiFieldC')),
+ 'third',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.multi_field', array('1' => 'first'), array('multiple' => 'checkbox')
+ );
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'
+ ),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => '1', 'id' => 'ModelMultiField1'
+ )),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'first',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array('Model' => array('tags' => array(1)));
+ $result = $this->Form->select(
+ 'Model.tags', array('1' => 'first', 'Array' => 'Array'), array('multiple' => 'checkbox')
+ );
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][tags]', 'value' => '', 'id' => 'ModelTags'
+ ),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][tags][]',
+ 'value' => '1', 'id' => 'ModelTags1', 'checked' => 'checked'
+ )),
+ array('label' => array('for' => 'ModelTags1', 'class' => 'selected')),
+ 'first',
+ '/label',
+ '/div',
+
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][tags][]',
+ 'value' => 'Array', 'id' => 'ModelTagsArray'
+ )),
+ array('label' => array('for' => 'ModelTagsArray')),
+ 'Array',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test multiple checkboxes with div styles.
+ *
+ * @return void
+ */
+ public function testSelectMultipleCheckboxDiv() {
+ $result = $this->Form->select(
+ 'Model.tags',
+ array('first', 'second'),
+ array('multiple' => 'checkbox', 'class' => 'my-class')
+ );
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][tags]', 'value' => '', 'id' => 'ModelTags'
+ ),
+ array('div' => array('class' => 'my-class')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][tags][]',
+ 'value' => '0', 'id' => 'ModelTags0'
+ )),
+ array('label' => array('for' => 'ModelTags0')), 'first', '/label',
+ '/div',
+
+ array('div' => array('class' => 'my-class')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][tags][]',
+ 'value' => '1', 'id' => 'ModelTags1'
+ )),
+ array('label' => array('for' => 'ModelTags1')), 'second', '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.tags', array(
+ 'options' => array('first', 'second'),
+ 'multiple' => 'checkbox',
+ 'class' => 'my-class',
+ 'div' => false,
+ 'label' => false
+ ));
+ $this->assertTags($result, $expected);
+
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors['tags'] = 'Select atleast one option';
+ $result = $this->Form->input('Contact.tags', array(
+ 'options' => array('one'),
+ 'multiple' => 'checkbox',
+ 'label' => false,
+ 'div' => false
+ ));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][tags]', 'value' => '', 'id' => 'ContactTags'),
+ array('div' => array('class' => 'checkbox form-error')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][tags][]', 'value' => '0', 'id' => 'ContactTags0')),
+ array('label' => array('for' => 'ContactTags0')),
+ 'one',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.tags', array(
+ 'options' => array('one'),
+ 'multiple' => 'checkbox',
+ 'class' => 'mycheckbox',
+ 'label' => false,
+ 'div' => false
+ ));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][tags]', 'value' => '', 'id' => 'ContactTags'),
+ array('div' => array('class' => 'mycheckbox form-error')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][tags][]', 'value' => '0', 'id' => 'ContactTags0')),
+ array('label' => array('for' => 'ContactTags0')),
+ 'one',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Checks the security hash array generated for multiple-input checkbox elements
+ *
+ * @return void
+ */
+ public function testSelectMultipleCheckboxSecurity() {
+ $this->Form->request['_Token'] = array('key' => 'testKey');
+ $this->assertEquals(array(), $this->Form->fields);
+
+ $result = $this->Form->select(
+ 'Model.multi_field', array('1' => 'first', '2' => 'second', '3' => 'third'),
+ array('multiple' => 'checkbox')
+ );
+ $this->assertEquals(array('Model.multi_field'), $this->Form->fields);
+
+ $result = $this->Form->secure($this->Form->fields);
+ $key = 'f7d573650a295b94e0938d32b323fde775e5f32b%3A';
+ $this->assertRegExp('/"' . $key . '"/', $result);
+ }
+
+/**
+ * testInputMultipleCheckboxes method
+ *
+ * test input() resulting in multi select elements being generated.
+ *
+ * @return void
+ */
+ public function testInputMultipleCheckboxes() {
+ $result = $this->Form->input('Model.multi_field', array(
+ 'options' => array('first', 'second', 'third'),
+ 'multiple' => 'checkbox'
+ ));
+ $expected = array(
+ array('div' => array('class' => 'input select')),
+ array('label' => array('for' => 'ModelMultiField')),
+ 'Multi Field',
+ '/label',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
+ array('label' => array('for' => 'ModelMultiField0')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'second',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '2', 'id' => 'ModelMultiField2')),
+ array('label' => array('for' => 'ModelMultiField2')),
+ 'third',
+ '/label',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.multi_field', array(
+ 'options' => array('a' => 'first', 'b' => 'second', 'c' => 'third'),
+ 'multiple' => 'checkbox'
+ ));
+ $expected = array(
+ array('div' => array('class' => 'input select')),
+ array('label' => array('for' => 'ModelMultiField')),
+ 'Multi Field',
+ '/label',
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => 'a', 'id' => 'ModelMultiFieldA')),
+ array('label' => array('for' => 'ModelMultiFieldA')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => 'b', 'id' => 'ModelMultiFieldB')),
+ array('label' => array('for' => 'ModelMultiFieldB')),
+ 'second',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => 'c', 'id' => 'ModelMultiFieldC')),
+ array('label' => array('for' => 'ModelMultiFieldC')),
+ 'third',
+ '/label',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.multi_field', array(
+ 'options' => array('1' => 'first'),
+ 'multiple' => 'checkbox',
+ 'label' => false,
+ 'div' => false
+ ));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'first',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.multi_field', array(
+ 'options' => array('2' => 'second'),
+ 'multiple' => 'checkbox',
+ 'label' => false,
+ 'div' => false
+ ));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'ModelMultiField'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '2', 'id' => 'ModelMultiField2')),
+ array('label' => array('for' => 'ModelMultiField2')),
+ 'second',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSelectHiddenFieldOmission method
+ *
+ * test that select() with 'hiddenField' => false omits the hidden field
+ *
+ * @return void
+ */
+ public function testSelectHiddenFieldOmission() {
+ $result = $this->Form->select('Model.multi_field',
+ array('first', 'second'),
+ array('multiple' => 'checkbox', 'hiddenField' => false, 'value' => null)
+ );
+ $expected = array(
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
+ array('label' => array('for' => 'ModelMultiField0')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'second',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.multi_field', array(
+ 'options' => array('first', 'second'),
+ 'multiple' => 'checkbox',
+ 'hiddenField' => false
+ ));
+ $expected = array(
+ array('div' => array('class' => 'input select')),
+ array('label' => array('for' => 'ModelMultiField')),
+ 'Multi Field',
+ '/label',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
+ array('label' => array('for' => 'ModelMultiField0')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'second',
+ '/label',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that select() with multiple = checkbox works with overriding name attribute.
+ *
+ * @return void
+ */
+ public function testSelectCheckboxMultipleOverrideName() {
+ $result = $this->Form->input('category', array(
+ 'type' => 'select',
+ 'multiple' => 'checkbox',
+ 'name' => 'data[fish]',
+ 'options' => array('1', '2'),
+ 'div' => false,
+ 'label' => false,
+ ));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[fish]', 'value' => '', 'id' => 'category'),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[fish][]', 'value' => '0', 'id' => 'Category0')),
+ array('label' => array('for' => 'Category0')), '1', '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[fish][]', 'value' => '1', 'id' => 'Category1')),
+ array('label' => array('for' => 'Category1')), '2', '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test that 'id' overrides all the checkbox id's as well.
+ *
+ * @return void
+ */
+ public function testSelectCheckboxMultipleId() {
+ $result = $this->Form->select(
+ 'Model.multi_field',
+ array('first', 'second', 'third'),
+ array('multiple' => 'checkbox', 'id' => 'CustomId')
+ );
+
+ $expected = array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Model][multi_field]', 'value' => '', 'id' => 'CustomId'
+ ),
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => '0', 'id' => 'CustomId0'
+ )),
+ array('label' => array('for' => 'CustomId0')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => '1', 'id' => 'CustomId1'
+ )),
+ array('label' => array('for' => 'CustomId1')),
+ 'second',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[Model][multi_field][]',
+ 'value' => '2', 'id' => 'CustomId2'
+ )),
+ array('label' => array('for' => 'CustomId2')),
+ 'third',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testCheckbox method
+ *
+ * Test generation of checkboxes
+ *
+ * @return void
+ */
+ public function testCheckbox() {
+ $result = $this->Form->checkbox('Model.field');
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('Model.field', array('id' => 'theID', 'value' => 'myvalue'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'theID_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => 'myvalue', 'id' => 'theID'))
+ );
+ $this->assertTags($result, $expected);
+
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors['field'] = 1;
+ $this->Form->request->data['Contact']['field'] = 'myvalue';
+ $result = $this->Form->checkbox('Contact.field', array('id' => 'theID', 'value' => 'myvalue'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'theID_'),
+ array('input' => array('preg:/[^<]+/', 'value' => 'myvalue', 'id' => 'theID', 'checked' => 'checked', 'class' => 'form-error'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('Contact.field', array('value' => 'myvalue'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'ContactField_'),
+ array('input' => array('preg:/[^<]+/', 'value' => 'myvalue', 'id' => 'ContactField', 'checked' => 'checked', 'class' => 'form-error'))
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['field'] = '';
+ $result = $this->Form->checkbox('Contact.field', array('id' => 'theID'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'theID_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][field]', 'value' => '1', 'id' => 'theID', 'class' => 'form-error'))
+ );
+ $this->assertTags($result, $expected);
+
+ $Contact->validationErrors = array();
+ $result = $this->Form->checkbox('Contact.field', array('value' => 'myvalue'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][field]', 'value' => '0', 'id' => 'ContactField_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][field]', 'value' => 'myvalue', 'id' => 'ContactField'))
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = 1;
+ $result = $this->Form->checkbox('Contact.published', array('id' => 'theID'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][published]', 'value' => '0', 'id' => 'theID_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][published]', 'value' => '1', 'id' => 'theID', 'checked' => 'checked'))
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = 0;
+ $result = $this->Form->checkbox('Contact.published', array('id' => 'theID'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Contact][published]', 'value' => '0', 'id' => 'theID_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Contact][published]', 'value' => '1', 'id' => 'theID'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('Model.CustomField.1.value');
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][CustomField][1][value]', 'value' => '0', 'id' => 'ModelCustomField1Value_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][CustomField][1][value]', 'value' => '1', 'id' => 'ModelCustomField1Value'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('CustomField.1.value');
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[CustomField][1][value]', 'value' => '0', 'id' => 'CustomField1Value_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[CustomField][1][value]', 'value' => '1', 'id' => 'CustomField1Value'))
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test checkbox() with a custom name attribute
+ *
+ * @return void
+ */
+ public function testCheckboxCustomNameAttribute() {
+ $result = $this->Form->checkbox('Test.test', array('name' => 'myField'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'myField', 'value' => '0', 'id' => 'TestTest_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'myField', 'value' => '1', 'id' => 'TestTest'))
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test the checked option for checkboxes.
+ *
+ * @return void
+ */
+ public function testCheckboxCheckedOption() {
+ $result = $this->Form->checkbox('Model.field', array('checked' => 'checked'));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('Model.field', array('checked' => 1));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('Model.field', array('checked' => true));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField', 'checked' => 'checked'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('Model.field', array('checked' => false));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField'))
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = 1;
+ $result = $this->Form->checkbox('Model.field', array('checked' => false));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[Model][field]', 'value' => '0', 'id' => 'ModelField_'),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][field]', 'value' => '1', 'id' => 'ModelField'))
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test that disabled attribute works on both the checkbox and hidden input.
+ *
+ * @return void
+ */
+ public function testCheckboxDisabling() {
+ $result = $this->Form->checkbox('Account.show_name', array('disabled' => 'disabled'));
+ $expected = array(
+ array('input' => array('type' => 'hidden', 'name' => 'data[Account][show_name]', 'value' => '0', 'id' => 'AccountShowName_', 'disabled' => 'disabled')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Account][show_name]', 'value' => '1', 'id' => 'AccountShowName', 'disabled' => 'disabled'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->checkbox('Account.show_name', array('disabled' => false));
+ $expected = array(
+ array('input' => array('type' => 'hidden', 'name' => 'data[Account][show_name]', 'value' => '0', 'id' => 'AccountShowName_')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Account][show_name]', 'value' => '1', 'id' => 'AccountShowName'))
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test that the hidden input for checkboxes can be omitted or set to a
+ * specific value.
+ *
+ * @return void
+ */
+ public function testCheckboxHiddenField() {
+ $result = $this->Form->input('UserForm.something', array(
+ 'type' => 'checkbox',
+ 'hiddenField' => false
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input checkbox'),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[UserForm][something]',
+ 'value' => '1', 'id' => 'UserFormSomething'
+ )),
+ 'label' => array('for' => 'UserFormSomething'),
+ 'Something',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('UserForm.something', array(
+ 'type' => 'checkbox',
+ 'value' => 'Y',
+ 'hiddenField' => 'N',
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input checkbox'),
+ array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[UserForm][something]',
+ 'value' => 'N', 'id' => 'UserFormSomething_'
+ )),
+ array('input' => array(
+ 'type' => 'checkbox', 'name' => 'data[UserForm][something]',
+ 'value' => 'Y', 'id' => 'UserFormSomething'
+ )),
+ 'label' => array('for' => 'UserFormSomething'),
+ 'Something',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testDateTime method
+ *
+ * Test generation of date/time select elements
+ *
+ * @return void
+ */
+ public function testDateTime() {
+ extract($this->dateRegex);
+
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('empty' => false));
+ $now = strtotime('now');
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
+ $daysRegex,
+ array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
+ date('j', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
+ $monthsRegex,
+ array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
+ date('F', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
+ $yearsRegex,
+ array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
+ date('Y', $now),
+ '/option',
+ '*/select',
+ array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
+ $hoursRegex,
+ array('option' => array('value' => date('h', $now), 'selected' => 'selected')),
+ date('g', $now),
+ '/option',
+ '*/select',
+ ':',
+ array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
+ $minutesRegex,
+ array('option' => array('value' => date('i', $now), 'selected' => 'selected')),
+ date('i', $now),
+ '/option',
+ '*/select',
+ ' ',
+ array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
+ $meridianRegex,
+ array('option' => array('value' => date('a', $now), 'selected' => 'selected')),
+ date('a', $now),
+ '/option',
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12');
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
+ $daysRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
+ $monthsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
+ $yearsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
+ $hoursRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ':',
+ array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
+ $minutesRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ' ',
+ array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
+ $meridianRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+ $this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
+
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('value' => false));
+ $this->assertTags($result, $expected);
+ $this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
+
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('value' => ''));
+ $this->assertTags($result, $expected);
+ $this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
+
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('interval' => 5, 'value' => ''));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
+ $daysRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
+ $monthsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
+ $yearsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
+ $hoursRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ':',
+ array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
+ $minutesRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '00')),
+ '00',
+ '/option',
+ array('option' => array('value' => '05')),
+ '05',
+ '/option',
+ array('option' => array('value' => '10')),
+ '10',
+ '/option',
+ '*/select',
+ ' ',
+ array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
+ $meridianRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+ $this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
+
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('minuteInterval' => 5, 'value' => ''));
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('minuteInterval' => 5, 'value' => ''));
+
+ $this->Form->request->data['Contact']['data'] = null;
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12');
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][date][day]', 'id' => 'ContactDateDay')),
+ $daysRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][month]', 'id' => 'ContactDateMonth')),
+ $monthsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][date][year]', 'id' => 'ContactDateYear')),
+ $yearsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ array('select' => array('name' => 'data[Contact][date][hour]', 'id' => 'ContactDateHour')),
+ $hoursRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ':',
+ array('select' => array('name' => 'data[Contact][date][min]', 'id' => 'ContactDateMin')),
+ $minutesRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ' ',
+ array('select' => array('name' => 'data[Contact][date][meridian]', 'id' => 'ContactDateMeridian')),
+ $meridianRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+ $this->assertNotRegExp('/<option[^<>]+value=""[^<>]+selected="selected"[^>]*>/', $result);
+
+ $this->Form->request->data['Model']['field'] = date('Y') . '-01-01 00:00:00';
+ $now = strtotime($this->Form->data['Model']['field']);
+ $result = $this->Form->dateTime('Model.field', 'DMY', '12', array('empty' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
+ $daysRegex,
+ array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
+ date('j', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
+ $monthsRegex,
+ array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
+ date('F', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Model][field][year]', 'id' => 'ModelFieldYear')),
+ $yearsRegex,
+ array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
+ date('Y', $now),
+ '/option',
+ '*/select',
+ array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
+ $hoursRegex,
+ array('option' => array('value' => date('h', $now), 'selected' => 'selected')),
+ date('g', $now),
+ '/option',
+ '*/select',
+ ':',
+ array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
+ $minutesRegex,
+ array('option' => array('value' => date('i', $now), 'selected' => 'selected')),
+ date('i', $now),
+ '/option',
+ '*/select',
+ ' ',
+ array('select' => array('name' => 'data[Model][field][meridian]', 'id' => 'ModelFieldMeridian')),
+ $meridianRegex,
+ array('option' => array('value' => date('a', $now), 'selected' => 'selected')),
+ date('a', $now),
+ '/option',
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $selected = strtotime('2008-10-26 12:33:00');
+ $result = $this->Form->dateTime('Model.field', 'DMY', '12', array('value' => $selected));
+ $this->assertRegExp('/<option[^<>]+value="2008"[^<>]+selected="selected"[^>]*>2008<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="10"[^<>]+selected="selected"[^>]*>October<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="26"[^<>]+selected="selected"[^>]*>26<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="12"[^<>]+selected="selected"[^>]*>12<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="33"[^<>]+selected="selected"[^>]*>33<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="pm"[^<>]+selected="selected"[^>]*>pm<\/option>/', $result);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->input('published');
+ $now = strtotime('now');
+ $expected = array(
+ 'div' => array('class' => 'input date'),
+ 'label' => array('for' => 'ContactPublishedMonth'),
+ 'Published',
+ '/label',
+ array('select' => array('name' => 'data[Contact][published][month]', 'id' => 'ContactPublishedMonth')),
+ $monthsRegex,
+ array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
+ date('F', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][published][day]', 'id' => 'ContactPublishedDay')),
+ $daysRegex,
+ array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
+ date('j', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ $yearsRegex,
+ array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
+ date('Y', $now),
+ '/option',
+ '*/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('published2', array('type' => 'date'));
+ $now = strtotime('now');
+ $expected = array(
+ 'div' => array('class' => 'input date'),
+ 'label' => array('for' => 'ContactPublished2Month'),
+ 'Published2',
+ '/label',
+ array('select' => array('name' => 'data[Contact][published2][month]', 'id' => 'ContactPublished2Month')),
+ $monthsRegex,
+ array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
+ date('F', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][published2][day]', 'id' => 'ContactPublished2Day')),
+ $daysRegex,
+ array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
+ date('j', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][published2][year]', 'id' => 'ContactPublished2Year')),
+ $yearsRegex,
+ array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
+ date('Y', $now),
+ '/option',
+ '*/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('Contact');
+ $result = $this->Form->input('published', array('monthNames' => false));
+ $now = strtotime('now');
+ $expected = array(
+ 'div' => array('class' => 'input date'),
+ 'label' => array('for' => 'ContactPublishedMonth'),
+ 'Published',
+ '/label',
+ array('select' => array('name' => 'data[Contact][published][month]', 'id' => 'ContactPublishedMonth')),
+ 'preg:/(?:<option value="([\d])+">[\d]+<\/option>[\r\n]*)*/',
+ array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
+ date('m', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][published][day]', 'id' => 'ContactPublishedDay')),
+ $daysRegex,
+ array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
+ date('j', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ $yearsRegex,
+ array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
+ date('Y', $now),
+ '/option',
+ '*/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('published', array('type' => 'time'));
+ $now = strtotime('now');
+ $expected = array(
+ 'div' => array('class' => 'input time'),
+ 'label' => array('for' => 'ContactPublishedHour'),
+ 'Published',
+ '/label',
+ array('select' => array('name' => 'data[Contact][published][hour]', 'id' => 'ContactPublishedHour')),
+ 'preg:/(?:<option value="([\d])+">[\d]+<\/option>[\r\n]*)*/',
+ array('option' => array('value' => date('h', $now), 'selected' => 'selected')),
+ date('g', $now),
+ '/option',
+ '*/select',
+ ':',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('published', array(
+ 'timeFormat' => 24,
+ 'interval' => 5,
+ 'selected' => strtotime('2009-09-03 13:37:00'),
+ 'type' => 'datetime'
+ ));
+ $this->assertRegExp('/<option[^<>]+value="2009"[^<>]+selected="selected"[^>]*>2009<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="09"[^<>]+selected="selected"[^>]*>September<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="03"[^<>]+selected="selected"[^>]*>3<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="13"[^<>]+selected="selected"[^>]*>13<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="35"[^<>]+selected="selected"[^>]*>35<\/option>/', $result);
+
+ $this->assertNoErrors();
+ $this->Form->request->data['Contact'] = array(
+ 'date' => array(
+ 'day' => '',
+ 'month' => '',
+ 'year' => '',
+ 'hour' => '',
+ 'min' => '',
+ 'meridian' => ''
+ )
+ );
+ $result = $this->Form->dateTime('Contact.date', 'DMY', '12', array('empty' => false));
+ }
+
+/**
+ * test that datetime() and default values work.
+ *
+ * @return void
+ */
+ public function testDatetimeWithDefault() {
+ $result = $this->Form->dateTime('Contact.updated', 'DMY', '12', array('value' => '2009-06-01 11:15:30'));
+ $this->assertRegExp('/<option[^<>]+value="2009"[^<>]+selected="selected"[^>]*>2009<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="01"[^<>]+selected="selected"[^>]*>1<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="06"[^<>]+selected="selected"[^>]*>June<\/option>/', $result);
+
+ $result = $this->Form->dateTime('Contact.updated', 'DMY', '12', array(
+ 'default' => '2009-06-01 11:15:30'
+ ));
+ $this->assertRegExp('/<option[^<>]+value="2009"[^<>]+selected="selected"[^>]*>2009<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="01"[^<>]+selected="selected"[^>]*>1<\/option>/', $result);
+ $this->assertRegExp('/<option[^<>]+value="06"[^<>]+selected="selected"[^>]*>June<\/option>/', $result);
+ }
+
+/**
+ * test that bogus non-date time data doesn't cause errors.
+ *
+ * @return void
+ */
+ public function testDateTimeWithBogusData() {
+ $result = $this->Form->dateTime('Contact.updated', 'DMY', '12', array('value' => 'CURRENT_TIMESTAMP'));
+ $this->assertNotRegExp('/selected="selected">\d/', $result);
+ }
+
+/**
+ * testFormDateTimeMulti method
+ *
+ * test multiple datetime element generation
+ *
+ * @return void
+ */
+ public function testFormDateTimeMulti() {
+ extract($this->dateRegex);
+
+ $result = $this->Form->dateTime('Contact.1.updated');
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][1][updated][day]', 'id' => 'Contact1UpdatedDay')),
+ $daysRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][1][updated][month]', 'id' => 'Contact1UpdatedMonth')),
+ $monthsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][1][updated][year]', 'id' => 'Contact1UpdatedYear')),
+ $yearsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ array('select' => array('name' => 'data[Contact][1][updated][hour]', 'id' => 'Contact1UpdatedHour')),
+ $hoursRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ':',
+ array('select' => array('name' => 'data[Contact][1][updated][min]', 'id' => 'Contact1UpdatedMin')),
+ $minutesRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ' ',
+ array('select' => array('name' => 'data[Contact][1][updated][meridian]', 'id' => 'Contact1UpdatedMeridian')),
+ $meridianRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->dateTime('Contact.2.updated');
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][2][updated][day]', 'id' => 'Contact2UpdatedDay')),
+ $daysRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][2][updated][month]', 'id' => 'Contact2UpdatedMonth')),
+ $monthsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array('name' => 'data[Contact][2][updated][year]', 'id' => 'Contact2UpdatedYear')),
+ $yearsRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ array('select' => array('name' => 'data[Contact][2][updated][hour]', 'id' => 'Contact2UpdatedHour')),
+ $hoursRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ':',
+ array('select' => array('name' => 'data[Contact][2][updated][min]', 'id' => 'Contact2UpdatedMin')),
+ $minutesRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select',
+ ' ',
+ array('select' => array('name' => 'data[Contact][2][updated][meridian]', 'id' => 'Contact2UpdatedMeridian')),
+ $meridianRegex,
+ array('option' => array('value' => '')),
+ '/option',
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * When changing the date format, the label should always focus the first select box when
+ * clicked.
+ *
+ * @return void
+ */
+ public function testDateTimeLabelIdMatchesFirstInput() {
+ $result = $this->Form->input('Model.date', array('type' => 'date'));
+ $this->assertContains('label for="ModelDateMonth"', $result);
+
+ $result = $this->Form->input('Model.date', array('type' => 'date', 'dateFormat' => 'DMY'));
+ $this->assertContains('label for="ModelDateDay"', $result);
+
+ $result = $this->Form->input('Model.date', array('type' => 'date', 'dateFormat' => 'YMD'));
+ $this->assertContains('label for="ModelDateYear"', $result);
+ }
+
+/**
+ * testMonth method
+ *
+ * @return void
+ */
+ public function testMonth() {
+ $result = $this->Form->month('Model.field');
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ date('F', strtotime('2008-01-01 00:00:00')),
+ '/option',
+ array('option' => array('value' => '02')),
+ date('F', strtotime('2008-02-01 00:00:00')),
+ '/option',
+ '*/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->month('Model.field', array('empty' => true));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ date('F', strtotime('2008-01-01 00:00:00')),
+ '/option',
+ array('option' => array('value' => '02')),
+ date('F', strtotime('2008-02-01 00:00:00')),
+ '/option',
+ '*/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->month('Model.field', array('monthNames' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ '01',
+ '/option',
+ array('option' => array('value' => '02')),
+ '02',
+ '/option',
+ '*/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $monthNames = array(
+ '01' => 'Jan', '02' => 'Feb', '03' => 'Mar', '04' => 'Apr', '05' => 'May', '06' => 'Jun',
+ '07' => 'Jul', '08' => 'Aug', '09' => 'Sep', '10' => 'Oct', '11' => 'Nov', '12' => 'Dec');
+ $result = $this->Form->month('Model.field', array('monthNames' => $monthNames));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][month]', 'id' => 'ModelFieldMonth')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ 'Jan',
+ '/option',
+ array('option' => array('value' => '02')),
+ 'Feb',
+ '/option',
+ '*/select',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testDay method
+ *
+ * @return void
+ */
+ public function testDay() {
+ extract($this->dateRegex);
+
+ $result = $this->Form->day('Model.field', array('value' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $daysRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '2006-10-10 23:12:32';
+ $result = $this->Form->day('Model.field');
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $daysRegex,
+ array('option' => array('value' => '10', 'selected' => 'selected')),
+ '10',
+ '/option',
+ $daysRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '';
+ $result = $this->Form->day('Model.field', array('value' => '10'));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $daysRegex,
+ array('option' => array('value' => '10', 'selected' => 'selected')),
+ '10',
+ '/option',
+ $daysRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '2006-10-10 23:12:32';
+ $result = $this->Form->day('Model.field', array('value' => true));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][day]', 'id' => 'ModelFieldDay')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $daysRegex,
+ array('option' => array('value' => '10', 'selected' => 'selected')),
+ '10',
+ '/option',
+ $daysRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testMinute method
+ *
+ * @return void
+ */
+ public function testMinute() {
+ extract($this->dateRegex);
+
+ $result = $this->Form->minute('Model.field');
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '00')),
+ '00',
+ '/option',
+ array('option' => array('value' => '01')),
+ '01',
+ '/option',
+ array('option' => array('value' => '02')),
+ '02',
+ '/option',
+ $minutesRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '2006-10-10 00:12:32';
+ $result = $this->Form->minute('Model.field');
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '00')),
+ '00',
+ '/option',
+ array('option' => array('value' => '01')),
+ '01',
+ '/option',
+ array('option' => array('value' => '02')),
+ '02',
+ '/option',
+ $minutesRegex,
+ array('option' => array('value' => '12', 'selected' => 'selected')),
+ '12',
+ '/option',
+ $minutesRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '';
+ $result = $this->Form->minute('Model.field', array('interval' => 5));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '00')),
+ '00',
+ '/option',
+ array('option' => array('value' => '05')),
+ '05',
+ '/option',
+ array('option' => array('value' => '10')),
+ '10',
+ '/option',
+ $minutesRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '2006-10-10 00:10:32';
+ $result = $this->Form->minute('Model.field', array('interval' => 5));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][min]', 'id' => 'ModelFieldMin')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '00')),
+ '00',
+ '/option',
+ array('option' => array('value' => '05')),
+ '05',
+ '/option',
+ array('option' => array('value' => '10', 'selected' => 'selected')),
+ '10',
+ '/option',
+ $minutesRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testHour method
+ *
+ * @return void
+ */
+ public function testHour() {
+ extract($this->dateRegex);
+
+ $result = $this->Form->hour('Model.field', false);
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $hoursRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '2006-10-10 00:12:32';
+ $result = $this->Form->hour('Model.field', false);
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $hoursRegex,
+ array('option' => array('value' => '12', 'selected' => 'selected')),
+ '12',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '';
+ $result = $this->Form->hour('Model.field', true, array('value' => '23'));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '00')),
+ '0',
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $hoursRegex,
+ array('option' => array('value' => '23', 'selected' => 'selected')),
+ '23',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['field'] = '2006-10-10 00:12:32';
+ $result = $this->Form->hour('Model.field', true);
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][hour]', 'id' => 'ModelFieldHour')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '00', 'selected' => 'selected')),
+ '0',
+ '/option',
+ array('option' => array('value' => '01')),
+ '1',
+ '/option',
+ array('option' => array('value' => '02')),
+ '2',
+ '/option',
+ $hoursRegex,
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ unset($this->Form->request->data['Model']['field']);
+ $result = $this->Form->hour('Model.field', true, array('value' => 'now'));
+ $thisHour = date('H');
+ $optValue = date('G');
+ $this->assertRegExp('/<option value="' . $thisHour . '" selected="selected">' . $optValue . '<\/option>/', $result);
+ }
+
+/**
+ * testYear method
+ *
+ * @return void
+ */
+ public function testYear() {
+ $result = $this->Form->year('Model.field', 2006, 2007);
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][year]', 'id' => 'ModelFieldYear')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->year('Model.field', 2006, 2007, array('orderYear' => 'asc'));
+ $expected = array(
+ array('select' => array('name' => 'data[Model][field][year]', 'id' => 'ModelFieldYear')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->request->data['Contact']['published'] = '';
+ $result = $this->Form->year('Contact.published', 2006, 2007, array('class' => 'year'));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear', 'class' => 'year')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = '2006-10-10';
+ $result = $this->Form->year('Contact.published', 2006, 2007, array('empty' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006', 'selected' => 'selected')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = '';
+ $result = $this->Form->year('Contact.published', 2006, 2007, array('value' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = '2006-10-10';
+ $result = $this->Form->year('Contact.published', 2006, 2007, array('empty' => false, 'value' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006', 'selected' => 'selected')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = '';
+ $result = $this->Form->year('Contact.published', 2006, 2007, array('value' => 2007));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '')),
+ '/option',
+ array('option' => array('value' => '2007', 'selected' => 'selected')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = '2006-10-10';
+ $result = $this->Form->year('Contact.published', 2006, 2007, array('empty' => false, 'value' => 2007));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '2007', 'selected' => 'selected')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = '';
+ $result = $this->Form->year('Contact.published', 2006, 2008, array('empty' => false, 'value' => 2007));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '2008')),
+ '2008',
+ '/option',
+ array('option' => array('value' => '2007', 'selected' => 'selected')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['published'] = '2006-10-10';
+ $result = $this->Form->year('Contact.published', 2006, 2008, array('empty' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '2008')),
+ '2008',
+ '/option',
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006', 'selected' => 'selected')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array();
+ $this->Form->create('Contact');
+ $result = $this->Form->year('published', 2006, 2008, array('empty' => false));
+ $expected = array(
+ array('select' => array('name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear')),
+ array('option' => array('value' => '2008')),
+ '2008',
+ '/option',
+ array('option' => array('value' => '2007')),
+ '2007',
+ '/option',
+ array('option' => array('value' => '2006')),
+ '2006',
+ '/option',
+ '/select',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->year('published', array(), array(), array('empty' => false));
+ $this->assertContains('data[Contact][published][year]', $result);
+ }
+
+/**
+ * testTextArea method
+ *
+ * @return void
+ */
+ public function testTextArea() {
+ $this->Form->request->data = array('Model' => array('field' => 'some test data'));
+ $result = $this->Form->textarea('Model.field');
+ $expected = array(
+ 'textarea' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ 'some test data',
+ '/textarea',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->textarea('Model.tmp');
+ $expected = array(
+ 'textarea' => array('name' => 'data[Model][tmp]', 'id' => 'ModelTmp'),
+ '/textarea',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array('Model' => array('field' => 'some <strong>test</strong> data with <a href="#">HTML</a> chars'));
+ $result = $this->Form->textarea('Model.field');
+ $expected = array(
+ 'textarea' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ htmlentities('some <strong>test</strong> data with <a href="#">HTML</a> chars'),
+ '/textarea',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array('Model' => array('field' => 'some <strong>test</strong> data with <a href="#">HTML</a> chars'));
+ $result = $this->Form->textarea('Model.field', array('escape' => false));
+ $expected = array(
+ 'textarea' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ 'some <strong>test</strong> data with <a href="#">HTML</a> chars',
+ '/textarea',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Model']['0']['OtherModel']['field'] = null;
+ $result = $this->Form->textarea('Model.0.OtherModel.field');
+ $expected = array(
+ 'textarea' => array('name' => 'data[Model][0][OtherModel][field]', 'id' => 'Model0OtherModelField'),
+ '/textarea'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testTextAreaWithStupidCharacters method
+ *
+ * test text area with non-ascii characters
+ *
+ * @return void
+ */
+ public function testTextAreaWithStupidCharacters() {
+ $this->loadFixtures('Post');
+ $result = $this->Form->input('Post.content', array(
+ 'label' => 'Current Text', 'value' => "GREAT®", 'rows' => '15', 'cols' => '75'
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'PostContent'),
+ 'Current Text',
+ '/label',
+ 'textarea' => array('name' => 'data[Post][content]', 'id' => 'PostContent', 'rows' => '15', 'cols' => '75'),
+ 'GREAT®',
+ '/textarea',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testHiddenField method
+ *
+ * @return void
+ */
+ public function testHiddenField() {
+ $Contact = ClassRegistry::getObject('Contact');
+ $Contact->validationErrors['field'] = 1;
+ $this->Form->request->data['Contact']['field'] = 'test';
+ $result = $this->Form->hidden('Contact.field', array('id' => 'theID'));
+ $this->assertTags($result, array(
+ 'input' => array('type' => 'hidden', 'class' => 'form-error', 'name' => 'data[Contact][field]', 'id' => 'theID', 'value' => 'test'))
+ );
+ }
+
+/**
+ * testFileUploadField method
+ *
+ * @return void
+ */
+ public function testFileUploadField() {
+ $result = $this->Form->file('Model.upload');
+ $this->assertTags($result, array('input' => array('type' => 'file', 'name' => 'data[Model][upload]', 'id' => 'ModelUpload')));
+
+ $this->Form->request->data['Model.upload'] = array("name" => "", "type" => "", "tmp_name" => "", "error" => 4, "size" => 0);
+ $result = $this->Form->input('Model.upload', array('type' => 'file'));
+ $expected = array(
+ 'div' => array('class' => 'input file'),
+ 'label' => array('for' => 'ModelUpload'),
+ 'Upload',
+ '/label',
+ 'input' => array('type' => 'file', 'name' => 'data[Model][upload]', 'id' => 'ModelUpload'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test File upload input on a model not used in create();
+ *
+ * @return void
+ */
+ public function testFileUploadOnOtherModel() {
+ $this->Form->create('ValidateUser', array('type' => 'file'));
+ $result = $this->Form->file('ValidateProfile.city');
+ $expected = array(
+ 'input' => array('type' => 'file', 'name' => 'data[ValidateProfile][city]', 'id' => 'ValidateProfileCity')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testButton method
+ *
+ * @return void
+ */
+ public function testButton() {
+ $result = $this->Form->button('Hi');
+ $this->assertTags($result, array('button' => array('type' => 'submit'), 'Hi', '/button'));
+
+ $result = $this->Form->button('Clear Form >', array('type' => 'reset'));
+ $this->assertTags($result, array('button' => array('type' => 'reset'), 'Clear Form >', '/button'));
+
+ $result = $this->Form->button('Clear Form >', array('type' => 'reset', 'id' => 'clearForm'));
+ $this->assertTags($result, array('button' => array('type' => 'reset', 'id' => 'clearForm'), 'Clear Form >', '/button'));
+
+ $result = $this->Form->button('<Clear Form>', array('type' => 'reset', 'escape' => true));
+ $this->assertTags($result, array('button' => array('type' => 'reset'), '&lt;Clear Form&gt;', '/button'));
+
+ $result = $this->Form->button('No type', array('type' => false));
+ $this->assertTags($result, array('button' => array(), 'No type', '/button'));
+
+ $result = $this->Form->button('Upload Text', array('onClick' => "$('#postAddForm').ajaxSubmit({target: '#postTextUpload', url: '/posts/text'});return false;'", 'escape' => false));
+ $this->assertNotRegExp('/\&039/', $result);
+ }
+
+/**
+ * Test that button() makes unlocked fields by default.
+ *
+ * @return void
+ */
+ public function testButtonUnlockedByDefault() {
+ $this->Form->request->params['_Token']['key'] = 'secured';
+ $this->Form->button('Save', array('name' => 'save'));
+ $this->Form->button('Clear');
+
+ $result = $this->Form->unlockField();
+ $this->assertEquals(array('save'), $result);
+ }
+
+/**
+ * testPostButton method
+ *
+ * @return void
+ */
+ public function testPostButton() {
+ $result = $this->Form->postButton('Hi', '/controller/action');
+ $this->assertTags($result, array(
+ 'form' => array('method' => 'post', 'action' => '/controller/action', 'accept-charset' => 'utf-8'),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div',
+ 'button' => array('type' => 'submit'),
+ 'Hi',
+ '/button',
+ '/form'
+ ));
+
+ $result = $this->Form->postButton('Send', '/', array('data' => array('extra' => 'value')));
+ $this->assertTrue(strpos($result, '<input type="hidden" name="data[extra]" value="value"/>') !== false);
+ }
+
+/**
+ * Test that postButton adds _Token fields.
+ *
+ * @return void
+ */
+ public function testSecurePostButton() {
+ $this->Form->request->params['_Token'] = array('key' => 'testkey');
+
+ $result = $this->Form->postButton('Delete', '/posts/delete/1');
+ $expected = array(
+ 'form' => array(
+ 'method' => 'post', 'action' => '/posts/delete/1', 'accept-charset' => 'utf-8',
+ ),
+ array('div' => array('style' => 'display:none;')),
+ array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
+ array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')),
+ '/div',
+ 'button' => array('type' => 'submit'),
+ 'Delete',
+ '/button',
+ array('div' => array('style' => 'display:none;')),
+ array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')),
+ array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')),
+ '/div',
+ '/form',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testPostLink method
+ *
+ * @return void
+ */
+ public function testPostLink() {
+ $result = $this->Form->postLink('Delete', '/posts/delete/1');
+ $this->assertTags($result, array(
+ 'form' => array(
+ 'method' => 'post', 'action' => '/posts/delete/1',
+ 'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
+ ),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/form',
+ 'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
+ 'Delete',
+ '/a'
+ ));
+
+ $result = $this->Form->postLink('Delete', '/posts/delete/1', array(), 'Confirm?');
+ $this->assertTags($result, array(
+ 'form' => array(
+ 'method' => 'post', 'action' => '/posts/delete/1',
+ 'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
+ ),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/form',
+ 'a' => array('href' => '#', 'onclick' => 'preg:/if \(confirm\(&#039;Confirm\?&#039;\)\) \{ document\.post_\w+\.submit\(\); \} event\.returnValue = false; return false;/'),
+ 'Delete',
+ '/a'
+ ));
+
+ $result = $this->Form->postLink('Delete', '/posts/delete', array('data' => array('id' => 1)));
+ $this->assertContains('<input type="hidden" name="data[id]" value="1"/>', $result);
+ }
+
+/**
+ * Test that postLink adds _Token fields.
+ *
+ * @return void
+ */
+ public function testSecurePostLink() {
+ $this->Form->request->params['_Token'] = array('key' => 'testkey');
+
+ $result = $this->Form->postLink('Delete', '/posts/delete/1');
+ $expected = array(
+ 'form' => array(
+ 'method' => 'post', 'action' => '/posts/delete/1',
+ 'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
+ ),
+ array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
+ array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')),
+ 'div' => array('style' => 'display:none;'),
+ array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')),
+ array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')),
+ '/div',
+ '/form',
+ 'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
+ 'Delete',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSubmitButton method
+ *
+ * @return void
+ */
+ public function testSubmitButton() {
+ $result = $this->Form->submit('');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => ''),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Test Submit');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'Test Submit'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Test Submit', array('div' => array('tag' => 'span')));
+ $expected = array(
+ 'span' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'Test Submit'),
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Test Submit', array('class' => 'save', 'div' => false));
+ $expected = array('input' => array('type' => 'submit', 'value' => 'Test Submit', 'class' => 'save'));
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Test Submit', array('div' => array('id' => 'SaveButton')));
+ $expected = array(
+ 'div' => array('class' => 'submit', 'id' => 'SaveButton'),
+ 'input' => array('type' => 'submit', 'value' => 'Test Submit'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Next >');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'Next &gt;'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Next >', array('escape' => false));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'Next >'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Reset!', array('type' => 'reset'));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'reset', 'value' => 'Reset!'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $before = '--before--';
+ $after = '--after--';
+ $result = $this->Form->submit('Test', array('before' => $before));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ '--before--',
+ 'input' => array('type' => 'submit', 'value' => 'Test'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Test', array('after' => $after));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'Test'),
+ '--after--',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Test', array('before' => $before, 'after' => $after));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ '--before--',
+ 'input' => array('type' => 'submit', 'value' => 'Test'),
+ '--after--',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test image submit types.
+ *
+ * @return void
+ */
+ public function testSubmitImage() {
+ $result = $this->Form->submit('http://example.com/cake.power.gif');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'image', 'src' => 'http://example.com/cake.power.gif'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('/relative/cake.power.gif');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'image', 'src' => 'relative/cake.power.gif'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('cake.power.gif');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Not.an.image');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'Not.an.image'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $after = '--after--';
+ $before = '--before--';
+ $result = $this->Form->submit('cake.power.gif', array('after' => $after));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
+ '--after--',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('cake.power.gif', array('before' => $before));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ '--before--',
+ 'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('cake.power.gif', array('before' => $before, 'after' => $after));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ '--before--',
+ 'input' => array('type' => 'image', 'src' => 'img/cake.power.gif'),
+ '--after--',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->submit('Not.an.image', array('before' => $before, 'after' => $after));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ '--before--',
+ 'input' => array('type' => 'submit', 'value' => 'Not.an.image'),
+ '--after--',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Submit buttons should be unlocked by default as there could be multiples, and only one will
+ * be submitted at a time.
+ *
+ * @return void
+ */
+ public function testSubmitUnlockedByDefault() {
+ $this->Form->request->params['_Token']['key'] = 'secured';
+ $this->Form->submit('Go go');
+ $this->Form->submit('Save', array('name' => 'save'));
+
+ $result = $this->Form->unlockField();
+ $this->assertEquals(array('save'), $result, 'Only submits with name attributes should be unlocked.');
+ }
+
+/**
+ * Test submit image with timestamps.
+ *
+ * @return void
+ */
+ public function testSubmitImageTimestamp() {
+ Configure::write('Asset.timestamp', 'force');
+
+ $result = $this->Form->submit('cake.power.gif');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'image', 'src' => 'preg:/img\/cake\.power\.gif\?\d*/'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test the create() method
+ *
+ * @return void
+ */
+ public function testCreate() {
+ $result = $this->Form->create('Contact');
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'preg:/display\s*\:\s*none;\s*/'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('Contact', array('type' => 'GET'));
+ $expected = array('form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'get', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ));
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('Contact', array('type' => 'get'));
+ $expected = array('form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'get', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ));
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('Contact', array('type' => 'put'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('Contact', array('type' => 'file'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding, 'enctype' => 'multipart/form-data'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['id'] = 1;
+ $this->Form->request->here = '/contacts/edit/1';
+ $this->Form->request['action'] = 'edit';
+ $result = $this->Form->create('Contact');
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactEditForm', 'method' => 'post', 'action' => '/contacts/edit/1',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['Contact']['id'] = 1;
+ $this->Form->request->here = '/contacts/edit/1';
+ $this->Form->request['action'] = 'edit';
+ $result = $this->Form->create('Contact', array('type' => 'file'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactEditForm', 'method' => 'post', 'action' => '/contacts/edit/1',
+ 'accept-charset' => $encoding, 'enctype' => 'multipart/form-data'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data['ContactNonStandardPk']['pk'] = 1;
+ $result = $this->Form->create('ContactNonStandardPk', array('url' => array('action' => 'edit')));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactNonStandardPkEditForm', 'method' => 'post',
+ 'action' => '/contact_non_standard_pks/edit/1','accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('Contact', array('id' => 'TestId'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'TestId', 'method' => 'post', 'action' => '/contacts/edit/1',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'PUT'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request['action'] = 'add';
+ $result = $this->Form->create('User', array('url' => array('action' => 'login')));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'UserAddForm', 'method' => 'post', 'action' => '/users/login',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('User', array('action' => 'login'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'UserLoginForm', 'method' => 'post', 'action' => '/users/login',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('User', array('url' => '/users/login'));
+ $expected = array(
+ 'form' => array('method' => 'post', 'action' => '/users/login', 'accept-charset' => $encoding, 'id' => 'UserAddForm'),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request['controller'] = 'pages';
+ $result = $this->Form->create('User', array('action' => 'signup'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'UserSignupForm', 'method' => 'post', 'action' => '/users/signup',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array();
+ $this->Form->request['controller'] = 'contacts';
+ $this->Form->request['models'] = array('Contact' => array('plugin' => null, 'className' => 'Contact'));
+ $result = $this->Form->create(array('url' => array('action' => 'index', 'param')));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/index/param',
+ 'accept-charset' => 'utf-8'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test the onsubmit option for create()
+ *
+ * @return void
+ */
+ public function testCreateOnSubmit() {
+ $this->Form->request->data = array();
+ $this->Form->request['controller'] = 'contacts';
+ $this->Form->request['models'] = array('Contact' => array('plugin' => null, 'className' => 'Contact'));
+ $result = $this->Form->create(array('url' => array('action' => 'index', 'param'), 'default' => false));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'onsubmit' => 'event.returnValue = false; return false;', 'action' => '/contacts/index/param',
+ 'accept-charset' => 'utf-8'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array();
+ $this->Form->request['controller'] = 'contacts';
+ $this->Form->request['models'] = array('Contact' => array('plugin' => null, 'className' => 'Contact'));
+ $result = $this->Form->create(array(
+ 'url' => array('action' => 'index', 'param'),
+ 'default' => false,
+ 'onsubmit' => 'someFunction();'
+ ));
+
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post',
+ 'onsubmit' => 'someFunction();event.returnValue = false; return false;',
+ 'action' => '/contacts/index/param',
+ 'accept-charset' => 'utf-8'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test create() with automatic url generation
+ *
+ * @return void
+ */
+ public function testCreateAutoUrl() {
+ Router::setRequestInfo(array(array(), array('base' => '/base_url')));
+ $this->Form->request->here = '/base_url/contacts/add/Contact:1';
+ $this->Form->request->base = '/base_url';
+ $result = $this->Form->create('Contact');
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/base_url/contacts/add/Contact:1',
+ 'accept-charset' => 'utf-8'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request['action'] = 'delete';
+ $this->Form->request->here = '/base_url/contacts/delete/10/User:42';
+ $this->Form->request->base = '/base_url';
+ $result = $this->Form->create('Contact');
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactDeleteForm', 'method' => 'post', 'action' => '/base_url/contacts/delete/10/User:42',
+ 'accept-charset' => 'utf-8'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test create() with a custom route
+ *
+ * @return void
+ */
+ public function testCreateCustomRoute() {
+ Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
+ $encoding = strtolower(Configure::read('App.encoding'));
+
+ $result = $this->Form->create('User', array('action' => 'login'));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'UserLoginForm', 'method' => 'post', 'action' => '/login',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that inputDefaults are stored and used.
+ *
+ * @return void
+ */
+ public function testCreateWithInputDefaults() {
+ $this->Form->create('User', array(
+ 'inputDefaults' => array(
+ 'div' => false,
+ 'label' => false,
+ 'error' => array('attributes' => array('wrap' => 'small', 'class' => 'error')),
+ 'format' => array('before', 'label', 'between', 'input', 'after', 'error')
+ )
+ ));
+ $result = $this->Form->input('username');
+ $expected = array(
+ 'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('username', array('div' => true, 'label' => 'username'));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'UserUsername'), 'username', '/label',
+ 'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('username', array('label' => 'Username', 'format' => array('input', 'label')));
+ $expected = array(
+ 'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername'),
+ 'label' => array('for' => 'UserUsername'), 'Username', '/label',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->create('User', array(
+ 'inputDefaults' => array(
+ 'div' => false,
+ 'label' => array('class' => 'nice', 'for' => 'changed'),
+ )
+ ));
+ $result = $this->Form->input('username', array('div' => true));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'changed', 'class' => 'nice'), 'Username', '/label',
+ 'input' => array('type' => 'text', 'name' => 'data[User][username]', 'id' => 'UserUsername'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test automatic accept-charset overriding
+ *
+ * @return void
+ */
+ public function testCreateWithAcceptCharset() {
+ $result = $this->Form->create('UserForm', array(
+ 'type' => 'post', 'action' => 'login','encoding' => 'iso-8859-1'
+ )
+ );
+ $expected = array(
+ 'form' => array(
+ 'method' => 'post', 'action' => '/user_forms/login', 'id' => 'UserFormLoginForm',
+ 'accept-charset' => 'iso-8859-1'
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test base form url when url param is passed with multiple parameters (&)
+ *
+ */
+ public function testCreateQuerystringrequest() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $result = $this->Form->create('Contact', array(
+ 'type' => 'post',
+ 'escape' => false,
+ 'url' => array(
+ 'controller' => 'controller',
+ 'action' => 'action',
+ '?' => array('param1' => 'value1', 'param2' => 'value2')
+ )
+ ));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm',
+ 'method' => 'post',
+ 'action' => '/controller/action?param1=value1&amp;param2=value2',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->create('Contact', array(
+ 'type' => 'post',
+ 'url' => array(
+ 'controller' => 'controller',
+ 'action' => 'action',
+ '?' => array('param1' => 'value1', 'param2' => 'value2')
+ )
+ ));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm',
+ 'method' => 'post',
+ 'action' => '/controller/action?param1=value1&amp;param2=value2',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that create() doesn't cause errors by multiple id's being in the primary key
+ * as could happen with multiple select or checkboxes.
+ *
+ * @return void
+ */
+ public function testCreateWithMultipleIdInData() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+
+ $this->Form->request->data['Contact']['id'] = array(1, 2);
+ $result = $this->Form->create('Contact');
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm',
+ 'method' => 'post',
+ 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that create() doesn't add in extra passed params.
+ *
+ * @return void
+ */
+ public function testCreatePassedArgs() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $this->Form->request->data['Contact']['id'] = 1;
+ $result = $this->Form->create('Contact', array(
+ 'type' => 'post',
+ 'escape' => false,
+ 'url' => array(
+ 'action' => 'edit',
+ 'myparam'
+ )
+ ));
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm',
+ 'method' => 'post',
+ 'action' => '/contacts/edit/myparam',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test creating a get form, and get form inputs.
+ *
+ * @return void
+ */
+ public function testGetFormCreate() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $result = $this->Form->create('Contact', array('type' => 'get'));
+ $this->assertTags($result, array('form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'get', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ )));
+
+ $result = $this->Form->text('Contact.name');
+ $this->assertTags($result, array('input' => array(
+ 'name' => 'name', 'type' => 'text', 'id' => 'ContactName',
+ )));
+
+ $result = $this->Form->password('password');
+ $this->assertTags($result, array('input' => array(
+ 'name' => 'password', 'type' => 'password', 'id' => 'ContactPassword'
+ )));
+ $this->assertNotRegExp('/<input[^<>]+[^id|name|type|value]=[^<>]*>$/', $result);
+
+ $result = $this->Form->text('user_form');
+ $this->assertTags($result, array('input' => array(
+ 'name' => 'user_form', 'type' => 'text', 'id' => 'ContactUserForm'
+ )));
+ }
+
+/**
+ * test get form, and inputs when the model param is false
+ *
+ * @return void
+ */
+ public function testGetFormWithFalseModel() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $this->Form->request['controller'] = 'contact_test';
+ $result = $this->Form->create(false, array('type' => 'get', 'url' => array('controller' => 'contact_test')));
+
+ $expected = array('form' => array(
+ 'id' => 'addForm', 'method' => 'get', 'action' => '/contact_test/add',
+ 'accept-charset' => $encoding
+ ));
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->text('reason');
+ $expected = array(
+ 'input' => array('type' => 'text', 'name' => 'reason', 'id' => 'reason')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that datetime() works with GET style forms.
+ *
+ * @return void
+ */
+ public function testDateTimeWithGetForms() {
+ extract($this->dateRegex);
+ $this->Form->create('Contact', array('type' => 'get'));
+ $result = $this->Form->datetime('created');
+
+ $this->assertRegExp('/name="created\[year\]"/', $result, 'year name attribute is wrong.');
+ $this->assertRegExp('/name="created\[month\]"/', $result, 'month name attribute is wrong.');
+ $this->assertRegExp('/name="created\[day\]"/', $result, 'day name attribute is wrong.');
+ $this->assertRegExp('/name="created\[hour\]"/', $result, 'hour name attribute is wrong.');
+ $this->assertRegExp('/name="created\[min\]"/', $result, 'min name attribute is wrong.');
+ $this->assertRegExp('/name="created\[meridian\]"/', $result, 'meridian name attribute is wrong.');
+ }
+
+/**
+ * testEditFormWithData method
+ *
+ * test auto populating form elements from submitted data.
+ *
+ * @return void
+ */
+ public function testEditFormWithData() {
+ $this->Form->request->data = array('Person' => array(
+ 'id' => 1,
+ 'first_name' => 'Nate',
+ 'last_name' => 'Abele',
+ 'email' => 'nate@example.com'
+ ));
+ $this->Form->request->addParams(array(
+ 'models' => array('Person'),
+ 'controller' => 'people',
+ 'action' => 'add'
+ ));
+ $options = array(1 => 'Nate', 2 => 'Garrett', 3 => 'Larry');
+
+ $this->Form->create();
+ $result = $this->Form->select('People.People', $options, array('multiple' => true));
+ $expected = array(
+ 'input' => array('type' => 'hidden', 'name' => 'data[People][People]', 'value' => '', 'id' => 'PeoplePeople_'),
+ 'select' => array(
+ 'name' => 'data[People][People][]', 'multiple' => 'multiple', 'id' => 'PeoplePeople'
+ ),
+ array('option' => array('value' => 1)), 'Nate', '/option',
+ array('option' => array('value' => 2)), 'Garrett', '/option',
+ array('option' => array('value' => 3)), 'Larry', '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test that required fields are created for various types of validation.
+ *
+ * @return void
+ */
+ public function testFormInputRequiredDetection() {
+ $this->Form->create('Contact');
+
+ $result = $this->Form->input('Contact.non_existing');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactNonExisting'),
+ 'Non Existing',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][non_existing]',
+ 'id' => 'ContactNonExisting'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequired');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequired'),
+ 'Imrequired',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequired]',
+ 'id' => 'ContactImrequired'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imalsorequired');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImalsorequired'),
+ 'Imalsorequired',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imalsorequired]',
+ 'id' => 'ContactImalsorequired'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequiredtoo');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequiredtoo'),
+ 'Imrequiredtoo',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequiredtoo]',
+ 'id' => 'ContactImrequiredtoo'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.required_one');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactRequiredOne'),
+ 'Required One',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][required_one]',
+ 'id' => 'ContactRequiredOne'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.string_required');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactStringRequired'),
+ 'String Required',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][string_required]',
+ 'id' => 'ContactStringRequired'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imnotrequired');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactImnotrequired'),
+ 'Imnotrequired',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imnotrequired]',
+ 'id' => 'ContactImnotrequired'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imalsonotrequired');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactImalsonotrequired'),
+ 'Imalsonotrequired',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imalsonotrequired]',
+ 'id' => 'ContactImalsonotrequired'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imnotrequiredeither');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactImnotrequiredeither'),
+ 'Imnotrequiredeither',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imnotrequiredeither]',
+ 'id' => 'ContactImnotrequiredeither'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormMagicInput method
+ *
+ * @return void
+ */
+ public function testFormMagicInput() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $result = $this->Form->create('Contact');
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('name');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactName'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][name]',
+ 'id' => 'ContactName', 'maxlength' => '255'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('non_existing_field_in_contact_model');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactNonExistingFieldInContactModel'),
+ 'Non Existing Field In Contact Model',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][non_existing_field_in_contact_model]',
+ 'id' => 'ContactNonExistingFieldInContactModel'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Address.street');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'AddressStreet'),
+ 'Street',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Address][street]',
+ 'id' => 'AddressStreet'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Address.non_existing_field_in_model');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'AddressNonExistingFieldInModel'),
+ 'Non Existing Field In Model',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Address][non_existing_field_in_model]',
+ 'id' => 'AddressNonExistingFieldInModel'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('name', array('div' => false));
+ $expected = array(
+ 'label' => array('for' => 'ContactName'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][name]',
+ 'id' => 'ContactName', 'maxlength' => '255'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ extract($this->dateRegex);
+ $now = strtotime('now');
+
+ $result = $this->Form->input('Contact.published', array('div' => false));
+ $expected = array(
+ 'label' => array('for' => 'ContactPublishedMonth'),
+ 'Published',
+ '/label',
+ array('select' => array(
+ 'name' => 'data[Contact][published][month]', 'id' => 'ContactPublishedMonth'
+ )),
+ $monthsRegex,
+ array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
+ date('F', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array(
+ 'name' => 'data[Contact][published][day]', 'id' => 'ContactPublishedDay'
+ )),
+ $daysRegex,
+ array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
+ date('j', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array(
+ 'name' => 'data[Contact][published][year]', 'id' => 'ContactPublishedYear'
+ )),
+ $yearsRegex,
+ array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
+ date('Y', $now),
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.updated', array('div' => false));
+ $expected = array(
+ 'label' => array('for' => 'ContactUpdatedMonth'),
+ 'Updated',
+ '/label',
+ array('select' => array(
+ 'name' => 'data[Contact][updated][month]', 'id' => 'ContactUpdatedMonth'
+ )),
+ $monthsRegex,
+ array('option' => array('value' => date('m', $now), 'selected' => 'selected')),
+ date('F', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array(
+ 'name' => 'data[Contact][updated][day]', 'id' => 'ContactUpdatedDay'
+ )),
+ $daysRegex,
+ array('option' => array('value' => date('d', $now), 'selected' => 'selected')),
+ date('j', $now),
+ '/option',
+ '*/select',
+ '-',
+ array('select' => array(
+ 'name' => 'data[Contact][updated][year]', 'id' => 'ContactUpdatedYear'
+ )),
+ $yearsRegex,
+ array('option' => array('value' => date('Y', $now), 'selected' => 'selected')),
+ date('Y', $now),
+ '*/select'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('UserForm.stuff');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'UserFormStuff'),
+ 'Stuff',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[UserForm][stuff]',
+ 'id' => 'UserFormStuff', 'maxlength' => 10
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testForMagicInputNonExistingNorValidated method
+ *
+ * @return void
+ */
+ public function testForMagicInputNonExistingNorValidated() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $result = $this->Form->create('Contact');
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.non_existing_nor_validated', array('div' => false));
+ $expected = array(
+ 'label' => array('for' => 'ContactNonExistingNorValidated'),
+ 'Non Existing Nor Validated',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][non_existing_nor_validated]',
+ 'id' => 'ContactNonExistingNorValidated'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.non_existing_nor_validated', array(
+ 'div' => false, 'value' => 'my value'
+ ));
+ $expected = array(
+ 'label' => array('for' => 'ContactNonExistingNorValidated'),
+ 'Non Existing Nor Validated',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][non_existing_nor_validated]',
+ 'value' => 'my value', 'id' => 'ContactNonExistingNorValidated'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->request->data = array(
+ 'Contact' => array('non_existing_nor_validated' => 'CakePHP magic'
+ ));
+ $result = $this->Form->input('Contact.non_existing_nor_validated', array('div' => false));
+ $expected = array(
+ 'label' => array('for' => 'ContactNonExistingNorValidated'),
+ 'Non Existing Nor Validated',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][non_existing_nor_validated]',
+ 'value' => 'CakePHP magic', 'id' => 'ContactNonExistingNorValidated'
+ )
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormMagicInputLabel method
+ *
+ * @return void
+ */
+ public function testFormMagicInputLabel() {
+ $encoding = strtolower(Configure::read('App.encoding'));
+ $result = $this->Form->create('Contact');
+ $expected = array(
+ 'form' => array(
+ 'id' => 'ContactAddForm', 'method' => 'post', 'action' => '/contacts/add',
+ 'accept-charset' => $encoding
+ ),
+ 'div' => array('style' => 'display:none;'),
+ 'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.name', array('div' => false, 'label' => false));
+ $this->assertTags($result, array('input' => array(
+ 'name' => 'data[Contact][name]', 'type' => 'text',
+ 'id' => 'ContactName', 'maxlength' => '255')
+ ));
+
+ $result = $this->Form->input('Contact.name', array('div' => false, 'label' => 'My label'));
+ $expected = array(
+ 'label' => array('for' => 'ContactName'),
+ 'My label',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][name]',
+ 'id' => 'ContactName', 'maxlength' => '255'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.name', array(
+ 'div' => false, 'label' => array('class' => 'mandatory')
+ ));
+ $expected = array(
+ 'label' => array('for' => 'ContactName', 'class' => 'mandatory'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][name]',
+ 'id' => 'ContactName', 'maxlength' => '255'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.name', array(
+ 'div' => false, 'label' => array('class' => 'mandatory', 'text' => 'My label')
+ ));
+ $expected = array(
+ 'label' => array('for' => 'ContactName', 'class' => 'mandatory'),
+ 'My label',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][name]',
+ 'id' => 'ContactName', 'maxlength' => '255'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.name', array(
+ 'div' => false, 'id' => 'my_id', 'label' => array('for' => 'my_id')
+ ));
+ $expected = array(
+ 'label' => array('for' => 'my_id'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][name]',
+ 'id' => 'my_id', 'maxlength' => '255'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('1.id');
+ $this->assertTags($result, array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[Contact][1][id]',
+ 'id' => 'Contact1Id'
+ )));
+
+ $result = $this->Form->input("1.name");
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'Contact1Name'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][1][name]',
+ 'id' => 'Contact1Name', 'maxlength' => '255'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.1.id');
+ $this->assertTags($result, array(
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Contact][1][id]',
+ 'id' => 'Contact1Id'
+ )
+ ));
+
+ $result = $this->Form->input("Model.1.name");
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'Model1Name'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Model][1][name]',
+ 'id' => 'Model1Name'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testFormEnd method
+ *
+ * @return void
+ */
+ public function testFormEnd() {
+ $this->assertEquals('</form>', $this->Form->end());
+
+ $result = $this->Form->end('');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => ''),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->end(array('label' => ''));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => ''),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->end('save');
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'save'),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->end(array('label' => 'save'));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'save'),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->end(array('label' => 'save', 'name' => 'Whatever'));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'save', 'name' => 'Whatever'),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->end(array('name' => 'Whatever'));
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'value' => 'Submit', 'name' => 'Whatever'),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->end(array('label' => 'save', 'name' => 'Whatever', 'div' => 'good'));
+ $expected = array(
+ 'div' => array('class' => 'good'),
+ 'input' => array('type' => 'submit', 'value' => 'save', 'name' => 'Whatever'),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->end(array(
+ 'label' => 'save', 'name' => 'Whatever', 'div' => array('class' => 'good')
+ ));
+ $expected = array(
+ 'div' => array('class' => 'good'),
+ 'input' => array('type' => 'submit', 'value' => 'save', 'name' => 'Whatever'),
+ '/div',
+ '/form'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testMultipleFormWithIdFields method
+ *
+ * @return void
+ */
+ public function testMultipleFormWithIdFields() {
+ $this->Form->create('UserForm');
+
+ $result = $this->Form->input('id');
+ $this->assertTags($result, array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[UserForm][id]', 'id' => 'UserFormId'
+ )));
+
+ $result = $this->Form->input('ValidateItem.id');
+ $this->assertTags($result, array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[ValidateItem][id]',
+ 'id' => 'ValidateItemId'
+ )));
+
+ $result = $this->Form->input('ValidateUser.id');
+ $this->assertTags($result, array('input' => array(
+ 'type' => 'hidden', 'name' => 'data[ValidateUser][id]',
+ 'id' => 'ValidateUserId'
+ )));
+ }
+
+/**
+ * testDbLessModel method
+ *
+ * @return void
+ */
+ public function testDbLessModel() {
+ $this->Form->create('TestMail');
+
+ $result = $this->Form->input('name');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'TestMailName'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'name' => 'data[TestMail][name]', 'type' => 'text',
+ 'id' => 'TestMailName'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ ClassRegistry::init('TestMail');
+ $this->Form->create('TestMail');
+ $result = $this->Form->input('name');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'TestMailName'),
+ 'Name',
+ '/label',
+ 'input' => array(
+ 'name' => 'data[TestMail][name]', 'type' => 'text',
+ 'id' => 'TestMailName'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testBrokenness method
+ *
+ * @return void
+ */
+ public function testBrokenness() {
+ /*
+ * #4 This test has two parents and four children. By default (as of r7117) both
+ * parents are show but the first parent is missing a child. This is the inconsistency
+ * in the default behaviour - one parent has all children, the other does not - dependent
+ * on the data values.
+ */
+ $result = $this->Form->select('Model.field', array(
+ 'Fred' => array(
+ 'freds_son_1' => 'Fred',
+ 'freds_son_2' => 'Freddie'
+ ),
+ 'Bert' => array(
+ 'berts_son_1' => 'Albert',
+ 'berts_son_2' => 'Bertie')
+ ),
+ array('showParents' => true, 'empty' => false)
+ );
+
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('optgroup' => array('label' => 'Fred')),
+ array('option' => array('value' => 'freds_son_1')),
+ 'Fred',
+ '/option',
+ array('option' => array('value' => 'freds_son_2')),
+ 'Freddie',
+ '/option',
+ '/optgroup',
+ array('optgroup' => array('label' => 'Bert')),
+ array('option' => array('value' => 'berts_son_1')),
+ 'Albert',
+ '/option',
+ array('option' => array('value' => 'berts_son_2')),
+ 'Bertie',
+ '/option',
+ '/optgroup',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+
+ /*
+ * #2 This is structurally identical to the test above (#1) - only the parent name has
+ * changed, so we should expect the same select list data, just with a different name
+ * for the parent. As of #7117, this test fails because option 3 => 'Three' disappears.
+ * This is where data corruption can occur, because when a select value is missing from
+ * a list a form will substitute the first value in the list - without the user knowing.
+ * If the optgroup name 'Parent' (above) is updated to 'Three' (below), this should not
+ * affect the availability of 3 => 'Three' as a valid option.
+ */
+ $options = array(1 => 'One', 2 => 'Two', 'Three' => array(
+ 3 => 'Three', 4 => 'Four', 5 => 'Five'
+ ));
+ $result = $this->Form->select(
+ 'Model.field', $options, array('showParents' => true, 'empty' => false)
+ );
+
+ $expected = array(
+ 'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
+ array('option' => array('value' => 1)),
+ 'One',
+ '/option',
+ array('option' => array('value' => 2)),
+ 'Two',
+ '/option',
+ array('optgroup' => array('label' => 'Three')),
+ array('option' => array('value' => 3)),
+ 'Three',
+ '/option',
+ array('option' => array('value' => 4)),
+ 'Four',
+ '/option',
+ array('option' => array('value' => 5)),
+ 'Five',
+ '/option',
+ '/optgroup',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test the generation of fields for a multi record form.
+ *
+ * @return void
+ */
+ public function testMultiRecordForm() {
+ $this->Form->create('ValidateProfile');
+ $this->Form->request->data['ValidateProfile'][1]['ValidateItem'][2]['name'] = 'Value';
+ $result = $this->Form->input('ValidateProfile.1.ValidateItem.2.name');
+ $expected = array(
+ 'div' => array('class' => 'input textarea'),
+ 'label' => array('for' => 'ValidateProfile1ValidateItem2Name'),
+ 'Name',
+ '/label',
+ 'textarea' => array(
+ 'id' => 'ValidateProfile1ValidateItem2Name',
+ 'name' => 'data[ValidateProfile][1][ValidateItem][2][name]',
+ 'cols' => 30,
+ 'rows' => 6
+ ),
+ 'Value',
+ '/textarea',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('ValidateProfile.1.ValidateItem.2.created',array('empty' => true));
+ $expected = array(
+ 'div' => array('class' => 'input date'),
+ 'label' => array('for' => 'ValidateProfile1ValidateItem2CreatedMonth'),
+ 'Created',
+ '/label',
+ array('select' => array(
+ 'name' => 'data[ValidateProfile][1][ValidateItem][2][created][month]',
+ 'id' => 'ValidateProfile1ValidateItem2CreatedMonth'
+ )
+ ),
+ array('option' => array('value' => '')), '/option',
+ $this->dateRegex['monthsRegex'],
+ '/select', '-',
+ array('select' => array(
+ 'name' => 'data[ValidateProfile][1][ValidateItem][2][created][day]',
+ 'id' => 'ValidateProfile1ValidateItem2CreatedDay'
+ )
+ ),
+ array('option' => array('value' => '')), '/option',
+ $this->dateRegex['daysRegex'],
+ '/select', '-',
+ array('select' => array(
+ 'name' => 'data[ValidateProfile][1][ValidateItem][2][created][year]',
+ 'id' => 'ValidateProfile1ValidateItem2CreatedYear'
+ )
+ ),
+ array('option' => array('value' => '')), '/option',
+ $this->dateRegex['yearsRegex'],
+ '/select',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $ValidateProfile = ClassRegistry::getObject('ValidateProfile');
+ $ValidateProfile->validationErrors[1]['ValidateItem'][2]['profile_id'] = 'Error';
+ $this->Form->request->data['ValidateProfile'][1]['ValidateItem'][2]['profile_id'] = '1';
+ $result = $this->Form->input('ValidateProfile.1.ValidateItem.2.profile_id');
+ $expected = array(
+ 'div' => array('class' => 'input select error'),
+ 'label' => array('for' => 'ValidateProfile1ValidateItem2ProfileId'),
+ 'Profile',
+ '/label',
+ 'select' => array(
+ 'name' => 'data[ValidateProfile][1][ValidateItem][2][profile_id]',
+ 'id' => 'ValidateProfile1ValidateItem2ProfileId',
+ 'class' => 'form-error'
+ ),
+ '/select',
+ array('div' => array('class' => 'error-message')),
+ 'Error',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test the correct display of multi-record form validation errors.
+ *
+ * @return void
+ */
+ public function testMultiRecordFormValidationErrors() {
+ $this->Form->create('ValidateProfile');
+ $ValidateProfile = ClassRegistry::getObject('ValidateProfile');
+ $ValidateProfile->validationErrors[2]['ValidateItem'][1]['name'] = array('Error in field name');
+ $result = $this->Form->error('ValidateProfile.2.ValidateItem.1.name');
+ $this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field name', '/div'));
+
+ $ValidateProfile->validationErrors[2]['city'] = array('Error in field city');
+ $result = $this->Form->error('ValidateProfile.2.city');
+ $this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div'));
+
+ $result = $this->Form->error('2.city');
+ $this->assertTags($result, array('div' => array('class' => 'error-message'), 'Error in field city', '/div'));
+ }
+
+/**
+ * tests the ability to change the order of the form input placeholder "input", "label", "before", "between", "after", "error"
+ *
+ * @return void
+ */
+ public function testInputTemplate() {
+ $result = $this->Form->input('Contact.email', array(
+ 'type' => 'text', 'format' => array('input')
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][email]',
+ 'id' => 'ContactEmail'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.email', array(
+ 'type' => 'text', 'format' => array('input', 'label'),
+ 'label' => '<em>Email (required)</em>'
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][email]',
+ 'id' => 'ContactEmail'
+ )),
+ 'label' => array('for' => 'ContactEmail'),
+ 'em' => array(),
+ 'Email (required)',
+ '/em',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.email', array(
+ 'type' => 'text', 'format' => array('input', 'between', 'label', 'after'),
+ 'between' => '<div>Something in the middle</div>',
+ 'after' => '<span>Some text at the end</span>'
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ array('input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][email]',
+ 'id' => 'ContactEmail'
+ )),
+ array('div' => array()),
+ 'Something in the middle',
+ '/div',
+ 'label' => array('for' => 'ContactEmail'),
+ 'Email',
+ '/label',
+ 'span' => array(),
+ 'Some text at the end',
+ '/span',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.method', array(
+ 'type' => 'radio',
+ 'options' => array('email' => 'Email', 'pigeon' => 'Pigeon'),
+ 'between' => 'I am between',
+ ));
+ $expected = array(
+ 'div' => array('class' => 'input radio'),
+ 'fieldset' => array(),
+ 'legend' => array(),
+ 'Method',
+ '/legend',
+ 'I am between',
+ 'input' => array(
+ 'type' => 'hidden', 'name' => 'data[Contact][method]',
+ 'value' => '', 'id' => 'ContactMethod_'
+ ),
+ array('input' => array(
+ 'type' => 'radio', 'name' => 'data[Contact][method]',
+ 'value' => 'email', 'id' => 'ContactMethodEmail'
+ )),
+ array('label' => array('for' => 'ContactMethodEmail')),
+ 'Email',
+ '/label',
+ array('input' => array(
+ 'type' => 'radio', 'name' => 'data[Contact][method]',
+ 'value' => 'pigeon', 'id' => 'ContactMethodPigeon'
+ )),
+ array('label' => array('for' => 'ContactMethodPigeon')),
+ 'Pigeon',
+ '/label',
+ '/fieldset',
+ '/div',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that some html5 inputs + FormHelper::__call() work
+ *
+ * @return void
+ */
+ public function testHtml5Inputs() {
+ $result = $this->Form->email('User.email');
+ $expected = array(
+ 'input' => array('type' => 'email', 'name' => 'data[User][email]', 'id' => 'UserEmail')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->search('User.query');
+ $expected = array(
+ 'input' => array('type' => 'search', 'name' => 'data[User][query]', 'id' => 'UserQuery')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->search('User.query', array('value' => 'test'));
+ $expected = array(
+ 'input' => array('type' => 'search', 'name' => 'data[User][query]', 'id' => 'UserQuery', 'value' => 'test')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->search('User.query', array('type' => 'text', 'value' => 'test'));
+ $expected = array(
+ 'input' => array('type' => 'text', 'name' => 'data[User][query]', 'id' => 'UserQuery', 'value' => 'test')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('User.website', array('type' => 'url', 'value' => 'http://domain.tld', 'div' => false, 'label' => false));
+ $expected = array(
+ 'input' => array('type' => 'url', 'name' => 'data[User][website]', 'id' => 'UserWebsite', 'value' => 'http://domain.tld')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testHtml5InputException() {
+ $this->Form->email();
+ }
+
+/**
+ * Tests that a model can be loaded from the model names passed in the request object
+ *
+ * @return void
+ */
+ public function testIntrospectModelFromRequest() {
+ $this->loadFixtures('Post');
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $this->Form->request['models'] = array('TestPluginPost' => array('plugin' => 'TestPlugin', 'className' => 'TestPluginPost'));
+
+ $this->assertFalse(ClassRegistry::isKeySet('TestPluginPost'));
+ $this->Form->create('TestPluginPost');
+ $this->assertTrue(ClassRegistry::isKeySet('TestPluginPost'));
+ $this->assertInstanceOf('TestPluginPost', ClassRegistry::getObject('TestPluginPost'));
+
+ CakePlugin::unload();
+ App::build();
+ }
+
+/**
+ * Tests that it is possible to set the validation errors directly in the helper for a field
+ *
+ * @return void
+ */
+ public function testCustomValidationErrors() {
+ $this->Form->validationErrors['Thing']['field'] = 'Badness!';
+ $result = $this->Form->error('Thing.field', null, array('wrap' => false));
+ $this->assertEquals('Badness!', $result);
+ }
+
+/**
+ * Tests that the 'on' key validates as expected on create
+ *
+ * @return void
+ */
+ public function testRequiredOnCreate() {
+ $this->Form->create('Contact');
+
+ $result = $this->Form->input('Contact.imrequiredonupdate');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactImrequiredonupdate'),
+ 'Imrequiredonupdate',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequiredonupdate]',
+ 'id' => 'ContactImrequiredonupdate'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequiredoncreate');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequiredoncreate'),
+ 'Imrequiredoncreate',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequiredoncreate]',
+ 'id' => 'ContactImrequiredoncreate'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequiredonboth');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequiredonboth'),
+ 'Imrequiredonboth',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequiredonboth]',
+ 'id' => 'ContactImrequiredonboth'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequired');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequired'),
+ 'Imrequired',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequired]',
+ 'id' => 'ContactImrequired'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Tests that the 'on' key validates as expected on update
+ *
+ * @return void
+ */
+ public function testRequiredOnUpdate() {
+ $this->Form->request->data['Contact']['id'] = 1;
+ $this->Form->create('Contact');
+
+ $result = $this->Form->input('Contact.imrequiredonupdate');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequiredonupdate'),
+ 'Imrequiredonupdate',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequiredonupdate]',
+ 'id' => 'ContactImrequiredonupdate'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ $result = $this->Form->input('Contact.imrequiredoncreate');
+ $expected = array(
+ 'div' => array('class' => 'input text'),
+ 'label' => array('for' => 'ContactImrequiredoncreate'),
+ 'Imrequiredoncreate',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequiredoncreate]',
+ 'id' => 'ContactImrequiredoncreate'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequiredonboth');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequiredonboth'),
+ 'Imrequiredonboth',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequiredonboth]',
+ 'id' => 'ContactImrequiredonboth'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequired');
+ $expected = array(
+ 'div' => array('class' => 'input text required'),
+ 'label' => array('for' => 'ContactImrequired'),
+ 'Imrequired',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][imrequired]',
+ 'id' => 'ContactImrequired'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test inputDefaults setter and getter
+ *
+ * @return void
+ */
+ public function testInputDefaults() {
+ $this->Form->create('Contact');
+
+ $this->Form->inputDefaults(array(
+ 'label' => false,
+ 'div' => array(
+ 'style' => 'color: #000;'
+ )
+ ));
+ $result = $this->Form->input('Contact.field1');
+ $expected = array(
+ 'div' => array('class' => 'input text', 'style' => 'color: #000;'),
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field1]',
+ 'id' => 'ContactField1'
+ ),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->inputDefaults(array(
+ 'div' => false,
+ 'label' => 'Label',
+ ));
+ $result = $this->Form->input('Contact.field1');
+ $expected = array(
+ 'label' => array('for' => 'ContactField1'),
+ 'Label',
+ '/label',
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field1]',
+ 'id' => 'ContactField1'
+ ),
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Form->inputDefaults(array(
+ 'label' => false,
+ ), true);
+ $result = $this->Form->input('Contact.field1');
+ $expected = array(
+ 'input' => array(
+ 'type' => 'text', 'name' => 'data[Contact][field1]',
+ 'id' => 'ContactField1'
+ ),
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->inputDefaults();
+ $expected = array(
+ 'div' => false,
+ 'label' => false,
+ );
+ $this->assertEqual($result, $expected);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php
new file mode 100644
index 0000000..678a1df
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php
@@ -0,0 +1,1910 @@
+<?php
+/**
+ * HtmlHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('Helper', 'View');
+App::uses('AppHelper', 'View/Helper');
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('FormHelper', 'View/Helper');
+App::uses('ClassRegistry', 'Utility');
+App::uses('Folder', 'Utility');
+
+if (!defined('FULL_BASE_URL')) {
+ define('FULL_BASE_URL', 'http://cakephp.org');
+}
+
+/**
+ * TheHtmlTestController class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class TheHtmlTestController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'TheTest'
+ */
+ public $name = 'TheTest';
+
+/**
+ * uses property
+ *
+ * @var mixed null
+ */
+ public $uses = null;
+}
+
+class TestHtmlHelper extends HtmlHelper {
+
+/**
+ * expose a method as public
+ *
+ * @param string $options
+ * @param string $exclude
+ * @param string $insertBefore
+ * @param string $insertAfter
+ * @return void
+ */
+ public function parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
+ return $this->_parseAttributes($options, $exclude, $insertBefore, $insertAfter);
+ }
+
+/**
+ * Get a protected attribute value
+ *
+ * @param string $attribute
+ * @return mixed
+ */
+ public function getAttribute($attribute) {
+ if (!isset($this->{$attribute})) {
+ return null;
+ }
+ return $this->{$attribute};
+ }
+
+}
+
+/**
+ * Html5TestHelper class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class Html5TestHelper extends TestHtmlHelper {
+
+/**
+ * Minimized
+ *
+ * @var array
+ */
+ protected $_minimizedAttributes = array('require', 'checked');
+
+/**
+ * Allow compact use in HTML
+ *
+ * @var string
+ */
+ protected $_minimizedAttributeFormat = '%s';
+
+/**
+ * Test to attribute format
+ *
+ * @var string
+ */
+ protected $_attributeFormat = 'data-%s="%s"';
+}
+
+/**
+ * HtmlHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class HtmlHelperTest extends CakeTestCase {
+
+/**
+ * Regexp for CDATA start block
+ *
+ * @var string
+ */
+ public $cDataStart = 'preg:/^\/\/<!\[CDATA\[[\n\r]*/';
+
+/**
+ * Regexp for CDATA end block
+ *
+ * @var string
+ */
+ public $cDataEnd = 'preg:/[^\]]*\]\]\>[\s\r\n]*/';
+
+/**
+ * html property
+ *
+ * @var object
+ */
+ public $Html = null;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->View = $this->getMock('View', array('append'), array(new TheHtmlTestController()));
+ $this->Html = new TestHtmlHelper($this->View);
+ $this->Html->request = new CakeRequest(null, false);
+ $this->Html->request->webroot = '';
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+
+ Configure::write('Asset.timestamp', false);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Html, $this->View);
+ }
+
+/**
+ * testDocType method
+ *
+ * @return void
+ */
+ public function testDocType() {
+ $result = $this->Html->docType();
+ $expected = '<!DOCTYPE html>';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Html->docType('html4-strict');
+ $expected = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">';
+ $this->assertEquals($expected, $result);
+
+ $this->assertNull($this->Html->docType('non-existing-doctype'));
+ }
+
+/**
+ * testLink method
+ *
+ * @return void
+ */
+ public function testLink() {
+ Router::connect('/:controller/:action/*');
+
+ $this->Html->request->webroot = '';
+
+ $result = $this->Html->link('/home');
+ $expected = array('a' => array('href' => '/home'), 'preg:/\/home/', '/a');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link(array('action' => 'login', '<[You]>'));
+ $expected = array(
+ 'a' => array('href' => '/login/%3C%5BYou%5D%3E'),
+ 'preg:/\/login\/&lt;\[You\]&gt;/',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ Router::reload();
+
+ $result = $this->Html->link('Posts', array('controller' => 'posts', 'action' => 'index', 'full_base' => true));
+ $expected = array('a' => array('href' => FULL_BASE_URL . '/posts'), 'Posts', '/a');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Home', '/home', array('confirm' => 'Are you sure you want to do this?'));
+ $expected = array(
+ 'a' => array('href' => '/home', 'onclick' => 'return confirm(&#039;Are you sure you want to do this?&#039;);'),
+ 'Home',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Home', '/home', array('default' => false));
+ $expected = array(
+ 'a' => array('href' => '/home', 'onclick' => 'event.returnValue = false; return false;'),
+ 'Home',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Home', '/home', array('default' => false, 'onclick' => 'someFunction();'));
+ $expected = array(
+ 'a' => array('href' => '/home', 'onclick' => 'someFunction(); event.returnValue = false; return false;'),
+ 'Home',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Next >', '#');
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'Next &gt;',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Next >', '#', array('escape' => true));
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'Next &gt;',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Next >', '#', array('escape' => 'utf-8'));
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'Next &gt;',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Next >', '#', array('escape' => false));
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'Next >',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Next >', '#', array(
+ 'title' => 'to escape &#8230; or not escape?',
+ 'escape' => false
+ ));
+ $expected = array(
+ 'a' => array('href' => '#', 'title' => 'to escape &#8230; or not escape?'),
+ 'Next >',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Next >', '#', array(
+ 'title' => 'to escape &#8230; or not escape?',
+ 'escape' => true
+ ));
+ $expected = array(
+ 'a' => array('href' => '#', 'title' => 'to escape &amp;#8230; or not escape?'),
+ 'Next &gt;',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('Original size', array(
+ 'controller' => 'images', 'action' => 'view', 3, '?' => array('height' => 100, 'width' => 200)
+ ));
+ $expected = array(
+ 'a' => array('href' => '/images/view/3?height=100&amp;width=200'),
+ 'Original size',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ Configure::write('Asset.timestamp', false);
+
+ $result = $this->Html->link($this->Html->image('test.gif'), '#', array('escape' => false));
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'img' => array('src' => 'img/test.gif', 'alt' => ''),
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->image('test.gif', array('url' => '#'));
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'img' => array('src' => 'img/test.gif', 'alt' => ''),
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link($this->Html->image('../favicon.ico'), '#', array('escape' => false));
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'img' => array('src' => 'img/../favicon.ico', 'alt' => ''),
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->image('../favicon.ico', array('url' => '#'));
+ $expected = array(
+ 'a' => array('href' => '#'),
+ 'img' => array('src' => 'img/../favicon.ico', 'alt' => ''),
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->link('http://www.example.org?param1=value1&param2=value2');
+ $expected = array('a' => array('href' => 'http://www.example.org?param1=value1&amp;param2=value2'), 'http://www.example.org?param1=value1&amp;param2=value2', '/a');
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testImageTag method
+ *
+ * @return void
+ */
+ public function testImageTag() {
+ $this->Html->request->webroot = '';
+
+ $result = $this->Html->image('test.gif');
+ $this->assertTags($result, array('img' => array('src' => 'img/test.gif', 'alt' => '')));
+
+ $result = $this->Html->image('http://google.com/logo.gif');
+ $this->assertTags($result, array('img' => array('src' => 'http://google.com/logo.gif', 'alt' => '')));
+
+ $result = $this->Html->image(array('controller' => 'test', 'action' => 'view', 1, 'ext' => 'gif'));
+ $this->assertTags($result, array('img' => array('src' => '/test/view/1.gif', 'alt' => '')));
+
+ $result = $this->Html->image('/test/view/1.gif');
+ $this->assertTags($result, array('img' => array('src' => '/test/view/1.gif', 'alt' => '')));
+
+ $result = $this->Html->image('test.gif?one=two&three=four');
+ $this->assertTags($result, array('img' => array('src' => 'img/test.gif?one=two&amp;three=four', 'alt' => '')));
+ }
+
+/**
+ * Test that image() works with fullBase and a webroot not equal to /
+ *
+ * @return void
+ */
+ public function testImageWithFullBase() {
+ $result = $this->Html->image('test.gif', array('fullBase' => true));
+ $here = $this->Html->url('/', true);
+ $this->assertTags($result, array('img' => array('src' => $here . 'img/test.gif', 'alt' => '')));
+
+ $result = $this->Html->image('sub/test.gif', array('fullBase' => true));
+ $here = $this->Html->url('/', true);
+ $this->assertTags($result, array('img' => array('src' => $here . 'img/sub/test.gif', 'alt' => '')));
+
+ $request = $this->Html->request;
+ $request->webroot = '/myproject/';
+ $request->base = '/myproject';
+ Router::setRequestInfo($request);
+
+ $result = $this->Html->image('sub/test.gif', array('fullBase' => true));
+ $here = $this->Html->url('/', true);
+ $this->assertTags($result, array('img' => array('src' => $here . 'img/sub/test.gif', 'alt' => '')));
+ }
+
+/**
+ * test image() with Asset.timestamp
+ *
+ * @return void
+ */
+ public function testImageWithTimestampping() {
+ Configure::write('Asset.timestamp', 'force');
+
+ $this->Html->request->webroot = '/';
+ $result = $this->Html->image('cake.icon.png');
+ $this->assertTags($result, array('img' => array('src' => 'preg:/\/img\/cake\.icon\.png\?\d+/', 'alt' => '')));
+
+ Configure::write('debug', 0);
+ Configure::write('Asset.timestamp', 'force');
+
+ $result = $this->Html->image('cake.icon.png');
+ $this->assertTags($result, array('img' => array('src' => 'preg:/\/img\/cake\.icon\.png\?\d+/', 'alt' => '')));
+
+ $this->Html->request->webroot = '/testing/longer/';
+ $result = $this->Html->image('cake.icon.png');
+ $expected = array(
+ 'img' => array('src' => 'preg:/\/testing\/longer\/img\/cake\.icon\.png\?[0-9]+/', 'alt' => '')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Tests creation of an image tag using a theme and asset timestamping
+ *
+ * @return void
+ */
+ public function testImageTagWithTheme() {
+ $this->skipIf(!is_writable(WWW_ROOT), 'Cannot write to webroot.');
+ $themeExists = is_dir(WWW_ROOT . 'theme');
+
+ App::uses('File', 'Utility');
+
+ $testfile = WWW_ROOT . 'theme' . DS . 'test_theme' . DS . 'img' . DS . '__cake_test_image.gif';
+ $File = new File($testfile, true);
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ Configure::write('Asset.timestamp', true);
+ Configure::write('debug', 1);
+
+ $this->Html->request->webroot = '/';
+ $this->Html->theme = 'test_theme';
+ $result = $this->Html->image('__cake_test_image.gif');
+ $this->assertTags($result, array(
+ 'img' => array(
+ 'src' => 'preg:/\/theme\/test_theme\/img\/__cake_test_image\.gif\?\d+/',
+ 'alt' => ''
+ )));
+
+ $this->Html->request->webroot = '/testing/';
+ $result = $this->Html->image('__cake_test_image.gif');
+
+ $this->assertTags($result, array(
+ 'img' => array(
+ 'src' => 'preg:/\/testing\/theme\/test_theme\/img\/__cake_test_image\.gif\?\d+/',
+ 'alt' => ''
+ )));
+
+ $dir = new Folder(WWW_ROOT . 'theme' . DS . 'test_theme');
+ $dir->delete();
+ if (!$themeExists) {
+ $dir = new Folder(WWW_ROOT . 'theme');
+ $dir->delete();
+ }
+ }
+
+/**
+ * test theme assets in main webroot path
+ *
+ * @return void
+ */
+ public function testThemeAssetsInMainWebrootPath() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $webRoot = Configure::read('App.www_root');
+ Configure::write('App.www_root', CAKE . 'Test' . DS . 'test_app' . DS . 'webroot' . DS);
+
+ $this->Html->theme = 'test_theme';
+ $result = $this->Html->css('webroot_test');
+ $expected = array(
+ 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*theme\/test_theme\/css\/webroot_test\.css/')
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Html->theme = 'test_theme';
+ $result = $this->Html->css('theme_webroot');
+ $expected = array(
+ 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*theme\/test_theme\/css\/theme_webroot\.css/')
+ );
+ $this->assertTags($result, $expected);
+
+ Configure::write('App.www_root', $webRoot);
+ }
+
+/**
+ * testStyle method
+ *
+ * @return void
+ */
+ public function testStyle() {
+ $result = $this->Html->style('display: none;');
+ $this->assertEquals('display: none;', $result);
+
+ $result = $this->Html->style(array('display' => 'none', 'margin' => '10px'));
+ $expected = 'display:none; margin:10px;';
+ $this->assertRegExp('/^display\s*:\s*none\s*;\s*margin\s*:\s*10px\s*;?$/', $expected);
+
+ $result = $this->Html->style(array('display' => 'none', 'margin' => '10px'), false);
+ $lines = explode("\n", $result);
+ $this->assertRegExp('/^\s*display\s*:\s*none\s*;\s*$/', $lines[0]);
+ $this->assertRegExp('/^\s*margin\s*:\s*10px\s*;?$/', $lines[1]);
+ }
+
+/**
+ * testCssLink method
+ *
+ * @return void
+ */
+ public function testCssLink() {
+ Configure::write('Asset.filter.css', false);
+
+ $result = $this->Html->css('screen');
+ $expected = array(
+ 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*css\/screen\.css/')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('screen.css');
+ $this->assertTags($result, $expected);
+
+ CakePlugin::load('TestPlugin');
+ $result = $this->Html->css('TestPlugin.style', null, array('plugin' => false));
+ $expected['link']['href'] = 'preg:/.*css\/TestPlugin\.style\.css/';
+ $this->assertTags($result, $expected);
+ CakePlugin::unload('TestPlugin');
+
+ $result = $this->Html->css('my.css.library');
+ $expected['link']['href'] = 'preg:/.*css\/my\.css\.library\.css/';
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('screen.css?1234');
+ $expected['link']['href'] = 'preg:/.*css\/screen\.css\?1234/';
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('screen.css?with=param&other=param');
+ $expected['link']['href'] = 'css/screen.css?with=param&amp;other=param';
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('http://whatever.com/screen.css?1234');
+ $expected['link']['href'] = 'preg:/http:\/\/.*\/screen\.css\?1234/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('Asset.filter.css', 'css.php');
+ $result = $this->Html->css('cake.generic');
+ $expected['link']['href'] = 'preg:/.*ccss\/cake\.generic\.css/';
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('//example.com/css/cake.generic.css');
+ $expected['link']['href'] = 'preg:/.*example\.com\/css\/cake\.generic\.css/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('Asset.filter.css', false);
+
+ $result = explode("\n", trim($this->Html->css(array('cake.generic', 'vendor.generic'))));
+ $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css/';
+ $this->assertTags($result[0], $expected);
+ $expected['link']['href'] = 'preg:/.*css\/vendor\.generic\.css/';
+ $this->assertTags($result[1], $expected);
+ $this->assertEquals(2, count($result));
+
+ $this->View->expects($this->at(0))
+ ->method('append')
+ ->with('css', $this->matchesRegularExpression('/css_in_head.css/'));
+
+ $this->View->expects($this->at(1))
+ ->method('append')
+ ->with('css', $this->matchesRegularExpression('/more_css_in_head.css/'));
+
+ $result = $this->Html->css('css_in_head', null, array('inline' => false));
+ $this->assertNull($result);
+
+ $result = $this->Html->css('more_css_in_head', null, array('inline' => false));
+ $this->assertNull($result);
+ }
+
+/**
+ * testPluginCssLink method
+ *
+ * @return void
+ */
+ public function testPluginCssLink() {
+ Configure::write('Asset.filter.css', false);
+ CakePlugin::load('TestPlugin');
+
+ $result = $this->Html->css('TestPlugin.test_plugin_asset');
+ $expected = array(
+ 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => 'preg:/.*test_plugin\/css\/test_plugin_asset\.css/')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('TestPlugin.test_plugin_asset.css');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('TestPlugin.my.css.library');
+ $expected['link']['href'] = 'preg:/.*test_plugin\/css\/my\.css\.library\.css/';
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->css('TestPlugin.test_plugin_asset.css?1234');
+ $expected['link']['href'] = 'preg:/.*test_plugin\/css\/test_plugin_asset\.css\?1234/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('Asset.filter.css', 'css.php');
+ $result = $this->Html->css('TestPlugin.test_plugin_asset');
+ $expected['link']['href'] = 'preg:/.*test_plugin\/ccss\/test_plugin_asset\.css/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('Asset.filter.css', false);
+
+ $result = explode("\n", trim($this->Html->css(array('TestPlugin.test_plugin_asset', 'TestPlugin.vendor.generic'))));
+ $expected['link']['href'] = 'preg:/.*test_plugin\/css\/test_plugin_asset\.css/';
+ $this->assertTags($result[0], $expected);
+ $expected['link']['href'] = 'preg:/.*test_plugin\/css\/vendor\.generic\.css/';
+ $this->assertTags($result[1], $expected);
+ $this->assertEquals(2, count($result));
+
+ CakePlugin::unload('TestPlugin');
+ }
+
+/**
+ * test use of css() and timestamping
+ *
+ * @return void
+ */
+ public function testCssTimestamping() {
+ Configure::write('debug', 2);
+ Configure::write('Asset.timestamp', true);
+
+ $expected = array(
+ 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => '')
+ );
+
+ $result = $this->Html->css('cake.generic');
+ $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('debug', 0);
+
+ $result = $this->Html->css('cake.generic');
+ $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('Asset.timestamp', 'force');
+
+ $result = $this->Html->css('cake.generic');
+ $expected['link']['href'] = 'preg:/.*css\/cake\.generic\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+
+ $this->Html->request->webroot = '/testing/';
+ $result = $this->Html->css('cake.generic');
+ $expected['link']['href'] = 'preg:/\/testing\/css\/cake\.generic\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+
+ $this->Html->request->webroot = '/testing/longer/';
+ $result = $this->Html->css('cake.generic');
+ $expected['link']['href'] = 'preg:/\/testing\/longer\/css\/cake\.generic\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test use of css() and timestamping with plugin syntax
+ *
+ * @return void
+ */
+ public function testPluginCssTimestamping() {
+ CakePlugin::load('TestPlugin');
+
+ Configure::write('debug', 2);
+ Configure::write('Asset.timestamp', true);
+
+ $expected = array(
+ 'link' => array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => '')
+ );
+
+ $result = $this->Html->css('TestPlugin.test_plugin_asset');
+ $expected['link']['href'] = 'preg:/.*test_plugin\/css\/test_plugin_asset\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('debug', 0);
+
+ $result = $this->Html->css('TestPlugin.test_plugin_asset');
+ $expected['link']['href'] = 'preg:/.*test_plugin\/css\/test_plugin_asset\.css/';
+ $this->assertTags($result, $expected);
+
+ Configure::write('Asset.timestamp', 'force');
+
+ $result = $this->Html->css('TestPlugin.test_plugin_asset');
+ $expected['link']['href'] = 'preg:/.*test_plugin\/css\/test_plugin_asset\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+
+ $this->Html->request->webroot = '/testing/';
+ $result = $this->Html->css('TestPlugin.test_plugin_asset');
+ $expected['link']['href'] = 'preg:/\/testing\/test_plugin\/css\/test_plugin_asset\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+
+ $this->Html->request->webroot = '/testing/longer/';
+ $result = $this->Html->css('TestPlugin.test_plugin_asset');
+ $expected['link']['href'] = 'preg:/\/testing\/longer\/test_plugin\/css\/test_plugin_asset\.css\?[0-9]+/';
+ $this->assertTags($result, $expected);
+
+ CakePlugin::unload('TestPlugin');
+ }
+
+/**
+ * test timestamp enforcement for script tags.
+ *
+ * @return void
+ */
+ public function testScriptTimestamping() {
+ $this->skipIf(!is_writable(JS), 'webroot/js is not Writable, timestamp testing has been skipped.');
+
+ Configure::write('debug', 2);
+ Configure::write('Asset.timestamp', true);
+
+ touch(WWW_ROOT . 'js' . DS . '__cake_js_test.js');
+ $timestamp = substr(strtotime('now'), 0, 8);
+
+ $result = $this->Html->script('__cake_js_test', array('inline' => true, 'once' => false));
+ $this->assertRegExp('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
+
+ Configure::write('debug', 0);
+ Configure::write('Asset.timestamp', 'force');
+ $result = $this->Html->script('__cake_js_test', array('inline' => true, 'once' => false));
+ $this->assertRegExp('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
+ unlink(WWW_ROOT . 'js' . DS . '__cake_js_test.js');
+ Configure::write('Asset.timestamp', false);
+ }
+
+/**
+ * test timestamp enforcement for script tags with plugin syntax.
+ *
+ * @return void
+ */
+ public function testPluginScriptTimestamping() {
+ CakePlugin::load('TestPlugin');
+
+ $pluginPath = App::pluginPath('TestPlugin');
+ $pluginJsPath = $pluginPath . 'webroot/js';
+ $this->skipIf(!is_writable($pluginJsPath), $pluginJsPath . ' is not Writable, timestamp testing has been skipped.');
+
+ Configure::write('debug', 2);
+ Configure::write('Asset.timestamp', true);
+
+ touch($pluginJsPath . DS . '__cake_js_test.js');
+ $timestamp = substr(strtotime('now'), 0, 8);
+
+ $result = $this->Html->script('TestPlugin.__cake_js_test', array('inline' => true, 'once' => false));
+ $this->assertRegExp('/test_plugin\/js\/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
+
+ Configure::write('debug', 0);
+ Configure::write('Asset.timestamp', 'force');
+ $result = $this->Html->script('TestPlugin.__cake_js_test', array('inline' => true, 'once' => false));
+ $this->assertRegExp('/test_plugin\/js\/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
+ unlink($pluginJsPath . DS . '__cake_js_test.js');
+ Configure::write('Asset.timestamp', false);
+
+ CakePlugin::unload('TestPlugin');
+ }
+
+/**
+ * test that scripts added with uses() are only ever included once.
+ * test script tag generation
+ *
+ * @return void
+ */
+ public function testScript() {
+ $result = $this->Html->script('foo');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/foo.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script(array('foobar', 'bar'));
+ $expected = array(
+ array('script' => array('type' => 'text/javascript', 'src' => 'js/foobar.js')),
+ '/script',
+ array('script' => array('type' => 'text/javascript', 'src' => 'js/bar.js')),
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('jquery-1.3');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/jquery-1.3.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('test.json');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/test.json.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('http://example.com/test.json');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'http://example.com/test.json')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('/plugin/js/jquery-1.3.2.js?someparam=foo');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => '/plugin/js/jquery-1.3.2.js?someparam=foo')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('test.json.js?foo=bar');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/test.json.js?foo=bar')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('test.json.js?foo=bar&other=test');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/test.json.js?foo=bar&amp;other=test')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('foo');
+ $this->assertNull($result, 'Script returned upon duplicate inclusion %s');
+
+ $result = $this->Html->script(array('foo', 'bar', 'baz'));
+ $this->assertNotRegExp('/foo.js/', $result);
+
+ $result = $this->Html->script('foo', array('inline' => true, 'once' => false));
+ $this->assertNotNull($result);
+
+ $result = $this->Html->script('jquery-1.3.2', array('defer' => true, 'encoding' => 'utf-8'));
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'js/jquery-1.3.2.js', 'defer' => 'defer', 'encoding' => 'utf-8')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that plugin scripts added with uses() are only ever included once.
+ * test script tag generation with plugin syntax
+ *
+ * @return void
+ */
+ public function testPluginScript() {
+ CakePlugin::load('TestPlugin');
+
+ $result = $this->Html->script('TestPlugin.foo');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'test_plugin/js/foo.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script(array('TestPlugin.foobar', 'TestPlugin.bar'));
+ $expected = array(
+ array('script' => array('type' => 'text/javascript', 'src' => 'test_plugin/js/foobar.js')),
+ '/script',
+ array('script' => array('type' => 'text/javascript', 'src' => 'test_plugin/js/bar.js')),
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('TestPlugin.jquery-1.3');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'test_plugin/js/jquery-1.3.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('TestPlugin.test.json');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'test_plugin/js/test.json.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('TestPlugin./jquery-1.3.2.js?someparam=foo');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'test_plugin/jquery-1.3.2.js?someparam=foo')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('TestPlugin.test.json.js?foo=bar');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'test_plugin/js/test.json.js?foo=bar')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('TestPlugin.foo');
+ $this->assertNull($result, 'Script returned upon duplicate inclusion %s');
+
+ $result = $this->Html->script(array('TestPlugin.foo', 'TestPlugin.bar', 'TestPlugin.baz'));
+ $this->assertNotRegExp('/test_plugin\/js\/foo.js/', $result);
+
+ $result = $this->Html->script('TestPlugin.foo', array('inline' => true, 'once' => false));
+ $this->assertNotNull($result);
+
+ $result = $this->Html->script('TestPlugin.jquery-1.3.2', array('defer' => true, 'encoding' => 'utf-8'));
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'test_plugin/js/jquery-1.3.2.js', 'defer' => 'defer', 'encoding' => 'utf-8')
+ );
+ $this->assertTags($result, $expected);
+
+ CakePlugin::unload('TestPlugin');
+ }
+
+/**
+ * test that script() works with blocks.
+ *
+ * @return void
+ */
+ public function testScriptWithBlocks() {
+ $this->View->expects($this->at(0))
+ ->method('append')
+ ->with('script', $this->matchesRegularExpression('/script_in_head.js/'));
+
+ $this->View->expects($this->at(1))
+ ->method('append')
+ ->with('script', $this->matchesRegularExpression('/bool_false.js/'));
+
+ $this->View->expects($this->at(2))
+ ->method('append')
+ ->with('headScripts', $this->matchesRegularExpression('/second_script.js/'));
+
+ $result = $this->Html->script('script_in_head', array('inline' => false));
+ $this->assertNull($result);
+
+ $result = $this->Html->script('bool_false', false);
+ $this->assertNull($result);
+
+ $result = $this->Html->script('second_script', array('block' => 'headScripts'));
+ $this->assertNull($result);
+ }
+
+/**
+ * Test that Asset.filter.js works.
+ *
+ * @return void
+ */
+ public function testScriptAssetFilter() {
+ Configure::write('Asset.filter.js', 'js.php');
+
+ $result = $this->Html->script('jquery-1.3');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'cjs/jquery-1.3.js')
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->script('//example.com/js/jquery-1.3.js');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => '//example.com/js/jquery-1.3.js')
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test a script file in the webroot/theme dir.
+ *
+ * @return void
+ */
+ public function testScriptInTheme() {
+ $this->skipIf(!is_writable(WWW_ROOT), 'Cannot write to webroot.');
+ $themeExists = is_dir(WWW_ROOT . 'theme');
+
+ App::uses('File', 'Utility');
+
+ $testfile = WWW_ROOT . 'theme' . DS . 'test_theme' . DS . 'js' . DS . '__test_js.js';
+ $File = new File($testfile, true);
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+
+ $this->Html->webroot = '/';
+ $this->Html->theme = 'test_theme';
+ $result = $this->Html->script('__test_js.js');
+ $expected = array(
+ 'script' => array('src' => '/theme/test_theme/js/__test_js.js', 'type' => 'text/javascript')
+ );
+ $this->assertTags($result, $expected);
+
+ $Folder = new Folder(WWW_ROOT . 'theme' . DS . 'test_theme');
+ $Folder->delete();
+
+ if (!$themeExists) {
+ $dir = new Folder(WWW_ROOT . 'theme');
+ $dir->delete();
+ }
+ }
+
+/**
+ * test Script block generation
+ *
+ * @return void
+ */
+ public function testScriptBlock() {
+ $result = $this->Html->scriptBlock('window.foo = 2;');
+ $expected = array(
+ 'script' => array('type' => 'text/javascript'),
+ $this->cDataStart,
+ 'window.foo = 2;',
+ $this->cDataEnd,
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => false));
+ $expected = array(
+ 'script' => array('type' => 'text/javascript'),
+ 'window.foo = 2;',
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => true));
+ $expected = array(
+ 'script' => array('type' => 'text/javascript'),
+ $this->cDataStart,
+ 'window.foo = 2;',
+ $this->cDataEnd,
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->View->expects($this->at(0))
+ ->method('append')
+ ->with('script', $this->matchesRegularExpression('/window\.foo\s\=\s2;/'));
+
+ $this->View->expects($this->at(1))
+ ->method('append')
+ ->with('scriptTop', $this->stringContains('alert('));
+
+ $result = $this->Html->scriptBlock('window.foo = 2;', array('inline' => false));
+ $this->assertNull($result);
+
+ $result = $this->Html->scriptBlock('alert("hi")', array('block' => 'scriptTop'));
+ $this->assertNull($result);
+
+ $result = $this->Html->scriptBlock('window.foo = 2;', array('safe' => false, 'encoding' => 'utf-8'));
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'encoding' => 'utf-8'),
+ 'window.foo = 2;',
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test script tag output buffering when using scriptStart() and scriptEnd();
+ *
+ * @return void
+ */
+ public function testScriptStartAndScriptEnd() {
+ $result = $this->Html->scriptStart(array('safe' => true));
+ $this->assertNull($result);
+ echo 'this is some javascript';
+
+ $result = $this->Html->scriptEnd();
+ $expected = array(
+ 'script' => array('type' => 'text/javascript'),
+ $this->cDataStart,
+ 'this is some javascript',
+ $this->cDataEnd,
+ '/script'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->scriptStart(array('safe' => false));
+ $this->assertNull($result);
+ echo 'this is some javascript';
+
+ $result = $this->Html->scriptEnd();
+ $expected = array(
+ 'script' => array('type' => 'text/javascript'),
+ 'this is some javascript',
+ '/script'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->View->expects($this->once())
+ ->method('append');
+ $result = $this->Html->scriptStart(array('safe' => false, 'inline' => false));
+ $this->assertNull($result);
+ echo 'this is some javascript';
+
+ $result = $this->Html->scriptEnd();
+ $this->assertNull($result);
+ }
+
+/**
+ * testCharsetTag method
+ *
+ * @return void
+ */
+ public function testCharsetTag() {
+ Configure::write('App.encoding', null);
+ $result = $this->Html->charset();
+ $this->assertTags($result, array('meta' => array('http-equiv' => 'Content-Type', 'content' => 'text/html; charset=utf-8')));
+
+ Configure::write('App.encoding', 'ISO-8859-1');
+ $result = $this->Html->charset();
+ $this->assertTags($result, array('meta' => array('http-equiv' => 'Content-Type', 'content' => 'text/html; charset=iso-8859-1')));
+
+ $result = $this->Html->charset('UTF-7');
+ $this->assertTags($result, array('meta' => array('http-equiv' => 'Content-Type', 'content' => 'text/html; charset=UTF-7')));
+ }
+
+/**
+ * testGetCrumb and addCrumb method
+ *
+ * @return void
+ */
+ public function testBreadcrumb() {
+ $this->assertNull($this->Html->getCrumbs());
+
+ $this->Html->addCrumb('First', '#first');
+ $this->Html->addCrumb('Second', '#second');
+ $this->Html->addCrumb('Third', '#third');
+
+ $result = $this->Html->getCrumbs();
+ $expected = array(
+ array('a' => array('href' => '#first')),
+ 'First',
+ '/a',
+ '&raquo;',
+ array('a' => array('href' => '#second')),
+ 'Second',
+ '/a',
+ '&raquo;',
+ array('a' => array('href' => '#third')),
+ 'Third',
+ '/a',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->getCrumbs(' &gt; ');
+ $expected = array(
+ array('a' => array('href' => '#first')),
+ 'First',
+ '/a',
+ ' &gt; ',
+ array('a' => array('href' => '#second')),
+ 'Second',
+ '/a',
+ ' &gt; ',
+ array('a' => array('href' => '#third')),
+ 'Third',
+ '/a',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Html->addCrumb('Fourth', null);
+
+ $result = $this->Html->getCrumbs();
+ $expected = array(
+ array('a' => array('href' => '#first')),
+ 'First',
+ '/a',
+ '&raquo;',
+ array('a' => array('href' => '#second')),
+ 'Second',
+ '/a',
+ '&raquo;',
+ array('a' => array('href' => '#third')),
+ 'Third',
+ '/a',
+ '&raquo;',
+ 'Fourth'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->getCrumbs('-', 'Start');
+ $expected = array(
+ array('a' => array('href' => '/')),
+ 'Start',
+ '/a',
+ '-',
+ array('a' => array('href' => '#first')),
+ 'First',
+ '/a',
+ '-',
+ array('a' => array('href' => '#second')),
+ 'Second',
+ '/a',
+ '-',
+ array('a' => array('href' => '#third')),
+ 'Third',
+ '/a',
+ '-',
+ 'Fourth'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test the array form of $startText
+ */
+ public function testGetCrumbFirstLink() {
+ $result = $this->Html->getCrumbList(null, 'Home');
+ $this->assertTags(
+ $result,
+ array(
+ '<ul',
+ array('li' => array('class' => 'first')),
+ array('a' => array('href' => '/')), 'Home', '/a',
+ '/li',
+ '/ul'
+ )
+ );
+
+ $this->Html->addCrumb('First', '#first');
+ $this->Html->addCrumb('Second', '#second');
+
+ $result = $this->Html->getCrumbs(' - ', array('url' => '/home', 'text' => '<img src="/home.png" />', 'escape' => false));
+ $expected = array(
+ array('a' => array('href' => '/home')),
+ 'img' => array('src' => '/home.png'),
+ '/a',
+ ' - ',
+ array('a' => array('href' => '#first')),
+ 'First',
+ '/a',
+ ' - ',
+ array('a' => array('href' => '#second')),
+ 'Second',
+ '/a',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testNestedList method
+ *
+ * @return void
+ */
+ public function testNestedList() {
+ $list = array(
+ 'Item 1',
+ 'Item 2' => array(
+ 'Item 2.1'
+ ),
+ 'Item 3',
+ 'Item 4' => array(
+ 'Item 4.1',
+ 'Item 4.2',
+ 'Item 4.3' => array(
+ 'Item 4.3.1',
+ 'Item 4.3.2'
+ )
+ ),
+ 'Item 5' => array(
+ 'Item 5.1',
+ 'Item 5.2'
+ )
+ );
+
+ $result = $this->Html->nestedList($list);
+ $expected = array(
+ '<ul',
+ '<li', 'Item 1', '/li',
+ '<li', 'Item 2',
+ '<ul', '<li', 'Item 2.1', '/li', '/ul',
+ '/li',
+ '<li', 'Item 3', '/li',
+ '<li', 'Item 4',
+ '<ul',
+ '<li', 'Item 4.1', '/li',
+ '<li', 'Item 4.2', '/li',
+ '<li', 'Item 4.3',
+ '<ul',
+ '<li', 'Item 4.3.1', '/li',
+ '<li', 'Item 4.3.2', '/li',
+ '/ul',
+ '/li',
+ '/ul',
+ '/li',
+ '<li', 'Item 5',
+ '<ul',
+ '<li', 'Item 5.1', '/li',
+ '<li', 'Item 5.2', '/li',
+ '/ul',
+ '/li',
+ '/ul'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->nestedList($list, null);
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->nestedList($list, array(), array(), 'ol');
+ $expected = array(
+ '<ol',
+ '<li', 'Item 1', '/li',
+ '<li', 'Item 2',
+ '<ol', '<li', 'Item 2.1', '/li', '/ol',
+ '/li',
+ '<li', 'Item 3', '/li',
+ '<li', 'Item 4',
+ '<ol',
+ '<li', 'Item 4.1', '/li',
+ '<li', 'Item 4.2', '/li',
+ '<li', 'Item 4.3',
+ '<ol',
+ '<li', 'Item 4.3.1', '/li',
+ '<li', 'Item 4.3.2', '/li',
+ '/ol',
+ '/li',
+ '/ol',
+ '/li',
+ '<li', 'Item 5',
+ '<ol',
+ '<li', 'Item 5.1', '/li',
+ '<li', 'Item 5.2', '/li',
+ '/ol',
+ '/li',
+ '/ol'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->nestedList($list, 'ol');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->nestedList($list, array('class' => 'list'));
+ $expected = array(
+ array('ul' => array('class' => 'list')),
+ '<li', 'Item 1', '/li',
+ '<li', 'Item 2',
+ array('ul' => array('class' => 'list')), '<li', 'Item 2.1', '/li', '/ul',
+ '/li',
+ '<li', 'Item 3', '/li',
+ '<li', 'Item 4',
+ array('ul' => array('class' => 'list')),
+ '<li', 'Item 4.1', '/li',
+ '<li', 'Item 4.2', '/li',
+ '<li', 'Item 4.3',
+ array('ul' => array('class' => 'list')),
+ '<li', 'Item 4.3.1', '/li',
+ '<li', 'Item 4.3.2', '/li',
+ '/ul',
+ '/li',
+ '/ul',
+ '/li',
+ '<li', 'Item 5',
+ array('ul' => array('class' => 'list')),
+ '<li', 'Item 5.1', '/li',
+ '<li', 'Item 5.2', '/li',
+ '/ul',
+ '/li',
+ '/ul'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->nestedList($list, array(), array('class' => 'item'));
+ $expected = array(
+ '<ul',
+ array('li' => array('class' => 'item')), 'Item 1', '/li',
+ array('li' => array('class' => 'item')), 'Item 2',
+ '<ul', array('li' => array('class' => 'item')), 'Item 2.1', '/li', '/ul',
+ '/li',
+ array('li' => array('class' => 'item')), 'Item 3', '/li',
+ array('li' => array('class' => 'item')), 'Item 4',
+ '<ul',
+ array('li' => array('class' => 'item')), 'Item 4.1', '/li',
+ array('li' => array('class' => 'item')), 'Item 4.2', '/li',
+ array('li' => array('class' => 'item')), 'Item 4.3',
+ '<ul',
+ array('li' => array('class' => 'item')), 'Item 4.3.1', '/li',
+ array('li' => array('class' => 'item')), 'Item 4.3.2', '/li',
+ '/ul',
+ '/li',
+ '/ul',
+ '/li',
+ array('li' => array('class' => 'item')), 'Item 5',
+ '<ul',
+ array('li' => array('class' => 'item')), 'Item 5.1', '/li',
+ array('li' => array('class' => 'item')), 'Item 5.2', '/li',
+ '/ul',
+ '/li',
+ '/ul'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->nestedList($list, array(), array('even' => 'even', 'odd' => 'odd'));
+ $expected = array(
+ '<ul',
+ array('li' => array('class' => 'odd')), 'Item 1', '/li',
+ array('li' => array('class' => 'even')), 'Item 2',
+ '<ul', array('li' => array('class' => 'odd')), 'Item 2.1', '/li', '/ul',
+ '/li',
+ array('li' => array('class' => 'odd')), 'Item 3', '/li',
+ array('li' => array('class' => 'even')), 'Item 4',
+ '<ul',
+ array('li' => array('class' => 'odd')), 'Item 4.1', '/li',
+ array('li' => array('class' => 'even')), 'Item 4.2', '/li',
+ array('li' => array('class' => 'odd')), 'Item 4.3',
+ '<ul',
+ array('li' => array('class' => 'odd')), 'Item 4.3.1', '/li',
+ array('li' => array('class' => 'even')), 'Item 4.3.2', '/li',
+ '/ul',
+ '/li',
+ '/ul',
+ '/li',
+ array('li' => array('class' => 'odd')), 'Item 5',
+ '<ul',
+ array('li' => array('class' => 'odd')), 'Item 5.1', '/li',
+ array('li' => array('class' => 'even')), 'Item 5.2', '/li',
+ '/ul',
+ '/li',
+ '/ul'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->nestedList($list, array('class' => 'list'), array('class' => 'item'));
+ $expected = array(
+ array('ul' => array('class' => 'list')),
+ array('li' => array('class' => 'item')), 'Item 1', '/li',
+ array('li' => array('class' => 'item')), 'Item 2',
+ array('ul' => array('class' => 'list')), array('li' => array('class' => 'item')), 'Item 2.1', '/li', '/ul',
+ '/li',
+ array('li' => array('class' => 'item')), 'Item 3', '/li',
+ array('li' => array('class' => 'item')), 'Item 4',
+ array('ul' => array('class' => 'list')),
+ array('li' => array('class' => 'item')), 'Item 4.1', '/li',
+ array('li' => array('class' => 'item')), 'Item 4.2', '/li',
+ array('li' => array('class' => 'item')), 'Item 4.3',
+ array('ul' => array('class' => 'list')),
+ array('li' => array('class' => 'item')), 'Item 4.3.1', '/li',
+ array('li' => array('class' => 'item')), 'Item 4.3.2', '/li',
+ '/ul',
+ '/li',
+ '/ul',
+ '/li',
+ array('li' => array('class' => 'item')), 'Item 5',
+ array('ul' => array('class' => 'list')),
+ array('li' => array('class' => 'item')), 'Item 5.1', '/li',
+ array('li' => array('class' => 'item')), 'Item 5.2', '/li',
+ '/ul',
+ '/li',
+ '/ul'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testMeta method
+ *
+ * @return void
+ */
+ public function testMeta() {
+ $result = $this->Html->meta('this is an rss feed', array('controller' => 'posts', 'ext' => 'rss'));
+ $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.rss/', 'type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => 'this is an rss feed')));
+
+ $result = $this->Html->meta('rss', array('controller' => 'posts', 'ext' => 'rss'), array('title' => 'this is an rss feed'));
+ $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.rss/', 'type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => 'this is an rss feed')));
+
+ $result = $this->Html->meta('atom', array('controller' => 'posts', 'ext' => 'xml'));
+ $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.xml/', 'type' => 'application/atom+xml', 'title' => 'atom')));
+
+ $result = $this->Html->meta('non-existing');
+ $this->assertTags($result, array('<meta'));
+
+ $result = $this->Html->meta('non-existing', '/posts.xpp');
+ $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.xpp/', 'type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => 'non-existing')));
+
+ $result = $this->Html->meta('non-existing', '/posts.xpp', array('type' => 'atom'));
+ $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/posts\.xpp/', 'type' => 'application/atom+xml', 'title' => 'non-existing')));
+
+ $result = $this->Html->meta('atom', array('controller' => 'posts', 'ext' => 'xml'), array('link' => '/articles.rss'));
+ $this->assertTags($result, array('link' => array('href' => 'preg:/.*\/articles\.rss/', 'type' => 'application/atom+xml', 'title' => 'atom')));
+
+ $result = $this->Html->meta(array('link' => 'favicon.ico', 'rel' => 'icon'));
+ $expected = array(
+ 'link' => array('href' => 'preg:/.*favicon\.ico/', 'rel' => 'icon'),
+ array('link' => array('href' => 'preg:/.*favicon\.ico/', 'rel' => 'shortcut icon'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->meta('icon', 'favicon.ico');
+ $expected = array(
+ 'link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'icon'),
+ array('link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'shortcut icon'))
+ );
+ $this->assertTags($result, $expected);
+ $result = $this->Html->meta('icon');
+ $expected = array(
+ 'link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'icon'),
+ array('link' => array('href' => 'preg:/.*favicon\.ico/', 'type' => 'image/x-icon', 'rel' => 'shortcut icon'))
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->meta('keywords', 'these, are, some, meta, keywords');
+ $this->assertTags($result, array('meta' => array('name' => 'keywords', 'content' => 'these, are, some, meta, keywords')));
+ $this->assertRegExp('/\s+\/>$/', $result);
+
+ $result = $this->Html->meta('description', 'this is the meta description');
+ $this->assertTags($result, array('meta' => array('name' => 'description', 'content' => 'this is the meta description')));
+
+ $result = $this->Html->meta(array('name' => 'ROBOTS', 'content' => 'ALL'));
+ $this->assertTags($result, array('meta' => array('name' => 'ROBOTS', 'content' => 'ALL')));
+ }
+
+/**
+ * Test the inline and block options for meta()
+ */
+ public function testMetaWithBlocks() {
+ $this->View->expects($this->at(0))
+ ->method('append')
+ ->with('meta', $this->stringContains('ROBOTS'));
+
+ $this->View->expects($this->at(1))
+ ->method('append')
+ ->with('metaTags', $this->stringContains('favicon.ico'));
+
+ $result = $this->Html->meta(array('name' => 'ROBOTS', 'content' => 'ALL'), null, array('inline' => false));
+ $this->assertNull($result);
+
+ $result = $this->Html->meta('icon', 'favicon.ico', array('block' => 'metaTags'));
+ $this->assertNull($result);
+ }
+
+/**
+ * testTableHeaders method
+ *
+ * @return void
+ */
+ public function testTableHeaders() {
+ $result = $this->Html->tableHeaders(array('ID', 'Name', 'Date'));
+ $expected = array('<tr', '<th', 'ID', '/th', '<th', 'Name', '/th', '<th', 'Date', '/th', '/tr');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->tableHeaders(array('ID', array('Name' => array('class' => 'highlight')), 'Date'));
+ $expected = array('<tr', '<th', 'ID', '/th', '<th class="highlight"', 'Name', '/th', '<th', 'Date', '/th', '/tr');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->tableHeaders(array('ID', array('Name' => array('class' => 'highlight', 'width' => '120px')), 'Date'));
+ $expected = array('<tr', '<th', 'ID', '/th', '<th class="highlight" width="120px"', 'Name', '/th', '<th', 'Date', '/th', '/tr');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->tableHeaders(array('ID', array('Name' => array()), 'Date'));
+ $expected = array('<tr', '<th', 'ID', '/th', '<th', 'Name', '/th', '<th', 'Date', '/th', '/tr');
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testTableCells method
+ *
+ * @return void
+ */
+ public function testTableCells() {
+ $tr = array(
+ 'td content 1',
+ array('td content 2', array("width" => "100px")),
+ array('td content 3', "width=100px")
+ );
+ $result = $this->Html->tableCells($tr);
+ $expected = array(
+ '<tr',
+ '<td', 'td content 1', '/td',
+ array('td' => array('width' => '100px')), 'td content 2', '/td',
+ array('td' => array('width' => 'preg:/100px/')), 'td content 3', '/td',
+ '/tr'
+ );
+ $this->assertTags($result, $expected);
+
+ $tr = array('td content 1', 'td content 2', 'td content 3');
+ $result = $this->Html->tableCells($tr, null, null, true);
+ $expected = array(
+ '<tr',
+ array('td' => array('class' => 'column-1')), 'td content 1', '/td',
+ array('td' => array('class' => 'column-2')), 'td content 2', '/td',
+ array('td' => array('class' => 'column-3')), 'td content 3', '/td',
+ '/tr'
+ );
+ $this->assertTags($result, $expected);
+
+ $tr = array('td content 1', 'td content 2', 'td content 3');
+ $result = $this->Html->tableCells($tr, true);
+ $expected = array(
+ '<tr',
+ array('td' => array('class' => 'column-1')), 'td content 1', '/td',
+ array('td' => array('class' => 'column-2')), 'td content 2', '/td',
+ array('td' => array('class' => 'column-3')), 'td content 3', '/td',
+ '/tr'
+ );
+ $this->assertTags($result, $expected);
+
+ $tr = array(
+ array('td content 1', 'td content 2', 'td content 3'),
+ array('td content 1', 'td content 2', 'td content 3'),
+ array('td content 1', 'td content 2', 'td content 3')
+ );
+ $result = $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'));
+ $expected = "<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>";
+ $this->assertEquals($expected, $result);
+
+ $tr = array(
+ array('td content 1', 'td content 2', 'td content 3'),
+ array('td content 1', 'td content 2', 'td content 3'),
+ array('td content 1', 'td content 2', 'td content 3'),
+ array('td content 1', 'td content 2', 'td content 3')
+ );
+ $result = $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'));
+ $expected = "<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>";
+ $this->assertEquals($expected, $result);
+
+ $tr = array(
+ array('td content 1', 'td content 2', 'td content 3'),
+ array('td content 1', 'td content 2', 'td content 3'),
+ array('td content 1', 'td content 2', 'td content 3')
+ );
+ $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'));
+ $result = $this->Html->tableCells($tr, array('class' => 'odd'), array('class' => 'even'), false, false);
+ $expected = "<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"even\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>\n<tr class=\"odd\"><td>td content 1</td> <td>td content 2</td> <td>td content 3</td></tr>";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testTag method
+ *
+ * @return void
+ */
+ public function testTag() {
+ $result = $this->Html->tag('div');
+ $this->assertTags($result, '<div');
+
+ $result = $this->Html->tag('div', 'text');
+ $this->assertTags($result, '<div', 'text', '/div');
+
+ $result = $this->Html->tag('div', '<text>', 'class-name');
+ $this->assertTags($result, array('div' => array('class' => 'class-name'), 'preg:/<text>/', '/div'));
+
+ $result = $this->Html->tag('div', '<text>', array('class' => 'class-name', 'escape' => true));
+ $this->assertTags($result, array('div' => array('class' => 'class-name'), '&lt;text&gt;', '/div'));
+ }
+
+/**
+ * testUseTag method
+ *
+ * @return void
+ */
+ public function testUseTag() {
+ $result = $this->Html->useTag('unknowntag');
+ $this->assertEquals('', $result);
+
+ $result = $this->Html->useTag('formend');
+ $this->assertTags($result, '/form');
+
+ $result = $this->Html->useTag('form', 'url', ' test');
+ $this->assertEquals('<form action="url" test>', $result);
+
+ $result = $this->Html->useTag('form', 'example.com', array('test' => 'ok'));
+ $this->assertTags($result, array('form' => array('test' => 'ok', 'action' => 'example.com')));
+ }
+
+/**
+ * testDiv method
+ *
+ * @return void
+ */
+ public function testDiv() {
+ $result = $this->Html->div('class-name');
+ $this->assertTags($result, array('div' => array('class' => 'class-name')));
+
+ $result = $this->Html->div('class-name', 'text');
+ $this->assertTags($result, array('div' => array('class' => 'class-name'), 'text', '/div'));
+
+ $result = $this->Html->div('class-name', '<text>', array('escape' => true));
+ $this->assertTags($result, array('div' => array('class' => 'class-name'), '&lt;text&gt;', '/div'));
+ }
+
+/**
+ * testPara method
+ *
+ * @return void
+ */
+ public function testPara() {
+ $result = $this->Html->para('class-name', '');
+ $this->assertTags($result, array('p' => array('class' => 'class-name')));
+
+ $result = $this->Html->para('class-name', 'text');
+ $this->assertTags($result, array('p' => array('class' => 'class-name'), 'text', '/p'));
+
+ $result = $this->Html->para('class-name', '<text>', array('escape' => true));
+ $this->assertTags($result, array('p' => array('class' => 'class-name'), '&lt;text&gt;', '/p'));
+ }
+
+/**
+ * testMedia method
+ *
+ * @return void
+ */
+ public function testMedia() {
+ $result = $this->Html->media('video.webm');
+ $expected = array('video' => array('src' => 'files/video.webm'), '/video');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->media('video.webm', array(
+ 'text' => 'Your browser does not support the HTML5 Video element.'
+ ));
+ $expected = array('video' => array('src' => 'files/video.webm'), 'Your browser does not support the HTML5 Video element.', '/video');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->media('video.webm', array('autoload', 'muted' => 'muted'));
+ $expected = array(
+ 'video' => array(
+ 'src' => 'files/video.webm',
+ 'autoload' => 'autoload',
+ 'muted' => 'muted'
+ ),
+ '/video'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->media(
+ array('video.webm', array('src' => 'video.ogv', 'type' => "video/ogg; codecs='theora, vorbis'")),
+ array('pathPrefix' => 'videos/', 'poster' => 'poster.jpg', 'text' => 'Your browser does not support the HTML5 Video element.')
+ );
+ $expected = array(
+ 'video' => array('poster' => IMAGES_URL . 'poster.jpg'),
+ array('source' => array('src' => 'videos/video.webm', 'type' => 'video/webm')),
+ array('source' => array('src' => 'videos/video.ogv', 'type' => 'video/ogg; codecs=&#039;theora, vorbis&#039;')),
+ 'Your browser does not support the HTML5 Video element.',
+ '/video'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->media('video.ogv', array('tag' => 'video'));
+ $expected = array('video' => array('src' => 'files/video.ogv'), '/video');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->media('audio.mp3');
+ $expected = array('audio' => array('src' => 'files/audio.mp3'), '/audio');
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->media(
+ array(array('src' => 'video.mov', 'type' => 'video/mp4'), 'video.webm')
+ );
+ $expected = array(
+ '<video',
+ array('source' => array('src' => 'files/video.mov', 'type' => 'video/mp4')),
+ array('source' => array('src' => 'files/video.webm', 'type' => 'video/webm')),
+ '/video'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Html->media(null, array('src' => 'video.webm'));
+ $expected = array(
+ 'video' => array('src' => 'files/video.webm'),
+ '/video'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testCrumbList method
+ *
+ *
+ * @return void
+ */
+ public function testCrumbList() {
+ $this->assertNull($this->Html->getCrumbList());
+
+ $this->Html->addCrumb('Home', '/', array('class' => 'home'));
+ $this->Html->addCrumb('Some page', '/some_page');
+ $this->Html->addCrumb('Another page');
+ $result = $this->Html->getCrumbList(
+ array('class' => 'breadcrumbs')
+ );
+ $this->assertTags(
+ $result,
+ array(
+ array('ul' => array('class' => 'breadcrumbs')),
+ array('li' => array('class' => 'first')),
+ array('a' => array('class' => 'home', 'href' => '/')), 'Home', '/a',
+ '/li',
+ '<li',
+ array('a' => array('href' => '/some_page')), 'Some page', '/a',
+ '/li',
+ array('li' => array('class' => 'last')),
+ 'Another page',
+ '/li',
+ '/ul'
+ )
+ );
+ }
+
+/**
+ * Test getCrumbList startText
+ */
+ public function testCrumbListFirstLink() {
+ $this->Html->addCrumb('First', '#first');
+ $this->Html->addCrumb('Second', '#second');
+
+ $result = $this->Html->getCrumbList(null, 'Home');
+ $this->assertTags(
+ $result,
+ array(
+ '<ul',
+ array('li' => array('class' => 'first')),
+ array('a' => array('href' => '/')), 'Home', '/a',
+ '/li',
+ '<li',
+ array('a' => array('href' => '#first')), 'First', '/a',
+ '/li',
+ array('li' => array('class' => 'last')),
+ array('a' => array('href' => '#second')), 'Second', '/a',
+ '/li',
+ '/ul'
+ )
+ );
+
+ $result = $this->Html->getCrumbList(null, array('url' => '/home', 'text' => '<img src="/home.png" />', 'escape' => false));
+ $this->assertTags(
+ $result,
+ array(
+ '<ul',
+ array('li' => array('class' => 'first')),
+ array('a' => array('href' => '/home')), 'img' => array('src' => '/home.png'), '/a',
+ '/li',
+ '<li',
+ array('a' => array('href' => '#first')), 'First', '/a',
+ '/li',
+ array('li' => array('class' => 'last')),
+ array('a' => array('href' => '#second')), 'Second', '/a',
+ '/li',
+ '/ul'
+ )
+ );
+ }
+
+/**
+ * testLoadConfig method
+ *
+ * @return void
+ */
+
+ public function testLoadConfig() {
+ $path = CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS;
+
+ $result = $this->Html->loadConfig('htmlhelper_tags', $path);
+ $expected = array(
+ 'tags' => array(
+ 'form' => 'start form',
+ 'formend' => 'finish form'
+ )
+ );
+ $this->assertEquals($expected, $result);
+ $tags = $this->Html->getAttribute('_tags');
+ $this->assertEquals('start form', $tags['form']);
+ $this->assertEquals('finish form', $tags['formend']);
+ $this->assertEquals('</select>', $tags['selectend']);
+
+ $result = $this->Html->loadConfig(array('htmlhelper_minimized.ini', 'ini'), $path);
+ $expected = array(
+ 'minimizedAttributeFormat' => 'format'
+ );
+ $this->assertEquals($expected, $result);
+ $this->assertEquals('format', $this->Html->getAttribute('_minimizedAttributeFormat'));
+ }
+
+/**
+ * testLoadConfigWrongFile method
+ *
+ * @return void
+ * @expectedException ConfigureException
+ */
+ public function testLoadConfigWrongFile() {
+ $result = $this->Html->loadConfig('wrong_file');
+ }
+
+/**
+ * testLoadConfigWrongReader method
+ *
+ * @return void
+ * @expectedException ConfigureException
+ */
+ public function testLoadConfigWrongReader() {
+ $path = CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS;
+ $result = $this->Html->loadConfig(array('htmlhelper_tags', 'wrong_reader'), $path);
+ }
+
+/**
+ * test parsing attributes.
+ *
+ * @return void
+ */
+ public function testParseAttributeCompact() {
+ $helper = new TestHtmlHelper($this->View);
+ $compact = array('compact', 'checked', 'declare', 'readonly', 'disabled',
+ 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize');
+
+ foreach ($compact as $attribute) {
+ foreach (array('true', true, 1, '1', $attribute) as $value) {
+ $attrs = array($attribute => $value);
+ $expected = ' ' . $attribute . '="' . $attribute . '"';
+ $this->assertEquals($expected, $helper->parseAttributes($attrs), '%s Failed on ' . $value);
+ }
+ }
+ $this->assertEquals(' compact="compact"', $helper->parseAttributes(array('compact')));
+
+ $attrs = array('class' => array('foo', 'bar'));
+ $expected = ' class="foo bar"';
+ $this->assertEquals(' class="foo bar"', $helper->parseAttributes($attrs));
+
+ $helper = new Html5TestHelper($this->View);
+ $expected = ' require';
+ $this->assertEquals($expected, $helper->parseAttributes(array('require')));
+ $this->assertEquals($expected, $helper->parseAttributes(array('require' => true)));
+ $this->assertEquals('', $helper->parseAttributes(array('require' => false)));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php
new file mode 100644
index 0000000..4823f1e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JqueryEngineHelperTest.php
@@ -0,0 +1,373 @@
+<?php
+/**
+ * JqueryEngineTestCase
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.View.Helper
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('JsHelper', 'View/Helper');
+App::uses('JqueryEngineHelper', 'View/Helper');
+App::uses('View', 'View');
+
+class JqueryEngineHelperTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $controller = null;
+ $this->View = $this->getMock('View', array('addScript'), array(&$controller));
+ $this->Jquery = new JqueryEngineHelper($this->View);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Jquery);
+ }
+
+/**
+ * test selector method
+ *
+ * @return void
+ */
+ public function testSelector() {
+ $result = $this->Jquery->get('#content');
+ $this->assertEquals($this->Jquery, $result);
+ $this->assertEquals($this->Jquery->selection, '$("#content")');
+
+ $result = $this->Jquery->get('document');
+ $this->assertEquals($this->Jquery, $result);
+ $this->assertEquals($this->Jquery->selection, '$(document)');
+
+ $result = $this->Jquery->get('window');
+ $this->assertEquals($this->Jquery, $result);
+ $this->assertEquals($this->Jquery->selection, '$(window)');
+
+ $result = $this->Jquery->get('ul');
+ $this->assertEquals($this->Jquery, $result);
+ $this->assertEquals($this->Jquery->selection, '$("ul")');
+ }
+
+/**
+ * test event binding
+ *
+ * @return void
+ */
+ public function testEvent() {
+ $this->Jquery->get('#myLink');
+ $result = $this->Jquery->event('click', 'doClick', array('wrap' => false));
+ $expected = '$("#myLink").bind("click", doClick);';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->event('click', '$(this).show();', array('stop' => false));
+ $expected = '$("#myLink").bind("click", function (event) {$(this).show();});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->event('click', '$(this).hide();');
+ $expected = '$("#myLink").bind("click", function (event) {$(this).hide();' . "\n" . 'return false;});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test dom ready event creation
+ *
+ * @return void
+ */
+ public function testDomReady() {
+ $result = $this->Jquery->domReady('foo.name = "bar";');
+ $expected = '$(document).ready(function () {foo.name = "bar";});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Each method
+ *
+ * @return void
+ */
+ public function testEach() {
+ $this->Jquery->get('#foo');
+ $result = $this->Jquery->each('$(this).hide();');
+ $expected = '$("#foo").each(function () {$(this).hide();});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Effect generation
+ *
+ * @return void
+ */
+ public function testEffect() {
+ $this->Jquery->get('#foo');
+ $result = $this->Jquery->effect('show');
+ $expected = '$("#foo").show();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('hide');
+ $expected = '$("#foo").hide();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('hide', array('speed' => 'fast'));
+ $expected = '$("#foo").hide("fast");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('fadeIn');
+ $expected = '$("#foo").fadeIn();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('fadeOut');
+ $expected = '$("#foo").fadeOut();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('slideIn');
+ $expected = '$("#foo").slideDown();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('slideOut');
+ $expected = '$("#foo").slideUp();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('slideDown');
+ $expected = '$("#foo").slideDown();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->effect('slideUp');
+ $expected = '$("#foo").slideUp();';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test Request Generation
+ *
+ * @return void
+ */
+ public function testRequest() {
+ $result = $this->Jquery->request(array('controller' => 'posts', 'action' => 'view', 1));
+ $expected = '$.ajax({url:"\\/posts\\/view\\/1"});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->request(array('controller' => 'posts', 'action' => 'view', 1), array(
+ 'update' => '#content'
+ ));
+ $expected = '$.ajax({dataType:"html", success:function (data, textStatus) {$("#content").html(data);}, url:"\/posts\/view\/1"});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'before' => 'doBefore',
+ 'complete' => 'doComplete',
+ 'success' => 'doSuccess',
+ 'error' => 'handleError',
+ 'type' => 'json',
+ 'data' => array('name' => 'jim', 'height' => '185cm'),
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$.ajax({beforeSend:doBefore, complete:doComplete, data:"name=jim&height=185cm", dataType:"json", error:handleError, success:doSuccess, type:"post", url:"\\/people\\/edit\\/1"});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->request('/people/edit/1', array(
+ 'update' => '#updated',
+ 'success' => 'doFoo',
+ 'method' => 'post',
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$.ajax({dataType:"html", success:function (data, textStatus) {doFoo$("#updated").html(data);}, type:"post", url:"\\/people\\/edit\\/1"});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->request('/people/edit/1', array(
+ 'update' => '#updated',
+ 'success' => 'doFoo',
+ 'method' => 'post',
+ 'dataExpression' => true,
+ 'data' => '$("#someId").serialize()',
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$.ajax({data:$("#someId").serialize(), dataType:"html", success:function (data, textStatus) {doFoo$("#updated").html(data);}, type:"post", url:"\\/people\\/edit\\/1"});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->request('/people/edit/1', array(
+ 'success' => 'doFoo',
+ 'before' => 'doBefore',
+ 'method' => 'post',
+ 'dataExpression' => true,
+ 'data' => '$("#someId").serialize()',
+ ));
+ $expected = '$.ajax({beforeSend:function (XMLHttpRequest) {doBefore}, data:$("#someId").serialize(), success:function (data, textStatus) {doFoo}, type:"post", url:"\\/people\\/edit\\/1"});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that alternate jQuery object values work for request()
+ *
+ * @return void
+ */
+ public function testRequestWithAlternateJqueryObject() {
+ $this->Jquery->jQueryObject = '$j';
+
+ $result = $this->Jquery->request('/people/edit/1', array(
+ 'update' => '#updated',
+ 'success' => 'doFoo',
+ 'method' => 'post',
+ 'dataExpression' => true,
+ 'data' => '$j("#someId").serialize()',
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$j.ajax({data:$j("#someId").serialize(), dataType:"html", success:function (data, textStatus) {doFoo$j("#updated").html(data);}, type:"post", url:"\\/people\\/edit\\/1"});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test sortable list generation
+ *
+ * @return void
+ */
+ public function testSortable() {
+ $this->Jquery->get('#myList');
+ $result = $this->Jquery->sortable(array(
+ 'distance' => 5,
+ 'containment' => 'parent',
+ 'start' => 'onStart',
+ 'complete' => 'onStop',
+ 'sort' => 'onSort',
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$("#myList").sortable({containment:"parent", distance:5, sort:onSort, start:onStart, stop:onStop});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->sortable(array(
+ 'distance' => 5,
+ 'containment' => 'parent',
+ 'start' => 'onStart',
+ 'complete' => 'onStop',
+ 'sort' => 'onSort',
+ ));
+ $expected = '$("#myList").sortable({containment:"parent", distance:5, sort:function (event, ui) {onSort}, start:function (event, ui) {onStart}, stop:function (event, ui) {onStop}});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test drag() method
+ *
+ * @return void
+ */
+ public function testDrag() {
+ $this->Jquery->get('#element');
+ $result = $this->Jquery->drag(array(
+ 'container' => '#content',
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ 'stop' => 'onStop',
+ 'snapGrid' => array(10, 10),
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$("#element").draggable({containment:"#content", drag:onDrag, grid:[10,10], start:onStart, stop:onStop});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->drag(array(
+ 'container' => '#content',
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ 'stop' => 'onStop',
+ 'snapGrid' => array(10, 10),
+ ));
+ $expected = '$("#element").draggable({containment:"#content", drag:function (event, ui) {onDrag}, grid:[10,10], start:function (event, ui) {onStart}, stop:function (event, ui) {onStop}});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test drop() method
+ *
+ * @return void
+ */
+ public function testDrop() {
+ $this->Jquery->get('#element');
+ $result = $this->Jquery->drop(array(
+ 'accept' => '.items',
+ 'hover' => 'onHover',
+ 'leave' => 'onExit',
+ 'drop' => 'onDrop',
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$("#element").droppable({accept:".items", drop:onDrop, out:onExit, over:onHover});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->drop(array(
+ 'accept' => '.items',
+ 'hover' => 'onHover',
+ 'leave' => 'onExit',
+ 'drop' => 'onDrop',
+ ));
+ $expected = '$("#element").droppable({accept:".items", drop:function (event, ui) {onDrop}, out:function (event, ui) {onExit}, over:function (event, ui) {onHover}});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test slider generation
+ *
+ * @return void
+ */
+ public function testSlider() {
+ $this->Jquery->get('#element');
+ $result = $this->Jquery->slider(array(
+ 'complete' => 'onComplete',
+ 'change' => 'onChange',
+ 'min' => 0,
+ 'max' => 10,
+ 'value' => 2,
+ 'direction' => 'vertical',
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$("#element").slider({change:onChange, max:10, min:0, orientation:"vertical", stop:onComplete, value:2});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->slider(array(
+ 'complete' => 'onComplete',
+ 'change' => 'onChange',
+ 'min' => 0,
+ 'max' => 10,
+ 'value' => 2,
+ 'direction' => 'vertical',
+ ));
+ $expected = '$("#element").slider({change:function (event, ui) {onChange}, max:10, min:0, orientation:"vertical", stop:function (event, ui) {onComplete}, value:2});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test the serializeForm method
+ *
+ * @return void
+ */
+ public function testSerializeForm() {
+ $this->Jquery->get('#element');
+ $result = $this->Jquery->serializeForm(array('isForm' => false));
+ $expected = '$("#element").closest("form").serialize();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->serializeForm(array('isForm' => true));
+ $expected = '$("#element").serialize();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Jquery->serializeForm(array('isForm' => false, 'inline' => true));
+ $expected = '$("#element").closest("form").serialize()';
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JsHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JsHelperTest.php
new file mode 100644
index 0000000..8589850
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/JsHelperTest.php
@@ -0,0 +1,928 @@
+<?php
+/**
+ * JsHelper Test Case
+ *
+ * TestCase for the JsHelper
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('JsHelper', 'View/Helper');
+App::uses('JsBaseEngineHelper', 'View/Helper');
+App::uses('FormHelper', 'View/Helper');
+App::uses('View', 'View');
+App::uses('ClassRegistry', 'Utility');
+
+class JsEncodingObject {
+
+ protected $_title = 'Old thing';
+
+ private $__noshow = 'Never ever';
+
+}
+
+class OptionEngineHelper extends JsBaseEngineHelper {
+
+ protected $_optionMap = array(
+ 'request' => array(
+ 'complete' => 'success',
+ 'request' => 'beforeSend',
+ 'type' => 'dataType'
+ )
+ );
+
+/**
+ * test method for testing option mapping
+ *
+ * @return array
+ */
+ public function testMap($options = array()) {
+ return $this->_mapOptions('request', $options);
+ }
+
+/**
+ * test method for option parsing
+ *
+ * @return void
+ */
+ public function testParseOptions($options, $safe = array()) {
+ return $this->_parseOptions($options, $safe);
+ }
+
+ public function get($selector) {
+ }
+
+ public function event($type, $callback, $options = array()) {
+ }
+
+ public function domReady($functionBody) {
+ }
+
+ public function each($callback) {
+ }
+
+ public function effect($name, $options = array()) {
+ }
+
+ public function request($url, $options = array()) {
+ }
+
+ public function drag($options = array()) {
+ }
+
+ public function drop($options = array()) {
+ }
+
+ public function sortable($options = array()) {
+ }
+
+ public function slider($options = array()) {
+ }
+
+ public function serializeForm($options = array()) {
+ }
+
+}
+
+/**
+ * JsHelper TestCase.
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class JsHelperTest extends CakeTestCase {
+
+/**
+ * Regexp for CDATA start block
+ *
+ * @var string
+ */
+ public $cDataStart = 'preg:/^\/\/<!\[CDATA\[[\n\r]*/';
+
+/**
+ * Regexp for CDATA end block
+ *
+ * @var string
+ */
+ public $cDataEnd = 'preg:/[^\]]*\]\]\>[\s\r\n]*/';
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ $this->_asset = Configure::read('Asset.timestamp');
+ Configure::write('Asset.timestamp', false);
+
+ $controller = null;
+ $this->View = $this->getMock('View', array('append'), array(&$controller));
+ $this->Js = new JsHelper($this->View, 'Option');
+ $request = new CakeRequest(null, false);
+ $this->Js->request = $request;
+ $this->Js->Html = new HtmlHelper($this->View);
+ $this->Js->Html->request = $request;
+ $this->Js->Form = new FormHelper($this->View);
+
+ $this->Js->Form->request = $request;
+ $this->Js->Form->Html = $this->Js->Html;
+ $this->Js->OptionEngine = new OptionEngineHelper($this->View);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ Configure::write('Asset.timestamp', $this->_asset);
+ unset($this->Js);
+ }
+
+/**
+ * Switches $this->Js to a mocked engine.
+ *
+ * @return void
+ */
+ protected function _useMock() {
+ $request = new CakeRequest(null, false);
+
+ if (!class_exists('TestJsEngineHelper', false)) {
+ $this->getMock('JsBaseEngineHelper', array(), array($this->View), 'TestJsEngineHelper');
+ }
+
+ $this->Js = new JsHelper($this->View, array('TestJs'));
+ $this->Js->TestJsEngine = new TestJsEngineHelper($this->View);
+ $this->mockObjects[] = $this->Js->TestJsEngine;
+ $this->Js->request = $request;
+ $this->Js->Html = new HtmlHelper($this->View);
+ $this->Js->Html->request = $request;
+ $this->Js->Form = new FormHelper($this->View);
+ $this->Js->Form->request = $request;
+ $this->Js->Form->Html = new HtmlHelper($this->View);
+ }
+
+/**
+ * test object construction
+ *
+ * @return void
+ */
+ public function testConstruction() {
+ $js = new JsHelper($this->View);
+ $this->assertEquals(array('Html', 'Form', 'JqueryEngine'), $js->helpers);
+
+ $js = new JsHelper($this->View, array('mootools'));
+ $this->assertEquals(array('Html', 'Form', 'mootoolsEngine'), $js->helpers);
+
+ $js = new JsHelper($this->View, 'prototype');
+ $this->assertEquals(array('Html', 'Form', 'prototypeEngine'), $js->helpers);
+
+ $js = new JsHelper($this->View, 'MyPlugin.Dojo');
+ $this->assertEquals(array('Html', 'Form', 'MyPlugin.DojoEngine'), $js->helpers);
+ }
+
+/**
+ * test that methods dispatch internally and to the engine class
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testMethodDispatching() {
+ $this->_useMock();
+
+ $this->Js->TestJsEngine
+ ->expects($this->once())
+ ->method('event')
+ ->with('click', 'callback');
+
+ $this->Js->event('click', 'callback');
+
+ $this->Js->TestJsEngine = new StdClass();
+ $this->Js->someMethodThatSurelyDoesntExist();
+ }
+
+/**
+ * Test that method dispatching for events respects buffer parameters and bufferedMethods Lists.
+ *
+ * @return void
+ */
+ public function testEventDispatchWithBuffering() {
+ $this->_useMock();
+
+ $this->Js->TestJsEngine->bufferedMethods = array('event', 'sortables');
+ $this->Js->TestJsEngine->expects($this->exactly(3))
+ ->method('event')
+ ->will($this->returnValue('This is an event call'));
+
+ $this->Js->event('click', 'foo');
+ $result = $this->Js->getBuffer();
+ $this->assertEquals(1, count($result));
+ $this->assertEquals('This is an event call', $result[0]);
+
+ $result = $this->Js->event('click', 'foo', array('buffer' => false));
+ $buffer = $this->Js->getBuffer();
+ $this->assertTrue(empty($buffer));
+ $this->assertEquals('This is an event call', $result);
+
+ $result = $this->Js->event('click', 'foo', false);
+ $buffer = $this->Js->getBuffer();
+ $this->assertTrue(empty($buffer));
+ $this->assertEquals('This is an event call', $result);
+ }
+
+/**
+ * Test that method dispatching for effects respects buffer parameters and bufferedMethods Lists.
+ *
+ * @return void
+ */
+ public function testEffectDispatchWithBuffering() {
+ $this->_useMock();
+ $this->Js->TestJsEngine->expects($this->exactly(4))
+ ->method('effect')
+ ->will($this->returnValue('I am not buffered.'));
+
+ $result = $this->Js->effect('slideIn');
+ $buffer = $this->Js->getBuffer();
+ $this->assertTrue(empty($buffer));
+ $this->assertEquals('I am not buffered.', $result);
+
+ $result = $this->Js->effect('slideIn', true);
+ $buffer = $this->Js->getBuffer();
+ $this->assertNull($result);
+ $this->assertEquals(1, count($buffer));
+ $this->assertEquals('I am not buffered.', $buffer[0]);
+
+ $result = $this->Js->effect('slideIn', array('speed' => 'slow'), true);
+ $buffer = $this->Js->getBuffer();
+ $this->assertNull($result);
+ $this->assertEquals(1, count($buffer));
+ $this->assertEquals('I am not buffered.', $buffer[0]);
+
+ $result = $this->Js->effect('slideIn', array('speed' => 'slow', 'buffer' => true));
+ $buffer = $this->Js->getBuffer();
+ $this->assertNull($result);
+ $this->assertEquals(1, count($buffer));
+ $this->assertEquals('I am not buffered.', $buffer[0]);
+ }
+
+/**
+ * test that writeScripts generates scripts inline.
+ *
+ * @return void
+ */
+ public function testWriteScriptsNoFile() {
+ $this->_useMock();
+ $this->Js->buffer('one = 1;');
+ $this->Js->buffer('two = 2;');
+ $result = $this->Js->writeBuffer(array('onDomReady' => false, 'cache' => false, 'clear' => false));
+ $expected = array(
+ 'script' => array('type' => 'text/javascript'),
+ $this->cDataStart,
+ "one = 1;\ntwo = 2;",
+ $this->cDataEnd,
+ '/script',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Js->TestJsEngine->expects($this->atLeastOnce())->method('domReady');
+ $result = $this->Js->writeBuffer(array('onDomReady' => true, 'cache' => false, 'clear' => false));
+
+ $this->View->expects($this->once())
+ ->method('append')
+ ->with('script', $this->matchesRegularExpression('/one\s\=\s1;\ntwo\s\=\s2;/'));
+ $result = $this->Js->writeBuffer(array('onDomReady' => false, 'inline' => false, 'cache' => false));
+ }
+
+/**
+ * test that writing the buffer with inline = false includes a script tag.
+ *
+ * @return void
+ */
+ public function testWriteBufferNotInline() {
+ $this->Js->set('foo', 1);
+
+ $this->View->expects($this->once())
+ ->method('append')
+ ->with('script', $this->matchesRegularExpression('#<script type="text\/javascript">window.app \= \{"foo"\:1\}\;<\/script>#'));
+
+ $result = $this->Js->writeBuffer(array('onDomReady' => false, 'inline' => false, 'safe' => false));
+ }
+
+/**
+ * test that writeBuffer() sets domReady = false when the request is done by XHR.
+ * Including a domReady() when in XHR can cause issues as events aren't triggered by some libraries
+ *
+ * @return void
+ */
+ public function testWriteBufferAndXhr() {
+ $this->_useMock();
+ $requestWith = null;
+ if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
+ $requestWith = $_SERVER['HTTP_X_REQUESTED_WITH'];
+ }
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
+
+ $this->Js->buffer('alert("test");');
+ $this->Js->TestJsEngine->expects($this->never())->method('domReady');
+ $result = $this->Js->writeBuffer();
+
+ unset($_SERVER['HTTP_X_REQUESTED_WITH']);
+ if ($requestWith !== null) {
+ $_SERVER['HTTP_X_REQUESTED_WITH'] = $requestWith;
+ }
+ }
+
+/**
+ * test that writeScripts makes files, and puts the events into them.
+ *
+ * @return void
+ */
+ public function testWriteScriptsInFile() {
+ $this->skipIf(!is_writable(JS), 'webroot/js is not Writable, script caching test has been skipped.');
+
+ $this->Js->request->webroot = '/';
+ $this->Js->JsBaseEngine = new TestJsEngineHelper($this->View);
+ $this->Js->buffer('one = 1;');
+ $this->Js->buffer('two = 2;');
+ $result = $this->Js->writeBuffer(array('onDomReady' => false, 'cache' => true));
+ $expected = array(
+ 'script' => array('type' => 'text/javascript', 'src' => 'preg:/(.)*\.js/'),
+ );
+ $this->assertTags($result, $expected);
+ preg_match('/src="(.*\.js)"/', $result, $filename);
+ $this->assertTrue(file_exists(WWW_ROOT . $filename[1]));
+ $contents = file_get_contents(WWW_ROOT . $filename[1]);
+ $this->assertRegExp('/one\s=\s1;\ntwo\s=\s2;/', $contents);
+
+ @unlink(WWW_ROOT . $filename[1]);
+ }
+
+/**
+ * test link()
+ *
+ * @return void
+ */
+ public function testLinkWithMock() {
+ $this->_useMock();
+
+ $options = array('update' => '#content');
+
+ $this->Js->TestJsEngine->expects($this->at(0))
+ ->method('get');
+
+ $this->Js->TestJsEngine->expects($this->at(1))
+ ->method('request')
+ ->with('/posts/view/1', $options)
+ ->will($this->returnValue('--ajax code--'));
+
+ $this->Js->TestJsEngine->expects($this->at(2))
+ ->method('event')
+ ->with('click', '--ajax code--', $options + array('buffer' => null));
+
+ $result = $this->Js->link('test link', '/posts/view/1', $options);
+ $expected = array(
+ 'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
+ 'test link',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test link with a mock and confirmation
+ *
+ * @return void
+ */
+ public function testLinkWithMockAndConfirm() {
+ $this->_useMock();
+
+ $options = array(
+ 'confirm' => 'Are you sure?',
+ 'update' => '#content',
+ 'class' => 'my-class',
+ 'id' => 'custom-id',
+ 'escape' => false
+ );
+ $this->Js->TestJsEngine->expects($this->once())
+ ->method('confirmReturn')
+ ->with($options['confirm'])
+ ->will($this->returnValue('--confirm script--'));
+
+ $this->Js->TestJsEngine->expects($this->once())
+ ->method('request')
+ ->with('/posts/view/1');
+
+ $this->Js->TestJsEngine->expects($this->once())
+ ->method('event')
+ ->with('click', '--confirm script--');
+
+ $result = $this->Js->link('test link »', '/posts/view/1', $options);
+ $expected = array(
+ 'a' => array('id' => $options['id'], 'class' => $options['class'], 'href' => '/posts/view/1'),
+ 'test link »',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test link passing on htmlAttributes
+ *
+ * @return void
+ */
+ public function testLinkWithAribtraryAttributes() {
+ $this->_useMock();
+
+ $options = array('id' => 'something', 'htmlAttributes' => array('arbitrary' => 'value', 'batman' => 'robin'));
+ $result = $this->Js->link('test link', '/posts/view/1', $options);
+ $expected = array(
+ 'a' => array('id' => $options['id'], 'href' => '/posts/view/1', 'arbitrary' => 'value',
+ 'batman' => 'robin'),
+ 'test link',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that link() and no buffering returns an <a> and <script> tags.
+ *
+ * @return void
+ */
+ public function testLinkWithNoBuffering() {
+ $this->_useMock();
+
+ $this->Js->TestJsEngine->expects($this->at(1))
+ ->method('request')
+ ->with('/posts/view/1', array('update' => '#content'))
+ ->will($this->returnValue('ajax code'));
+
+ $this->Js->TestJsEngine->expects($this->at(2))
+ ->method('event')
+ ->will($this->returnValue('-event handler-'));
+
+ $options = array('update' => '#content', 'buffer' => false);
+ $result = $this->Js->link('test link', '/posts/view/1', $options);
+ $expected = array(
+ 'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
+ 'test link',
+ '/a',
+ 'script' => array('type' => 'text/javascript'),
+ $this->cDataStart,
+ '-event handler-',
+ $this->cDataEnd,
+ '/script'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test link with buffering off and safe on.
+ *
+ * @return void
+ */
+ public function testLinkWithNoBufferingAndSafe() {
+ $this->_useMock();
+
+ $this->Js->TestJsEngine->expects($this->at(1))
+ ->method('request')
+ ->with('/posts/view/1', array('update' => '#content'))
+ ->will($this->returnValue('ajax code'));
+
+ $this->Js->TestJsEngine->expects($this->at(2))
+ ->method('event')
+ ->will($this->returnValue('-event handler-'));
+
+ $options = array('update' => '#content', 'buffer' => false, 'safe' => false);
+ $result = $this->Js->link('test link', '/posts/view/1', $options);
+
+ $expected = array(
+ 'a' => array('id' => 'preg:/link-\d+/', 'href' => '/posts/view/1'),
+ 'test link',
+ '/a',
+ 'script' => array('type' => 'text/javascript'),
+ '-event handler-',
+ '/script'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test submit() with a Mock to check Engine method calls
+ *
+ * @return void
+ */
+ public function testSubmitWithMock() {
+ $this->_useMock();
+
+ $options = array('update' => '#content', 'id' => 'test-submit', 'style' => 'margin: 0');
+
+ $this->Js->TestJsEngine->expects($this->at(0))
+ ->method('get');
+
+ $this->Js->TestJsEngine->expects($this->at(1))
+ ->method('serializeForm')
+ ->will($this->returnValue('serialize-code'));
+
+ $this->Js->TestJsEngine->expects($this->at(2))
+ ->method('request')
+ ->will($this->returnValue('ajax-code'));
+
+ $params = array(
+ 'update' => $options['update'], 'data' => 'serialize-code',
+ 'method' => 'post', 'dataExpression' => true, 'buffer' => null
+ );
+
+ $this->Js->TestJsEngine->expects($this->at(3))
+ ->method('event')
+ ->with('click', "ajax-code", $params);
+
+ $result = $this->Js->submit('Save', $options);
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save', 'style' => 'margin: 0'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test submit() with a mock
+ *
+ * @return void
+ */
+ public function testSubmitWithMockRequestParams() {
+ $this->_useMock();
+
+ $this->Js->TestJsEngine->expects($this->at(0))
+ ->method('get');
+
+ $this->Js->TestJsEngine->expects($this->at(1))
+ ->method('serializeForm')
+ ->will($this->returnValue('serialize-code'));
+
+ $requestParams = array(
+ 'update' => '#content',
+ 'data' => 'serialize-code',
+ 'method' => 'post',
+ 'dataExpression' => true
+ );
+
+ $this->Js->TestJsEngine->expects($this->at(2))
+ ->method('request')
+ ->with('/custom/url', $requestParams)
+ ->will($this->returnValue('ajax-code'));
+
+ $params = array(
+ 'update' => '#content', 'data' => 'serialize-code',
+ 'method' => 'post', 'dataExpression' => true, 'buffer' => null
+ );
+
+ $this->Js->TestJsEngine->expects($this->at(3))
+ ->method('event')
+ ->with('click', "ajax-code", $params);
+
+ $options = array('update' => '#content', 'id' => 'test-submit', 'url' => '/custom/url');
+ $result = $this->Js->submit('Save', $options);
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save'),
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that no buffer works with submit() and that parameters are leaking into the script tag.
+ *
+ * @return void
+ */
+ public function testSubmitWithNoBuffer() {
+ $this->_useMock();
+ $options = array('update' => '#content', 'id' => 'test-submit', 'buffer' => false, 'safe' => false);
+
+ $this->Js->TestJsEngine->expects($this->at(0))
+ ->method('get');
+
+ $this->Js->TestJsEngine->expects($this->at(1))
+ ->method('serializeForm')
+ ->will($this->returnValue('serialize-code'));
+
+ $this->Js->TestJsEngine->expects($this->at(2))
+ ->method('request')
+ ->will($this->returnValue('ajax-code'));
+
+ $this->Js->TestJsEngine->expects($this->at(3))
+ ->method('event')
+ ->will($this->returnValue('event-handler'));
+
+ $params = array(
+ 'update' => $options['update'], 'data' => 'serialize-code',
+ 'method' => 'post', 'dataExpression' => true, 'buffer' => false
+ );
+
+ $this->Js->TestJsEngine->expects($this->at(3))
+ ->method('event')
+ ->with('click', "ajax-code", $params);
+
+ $result = $this->Js->submit('Save', $options);
+ $expected = array(
+ 'div' => array('class' => 'submit'),
+ 'input' => array('type' => 'submit', 'id' => $options['id'], 'value' => 'Save'),
+ '/div',
+ 'script' => array('type' => 'text/javascript'),
+ 'event-handler',
+ '/script'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Test that Object::Object() is not breaking json output in JsHelper
+ *
+ * @return void
+ */
+ public function testObjectPassThrough() {
+ $result = $this->Js->object(array('one' => 'first', 'two' => 'second'));
+ $expected = '{"one":"first","two":"second"}';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that inherited Helper::value() is overwritten in JsHelper::value()
+ * and calls JsBaseEngineHelper::value().
+ *
+ * @return void
+ */
+ public function testValuePassThrough() {
+ $result = $this->Js->value('string "quote"', true);
+ $expected = '"string \"quote\""';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test set()'ing variables to the Javascript buffer and controlling the output var name.
+ *
+ * @return void
+ */
+ public function testSet() {
+ $this->Js->set('loggedIn', true);
+ $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
+ $result = $this->Js->getBuffer();
+ $expected = 'window.app = {"loggedIn":true,"height":"tall","color":"purple"};';
+ $this->assertEquals($expected, $result[0]);
+
+ $this->Js->set('loggedIn', true);
+ $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
+ $this->Js->setVariable = 'WICKED';
+ $result = $this->Js->getBuffer();
+ $expected = 'window.WICKED = {"loggedIn":true,"height":"tall","color":"purple"};';
+ $this->assertEquals($expected, $result[0]);
+
+ $this->Js->set('loggedIn', true);
+ $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
+ $this->Js->setVariable = 'Application.variables';
+ $result = $this->Js->getBuffer();
+ $expected = 'Application.variables = {"loggedIn":true,"height":"tall","color":"purple"};';
+ $this->assertEquals($expected, $result[0]);
+ }
+
+/**
+ * test that vars set with Js->set() go to the top of the buffered scripts list.
+ *
+ * @return void
+ */
+ public function testSetVarsAtTopOfBufferedScripts() {
+ $this->Js->set(array('height' => 'tall', 'color' => 'purple'));
+ $this->Js->alert('hey you!', array('buffer' => true));
+ $this->Js->confirm('Are you sure?', array('buffer' => true));
+ $result = $this->Js->getBuffer(false);
+
+ $expected = 'window.app = {"height":"tall","color":"purple"};';
+ $this->assertEquals($expected, $result[0]);
+ $this->assertEquals('alert("hey you!");', $result[1]);
+ $this->assertEquals('confirm("Are you sure?");', $result[2]);
+ }
+
+}
+
+/**
+ * JsBaseEngine Class Test case
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class JsBaseEngineTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $controller = null;
+ $this->View = $this->getMock('View', array('append'), array(&$controller));
+ $this->JsEngine = new OptionEngineHelper($this->View);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->JsEngine);
+ }
+
+/**
+ * test escape string skills
+ *
+ * @return void
+ */
+ public function testEscaping() {
+ $result = $this->JsEngine->escape('');
+ $expected = '';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->escape('CakePHP' . "\n" . 'Rapid Development Framework');
+ $expected = 'CakePHP\\nRapid Development Framework';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->escape('CakePHP' . "\r\n" . 'Rapid Development Framework' . "\r" . 'For PHP');
+ $expected = 'CakePHP\\r\\nRapid Development Framework\\rFor PHP';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->escape('CakePHP: "Rapid Development Framework"');
+ $expected = 'CakePHP: \\"Rapid Development Framework\\"';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->escape("CakePHP: 'Rapid Development Framework'");
+ $expected = "CakePHP: 'Rapid Development Framework'";
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->escape('my \\"string\\"');
+ $expected = 'my \\\\\\"string\\\\\\"';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test prompt() creation
+ *
+ * @return void
+ */
+ public function testPrompt() {
+ $result = $this->JsEngine->prompt('Hey, hey you', 'hi!');
+ $expected = 'prompt("Hey, hey you", "hi!");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->prompt('"Hey"', '"hi"');
+ $expected = 'prompt("\"Hey\"", "\"hi\"");';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test alert generation
+ *
+ * @return void
+ */
+ public function testAlert() {
+ $result = $this->JsEngine->alert('Hey there');
+ $expected = 'alert("Hey there");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->alert('"Hey"');
+ $expected = 'alert("\"Hey\"");';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test confirm generation
+ *
+ * @return void
+ */
+ public function testConfirm() {
+ $result = $this->JsEngine->confirm('Are you sure?');
+ $expected = 'confirm("Are you sure?");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->confirm('"Are you sure?"');
+ $expected = 'confirm("\"Are you sure?\"");';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Redirect
+ *
+ * @return void
+ */
+ public function testRedirect() {
+ $result = $this->JsEngine->redirect(array('controller' => 'posts', 'action' => 'view', 1));
+ $expected = 'window.location = "/posts/view/1";';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testObject encoding with non-native methods.
+ *
+ * @return void
+ */
+ public function testObject() {
+ $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8));
+ $result = $this->JsEngine->object($object);
+ $expected = '{"title":"New thing","indexes":[5,6,7,8]}';
+ $this->assertEquals($expected, $result);
+
+ $object = new JsEncodingObject();
+ $object->title = 'New thing';
+ $object->indexes = array(5,6,7,8);
+ $result = $this->JsEngine->object($object);
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->object(array('default' => 0));
+ $expected = '{"default":0}';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->JsEngine->object(array(
+ '2007' => array(
+ 'Spring' => array(
+ '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
+ ),
+ 'Fall' => array(
+ '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
+ )
+ ),
+ '2006' => array(
+ 'Spring' => array(
+ '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
+ ),
+ 'Fall' => array(
+ '1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
+ )
+ )
+ ));
+ $expected = '{"2007":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}},"2006":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}}}';
+ $this->assertEquals($expected, $result);
+
+ foreach (array('true' => true, 'false' => false, 'null' => null) as $expected => $data) {
+ $result = $this->JsEngine->object($data);
+ $this->assertEquals($expected, $result);
+ }
+
+ $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8), 'object' => array('inner' => array('value' => 1)));
+ $result = $this->JsEngine->object($object, array('prefix' => 'PREFIX', 'postfix' => 'POSTFIX'));
+ $this->assertRegExp('/^PREFIX/', $result);
+ $this->assertRegExp('/POSTFIX$/', $result);
+ $this->assertNotRegExp('/.PREFIX./', $result);
+ $this->assertNotRegExp('/.POSTFIX./', $result);
+ }
+
+/**
+ * test Mapping of options.
+ *
+ * @return void
+ */
+ public function testOptionMapping() {
+ $JsEngine = new OptionEngineHelper($this->View);
+ $result = $JsEngine->testMap();
+ $this->assertEquals(array(), $result);
+
+ $result = $JsEngine->testMap(array('foo' => 'bar', 'baz' => 'sho'));
+ $this->assertEquals(array('foo' => 'bar', 'baz' => 'sho'), $result);
+
+ $result = $JsEngine->testMap(array('complete' => 'myFunc', 'type' => 'json', 'update' => '#element'));
+ $this->assertEquals(array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'), $result);
+
+ $result = $JsEngine->testMap(array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'));
+ $this->assertEquals(array('success' => 'myFunc', 'dataType' => 'json', 'update' => '#element'), $result);
+ }
+
+/**
+ * test that option parsing escapes strings and saves what is supposed to be saved.
+ *
+ * @return void
+ */
+ public function testOptionParsing() {
+ $JsEngine = new OptionEngineHelper($this->View);
+
+ $result = $JsEngine->testParseOptions(array('url' => '/posts/view/1', 'key' => 1));
+ $expected = 'key:1, url:"\\/posts\\/view\\/1"';
+ $this->assertEquals($expected, $result);
+
+ $result = $JsEngine->testParseOptions(array('url' => '/posts/view/1', 'success' => 'doSuccess'), array('success'));
+ $expected = 'success:doSuccess, url:"\\/posts\\/view\\/1"';
+ $this->assertEquals($expected, $result);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php
new file mode 100644
index 0000000..91af71e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/MootoolsEngineHelperTest.php
@@ -0,0 +1,378 @@
+<?php
+/**
+ * MooEngineTestCase
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.View.Helper
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('JsHelper', 'View/Helper');
+App::uses('MootoolsEngineHelper', 'View/Helper');
+
+class MootoolsEngineHelperTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $controller = null;
+ $this->View = $this->getMock('View', array('addScript'), array(&$controller));
+ $this->Moo = new MootoolsEngineHelper($this->View);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Moo);
+ }
+
+/**
+ * test selector method
+ *
+ * @return void
+ */
+ public function testSelector() {
+ $result = $this->Moo->get('#content');
+ $this->assertEquals($this->Moo, $result);
+ $this->assertEquals($this->Moo->selection, '$("content")');
+
+ $result = $this->Moo->get('a .remove');
+ $this->assertEquals($this->Moo, $result);
+ $this->assertEquals($this->Moo->selection, '$$("a .remove")');
+
+ $result = $this->Moo->get('document');
+ $this->assertEquals($this->Moo, $result);
+ $this->assertEquals($this->Moo->selection, "$(document)");
+
+ $result = $this->Moo->get('window');
+ $this->assertEquals($this->Moo, $result);
+ $this->assertEquals($this->Moo->selection, "$(window)");
+
+ $result = $this->Moo->get('ul');
+ $this->assertEquals($this->Moo, $result);
+ $this->assertEquals($this->Moo->selection, '$$("ul")');
+
+ $result = $this->Moo->get('#some_long-id.class');
+ $this->assertEquals($this->Moo, $result);
+ $this->assertEquals($this->Moo->selection, '$$("#some_long-id.class")');
+ }
+
+/**
+ * test event binding
+ *
+ * @return void
+ */
+ public function testEvent() {
+ $this->Moo->get('#myLink');
+ $result = $this->Moo->event('click', 'doClick', array('wrap' => false));
+ $expected = '$("myLink").addEvent("click", doClick);';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->event('click', 'this.setStyle("display", "");', array('stop' => false));
+ $expected = '$("myLink").addEvent("click", function (event) {this.setStyle("display", "");});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->event('click', 'this.setStyle("display", "none");');
+ $expected = "\$(\"myLink\").addEvent(\"click\", function (event) {event.stop();\nthis.setStyle(\"display\", \"none\");});";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test dom ready event creation
+ *
+ * @return void
+ */
+ public function testDomReady() {
+ $result = $this->Moo->domReady('foo.name = "bar";');
+ $expected = 'window.addEvent("domready", function (event) {foo.name = "bar";});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Each method
+ *
+ * @return void
+ */
+ public function testEach() {
+ $this->Moo->get('#foo');
+ $result = $this->Moo->each('item.setStyle("display", "none");');
+ $expected = '$("foo").each(function (item, index) {item.setStyle("display", "none");});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Effect generation
+ *
+ * @return void
+ */
+ public function testEffect() {
+ $this->Moo->get('#foo');
+ $result = $this->Moo->effect('show');
+ $expected = '$("foo").setStyle("display", "");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->effect('hide');
+ $expected = '$("foo").setStyle("display", "none");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->effect('fadeIn');
+ $expected = '$("foo").fade("in");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->effect('fadeOut');
+ $expected = '$("foo").fade("out");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->effect('slideIn');
+ $expected = '$("foo").slide("in");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->effect('slideOut');
+ $expected = '$("foo").slide("out");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->effect('slideOut', array('speed' => 'fast'));
+ $expected = '$("foo").set("slide", {duration:"short"}).slide("out");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->effect('slideOut', array('speed' => 'slow'));
+ $expected = '$("foo").set("slide", {duration:"long"}).slide("out");';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test Request Generation
+ *
+ * @return void
+ */
+ public function testRequest() {
+ $result = $this->Moo->request(array('controller' => 'posts', 'action' => 'view', 1));
+ $expected = 'var jsRequest = new Request({url:"\\/posts\\/view\\/1"}).send();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->request('/posts/view/1', array('update' => 'content'));
+ $expected = 'var jsRequest = new Request.HTML({update:"content", url:"\\/posts\\/view\\/1"}).send();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'complete' => 'doSuccess',
+ 'error' => 'handleError',
+ 'type' => 'json',
+ 'data' => array('name' => 'jim', 'height' => '185cm'),
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Request.JSON({method:"post", onComplete:doSuccess, onFailure:handleError, url:"\\/people\\/edit\\/1"}).send({"name":"jim","height":"185cm"});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'complete' => 'doSuccess',
+ 'update' => '#update-zone',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:doSuccess, update:"update-zone", url:"\\/people\\/edit\\/1"}).send();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'complete' => 'doComplete',
+ 'success' => 'doSuccess',
+ 'error' => 'doFailure',
+ 'before' => 'doBefore',
+ 'update' => 'update-zone',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:doComplete, onFailure:doFailure, onRequest:doBefore, onSuccess:doSuccess, update:"update-zone", url:"\\/people\\/edit\\/1"}).send();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'complete' => 'doComplete',
+ 'success' => 'doSuccess',
+ 'error' => 'doFailure',
+ 'before' => 'doBefore',
+ 'update' => 'update-zone',
+ 'dataExpression' => true,
+ 'data' => '$("foo").toQueryString()',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:doComplete, onFailure:doFailure, onRequest:doBefore, onSuccess:doSuccess, update:"update-zone", url:"\\/people\\/edit\\/1"}).send($("foo").toQueryString());';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'before' => 'doBefore',
+ 'success' => 'doSuccess',
+ 'complete' => 'doComplete',
+ 'update' => '#update-zone',
+ ));
+ $expected = 'var jsRequest = new Request.HTML({method:"post", onComplete:function () {doComplete}, onRequest:function () {doBefore}, onSuccess:function (responseText, responseXML) {doSuccess}, update:"update-zone", url:"\\/people\\/edit\\/1"}).send();';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test sortable list generation
+ *
+ * @return void
+ */
+ public function testSortable() {
+ $this->Moo->get('#myList');
+ $result = $this->Moo->sortable(array(
+ 'distance' => 5,
+ 'containment' => 'parent',
+ 'start' => 'onStart',
+ 'complete' => 'onStop',
+ 'sort' => 'onSort',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsSortable = new Sortables($("myList"), {constrain:"parent", onComplete:onStop, onSort:onSort, onStart:onStart, snap:5});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test drag() method
+ *
+ * @return void
+ */
+ public function testDrag() {
+ $this->Moo->get('#drag-me');
+ $result = $this->Moo->drag(array(
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ 'stop' => 'onStop',
+ 'snapGrid' => array(10,10),
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$("drag-me").makeDraggable({onComplete:onStop, onDrag:onDrag, onStart:onStart, snap:[10,10]});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test drop() method with the required drag option missing
+ *
+ * @expectedException PHPUnit_Framework_Error_Warning
+ * @return void
+ */
+ public function testDropWithMissingOption() {
+ $this->Moo->get('#drop-me');
+ $this->Moo->drop(array(
+ 'drop' => 'onDrop',
+ 'leave' => 'onLeave',
+ 'hover' => 'onHover',
+ ));
+ }
+
+/**
+ * test drop() method
+ *
+ * @return void
+ */
+ public function testDrop() {
+ $this->Moo->get('#drop-me');
+ $result = $this->Moo->drop(array(
+ 'drop' => 'onDrop',
+ 'leave' => 'onLeave',
+ 'hover' => 'onHover',
+ 'drag' => '#my-drag',
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$("my-drag").makeDraggable({droppables:$("drop-me"), onDrop:onDrop, onEnter:onHover, onLeave:onLeave});';
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($this->Moo->selection, '$("drop-me")');
+
+ $result = $this->Moo->drop(array(
+ 'drop' => 'onDrop',
+ 'leave' => 'onLeave',
+ 'hover' => 'onHover',
+ 'drag' => '#my-drag',
+ ));
+ $expected = '$("my-drag").makeDraggable({droppables:$("drop-me"), onDrop:function (element, droppable, event) {onDrop}, onEnter:function (element, droppable) {onHover}, onLeave:function (element, droppable) {onLeave}});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test slider generation
+ *
+ * @return void
+ */
+ public function testSlider() {
+ $this->Moo->get('#slider');
+ $result = $this->Moo->slider(array(
+ 'handle' => '#my-handle',
+ 'complete' => 'onComplete',
+ 'change' => 'onChange',
+ 'direction' => 'horizontal',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsSlider = new Slider($("slider"), $("my-handle"), {mode:"horizontal", onChange:onChange, onComplete:onComplete});';
+ $this->assertEquals($expected, $result);
+ $this->assertEquals($this->Moo->selection, '$("slider")');
+
+ $this->Moo->get('#slider');
+ $result = $this->Moo->slider(array(
+ 'handle' => '#my-handle',
+ 'complete' => 'onComplete',
+ 'change' => 'onChange',
+ 'direction' => 'horizontal',
+ 'min' => 10,
+ 'max' => 40,
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsSlider = new Slider($("slider"), $("my-handle"), {mode:"horizontal", onChange:onChange, onComplete:onComplete, range:[10,40]});';
+ $this->assertEquals($expected, $result);
+
+ $this->Moo->get('#slider');
+ $result = $this->Moo->slider(array(
+ 'handle' => '#my-handle',
+ 'complete' => 'complete;',
+ 'change' => 'change;',
+ 'direction' => 'horizontal',
+ ));
+ $expected = 'var jsSlider = new Slider($("slider"), $("my-handle"), {mode:"horizontal", onChange:function (step) {change;}, onComplete:function (event) {complete;}});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test the serializeForm implementation.
+ *
+ * @return void
+ */
+ public function testSerializeForm() {
+ $this->Moo->get('#element');
+ $result = $this->Moo->serializeForm(array('isForm' => true));
+ $expected = '$("element").toQueryString();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->serializeForm(array('isForm' => true, 'inline' => true));
+ $expected = '$("element").toQueryString()';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->serializeForm(array('isForm' => false));
+ $expected = '$($("element").form).toQueryString();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Moo->serializeForm(array('isForm' => false, 'inline' => true));
+ $expected = '$($("element").form).toQueryString()';
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php
new file mode 100644
index 0000000..f75ffd9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/NumberHelperTest.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * NumberHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('NumberHelper', 'View/Helper');
+
+/**
+ * NumberHelperTestObject class
+ */
+class NumberHelperTestObject extends NumberHelper {
+
+ public function attach(CakeNumberMock $cakeNumber) {
+ $this->_engine = $cakeNumber;
+ }
+
+ public function engine() {
+ return $this->_engine;
+ }
+
+}
+
+/**
+ * CakeNumberMock class
+ */
+class CakeNumberMock {
+}
+
+/**
+ * NumberHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class NumberHelperTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->View = new View(null);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->View);
+ }
+
+/**
+ * test CakeNumber class methods are called correctly
+ */
+ public function testNumberHelperProxyMethodCalls() {
+ $methods = array(
+ 'precision', 'toReadableSize', 'toPercentage', 'format',
+ 'currency', 'addFormat',
+ );
+ $CakeNumber = $this->getMock('CakeNumberMock', $methods);
+ $Number = new NumberHelperTestObject($this->View, array('engine' => 'CakeNumberMock'));
+ $Number->attach($CakeNumber);
+ foreach ($methods as $method) {
+ $CakeNumber->expects($this->at(0))->method($method);
+ $Number->{$method}('who', 'what', 'when', 'where', 'how');
+ }
+ }
+
+/**
+ * test engine override
+ */
+ public function testEngineOverride() {
+ App::build(array(
+ 'Utility' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Utility' . DS)
+ ), App::REGISTER);
+ $Number = new NumberHelperTestObject($this->View, array('engine' => 'TestAppEngine'));
+ $this->assertInstanceOf('TestAppEngine', $Number->engine());
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $Number = new NumberHelperTestObject($this->View, array('engine' => 'TestPlugin.TestPluginEngine'));
+ $this->assertInstanceOf('TestPluginEngine', $Number->engine());
+ CakePlugin::unload('TestPlugin');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php
new file mode 100644
index 0000000..fb8289f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php
@@ -0,0 +1,2501 @@
+<?php
+/**
+ * PaginatorHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('View', 'View');
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('JsHelper', 'View/Helper');
+App::uses('PaginatorHelper', 'View/Helper');
+App::uses('FormHelper', 'View/Helper');
+
+if (!defined('FULL_BASE_URL')) {
+ define('FULL_BASE_URL', 'http://cakephp.org');
+}
+
+/**
+ * PaginatorHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class PaginatorHelperTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ $controller = null;
+ $this->View = new View($controller);
+ $this->Paginator = new PaginatorHelper($this->View);
+ $this->Paginator->Js = $this->getMock('PaginatorHelper', array(), array($this->View));
+ $this->Paginator->request = new CakeRequest(null, false);
+ $this->Paginator->request->addParams(array(
+ 'paging' => array(
+ 'Article' => array(
+ 'page' => 2,
+ 'current' => 9,
+ 'count' => 62,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 7,
+ 'order' => null,
+ 'limit' => 20,
+ 'options' => array(
+ 'page' => 1,
+ 'conditions' => array()
+ ),
+ 'paramType' => 'named'
+ )
+ )
+ ));
+ $this->Paginator->Html = new HtmlHelper($this->View);
+
+ Configure::write('Routing.prefixes', array());
+ Router::reload();
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->View, $this->Paginator);
+ }
+
+/**
+ * testHasPrevious method
+ *
+ * @return void
+ */
+ public function testHasPrevious() {
+ $this->assertSame($this->Paginator->hasPrev(), false);
+ $this->Paginator->request->params['paging']['Article']['prevPage'] = true;
+ $this->assertSame($this->Paginator->hasPrev(), true);
+ $this->Paginator->request->params['paging']['Article']['prevPage'] = false;
+ }
+
+/**
+ * testHasNext method
+ *
+ * @return void
+ */
+ public function testHasNext() {
+ $this->assertSame($this->Paginator->hasNext(), true);
+ $this->Paginator->request->params['paging']['Article']['nextPage'] = false;
+ $this->assertSame($this->Paginator->hasNext(), false);
+ $this->Paginator->request->params['paging']['Article']['nextPage'] = true;
+ }
+
+/**
+ * testDisabledLink method
+ *
+ * @return void
+ */
+ public function testDisabledLink() {
+ $this->Paginator->request->params['paging']['Article']['nextPage'] = false;
+ $this->Paginator->request->params['paging']['Article']['page'] = 1;
+ $result = $this->Paginator->next('Next', array(), true);
+ $expected = '<span class="next">Next</span>';
+ $this->assertEquals($expected, $result);
+
+ $this->Paginator->request->params['paging']['Article']['prevPage'] = false;
+ $result = $this->Paginator->prev('prev', array('update' => 'theList', 'indicator' => 'loading', 'url' => array('controller' => 'posts')), null, array('class' => 'disabled', 'tag' => 'span'));
+ $expected = array(
+ 'span' => array('class' => 'disabled'), 'prev', '/span'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSortLinks method
+ *
+ * @return void
+ */
+ public function testSortLinks() {
+ Router::reload();
+ Router::parse('/');
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'url' => array('url' => 'accounts/')),
+ array('base' => '/officespace', 'here' => '/officespace/accounts/', 'webroot' => '/officespace/')
+ ));
+ $this->Paginator->options(array('url' => array('param')));
+ $this->Paginator->request['paging'] = array(
+ 'Article' => array(
+ 'current' => 9,
+ 'count' => 62,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 7,
+ 'options' => array(
+ 'page' => 1,
+ 'order' => array('date' => 'asc'),
+ 'conditions' => array()
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->sort('title');
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/param/page:1/sort:title/direction:asc'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->sort('date');
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/param/page:1/sort:date/direction:desc', 'class' => 'asc'),
+ 'Date',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->sort('title', 'TestTitle');
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/param/page:1/sort:title/direction:asc'),
+ 'TestTitle',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->sort('title', array('asc' => 'ascending', 'desc' => 'descending'));
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/param/page:1/sort:title/direction:asc'),
+ 'ascending',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = 'title';
+ $result = $this->Paginator->sort('title', array('asc' => 'ascending', 'desc' => 'descending'));
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/param/page:1/sort:title/direction:desc', 'class' => 'asc'),
+ 'descending',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'desc');
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = null;
+ $result = $this->Paginator->sort('title');
+ $this->assertRegExp('/\/accounts\/index\/param\/page:1\/sort:title\/direction:asc" class="desc">Title<\/a>$/', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = null;
+ $result = $this->Paginator->sort('title');
+ $this->assertRegExp('/\/accounts\/index\/param\/page:1\/sort:title\/direction:desc" class="asc">Title<\/a>$/', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'desc');
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = null;
+ $result = $this->Paginator->sort('title', 'Title', array('direction' => 'desc'));
+ $this->assertRegExp('/\/accounts\/index\/param\/page:1\/sort:title\/direction:asc" class="desc">Title<\/a>$/', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'desc');
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = null;
+ $result = $this->Paginator->sort('title', 'Title', array('direction' => 'asc'));
+ $this->assertRegExp('/\/accounts\/index\/param\/page:1\/sort:title\/direction:asc" class="desc">Title<\/a>$/', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = null;
+ $result = $this->Paginator->sort('title', 'Title', array('direction' => 'asc'));
+ $this->assertRegExp('/\/accounts\/index\/param\/page:1\/sort:title\/direction:desc" class="asc">Title<\/a>$/', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = null;
+ $result = $this->Paginator->sort('title', 'Title', array('direction' => 'desc'));
+ $this->assertRegExp('/\/accounts\/index\/param\/page:1\/sort:title\/direction:desc" class="asc">Title<\/a>$/', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
+ $this->Paginator->request->params['paging']['Article']['options']['sort'] = null;
+ $result = $this->Paginator->sort('title', 'Title', array('direction' => 'desc', 'class' => 'foo'));
+ $this->assertRegExp('/\/accounts\/index\/param\/page:1\/sort:title\/direction:desc" class="foo asc">Title<\/a>$/', $result);
+ }
+
+/**
+ * test that sort() works with virtual field order options.
+ *
+ * @return void
+ */
+ public function testSortLinkWithVirtualField() {
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'form' => array(), 'url' => array('url' => 'accounts/')),
+ array('base' => '', 'here' => '/accounts/', 'webroot' => '/')
+ ));
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('full_name' => 'asc');
+
+ $result = $this->Paginator->sort('Article.full_name');
+ $expected = array(
+ 'a' => array('href' => '/accounts/index/page:1/sort:Article.full_name/direction:desc', 'class' => 'asc'),
+ 'Article.full Name',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->sort('full_name');
+ $expected = array(
+ 'a' => array('href' => '/accounts/index/page:1/sort:full_name/direction:desc', 'class' => 'asc'),
+ 'Full Name',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('full_name' => 'desc');
+ $result = $this->Paginator->sort('Article.full_name');
+ $expected = array(
+ 'a' => array('href' => '/accounts/index/page:1/sort:Article.full_name/direction:asc', 'class' => 'desc'),
+ 'Article.full Name',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->sort('full_name');
+ $expected = array(
+ 'a' => array('href' => '/accounts/index/page:1/sort:full_name/direction:asc', 'class' => 'desc'),
+ 'Full Name',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSortLinksUsingDirectionOption method
+ *
+ * @return void
+ */
+ public function testSortLinksUsingDirectionOption() {
+ Router::reload();
+ Router::parse('/');
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(),
+ 'url' => array('url' => 'accounts/', 'mod_rewrite' => 'true')),
+ array('base' => '/', 'here' => '/accounts/', 'webroot' => '/',)
+ ));
+ $this->Paginator->options(array('url' => array('param')));
+
+ $result = $this->Paginator->sort('title', 'TestTitle', array('direction' => 'desc'));
+ $expected = array(
+ 'a' => array('href' => '/accounts/index/param/page:1/sort:title/direction:desc'),
+ 'TestTitle',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->sort('title', array('asc' => 'ascending', 'desc' => 'descending'), array('direction' => 'desc'));
+ $expected = array(
+ 'a' => array('href' => '/accounts/index/param/page:1/sort:title/direction:desc'),
+ 'descending',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSortLinksUsingDotNotation method
+ *
+ * @return void
+ */
+ public function testSortLinksUsingDotNotation() {
+ Router::reload();
+ Router::parse('/');
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'form' => array(), 'url' => array('url' => 'accounts/', 'mod_rewrite' => 'true'), 'bare' => 0),
+ array('base' => '/officespace', 'here' => '/officespace/accounts/', 'webroot' => '/officespace/')
+ ));
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'desc');
+ $result = $this->Paginator->sort('Article.title', 'Title');
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/page:1/sort:Article.title/direction:asc', 'class' => 'desc'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
+ $result = $this->Paginator->sort('Article.title', 'Title');
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/page:1/sort:Article.title/direction:desc', 'class' => 'asc'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Account.title' => 'asc');
+ $result = $this->Paginator->sort('title');
+ $expected = array(
+ 'a' => array('href' => '/officespace/accounts/index/page:1/sort:title/direction:asc'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testSortKey method
+ *
+ * @return void
+ */
+ public function testSortKey() {
+ $result = $this->Paginator->sortKey(null, array(
+ 'order' => array('Article.title' => 'desc'
+ )));
+ $this->assertEquals('Article.title', $result);
+
+ $result = $this->Paginator->sortKey('Article', array('order' => 'Article.title'));
+ $this->assertEquals('Article.title', $result);
+
+ $result = $this->Paginator->sortKey('Article', array('sort' => 'Article.title'));
+ $this->assertEquals('Article.title', $result);
+
+ $result = $this->Paginator->sortKey('Article', array('sort' => 'Article'));
+ $this->assertEquals('Article', $result);
+ }
+
+/**
+ * Test that sortKey falls back to the default sorting options set
+ * in the $params which are the default pagination options.
+ *
+ * @return void
+ */
+ public function testSortKeyFallbackToParams() {
+ $this->Paginator->request->params['paging']['Article']['order'] = 'Article.body';
+ $result = $this->Paginator->sortKey();
+ $this->assertEquals('Article.body', $result);
+
+ $result = $this->Paginator->sortKey('Article');
+ $this->assertEquals('Article.body', $result);
+
+ $this->Paginator->request->params['paging']['Article']['order'] = array(
+ 'Article.body' => 'DESC'
+ );
+ $result = $this->Paginator->sortKey();
+ $this->assertEquals('Article.body', $result);
+
+ $result = $this->Paginator->sortKey('Article');
+ $this->assertEquals('Article.body', $result);
+ }
+
+/**
+ * testSortDir method
+ *
+ * @return void
+ */
+ public function testSortDir() {
+ $result = $this->Paginator->sortDir();
+ $expected = 'asc';
+
+ $this->assertEquals($expected, $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'desc');
+ $result = $this->Paginator->sortDir();
+ $expected = 'desc';
+
+ $this->assertEquals($expected, $result);
+
+ unset($this->Paginator->request->params['paging']['Article']['options']);
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
+ $result = $this->Paginator->sortDir();
+ $expected = 'asc';
+
+ $this->assertEquals($expected, $result);
+
+ unset($this->Paginator->request->params['paging']['Article']['options']);
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('title' => 'desc');
+ $result = $this->Paginator->sortDir();
+ $expected = 'desc';
+
+ $this->assertEquals($expected, $result);
+
+ unset($this->Paginator->request->params['paging']['Article']['options']);
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('title' => 'asc');
+ $result = $this->Paginator->sortDir();
+ $expected = 'asc';
+
+ $this->assertEquals($expected, $result);
+
+ unset($this->Paginator->request->params['paging']['Article']['options']);
+ $this->Paginator->request->params['paging']['Article']['options']['direction'] = 'asc';
+ $result = $this->Paginator->sortDir();
+ $expected = 'asc';
+
+ $this->assertEquals($expected, $result);
+
+ unset($this->Paginator->request->params['paging']['Article']['options']);
+ $this->Paginator->request->params['paging']['Article']['options']['direction'] = 'desc';
+ $result = $this->Paginator->sortDir();
+ $expected = 'desc';
+
+ $this->assertEquals($expected, $result);
+
+ unset($this->Paginator->request->params['paging']['Article']['options']);
+ $result = $this->Paginator->sortDir('Article', array('direction' => 'asc'));
+ $expected = 'asc';
+
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->sortDir('Article', array('direction' => 'desc'));
+ $expected = 'desc';
+
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->sortDir('Article', array('direction' => 'asc'));
+ $expected = 'asc';
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test that sortDir falls back to the default sorting options set
+ * in the $params which are the default pagination options.
+ *
+ * @return void
+ */
+ public function testSortDirFallbackToParams() {
+ $this->Paginator->request->params['paging']['Article']['order'] = array(
+ 'Article.body' => 'ASC'
+ );
+ $result = $this->Paginator->sortDir();
+ $this->assertEquals('asc', $result);
+
+ $result = $this->Paginator->sortDir('Article');
+ $this->assertEquals('asc', $result);
+
+ $this->Paginator->request->params['paging']['Article']['order'] = array(
+ 'Article.body' => 'DESC'
+ );
+ $result = $this->Paginator->sortDir();
+ $this->assertEquals('desc', $result);
+
+ $result = $this->Paginator->sortDir('Article');
+ $this->assertEquals('desc', $result);
+ }
+
+/**
+ * testSortAdminLinks method
+ *
+ * @return void
+ */
+ public function testSortAdminLinks() {
+ Configure::write('Routing.prefixes', array('admin'));
+
+ Router::reload();
+ Router::setRequestInfo(array(
+ array('pass' => array(), 'named' => array(), 'controller' => 'users', 'plugin' => null, 'action' => 'admin_index', 'prefix' => 'admin', 'admin' => true, 'url' => array('ext' => 'html', 'url' => 'admin/users')),
+ array('base' => '', 'here' => '/admin/users', 'webroot' => '/')
+ ));
+ Router::parse('/admin/users');
+ $this->Paginator->request->params['paging']['Article']['page'] = 1;
+ $result = $this->Paginator->next('Next');
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/admin/users/index/page:2', 'rel' => 'next'),
+ 'Next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ Router::reload();
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'test', 'action' => 'admin_index', 'pass' => array(), 'prefix' => 'admin', 'admin' => true, 'url' => array('url' => 'admin/test')),
+ array('base' => '', 'here' => '/admin/test', 'webroot' => '/')
+ ));
+ Router::parse('/');
+ $this->Paginator->options(array('url' => array('param')));
+ $result = $this->Paginator->sort('title');
+ $expected = array(
+ 'a' => array('href' => '/admin/test/index/param/page:1/sort:title/direction:asc'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->options(array('url' => array('param')));
+ $result = $this->Paginator->sort('Article.title', 'Title');
+ $expected = array(
+ 'a' => array('href' => '/admin/test/index/param/page:1/sort:Article.title/direction:asc'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testUrlGeneration method
+ *
+ * @return void
+ */
+ public function testUrlGeneration() {
+ $result = $this->Paginator->sort('controller');
+ $expected = array(
+ 'a' => array('href' => '/index/page:1/sort:controller/direction:asc'),
+ 'Controller',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->url();
+ $this->assertEquals('/index/page:1', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['page'] = 2;
+ $result = $this->Paginator->url();
+ $this->assertEquals('/index/page:2', $result);
+
+ $options = array('order' => array('Article' => 'desc'));
+ $result = $this->Paginator->url($options);
+ $this->assertEquals('/index/page:2/sort:Article/direction:desc', $result);
+
+ $this->Paginator->request->params['paging']['Article']['options']['page'] = 3;
+ $options = array('order' => array('Article.name' => 'desc'));
+ $result = $this->Paginator->url($options);
+ $this->assertEquals('/index/page:3/sort:Article.name/direction:desc', $result);
+ }
+
+/**
+ * test URL generation with prefix routes
+ *
+ * @return void
+ */
+ public function testUrlGenerationWithPrefixes() {
+ $_back = Configure::read('Routing');
+
+ Configure::write('Routing.prefixes', array('members'));
+ Router::reload();
+
+ Router::parse('/');
+
+ Router::setRequestInfo(array(
+ array('controller' => 'posts', 'action' => 'index', 'form' => array(), 'url' => array(), 'plugin' => null),
+ array('base' => '', 'here' => 'posts/index', 'webroot' => '/')
+ ));
+
+ $this->Paginator->request->params['paging']['Article']['options']['page'] = 2;
+ $this->Paginator->request->params['paging']['Article']['page'] = 2;
+ $this->Paginator->request->params['paging']['Article']['prevPage'] = true;
+ $options = array('members' => true);
+
+ $result = $this->Paginator->url($options);
+ $expected = '/members/posts/index/page:2';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->sort('name', null, array('url' => $options));
+ $expected = array(
+ 'a' => array('href' => '/members/posts/index/page:2/sort:name/direction:asc'),
+ 'Name',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('next', array('url' => $options));
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/members/posts/index/page:3', 'rel' => 'next'),
+ 'next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->prev('prev', array('url' => $options));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array('href' => '/members/posts/index/page:1', 'rel' => 'prev'),
+ 'prev',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $options = array('members' => true, 'controller' => 'posts', 'order' => array('name' => 'desc'));
+ $result = $this->Paginator->url($options);
+ $expected = '/members/posts/index/page:2/sort:name/direction:desc';
+ $this->assertEquals($expected, $result);
+
+ $options = array('controller' => 'posts', 'order' => array('Article.name' => 'desc'));
+ $result = $this->Paginator->url($options);
+ $expected = '/posts/index/page:2/sort:Article.name/direction:desc';
+ $this->assertEquals($expected, $result);
+
+ Configure::write('Routing', $_back);
+ }
+
+/**
+ * testOptions method
+ *
+ * @return void
+ */
+ public function testOptions() {
+ $this->Paginator->options('myDiv');
+ $this->assertEquals('myDiv', $this->Paginator->options['update']);
+
+ $this->Paginator->options = array();
+ $this->Paginator->request->params = array();
+
+ $options = array('paging' => array('Article' => array(
+ 'order' => 'desc',
+ 'sort' => 'title'
+ )));
+ $this->Paginator->options($options);
+
+ $expected = array('Article' => array(
+ 'order' => 'desc',
+ 'sort' => 'title'
+ ));
+ $this->assertEquals($expected, $this->Paginator->request->params['paging']);
+
+ $this->Paginator->options = array();
+ $this->Paginator->request->params = array();
+
+ $options = array('Article' => array(
+ 'order' => 'desc',
+ 'sort' => 'title'
+ ));
+ $this->Paginator->options($options);
+ $this->assertEquals($expected, $this->Paginator->request->params['paging']);
+
+ $options = array('paging' => array('Article' => array(
+ 'order' => 'desc',
+ 'sort' => 'Article.title'
+ )));
+ $this->Paginator->options($options);
+
+ $expected = array('Article' => array(
+ 'order' => 'desc',
+ 'sort' => 'Article.title'
+ ));
+ $this->assertEquals($expected, $this->Paginator->request->params['paging']);
+ }
+
+/**
+ * testPassedArgsMergingWithUrlOptions method
+ *
+ * @return void
+ */
+ public function testPassedArgsMergingWithUrlOptions() {
+ Router::reload();
+ Router::parse('/');
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'articles', 'action' => 'index', 'pass' => array('2'), 'named' => array('foo' => 'bar'), 'url' => array('url' => 'articles/index/2/foo:bar')),
+ array('base' => '/', 'here' => '/articles/', 'webroot' => '/')
+ ));
+ $this->Paginator->request->params['paging'] = array(
+ 'Article' => array(
+ 'page' => 1, 'current' => 3, 'count' => 13,
+ 'prevPage' => false, 'nextPage' => true, 'pageCount' => 8,
+ 'options' => array(
+ 'page' => 1,
+ 'order' => array(),
+ 'conditions' => array()
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $this->Paginator->request->params['pass'] = array(2);
+ $this->Paginator->request->params['named'] = array('foo' => 'bar');
+ $this->Paginator->request->query = array('x' => 'y');
+ $this->Paginator->beforeRender('posts/index');
+
+ $result = $this->Paginator->sort('title');
+ $expected = array(
+ 'a' => array('href' => '/articles/index/2/page:1/foo:bar/sort:title/direction:asc?x=y'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers();
+ $expected = array(
+ array('span' => array('class' => 'current')), '1', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/page:2/foo:bar?x=y')), '2', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/page:3/foo:bar?x=y')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/page:4/foo:bar?x=y')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/page:5/foo:bar?x=y')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/page:6/foo:bar?x=y')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/page:7/foo:bar?x=y')), '7', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('Next');
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/articles/index/2/page:2/foo:bar?x=y', 'rel' => 'next'),
+ 'Next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testPassedArgsMergingWithUrlOptionsParamTypeQuerystring method
+ *
+ * @return void
+ */
+ public function testPassedArgsMergingWithUrlOptionsParamTypeQuerystring() {
+ Router::reload();
+ Router::parse('/');
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'articles', 'action' => 'index', 'pass' => array('2'), 'named' => array('foo' => 'bar'), 'url' => array('url' => 'articles/index/2/foo:bar')),
+ array('base' => '/', 'here' => '/articles/', 'webroot' => '/')
+ ));
+ $this->Paginator->request->params['paging'] = array(
+ 'Article' => array(
+ 'page' => 1, 'current' => 3, 'count' => 13,
+ 'prevPage' => false, 'nextPage' => true, 'pageCount' => 8,
+ 'options' => array(
+ 'page' => 1,
+ 'order' => array(),
+ 'conditions' => array()
+ ),
+ 'paramType' => 'querystring'
+ )
+ );
+
+ $this->Paginator->request->params['pass'] = array(2);
+ $this->Paginator->request->params['named'] = array('foo' => 'bar');
+ $this->Paginator->request->query = array('x' => 'y');
+ $this->Paginator->beforeRender('posts/index');
+
+ $result = $this->Paginator->sort('title');
+ $expected = array(
+ 'a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=1&amp;sort=title&amp;direction=asc'),
+ 'Title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers();
+ $expected = array(
+ array('span' => array('class' => 'current')), '1', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=2')), '2', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=3')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=7')), '7', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('Next');
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/articles/index/2/foo:bar?x=y&amp;page=2', 'rel' => 'next'),
+ 'Next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testPagingLinks method
+ *
+ * @return void
+ */
+ public function testPagingLinks() {
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 3,
+ 'count' => 13,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 5,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled'));
+ $expected = array(
+ 'span' => array('class' => 'disabled'),
+ '&lt;&lt; Previous',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled', 'tag' => 'div'));
+ $expected = array(
+ 'div' => array('class' => 'disabled'),
+ '&lt;&lt; Previous',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 2;
+ $this->Paginator->request->params['paging']['Client']['prevPage'] = true;
+ $result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled'));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array('href' => '/index/page:1', 'rel' => 'prev'),
+ '&lt;&lt; Previous',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('Next');
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/index/page:3', 'rel' => 'next'),
+ 'Next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('Next', array('tag' => 'li'));
+ $expected = array(
+ 'li' => array('class' => 'next'),
+ 'a' => array('href' => '/index/page:3', 'rel' => 'next'),
+ 'Next',
+ '/a',
+ '/li'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->prev('<< Previous', array('escape' => true));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array('href' => '/index/page:1', 'rel' => 'prev'),
+ '&lt;&lt; Previous',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->prev('<< Previous', array('escape' => false));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array('href' => '/index/page:1', 'rel' => 'prev'),
+ 'preg:/<< Previous/',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 1,
+ 'count' => 13,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 5,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->prev('<< Previous', null, '<strong>Disabled</strong>');
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ '&lt;strong&gt;Disabled&lt;/strong&gt;',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->prev('<< Previous', null, '<strong>Disabled</strong>', array('escape' => true));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ '&lt;strong&gt;Disabled&lt;/strong&gt;',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->prev('<< Previous', null, '<strong>Disabled</strong>', array('escape' => false));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ '<strong', 'Disabled', '/strong',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 3,
+ 'count' => 13,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 5,
+ 'options' => array(
+ 'page' => 1,
+ 'limit' => 3,
+ 'order' => array('Client.name' => 'DESC'),
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 2;
+ $this->Paginator->request->params['paging']['Client']['prevPage'] = true;
+ $result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled'));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array(
+ 'href' => '/index/page:1/limit:3/sort:Client.name/direction:DESC',
+ 'rel' => 'prev'
+ ),
+ '&lt;&lt; Previous',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('Next');
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array(
+ 'href' => '/index/page:3/limit:3/sort:Client.name/direction:DESC',
+ 'rel' => 'next'
+ ),
+ 'Next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 2,
+ 'current' => 1,
+ 'count' => 13,
+ 'prevPage' => true,
+ 'nextPage' => false,
+ 'pageCount' => 2,
+ 'options' => array(
+ 'page' => 2,
+ 'limit' => 10,
+ 'order' => array(),
+ 'conditions' => array()
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->prev('Prev');
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array('href' => '/index/page:1/limit:10', 'rel' => 'prev'),
+ 'Prev',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 2, 'current' => 1, 'count' => 13, 'prevPage' => true,
+ 'nextPage' => false, 'pageCount' => 2,
+ 'defaults' => array(),
+ 'options' => array(
+ 'page' => 2, 'limit' => 10, 'order' => array(), 'conditions' => array()
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $this->Paginator->options(array('url' => array(12, 'page' => 3)));
+ $result = $this->Paginator->prev('Prev', array('url' => array('foo' => 'bar')));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array('href' => '/index/12/page:1/limit:10/foo:bar', 'rel' => 'prev'),
+ 'Prev',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that __pagingLink methods use $options when $disabledOptions is an empty value.
+ * allowing you to use shortcut syntax
+ *
+ * @return void
+ */
+ public function testPagingLinksOptionsReplaceEmptyDisabledOptions() {
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 3,
+ 'count' => 13,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 5,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->prev('<< Previous', array('escape' => false));
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'preg:/<< Previous/',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('Next >>', array('escape' => false));
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/index/page:2', 'rel' => 'next'),
+ 'preg:/Next >>/',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testPagingLinksNotDefaultModel
+ *
+ * Test the creation of paging links when the non default model is used.
+ *
+ * @return void
+ */
+ public function testPagingLinksNotDefaultModel() {
+ // Multiple Model Paginate
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 3,
+ 'count' => 13,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 5,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ ),
+ 'Server' => array(
+ 'page' => 1,
+ 'current' => 1,
+ 'count' => 5,
+ 'prevPage' => false,
+ 'nextPage' => false,
+ 'pageCount' => 5,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->next('Next', array('model' => 'Client'));
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/index/page:2', 'rel' => 'next'),
+ 'Next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->next('Next', array('model' => 'Server'), 'No Next', array('model' => 'Server'));
+ $expected = array(
+ 'span' => array('class' => 'next'), 'No Next', '/span'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testGenericLinks method
+ *
+ * @return void
+ */
+ public function testGenericLinks() {
+ $result = $this->Paginator->link('Sort by title on page 5', array('sort' => 'title', 'page' => 5, 'direction' => 'desc'));
+ $expected = array(
+ 'a' => array('href' => '/index/page:5/sort:title/direction:desc'),
+ 'Sort by title on page 5',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['options']['page'] = 2;
+ $result = $this->Paginator->link('Sort by title', array('sort' => 'title', 'direction' => 'desc'));
+ $expected = array(
+ 'a' => array('href' => '/index/page:2/sort:title/direction:desc'),
+ 'Sort by title',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['options']['page'] = 4;
+ $result = $this->Paginator->link('Sort by title on page 4', array('sort' => 'Article.title', 'direction' => 'desc'));
+ $expected = array(
+ 'a' => array('href' => '/index/page:4/sort:Article.title/direction:desc'),
+ 'Sort by title on page 4',
+ '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Tests generation of generic links with preset options
+ *
+ * @return void
+ */
+ public function testGenericLinksWithPresetOptions() {
+ $result = $this->Paginator->link('Foo!', array('page' => 1));
+ $this->assertTags($result, array('a' => array('href' => '/index/page:1'), 'Foo!', '/a'));
+
+ $this->Paginator->options(array('sort' => 'title', 'direction' => 'desc'));
+ $result = $this->Paginator->link('Foo!', array('page' => 1));
+ $this->assertTags($result, array(
+ 'a' => array(
+ 'href' => '/index/page:1',
+ 'sort' => 'title',
+ 'direction' => 'desc'
+ ),
+ 'Foo!',
+ '/a'
+ ));
+
+ $this->Paginator->options(array('sort' => null, 'direction' => null));
+ $result = $this->Paginator->link('Foo!', array('page' => 1));
+ $this->assertTags($result, array('a' => array('href' => '/index/page:1'), 'Foo!', '/a'));
+
+ $this->Paginator->options(array('url' => array(
+ 'sort' => 'title',
+ 'direction' => 'desc'
+ )));
+ $result = $this->Paginator->link('Foo!', array('page' => 1));
+ $this->assertTags($result, array(
+ 'a' => array('href' => '/index/page:1/sort:title/direction:desc'),
+ 'Foo!',
+ '/a'
+ ));
+ }
+
+/**
+ * testNumbers method
+ *
+ * @return void
+ */
+ public function testNumbers() {
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 8,
+ 'current' => 3,
+ 'count' => 30,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 15,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->numbers();
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '8', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:10')), '10', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:11')), '11', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:12')), '12', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(array('tag' => 'li'));
+ $expected = array(
+ array('li' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/li',
+ ' | ',
+ array('li' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/li',
+ ' | ',
+ array('li' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/li',
+ ' | ',
+ array('li' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/li',
+ ' | ',
+ array('li' => array('class' => 'current')), '8', '/li',
+ ' | ',
+ array('li' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/li',
+ ' | ',
+ array('li' => array()), array('a' => array('href' => '/index/page:10')), '10', '/a', '/li',
+ ' | ',
+ array('li' => array()), array('a' => array('href' => '/index/page:11')), '11', '/a', '/li',
+ ' | ',
+ array('li' => array()), array('a' => array('href' => '/index/page:12')), '12', '/a', '/li',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(array('tag' => 'li', 'separator' => false));
+ $expected = array(
+ array('li' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/li',
+ array('li' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/li',
+ array('li' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/li',
+ array('li' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/li',
+ array('li' => array('class' => 'current')), '8', '/li',
+ array('li' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/li',
+ array('li' => array()), array('a' => array('href' => '/index/page:10')), '10', '/a', '/li',
+ array('li' => array()), array('a' => array('href' => '/index/page:11')), '11', '/a', '/li',
+ array('li' => array()), array('a' => array('href' => '/index/page:12')), '12', '/a', '/li',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(true);
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1', 'rel' => 'first')), 'first', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '8', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:10')), '10', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:11')), '11', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:12')), '12', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:15', 'rel' => 'last')), 'last', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 3,
+ 'count' => 30,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 15,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->numbers();
+ $expected = array(
+ array('span' => array('class' => 'current')), '1', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 14,
+ 'current' => 3,
+ 'count' => 30,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 15,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->numbers();
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:10')), '10', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:11')), '11', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:12')), '12', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:13')), '13', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '14', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:15')), '15', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 2,
+ 'current' => 3,
+ 'count' => 27,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 9,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->numbers(array('first' => 1, 'class' => 'page-link'));
+ $expected = array(
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current page-link')), '2', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(array('first' => 1, 'currentClass' => 'active'));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'active')), '2', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(array('first' => 1, 'class' => 'page-link', 'currentClass' => 'active'));
+ $expected = array(
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'active page-link')), '2', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(array('last' => 1));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '2', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 15,
+ 'current' => 3,
+ 'count' => 30,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 15,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->numbers(array('first' => 1));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:10')), '10', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:11')), '11', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:12')), '12', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:13')), '13', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:14')), '14', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '15', '/span',
+
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 10,
+ 'current' => 3,
+ 'count' => 30,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 15,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->numbers(array('first' => 1, 'last' => 1));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '10', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:11')), '11', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:12')), '12', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:13')), '13', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:14')), '14', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:15')), '15', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 6,
+ 'current' => 15,
+ 'count' => 623,
+ 'prevPage' => 1,
+ 'nextPage' => 1,
+ 'pageCount' => 42,
+ 'options' => array(
+ 'page' => 6,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->numbers(array('first' => 1, 'last' => 1));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '6', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:8')), '8', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:9')), '9', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:10')), '10', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:42')), '42', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 37,
+ 'current' => 15,
+ 'count' => 623,
+ 'prevPage' => 1,
+ 'nextPage' => 1,
+ 'pageCount' => 42,
+ 'options' => array(
+ 'page' => 37,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->numbers(array('first' => 1, 'last' => 1));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:33')), '33', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:34')), '34', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:35')), '35', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:36')), '36', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '37', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:38')), '38', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:39')), '39', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:40')), '40', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:41')), '41', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:42')), '42', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 10,
+ 'count' => 30,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 3,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $options = array('modulus' => 10);
+ $result = $this->Paginator->numbers($options);
+ $expected = array(
+ array('span' => array('class' => 'current')), '1', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 2,
+ 'current' => 10,
+ 'count' => 31,
+ 'prevPage' => true,
+ 'nextPage' => true,
+ 'pageCount' => 4,
+ 'options' => array(
+ 'page' => 1,
+ 'order' => array('Client.name' => 'DESC'),
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $result = $this->Paginator->numbers(array('class' => 'page-link'));
+ $expected = array(
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:1/sort:Client.name/direction:DESC')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current page-link')), '2', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:3/sort:Client.name/direction:DESC')), '3', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:4/sort:Client.name/direction:DESC')), '4', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 4895,
+ 'current' => 10,
+ 'count' => 48962,
+ 'prevPage' => 1,
+ 'nextPage' => 1,
+ 'pageCount' => 4897,
+ 'options' => array(
+ 'page' => 4894,
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:4894')), '4894', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '4895', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 3;
+
+ $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' | ',
+ array('span' => array('class' => 'current')), '3', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' | ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2, 'separator' => ' - '));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' - ',
+ array('span' => array('class' => 'current')), '3', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->numbers(array('first' => 5, 'modulus' => 5, 'last' => 5, 'separator' => ' - '));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' - ',
+ array('span' => array('class' => 'current')), '3', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:4893')), '4893', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4894')), '4894', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4895')), '4895', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 4893;
+ $result = $this->Paginator->numbers(array('first' => 5, 'modulus' => 4, 'last' => 5, 'separator' => ' - '));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:4891')), '4891', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4892')), '4892', '/a', '/span',
+ ' - ',
+ array('span' => array('class' => 'current')), '4893', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4894')), '4894', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4895')), '4895', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 58;
+ $result = $this->Paginator->numbers(array('first' => 5, 'modulus' => 4, 'last' => 5, 'separator' => ' - '));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:5')), '5', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:56')), '56', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:57')), '57', '/a', '/span',
+ ' - ',
+ array('span' => array('class' => 'current')), '58', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:59')), '59', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:60')), '60', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:4893')), '4893', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4894')), '4894', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4895')), '4895', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 5;
+ $result = $this->Paginator->numbers(array('first' => 5, 'modulus' => 4, 'last' => 5, 'separator' => ' - '));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:3')), '3', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' - ',
+ array('span' => array('class' => 'current')), '5', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:6')), '6', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:7')), '7', '/a', '/span',
+ '...',
+ array('span' => array()), array('a' => array('href' => '/index/page:4893')), '4893', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4894')), '4894', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4895')), '4895', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 3;
+ $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2, 'separator' => ' - ', 'ellipsis' => ' ~~~ '));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' - ',
+ array('span' => array('class' => 'current')), '3', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ ' ~~~ ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Client']['page'] = 3;
+ $result = $this->Paginator->numbers(array('first' => 2, 'modulus' => 2, 'last' => 2, 'separator' => ' - ', 'ellipsis' => '<span class="ellipsis">...</span>'));
+ $expected = array(
+ array('span' => array()), array('a' => array('href' => '/index/page:1')), '1', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:2')), '2', '/a', '/span',
+ ' - ',
+ array('span' => array('class' => 'current')), '3', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4')), '4', '/a', '/span',
+ array('span' => array('class' => 'ellipsis')), '...', '/span',
+ array('span' => array()), array('a' => array('href' => '/index/page:4896')), '4896', '/a', '/span',
+ ' - ',
+ array('span' => array()), array('a' => array('href' => '/index/page:4897')), '4897', '/a', '/span',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test first() and last() with tag options
+ *
+ * @return void
+ */
+ public function testFirstAndLastTag() {
+ $result = $this->Paginator->first('<<', array('tag' => 'li', 'class' => 'first'));
+ $expected = array(
+ 'li' => array('class' => 'first'),
+ 'a' => array('href' => '/index/page:1', 'rel' => 'first'),
+ '&lt;&lt;',
+ '/a',
+ '/li'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->last(2, array('tag' => 'li', 'class' => 'last'));
+ $expected = array(
+ '...',
+ 'li' => array('class' => 'last'),
+ array('a' => array('href' => '/index/page:6')), '6', '/a',
+ '/li',
+ ' | ',
+ array('li' => array('class' => 'last')),
+ array('a' => array('href' => '/index/page:7')), '7', '/a',
+ '/li',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that on the last page you don't get a link ot the last page.
+ *
+ * @return void
+ */
+ public function testLastNoOutput() {
+ $this->Paginator->request->params['paging']['Article']['page'] = 15;
+ $this->Paginator->request->params['paging']['Article']['pageCount'] = 15;
+
+ $result = $this->Paginator->last();
+ $expected = '';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test first() on the first page.
+ *
+ * @return void
+ */
+ public function testFirstEmpty() {
+ $this->Paginator->request->params['paging']['Article']['page'] = 1;
+
+ $result = $this->Paginator->first();
+ $expected = '';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test first() and options()
+ *
+ * @return void
+ */
+ public function testFirstFullBaseUrl() {
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'DESC');
+
+ $this->Paginator->options(array('url' => array('full_base' => true)));
+
+ $result = $this->Paginator->first();
+ $expected = array(
+ '<span',
+ array('a' => array(
+ 'href' => FULL_BASE_URL . '/index/page:1/sort:Article.title/direction:DESC', 'rel' => 'first'
+ )),
+ '&lt;&lt; first',
+ '/a',
+ '/span',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test first() on the fence-post
+ *
+ * @return void
+ */
+ public function testFirstBoundaries() {
+ $result = $this->Paginator->first();
+ $expected = array(
+ '<span',
+ 'a' => array('href' => '/index/page:1', 'rel' => 'first'),
+ '&lt;&lt; first',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->first(2);
+ $expected = array(
+ '<span',
+ array('a' => array('href' => '/index/page:1')), '1', '/a',
+ '/span',
+ ' | ',
+ '<span',
+ array('a' => array('href' => '/index/page:2')), '2', '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['page'] = 2;
+ $result = $this->Paginator->first(3);
+ $this->assertEquals('', $result, 'When inside the first links range, no links should be made');
+ }
+
+/**
+ * test Last method
+ *
+ * @return void
+ */
+ public function testLast() {
+ $result = $this->Paginator->last();
+ $expected = array(
+ '<span',
+ 'a' => array('href' => '/index/page:7', 'rel' => 'last'),
+ 'last &gt;&gt;',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->last(1);
+ $expected = array(
+ '...',
+ '<span',
+ 'a' => array('href' => '/index/page:7'),
+ '7',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->request->params['paging']['Article']['page'] = 6;
+
+ $result = $this->Paginator->last(2);
+ $expected = array(
+ '...',
+ '<span',
+ array('a' => array('href' => '/index/page:6')), '6', '/a',
+ '/span',
+ ' | ',
+ '<span',
+ array('a' => array('href' => '/index/page:7')), '7', '/a',
+ '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->last(3);
+ $this->assertEquals('', $result, 'When inside the last links range, no links should be made');
+ }
+
+/**
+ * undocumented function
+ *
+ * @return void
+ */
+ public function testLastOptions() {
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 4,
+ 'current' => 3,
+ 'count' => 30,
+ 'prevPage' => false,
+ 'nextPage' => 2,
+ 'pageCount' => 15,
+ 'options' => array(
+ 'page' => 1,
+ 'order' => array('Client.name' => 'DESC'),
+ ),
+ 'paramType' => 'named'
+ )
+ );
+
+ $result = $this->Paginator->last();
+ $expected = array(
+ '<span',
+ array('a' => array(
+ 'href' => '/index/page:15/sort:Client.name/direction:DESC',
+ 'rel' => 'last'
+ )),
+ 'last &gt;&gt;', '/a',
+ '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->last(1);
+ $expected = array(
+ '...',
+ '<span',
+ array('a' => array('href' => '/index/page:15/sort:Client.name/direction:DESC')), '15', '/a',
+ '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->last(2);
+ $expected = array(
+ '...',
+ '<span',
+ array('a' => array('href' => '/index/page:14/sort:Client.name/direction:DESC')), '14', '/a',
+ '/span',
+ ' | ',
+ '<span',
+ array('a' => array('href' => '/index/page:15/sort:Client.name/direction:DESC')), '15', '/a',
+ '/span',
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->last(2, array('ellipsis' => '<span class="ellipsis">...</span>'));
+ $expected = array(
+ array('span' => array('class' => 'ellipsis')), '...', '/span',
+ '<span',
+ array('a' => array('href' => '/index/page:14/sort:Client.name/direction:DESC')), '14', '/a',
+ '/span',
+ ' | ',
+ '<span',
+ array('a' => array('href' => '/index/page:15/sort:Client.name/direction:DESC')), '15', '/a',
+ '/span',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testCounter method
+ *
+ * @return void
+ */
+ public function testCounter() {
+ $this->Paginator->request->params['paging'] = array(
+ 'Client' => array(
+ 'page' => 1,
+ 'current' => 3,
+ 'count' => 13,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 5,
+ 'limit' => 3,
+ 'options' => array(
+ 'page' => 1,
+ 'order' => array('Client.name' => 'DESC'),
+ ),
+ 'paramType' => 'named'
+ )
+ );
+ $input = 'Page %page% of %pages%, showing %current% records out of %count% total, ';
+ $input .= 'starting on record %start%, ending on %end%';
+ $result = $this->Paginator->counter($input);
+ $expected = 'Page 1 of 5, showing 3 records out of 13 total, starting on record 1, ';
+ $expected .= 'ending on 3';
+ $this->assertEquals($expected, $result);
+
+ $input = 'Page {:page} of {:pages}, showing {:current} records out of {:count} total, ';
+ $input .= 'starting on record {:start}, ending on {:end}';
+ $result = $this->Paginator->counter($input);
+ $this->assertEquals($expected, $result);
+
+ $input = 'Page %page% of %pages%';
+ $result = $this->Paginator->counter($input);
+ $expected = 'Page 1 of 5';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->counter(array('format' => $input));
+ $expected = 'Page 1 of 5';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->counter(array('format' => 'pages'));
+ $expected = '1 of 5';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->counter(array('format' => 'range'));
+ $expected = '1 - 3 of 13';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->counter('Showing %page% of %pages% %model%');
+ $this->assertEquals('Showing 1 of 5 clients', $result);
+ }
+
+/**
+ * testHasPage method
+ *
+ * @return void
+ */
+ public function testHasPage() {
+ $result = $this->Paginator->hasPage('Article', 15);
+ $this->assertFalse($result);
+
+ $result = $this->Paginator->hasPage('UndefinedModel', 2);
+ $this->assertFalse($result);
+
+ $result = $this->Paginator->hasPage('Article', 2);
+ $this->assertTrue($result);
+
+ $result = $this->Paginator->hasPage(2);
+ $this->assertTrue($result);
+ }
+
+/**
+ * testWithPlugin method
+ *
+ * @return void
+ */
+ public function testWithPlugin() {
+ Router::reload();
+ Router::setRequestInfo(array(
+ array(
+ 'pass' => array(), 'named' => array(), 'prefix' => null, 'form' => array(),
+ 'controller' => 'magazines', 'plugin' => 'my_plugin', 'action' => 'index',
+ 'url' => array('ext' => 'html', 'url' => 'my_plugin/magazines')),
+ array('base' => '', 'here' => '/my_plugin/magazines', 'webroot' => '/')
+ ));
+
+ $result = $this->Paginator->link('Page 3', array('page' => 3));
+ $expected = array(
+ 'a' => array('href' => '/my_plugin/magazines/index/page:3'), 'Page 3', '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->options(array('url' => array('action' => 'another_index')));
+ $result = $this->Paginator->link('Page 3', array('page' => 3));
+ $expected = array(
+ 'a' => array('href' => '/my_plugin/magazines/another_index/page:3'), 'Page 3', '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->options(array('url' => array('controller' => 'issues')));
+ $result = $this->Paginator->link('Page 3', array('page' => 3));
+ $expected = array(
+ 'a' => array('href' => '/my_plugin/issues/index/page:3'), 'Page 3', '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->options(array('url' => array('plugin' => null)));
+ $result = $this->Paginator->link('Page 3', array('page' => 3));
+ $expected = array(
+ 'a' => array('href' => '/magazines/index/page:3'), 'Page 3', '/a'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->Paginator->options(array('url' => array('plugin' => null, 'controller' => 'issues')));
+ $result = $this->Paginator->link('Page 3', array('page' => 3));
+ $expected = array(
+ 'a' => array('href' => '/issues/index/page:3'), 'Page 3', '/a'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testNextLinkUsingDotNotation method
+ *
+ * @return void
+ */
+ public function testNextLinkUsingDotNotation() {
+ Router::reload();
+ Router::parse('/');
+ Router::setRequestInfo(array(
+ array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'url' => array('url' => 'accounts/')),
+ array('base' => '/officespace', 'here' => '/officespace/accounts/', 'webroot' => '/officespace/', 'passedArgs' => array())
+ ));
+
+ $this->Paginator->request->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
+ $this->Paginator->request->params['paging']['Article']['page'] = 1;
+
+ $test = array('url' => array(
+ 'page' => '1',
+ 'sort' => 'Article.title',
+ 'direction' => 'asc',
+ ));
+ $this->Paginator->options($test);
+
+ $result = $this->Paginator->next('Next');
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array(
+ 'href' => '/officespace/accounts/index/page:2/sort:Article.title/direction:asc',
+ 'rel' => 'next'
+ ),
+ 'Next',
+ '/a',
+ '/span',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * Ensure that the internal link class object is called when the update key is present
+ *
+ * @return void
+ */
+ public function testAjaxLinkGenerationNumbers() {
+ $this->Paginator->Js->expectCallCount('link', 2);
+ $result = $this->Paginator->numbers(array(
+ 'modulus' => '2',
+ 'url' => array('controller' => 'projects', 'action' => 'sort'),
+ 'update' => 'list'
+ ));
+ }
+
+/**
+ * test that paginatorHelper::link() uses JsHelper to make links when 'update' key is present
+ *
+ * @return void
+ */
+ public function testAjaxLinkGenerationLink() {
+ $this->Paginator->Js->expects($this->once())
+ ->method('link')
+ ->will($this->returnValue('I am a link'));
+
+ $result = $this->Paginator->link('test', array('controller' => 'posts'), array('update' => '#content'));
+ $this->assertEquals('I am a link', $result);
+ }
+
+/**
+ * test that mock classes injected into paginatorHelper are called when using link()
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testMockAjaxProviderClassInjection() {
+ $mock = $this->getMock('PaginatorHelper', array(), array($this->View), 'PaginatorMockJsHelper');
+ $Paginator = new PaginatorHelper($this->View, array('ajax' => 'PaginatorMockJs'));
+ $Paginator->request->params['paging'] = array(
+ 'Article' => array(
+ 'current' => 9,
+ 'count' => 62,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 7,
+ 'defaults' => array(),
+ 'options' => array(),
+ 'paramType' => 'named'
+ )
+ );
+ $Paginator->PaginatorMockJs = $mock;
+ $Paginator->PaginatorMockJs->expects($this->once())->method('link');
+ $result = $Paginator->link('Page 2', array('page' => 2), array('update' => '#content'));
+
+ $Paginator = new PaginatorHelper($this->View, array('ajax' => 'Form'));
+ }
+
+/**
+ * test that querystring urls can be generated.
+ *
+ * @return void
+ */
+ public function testQuerystringUrlGeneration() {
+ $this->Paginator->request->params['paging']['Article']['paramType'] = 'querystring';
+ $result = $this->Paginator->url(array('page' => '4'));
+ $expected = '/?page=4';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Paginator->url(array('page' => '4', 'limit' => 10, 'something' => 'else'));
+ $expected = '/index/something:else?page=4&amp;limit=10';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test querystring paging link.
+ *
+ * @return void
+ */
+ public function testQuerystringNextAndPrev() {
+ $this->Paginator->request->params['paging']['Article']['paramType'] = 'querystring';
+ $this->Paginator->request->params['paging']['Article']['page'] = 2;
+ $this->Paginator->request->params['paging']['Article']['nextPage'] = true;
+ $this->Paginator->request->params['paging']['Article']['prevPage'] = true;
+
+ $result = $this->Paginator->next('Next');
+ $expected = array(
+ 'span' => array('class' => 'next'),
+ 'a' => array('href' => '/?page=3', 'rel' => 'next'),
+ 'Next',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Paginator->prev('Prev');
+ $expected = array(
+ 'span' => array('class' => 'prev'),
+ 'a' => array('href' => '/?page=1', 'rel' => 'prev'),
+ 'Prev',
+ '/a',
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test that additional keys can be flagged as query string args.
+ *
+ * @return void
+ */
+ public function testOptionsConvertKeys() {
+ $this->Paginator->options(array(
+ 'convertKeys' => array('something'),
+ 'Article' => array('paramType' => 'querystring')
+ ));
+ $result = $this->Paginator->url(array('page' => '4', 'something' => 'bar'));
+ $expected = '/?page=4&amp;something=bar';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test the current() method
+ *
+ * @return void
+ */
+ public function testCurrent() {
+ $result = $this->Paginator->current();
+ $this->assertEquals($this->Paginator->request->params['paging']['Article']['page'], $result);
+
+ $result = $this->Paginator->current('Incorrect');
+ $this->assertEquals(1, $result);
+ }
+
+/**
+ * test the defaultModel() method
+ *
+ * @return void
+ */
+ public function testNoDefaultModel() {
+ $this->Paginator->request = new CakeRequest(null, false);
+ $this->assertNull($this->Paginator->defaultModel());
+ }
+
+/**
+ * test the numbers() method when there is only one page
+ *
+ * @return void
+ */
+ public function testWithOnePage() {
+ $this->Paginator->request['paging'] = array(
+ 'Article' => array(
+ 'page' => 1,
+ 'current' => 2,
+ 'count' => 2,
+ 'prevPage' => false,
+ 'nextPage' => true,
+ 'pageCount' => 1,
+ 'options' => array(
+ 'page' => 1,
+ ),
+ 'paramType' => 'named',
+ )
+ );
+ $this->assertFalse($this->Paginator->numbers());
+ $this->assertFalse($this->Paginator->first());
+ $this->assertFalse($this->Paginator->last());
+ }
+
+/**
+ * test the numbers() method when there is only one page
+ *
+ * @return void
+ */
+ public function testWithZeroPages() {
+ $this->Paginator->request['paging'] = array(
+ 'Article' => array(
+ 'page' => 0,
+ 'current' => 0,
+ 'count' => 0,
+ 'prevPage' => false,
+ 'nextPage' => false,
+ 'pageCount' => 0,
+ 'limit' => 10,
+ 'options' => array(
+ 'page' => 0,
+ 'conditions' => array()
+ ),
+ 'paramType' => 'named',
+ )
+ );
+
+ $result = $this->Paginator->counter(array('format' => 'pages'));
+ $expected = '0 of 1';
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php
new file mode 100644
index 0000000..2df8cef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/PrototypeEngineHelperTest.php
@@ -0,0 +1,386 @@
+<?php
+/**
+ * PrototypeEngine TestCase
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.Case.View.Helper
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('JsHelper', 'View/Helper');
+App::uses('PrototypeEngineHelper', 'View/Helper');
+
+class PrototypeEngineHelperTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $controller = null;
+ $this->View = $this->getMock('View', array('addScript'), array(&$controller));
+ $this->Proto = new PrototypeEngineHelper($this->View);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Proto);
+ }
+
+/**
+ * test selector method
+ *
+ * @return void
+ */
+ public function testSelector() {
+ $result = $this->Proto->get('#content');
+ $this->assertEquals($this->Proto, $result);
+ $this->assertEquals($this->Proto->selection, '$("content")');
+
+ $result = $this->Proto->get('a .remove');
+ $this->assertEquals($this->Proto, $result);
+ $this->assertEquals($this->Proto->selection, '$$("a .remove")');
+
+ $result = $this->Proto->get('document');
+ $this->assertEquals($this->Proto, $result);
+ $this->assertEquals($this->Proto->selection, "$(document)");
+
+ $result = $this->Proto->get('window');
+ $this->assertEquals($this->Proto, $result);
+ $this->assertEquals($this->Proto->selection, "$(window)");
+
+ $result = $this->Proto->get('ul');
+ $this->assertEquals($this->Proto, $result);
+ $this->assertEquals($this->Proto->selection, '$$("ul")');
+
+ $result = $this->Proto->get('#some_long-id.class');
+ $this->assertEquals($this->Proto, $result);
+ $this->assertEquals($this->Proto->selection, '$$("#some_long-id.class")');
+ }
+
+/**
+ * test event binding
+ *
+ * @return void
+ */
+ public function testEvent() {
+ $this->Proto->get('#myLink');
+ $result = $this->Proto->event('click', 'doClick', array('wrap' => false));
+ $expected = '$("myLink").observe("click", doClick);';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->event('click', 'Element.hide(this);', array('stop' => false));
+ $expected = '$("myLink").observe("click", function (event) {Element.hide(this);});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->event('click', 'Element.hide(this);');
+ $expected = "\$(\"myLink\").observe(\"click\", function (event) {event.stop();\nElement.hide(this);});";
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test dom ready event creation
+ *
+ * @return void
+ */
+ public function testDomReady() {
+ $result = $this->Proto->domReady('foo.name = "bar";');
+ $expected = 'document.observe("dom:loaded", function (event) {foo.name = "bar";});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Each method
+ *
+ * @return void
+ */
+ public function testEach() {
+ $this->Proto->get('#foo li');
+ $result = $this->Proto->each('item.hide();');
+ $expected = '$$("#foo li").each(function (item, index) {item.hide();});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test Effect generation
+ *
+ * @return void
+ */
+ public function testEffect() {
+ $this->Proto->get('#foo');
+ $result = $this->Proto->effect('show');
+ $expected = '$("foo").show();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('hide');
+ $expected = '$("foo").hide();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('fadeIn');
+ $expected = '$("foo").appear();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('fadeIn', array('speed' => 'fast'));
+ $expected = '$("foo").appear({duration:0.50000000000});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('fadeIn', array('speed' => 'slow'));
+ $expected = '$("foo").appear({duration:2});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('fadeOut');
+ $expected = '$("foo").fade();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('fadeOut', array('speed' => 'fast'));
+ $expected = '$("foo").fade({duration:0.50000000000});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('fadeOut', array('speed' => 'slow'));
+ $expected = '$("foo").fade({duration:2});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('slideIn');
+ $expected = 'Effect.slideDown($("foo"));';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('slideOut');
+ $expected = 'Effect.slideUp($("foo"));';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('slideOut', array('speed' => 'fast'));
+ $expected = 'Effect.slideUp($("foo"), {duration:0.50000000000});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->effect('slideOut', array('speed' => 'slow'));
+ $expected = 'Effect.slideUp($("foo"), {duration:2});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test Request Generation
+ *
+ * @return void
+ */
+ public function testRequest() {
+ $result = $this->Proto->request(array('controller' => 'posts', 'action' => 'view', 1));
+ $expected = 'var jsRequest = new Ajax.Request("/posts/view/1");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->request('/posts/view/1', array(
+ 'method' => 'post',
+ 'complete' => 'doComplete',
+ 'before' => 'doBefore',
+ 'success' => 'doSuccess',
+ 'error' => 'doError',
+ 'data' => array('name' => 'jim', 'height' => '185cm'),
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Ajax.Request("/posts/view/1", {method:"post", onComplete:doComplete, onCreate:doBefore, onFailure:doError, onSuccess:doSuccess, parameters:{"name":"jim","height":"185cm"}});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->request('/posts/view/1', array('update' => 'content'));
+ $expected = 'var jsRequest = new Ajax.Updater("content", "/posts/view/1");';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'complete' => 'doSuccess',
+ 'update' => '#update-zone',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Ajax.Updater("update-zone", "/people/edit/1", {method:"post", onComplete:doSuccess});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'complete' => 'doSuccess',
+ 'error' => 'handleError',
+ 'type' => 'json',
+ 'data' => array('name' => 'jim', 'height' => '185cm'),
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Ajax.Request("/people/edit/1", {method:"post", onComplete:doSuccess, onFailure:handleError, parameters:{"name":"jim","height":"185cm"}});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'complete' => 'doSuccess',
+ 'error' => 'handleError',
+ 'type' => 'json',
+ 'data' => '$("element").serialize()',
+ 'dataExpression' => true,
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsRequest = new Ajax.Request("/people/edit/1", {method:"post", onComplete:doSuccess, onFailure:handleError, parameters:$("element").serialize()});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->request('/people/edit/1', array(
+ 'method' => 'post',
+ 'before' => 'doBefore();',
+ 'success' => 'doSuccess();',
+ 'complete' => 'doComplete();',
+ 'error' => 'handleError();',
+ ));
+ $expected = 'var jsRequest = new Ajax.Request("/people/edit/1", {method:"post", onComplete:function (transport) {doComplete();}, onCreate:function (transport) {doBefore();}, onFailure:function (response, jsonHeader) {handleError();}, onSuccess:function (response, jsonHeader) {doSuccess();}});';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->request('/people/edit/1', array(
+ 'async' => false,
+ 'method' => 'post',
+ 'before' => 'doBefore();',
+ 'success' => 'doSuccess();',
+ 'complete' => 'doComplete();',
+ 'error' => 'handleError();',
+ ));
+ $expected = 'var jsRequest = new Ajax.Request("/people/edit/1", {asynchronous:false, method:"post", onComplete:function (transport) {doComplete();}, onCreate:function (transport) {doBefore();}, onFailure:function (response, jsonHeader) {handleError();}, onSuccess:function (response, jsonHeader) {doSuccess();}});';
+ $this->assertEquals($expected, $result);
+
+ $this->Proto->get('#submit');
+ $result = $this->Proto->request('/users/login', array(
+ 'before' => 'login.create(event)',
+ 'complete' => 'login.complete(event)',
+ 'update' => 'auth',
+ 'data' => $this->Proto->serializeForm(array('isForm' => false, 'inline' => true)),
+ 'dataExpression' => true
+ ));
+ $this->assertTrue(strpos($result, '$($("submit").form).serialize()') > 0);
+ $this->assertFalse(strpos($result, 'parameters:function () {$($("submit").form).serialize()}') > 0);
+ }
+
+/**
+ * test sortable list generation
+ *
+ * @return void
+ */
+ public function testSortable() {
+ $this->Proto->get('#myList');
+ $result = $this->Proto->sortable(array(
+ 'complete' => 'onComplete',
+ 'sort' => 'onSort',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsSortable = Sortable.create($("myList"), {onChange:onSort, onUpdate:onComplete});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test drag() method. Scriptaculous lacks the ability to take an Array of Elements
+ * in new Drag() when selection is a multiple type. Iterate over the array.
+ *
+ * @return void
+ */
+ public function testDrag() {
+ $this->Proto->get('#element');
+ $result = $this->Proto->drag(array(
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ 'stop' => 'onStop',
+ 'snapGrid' => array(10, 10),
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsDrag = new Draggable($("element"), {onDrag:onDrag, onEnd:onStop, onStart:onStart, snap:[10,10]});';
+ $this->assertEquals($expected, $result);
+
+ $this->Proto->get('div.dragger');
+ $result = $this->Proto->drag(array(
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ 'stop' => 'onStop',
+ 'snapGrid' => array(10, 10),
+ 'wrapCallbacks' => false
+ ));
+ $expected = '$$("div.dragger").each(function (item, index) {new Draggable(item, {onDrag:onDrag, onEnd:onStop, onStart:onStart, snap:[10,10]});});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test drop() method
+ *
+ * @return void
+ */
+ public function testDrop() {
+ $this->Proto->get('#element');
+ $result = $this->Proto->drop(array(
+ 'hover' => 'onHover',
+ 'drop' => 'onDrop',
+ 'accept' => '.drag-me',
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'Droppables.add($("element"), {accept:".drag-me", onDrop:onDrop, onHover:onHover});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * ensure that slider() method behaves properly
+ *
+ * @return void
+ */
+ public function testSlider() {
+ $this->Proto->get('#element');
+ $result = $this->Proto->slider(array(
+ 'handle' => '#handle',
+ 'direction' => 'horizontal',
+ 'change' => 'onChange',
+ 'complete' => 'onComplete',
+ 'value' => 4,
+ 'wrapCallbacks' => false
+ ));
+ $expected = 'var jsSlider = new Control.Slider($("handle"), $("element"), {axis:"horizontal", onChange:onComplete, onSlide:onChange, sliderValue:4});';
+ $this->assertEquals($expected, $result);
+
+ $this->Proto->get('#element');
+ $result = $this->Proto->slider(array(
+ 'handle' => '#handle',
+ 'change' => 'change();',
+ 'complete' => 'complete();',
+ 'value' => 4,
+ 'min' => 10,
+ 'max' => 100
+ ));
+ $expected = 'var jsSlider = new Control.Slider($("handle"), $("element"), {onChange:function (value) {complete();}, onSlide:function (value) {change();}, range:$R(10,100), sliderValue:4});';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test the serializeForm implementation.
+ *
+ * @return void
+ */
+ public function testSerializeForm() {
+ $this->Proto->get('#element');
+ $result = $this->Proto->serializeForm(array('isForm' => true));
+ $expected = '$("element").serialize();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->serializeForm(array('isForm' => true, 'inline' => true));
+ $expected = '$("element").serialize()';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->serializeForm(array('isForm' => false));
+ $expected = '$($("element").form).serialize();';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Proto->serializeForm(array('isForm' => false, 'inline' => true));
+ $expected = '$($("element").form).serialize()';
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/RssHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/RssHelperTest.php
new file mode 100644
index 0000000..bfffdf4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/RssHelperTest.php
@@ -0,0 +1,720 @@
+<?php
+/**
+ * RssHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('View', 'View');
+App::uses('RssHelper', 'View/Helper');
+App::uses('TimeHelper', 'View/Helper');
+App::uses('File', 'Utility');
+
+/**
+ * RssHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class RssHelperTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $controller = null;
+ $this->View = new View($controller);
+ $this->Rss = new RssHelper($this->View);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->Rss);
+ }
+
+/**
+ * testDocument method
+ *
+ * @return void
+ */
+ public function testDocument() {
+ $result = $this->Rss->document();
+ $expected = array(
+ 'rss' => array(
+ 'version' => '2.0'
+ )
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Rss->document(null, 'content');
+ $expected = array(
+ 'rss' => array(
+ 'version' => '2.0'
+ ),
+ 'content'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Rss->document(array('contrived' => 'parameter'), 'content');
+ $expected = array(
+ 'rss' => array(
+ 'contrived' => 'parameter',
+ 'version' => '2.0'
+ ),
+ 'content'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testChannel method
+ *
+ * @return void
+ */
+ public function testChannel() {
+ $attrib = array('a' => '1', 'b' => '2');
+ $elements = array('title' => 'title');
+ $content = 'content';
+
+ $result = $this->Rss->channel($attrib, $elements, $content);
+ $expected = array(
+ 'channel' => array(
+ 'a' => '1',
+ 'b' => '2'
+ ),
+ '<title',
+ 'title',
+ '/title',
+ '<link',
+ $this->Rss->url('/', true),
+ '/link',
+ '<description',
+ 'content',
+ '/channel'
+ );
+ $this->assertTags($result, $expected);
+
+ $this->View->pageTitle = 'title';
+ $attrib = array('a' => '1', 'b' => '2');
+ $elements = array();
+ $content = 'content';
+
+ $result = $this->Rss->channel($attrib, $elements, $content);
+ $expected = array(
+ 'channel' => array(
+ 'a' => '1',
+ 'b' => '2'
+ ),
+ '<title',
+ 'title',
+ '/title',
+ '<link',
+ $this->Rss->url('/', true),
+ '/link',
+ '<description',
+ 'content',
+ '/channel'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test correct creation of channel sub elements.
+ *
+ * @return void
+ */
+ public function testChannelElements() {
+ $attrib = array();
+ $elements = array(
+ 'title' => 'Title of RSS Feed',
+ 'link' => 'http://example.com',
+ 'description' => 'Description of RSS Feed',
+ 'image' => array(
+ 'title' => 'Title of image',
+ 'url' => 'http://example.com/example.png',
+ 'link' => 'http://example.com'
+ ),
+ 'cloud' => array(
+ 'domain' => "rpc.sys.com",
+ 'port' => "80",
+ 'path' => "/RPC2",
+ 'registerProcedure' => "myCloud.rssPleaseNotify",
+ 'protocol' => "xml-rpc"
+ )
+ );
+ $content = 'content-here';
+ $result = $this->Rss->channel($attrib, $elements, $content);
+ $expected = array(
+ '<channel',
+ '<title', 'Title of RSS Feed', '/title',
+ '<link', 'http://example.com', '/link',
+ '<description', 'Description of RSS Feed', '/description',
+ '<image',
+ '<title', 'Title of image', '/title',
+ '<url', 'http://example.com/example.png', '/url',
+ '<link', 'http://example.com', '/link',
+ '/image',
+ 'cloud' => array(
+ 'domain' => "rpc.sys.com",
+ 'port' => "80",
+ 'path' => "/RPC2",
+ 'registerProcedure' => "myCloud.rssPleaseNotify",
+ 'protocol' => "xml-rpc"
+ ),
+ 'content-here',
+ '/channel',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+ public function testChannelElementAttributes() {
+ $attrib = array();
+ $elements = array(
+ 'title' => 'Title of RSS Feed',
+ 'link' => 'http://example.com',
+ 'description' => 'Description of RSS Feed',
+ 'image' => array(
+ 'title' => 'Title of image',
+ 'url' => 'http://example.com/example.png',
+ 'link' => 'http://example.com'
+ ),
+ 'atom:link' => array(
+ 'attrib' => array(
+ 'href' => 'http://www.example.com/rss.xml',
+ 'rel' => 'self',
+ 'type' => 'application/rss+xml')
+ )
+ );
+ $content = 'content-here';
+ $result = $this->Rss->channel($attrib, $elements, $content);
+ $expected = array(
+ '<channel',
+ '<title', 'Title of RSS Feed', '/title',
+ '<link', 'http://example.com', '/link',
+ '<description', 'Description of RSS Feed', '/description',
+ '<image',
+ '<title', 'Title of image', '/title',
+ '<url', 'http://example.com/example.png', '/url',
+ '<link', 'http://example.com', '/link',
+ '/image',
+ 'atom:link' => array(
+ 'xmlns:atom' => 'http://www.w3.org/2005/Atom',
+ 'href' => "http://www.example.com/rss.xml",
+ 'rel' => "self",
+ 'type' => "application/rss+xml"
+ ),
+ 'content-here',
+ '/channel',
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * testItems method
+ *
+ * @return void
+ */
+ public function testItems() {
+ $items = array(
+ array('title' => 'title1', 'guid' => 'http://www.example.com/guid1', 'link' => 'http://www.example.com/link1', 'description' => 'description1'),
+ array('title' => 'title2', 'guid' => 'http://www.example.com/guid2', 'link' => 'http://www.example.com/link2', 'description' => 'description2'),
+ array('title' => 'title3', 'guid' => 'http://www.example.com/guid3', 'link' => 'http://www.example.com/link3', 'description' => 'description3')
+ );
+
+ $result = $this->Rss->items($items);
+ $expected = array(
+ '<item',
+ '<title', 'title1', '/title',
+ '<guid', 'http://www.example.com/guid1', '/guid',
+ '<link', 'http://www.example.com/link1', '/link',
+ '<description', 'description1', '/description',
+ '/item',
+ '<item',
+ '<title', 'title2', '/title',
+ '<guid', 'http://www.example.com/guid2', '/guid',
+ '<link', 'http://www.example.com/link2', '/link',
+ '<description', 'description2', '/description',
+ '/item',
+ '<item',
+ '<title', 'title3', '/title',
+ '<guid', 'http://www.example.com/guid3', '/guid',
+ '<link', 'http://www.example.com/link3', '/link',
+ '<description', 'description3', '/description',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $items = array(
+ array('title' => 'title1', 'guid' => 'http://www.example.com/guid1', 'link' => 'http://www.example.com/link1', 'description' => 'description1'),
+ array('title' => 'title2', 'guid' => 'http://www.example.com/guid2', 'link' => 'http://www.example.com/link2', 'description' => 'description2'),
+ array('title' => 'title3', 'guid' => 'http://www.example.com/guid3', 'link' => 'http://www.example.com/link3', 'description' => 'description3')
+ );
+
+ $result = $this->Rss->items($items, create_function('$v', '$v[\'title\'] = $v[\'title\'] . \'-transformed\'; return $v;'));
+ $expected = array(
+ '<item',
+ '<title', 'title1-transformed', '/title',
+ '<guid', 'http://www.example.com/guid1', '/guid',
+ '<link', 'http://www.example.com/link1', '/link',
+ '<description', 'description1', '/description',
+ '/item',
+ '<item',
+ '<title', 'title2-transformed', '/title',
+ '<guid', 'http://www.example.com/guid2', '/guid',
+ '<link', 'http://www.example.com/link2', '/link',
+ '<description', 'description2', '/description',
+ '/item',
+ '<item',
+ '<title', 'title3-transformed', '/title',
+ '<guid', 'http://www.example.com/guid3', '/guid',
+ '<link', 'http://www.example.com/link3', '/link',
+ '<description', 'description3', '/description',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Rss->items(array());
+ $expected = '';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testItem method
+ *
+ * @return void
+ */
+ public function testItem() {
+ $item = array(
+ 'title' => 'My title',
+ 'description' => 'My description',
+ 'link' => 'http://www.google.com/'
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ '<title',
+ 'My title',
+ '/title',
+ '<description',
+ 'My description',
+ '/description',
+ '<link',
+ 'http://www.google.com/',
+ '/link',
+ '<guid',
+ 'http://www.google.com/',
+ '/guid',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'title' => 'My Title',
+ 'link' => 'http://www.example.com/1',
+ 'description' => 'descriptive words',
+ 'pubDate' => '2008-05-31 12:00:00',
+ 'source' => array('http://www.google.com/', 'Google'),
+ 'guid' => 'http://www.example.com/1'
+ );
+ $result = $this->Rss->item(null, $item);
+
+ $expected = array(
+ '<item',
+ '<title',
+ 'My Title',
+ '/title',
+ '<link',
+ 'http://www.example.com/1',
+ '/link',
+ '<description',
+ 'descriptive words',
+ '/description',
+ '<pubDate',
+ date('r', strtotime('2008-05-31 12:00:00')),
+ '/pubDate',
+ 'source' => array('url' => 'http://www.google.com/'),
+ 'Google',
+ '/source',
+ '<guid',
+ 'http://www.example.com/1',
+ '/guid',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'title' => 'My Title & more'
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ '<title', 'My Title &amp; more', '/title',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'title' => 'Foo bar',
+ 'link' => array(
+ 'url' => 'http://example.com/foo?a=1&b=2',
+ 'convertEntities' => false
+ ),
+ 'description' => array(
+ 'value' => 'descriptive words',
+ 'cdata' => true,
+ ),
+ 'pubDate' => '2008-05-31 12:00:00',
+ 'source' => 'http://www.google.com/'
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ '<title',
+ 'Foo bar',
+ '/title',
+ '<link',
+ 'http://example.com/foo?a=1&amp;b=2',
+ '/link',
+ '<description',
+ '<![CDATA[descriptive words]]',
+ '/description',
+ '<pubDate',
+ date('r', strtotime('2008-05-31 12:00:00')),
+ '/pubDate',
+ '<source',
+ 'http://www.google.com/',
+ '/source',
+ '<guid',
+ 'http://example.com/foo?a=1&amp;b=2',
+ '/guid',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'title' => 'My title',
+ 'description' => 'My description',
+ 'link' => 'http://www.google.com/',
+ 'source' => array('url' => 'http://www.example.com/', 'title' => 'Example website')
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ '<title',
+ 'My title',
+ '/title',
+ '<description',
+ 'My description',
+ '/description',
+ '<link',
+ 'http://www.google.com/',
+ '/link',
+ 'source' => array('url' => 'http://www.example.com/'),
+ 'Example website',
+ '/source',
+ '<guid',
+ 'http://www.google.com/',
+ '/guid',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'title' => 'My title',
+ 'description' => 'My description',
+ 'link' => 'http://www.google.com/',
+ 'category' => array('Category One', 'Category Two')
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ '<title',
+ 'My title',
+ '/title',
+ '<description',
+ 'My description',
+ '/description',
+ '<link',
+ 'http://www.google.com/',
+ '/link',
+ '<category',
+ 'Category One',
+ '/category',
+ '<category',
+ 'Category Two',
+ '/category',
+ '<guid',
+ 'http://www.google.com/',
+ '/guid',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test item() with cdata blocks.
+ *
+ * @return void
+ */
+ public function testItemCdata() {
+ $item = array(
+ 'title' => array(
+ 'value' => 'My Title & more',
+ 'cdata' => true,
+ 'convertEntities' => false,
+ )
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ '<title',
+ '<![CDATA[My Title & more]]',
+ '/title',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'category' => array(
+ 'value' => 'CakePHP',
+ 'cdata' => true,
+ 'domain' => 'http://www.cakephp.org',
+ )
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ 'category' => array('domain' => 'http://www.cakephp.org'),
+ '<![CDATA[CakePHP]]',
+ '/category',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'category' => array(
+ array(
+ 'value' => 'CakePHP',
+ 'cdata' => true,
+ 'domain' => 'http://www.cakephp.org'
+ ),
+ array(
+ 'value' => 'Bakery',
+ 'cdata' => true
+ )
+ )
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ 'category' => array('domain' => 'http://www.cakephp.org'),
+ '<![CDATA[CakePHP]]',
+ '/category',
+ '<category',
+ '<![CDATA[Bakery]]',
+ '/category',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $item = array(
+ 'title' => array(
+ 'value' => 'My Title',
+ 'cdata' => true,
+ ),
+ 'link' => 'http://www.example.com/1',
+ 'description' => array(
+ 'value' => 'descriptive words',
+ 'cdata' => true,
+ ),
+ 'enclosure' => array(
+ 'url' => '/test.flv'
+ ),
+ 'pubDate' => '2008-05-31 12:00:00',
+ 'guid' => 'http://www.example.com/1',
+ 'category' => array(
+ array(
+ 'value' => 'CakePHP',
+ 'cdata' => true,
+ 'domain' => 'http://www.cakephp.org'
+ ),
+ array(
+ 'value' => 'Bakery',
+ 'cdata' => true
+ )
+ )
+ );
+ $result = $this->Rss->item(null, $item);
+ $expected = array(
+ '<item',
+ '<title',
+ '<![CDATA[My Title]]',
+ '/title',
+ '<link',
+ 'http://www.example.com/1',
+ '/link',
+ '<description',
+ '<![CDATA[descriptive words]]',
+ '/description',
+ 'enclosure' => array('url' => $this->Rss->url('/test.flv', true)),
+ '<pubDate',
+ date('r', strtotime('2008-05-31 12:00:00')),
+ '/pubDate',
+ '<guid',
+ 'http://www.example.com/1',
+ '/guid',
+ 'category' => array('domain' => 'http://www.cakephp.org'),
+ '<![CDATA[CakePHP]]',
+ '/category',
+ '<category',
+ '<![CDATA[Bakery]]',
+ '/category',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+/**
+ * test item() with enclosure data.
+ *
+ * @return void
+ */
+ public function testItemEnclosureLength() {
+ if (!is_writable(WWW_ROOT)) {
+ $this->markTestSkipped(__d('cake_dev', 'Webroot is not writable.'));
+ }
+ $testExists = is_dir(WWW_ROOT . 'tests');
+
+ $tmpFile = WWW_ROOT . 'tests' . DS . 'cakephp.file.test.tmp';
+ $File = new File($tmpFile, true);
+
+ $this->assertTrue($File->write('123'), 'Could not write to ' . $tmpFile);
+
+ if (50300 <= PHP_VERSION_ID) {
+ clearstatcache(true, $tmpFile);
+ } else {
+ clearstatcache();
+ }
+
+ $item = array(
+ 'title' => array(
+ 'value' => 'My Title',
+ 'cdata' => true,
+ ),
+ 'link' => 'http://www.example.com/1',
+ 'description' => array(
+ 'value' => 'descriptive words',
+ 'cdata' => true,
+ ),
+ 'enclosure' => array(
+ 'url' => '/tests/cakephp.file.test.tmp'
+ ),
+ 'pubDate' => '2008-05-31 12:00:00',
+ 'guid' => 'http://www.example.com/1',
+ 'category' => array(
+ array(
+ 'value' => 'CakePHP',
+ 'cdata' => true,
+ 'domain' => 'http://www.cakephp.org'
+ ),
+ array(
+ 'value' => 'Bakery',
+ 'cdata' => true
+ )
+ )
+ );
+ $result = $this->Rss->item(null, $item);
+ if (!function_exists('finfo_open') &&
+ (function_exists('mime_content_type') && false === mime_content_type($tmpFile))
+ ) {
+ $type = false;
+ } else {
+ $type = 'text/plain';
+ }
+ $expected = array(
+ '<item',
+ '<title',
+ '<![CDATA[My Title]]',
+ '/title',
+ '<link',
+ 'http://www.example.com/1',
+ '/link',
+ '<description',
+ '<![CDATA[descriptive words]]',
+ '/description',
+ 'enclosure' => array(
+ 'url' => $this->Rss->url('/tests/cakephp.file.test.tmp', true),
+ 'length' => filesize($tmpFile),
+ 'type' => $type
+ ),
+ '<pubDate',
+ date('r', strtotime('2008-05-31 12:00:00')),
+ '/pubDate',
+ '<guid',
+ 'http://www.example.com/1',
+ '/guid',
+ 'category' => array('domain' => 'http://www.cakephp.org'),
+ '<![CDATA[CakePHP]]',
+ '/category',
+ '<category',
+ '<![CDATA[Bakery]]',
+ '/category',
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+
+ $File->delete();
+
+ if (!$testExists) {
+ $Folder = new Folder(WWW_ROOT . 'tests');
+ $Folder->delete();
+ }
+ }
+
+/**
+ * testElementAttrNotInParent method
+ *
+ * @return void
+ */
+ public function testElementAttrNotInParent() {
+ $attributes = array(
+ 'title' => 'Some Title',
+ 'link' => 'http://link.com',
+ 'description' => 'description'
+ );
+ $elements = array('enclosure' => array('url' => 'http://test.com'));
+
+ $result = $this->Rss->item($attributes, $elements);
+ $expected = array(
+ 'item' => array(
+ 'title' => 'Some Title',
+ 'link' => 'http://link.com',
+ 'description' => 'description'
+ ),
+ 'enclosure' => array(
+ 'url' => 'http://test.com'
+ ),
+ '/item'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php
new file mode 100644
index 0000000..62fc004
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/SessionHelperTest.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * SessionHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('View', 'View');
+App::uses('SessionHelper', 'View/Helper');
+
+/**
+ * SessionHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class SessionHelperTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $controller = null;
+ $this->View = new View($controller);
+ $this->Session = new SessionHelper($this->View);
+ CakeSession::start();
+
+ if (!CakeSession::started()) {
+ CakeSession::start();
+ }
+
+ $_SESSION = array(
+ 'test' => 'info',
+ 'Message' => array(
+ 'flash' => array(
+ 'element' => 'default',
+ 'params' => array(),
+ 'message' => 'This is a calling'
+ ),
+ 'notification' => array(
+ 'element' => 'session_helper',
+ 'params' => array('title' => 'Notice!', 'name' => 'Alert!'),
+ 'message' => 'This is a test of the emergency broadcasting system',
+ ),
+ 'classy' => array(
+ 'element' => 'default',
+ 'params' => array('class' => 'positive'),
+ 'message' => 'Recorded'
+ ),
+ 'bare' => array(
+ 'element' => null,
+ 'message' => 'Bare message',
+ 'params' => array(),
+ ),
+ ),
+ 'Deeply' => array('nested' => array('key' => 'value')),
+ );
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ $_SESSION = array();
+ unset($this->View, $this->Session);
+ CakePlugin::unload();
+ parent::tearDown();
+ }
+
+/**
+ * testRead method
+ *
+ * @return void
+ */
+ public function testRead() {
+ $result = $this->Session->read('Deeply.nested.key');
+ $this->assertEquals('value', $result);
+
+ $result = $this->Session->read('test');
+ $this->assertEquals('info', $result);
+ }
+
+/**
+ * testCheck method
+ *
+ * @return void
+ */
+ public function testCheck() {
+ $this->assertTrue($this->Session->check('test'));
+
+ $this->assertTrue($this->Session->check('Message.flash.element'));
+
+ $this->assertFalse($this->Session->check('Does.not.exist'));
+
+ $this->assertFalse($this->Session->check('Nope'));
+ }
+
+/**
+ * testFlash method
+ *
+ * @return void
+ */
+ public function testFlash() {
+ $result = $this->Session->flash('flash');
+ $expected = '<div id="flashMessage" class="message">This is a calling</div>';
+ $this->assertEquals($expected, $result);
+ $this->assertFalse($this->Session->check('Message.flash'));
+
+ $expected = '<div id="classyMessage" class="positive">Recorded</div>';
+ $result = $this->Session->flash('classy');
+ $this->assertEquals($expected, $result);
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $result = $this->Session->flash('notification');
+ $result = str_replace("\r\n", "\n", $result);
+ $expected = "<div id=\"notificationLayout\">\n\t<h1>Alert!</h1>\n\t<h3>Notice!</h3>\n\t<p>This is a test of the emergency broadcasting system</p>\n</div>";
+ $this->assertEquals($expected, $result);
+ $this->assertFalse($this->Session->check('Message.notification'));
+
+ $result = $this->Session->flash('bare');
+ $expected = 'Bare message';
+ $this->assertEquals($expected, $result);
+ $this->assertFalse($this->Session->check('Message.bare'));
+ }
+
+/**
+ * test flash() with the attributes.
+ *
+ * @return void
+ */
+ public function testFlashAttributes() {
+ $result = $this->Session->flash('flash', array('params' => array('class' => 'test-message')));
+ $expected = '<div id="flashMessage" class="test-message">This is a calling</div>';
+ $this->assertEquals($expected, $result);
+ $this->assertFalse($this->Session->check('Message.flash'));
+ }
+
+/**
+ * test setting the element from the attrs.
+ *
+ * @return void
+ */
+ public function testFlashElementInAttrs() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $result = $this->Session->flash('flash', array(
+ 'element' => 'session_helper',
+ 'params' => array('title' => 'Notice!', 'name' => 'Alert!')
+ ));
+ $expected = "<div id=\"notificationLayout\">\n\t<h1>Alert!</h1>\n\t<h3>Notice!</h3>\n\t<p>This is a calling</p>\n</div>";
+ $this->assertTextEquals($expected, $result);
+ }
+
+/**
+ * test using elements in plugins.
+ *
+ * @return void
+ */
+ public function testFlashWithPluginElement() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+
+ $result = $this->Session->flash('flash', array(
+ 'element' => 'plugin_element',
+ 'params' => array('plugin' => 'TestPlugin')
+ ));
+ $expected = 'this is the plugin element using params[plugin]';
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TextHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TextHelperTest.php
new file mode 100644
index 0000000..7538f20
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TextHelperTest.php
@@ -0,0 +1,301 @@
+<?php
+/**
+ * TextHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('TextHelper', 'View/Helper');
+
+class TextHelperTestObject extends TextHelper {
+
+ public function attach(StringMock $string) {
+ $this->_engine = $string;
+ }
+
+ public function engine() {
+ return $this->_engine;
+ }
+
+}
+
+/**
+ * StringMock class
+ */
+class StringMock {
+}
+
+/**
+ * TextHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class TextHelperTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->View = new View(null);
+ $this->Text = new TextHelper($this->View);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->View);
+ parent::tearDown();
+ }
+
+/**
+ * test String class methods are called correctly
+ */
+ public function testTextHelperProxyMethodCalls() {
+ $methods = array(
+ 'highlight', 'stripLinks', 'truncate', 'excerpt', 'toList',
+ );
+ $String = $this->getMock('StringMock', $methods);
+ $Text = new TextHelperTestObject($this->View, array('engine' => 'StringMock'));
+ $Text->attach($String);
+ foreach ($methods as $method) {
+ $String->expects($this->at(0))->method($method);
+ $Text->{$method}('who', 'what', 'when', 'where', 'how');
+ }
+ }
+
+/**
+ * test engine override
+ */
+ public function testEngineOverride() {
+ App::build(array(
+ 'Utility' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Utility' . DS)
+ ), App::REGISTER);
+ $Text = new TextHelperTestObject($this->View, array('engine' => 'TestAppEngine'));
+ $this->assertInstanceOf('TestAppEngine', $Text->engine());
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $Text = new TextHelperTestObject($this->View, array('engine' => 'TestPlugin.TestPluginEngine'));
+ $this->assertInstanceOf('TestPluginEngine', $Text->engine());
+ CakePlugin::unload('TestPlugin');
+ }
+
+/**
+ * testAutoLink method
+ *
+ * @return void
+ */
+ public function testAutoLink() {
+ $text = 'This is a test text';
+ $expected = 'This is a test text';
+ $result = $this->Text->autoLink($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a partial www.cakephp.org URL and test@cakephp.org email address';
+ $result = $this->Text->autoLink($text);
+ $expected = 'Text with a partial <a href="http://www.cakephp.org">www.cakephp.org</a> URL and <a href="mailto:test@cakephp\.org">test@cakephp\.org</a> email address';
+ $this->assertRegExp('#^' . $expected . '$#', $result);
+
+ $text = 'This is a test text with URL http://www.cakephp.org';
+ $expected = 'This is a test text with URL <a href="http://www.cakephp.org">http://www.cakephp.org</a>';
+ $result = $this->Text->autoLink($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a test text with URL http://www.cakephp.org and some more text';
+ $expected = 'This is a test text with URL <a href="http://www.cakephp.org">http://www.cakephp.org</a> and some more text';
+ $result = $this->Text->autoLink($text);
+ $this->assertEquals($expected, $result);
+
+ $text = "This is a test text with URL http://www.cakephp.org\tand some more text";
+ $expected = "This is a test text with URL <a href=\"http://www.cakephp.org\">http://www.cakephp.org</a>\tand some more text";
+ $result = $this->Text->autoLink($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a test text with URL http://www.cakephp.org(and some more text)';
+ $expected = 'This is a test text with URL <a href="http://www.cakephp.org">http://www.cakephp.org</a>(and some more text)';
+ $result = $this->Text->autoLink($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a test text with URL http://www.cakephp.org';
+ $expected = 'This is a test text with URL <a href="http://www.cakephp.org" class="link">http://www.cakephp.org</a>';
+ $result = $this->Text->autoLink($text, array('class' => 'link'));
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a test text with URL http://www.cakephp.org';
+ $expected = 'This is a test text with URL <a href="http://www.cakephp.org" class="link" id="MyLink">http://www.cakephp.org</a>';
+ $result = $this->Text->autoLink($text, array('class' => 'link', 'id' => 'MyLink'));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test escaping for autoLink
+ *
+ * @return void
+ */
+ public function testAutoLinkEscape() {
+ $text = 'This is a <b>test</b> text with URL http://www.cakephp.org';
+ $expected = 'This is a &lt;b&gt;test&lt;/b&gt; text with URL <a href="http://www.cakephp.org">http://www.cakephp.org</a>';
+ $result = $this->Text->autoLink($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a <b>test</b> text with URL http://www.cakephp.org';
+ $expected = 'This is a <b>test</b> text with URL <a href="http://www.cakephp.org">http://www.cakephp.org</a>';
+ $result = $this->Text->autoLink($text, array('escape' => false));
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testAutoLinkUrls method
+ *
+ * @return void
+ */
+ public function testAutoLinkUrls() {
+ $text = 'This is a test text';
+ $expected = 'This is a test text';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'This is a test that includes (www.cakephp.org)';
+ $expected = 'This is a test that includes (<a href="http://www.cakephp.org">www.cakephp.org</a>)';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a partial www.cakephp.org URL';
+ $expected = 'Text with a partial <a href="http://www.cakephp.org"\s*>www.cakephp.org</a> URL';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertRegExp('#^' . $expected . '$#', $result);
+
+ $text = 'Text with a partial www.cakephp.org URL';
+ $expected = 'Text with a partial <a href="http://www.cakephp.org" \s*class="link">www.cakephp.org</a> URL';
+ $result = $this->Text->autoLinkUrls($text, array('class' => 'link'));
+ $this->assertRegExp('#^' . $expected . '$#', $result);
+
+ $text = 'Text with a partial WWW.cakephp.org URL';
+ $expected = 'Text with a partial <a href="http://WWW.cakephp.org"\s*>WWW.cakephp.org</a> URL';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertRegExp('#^' . $expected . '$#', $result);
+
+ $text = 'Text with a partial WWW.cakephp.org &copy; URL';
+ $expected = 'Text with a partial <a href="http://WWW.cakephp.org"\s*>WWW.cakephp.org</a> &copy; URL';
+ $result = $this->Text->autoLinkUrls($text, array('escape' => false));
+ $this->assertRegExp('#^' . $expected . '$#', $result);
+
+ $text = 'Text with a url www.cot.ag/cuIb2Q and more';
+ $expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q">www.cot.ag/cuIb2Q</a> and more';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a url http://www.does--not--work.com and more';
+ $expected = 'Text with a url <a href="http://www.does--not--work.com">http://www.does--not--work.com</a> and more';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a url http://www.not--work.com and more';
+ $expected = 'Text with a url <a href="http://www.not--work.com">http://www.not--work.com</a> and more';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test autoLinkUrls with the escape option.
+ *
+ * @return void
+ */
+ public function testAutoLinkUrlsEscape() {
+ $text = 'Text with a partial <a href="http://www.cakephp.org">link</a> link';
+ $expected = 'Text with a partial <a href="http://www.cakephp.org">link</a> link';
+ $result = $this->Text->autoLinkUrls($text, array('escape' => false));
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a partial <iframe src="http://www.cakephp.org" /> link';
+ $expected = 'Text with a partial <iframe src="http://www.cakephp.org" /> link';
+ $result = $this->Text->autoLinkUrls($text, array('escape' => false));
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a partial <iframe src="http://www.cakephp.org" /> link';
+ $expected = 'Text with a partial &lt;iframe src=&quot;http://www.cakephp.org&quot; /&gt; link';
+ $result = $this->Text->autoLinkUrls($text, array('escape' => true));
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a url <a href="http://www.not-working-www.com">www.not-working-www.com</a> and more';
+ $expected = 'Text with a url &lt;a href=&quot;http://www.not-working-www.com&quot;&gt;www.not-working-www.com&lt;/a&gt; and more';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a url www.not-working-www.com and more';
+ $expected = 'Text with a url <a href="http://www.not-working-www.com">www.not-working-www.com</a> and more';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a url http://www.not-working-www.com and more';
+ $expected = 'Text with a url <a href="http://www.not-working-www.com">http://www.not-working-www.com</a> and more';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with a url http://www.www.not-working-www.com and more';
+ $expected = 'Text with a url <a href="http://www.www.not-working-www.com">http://www.www.not-working-www.com</a> and more';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testAutoLinkEmails method
+ *
+ * @return void
+ */
+ public function testAutoLinkEmails() {
+ $text = 'This is a test text';
+ $expected = 'This is a test text';
+ $result = $this->Text->autoLinkUrls($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with email@example.com address';
+ $expected = 'Text with <a href="mailto:email@example.com"\s*>email@example.com</a> address';
+ $result = $this->Text->autoLinkEmails($text);
+ $this->assertRegExp('#^' . $expected . '$#', $result);
+
+ $text = "Text with o'hare._-bob@example.com address";
+ $expected = 'Text with <a href="mailto:o&#039;hare._-bob@example.com">o&#039;hare._-bob@example.com</a> address';
+ $result = $this->Text->autoLinkEmails($text);
+ $this->assertEquals($expected, $result);
+
+ $text = 'Text with email@example.com address';
+ $expected = 'Text with <a href="mailto:email@example.com" \s*class="link">email@example.com</a> address';
+ $result = $this->Text->autoLinkEmails($text, array('class' => 'link'));
+ $this->assertRegExp('#^' . $expected . '$#', $result);
+ }
+
+/**
+ * test invalid email addresses.
+ *
+ * @return void
+ */
+ public function testAutoLinkEmailInvalid() {
+ $result = $this->Text->autoLinkEmails('this is a myaddress@gmx-de test');
+ $expected = 'this is a myaddress@gmx-de test';
+ $this->assertEquals($expected, $result);
+ }
+
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php
new file mode 100644
index 0000000..1eecd96
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/Helper/TimeHelperTest.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * TimeHelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('TimeHelper', 'View/Helper');
+App::uses('View', 'View');
+App::uses('CakeTime', 'Utility');
+
+/**
+ * TimeHelperTestObject class
+ */
+class TimeHelperTestObject extends TimeHelper {
+
+ public function attach(CakeTimeMock $cakeTime) {
+ $this->_engine = $cakeTime;
+ }
+
+ public function engine() {
+ return $this->_engine;
+ }
+
+}
+
+/**
+ * CakeTimeMock class
+ */
+class CakeTimeMock {
+}
+
+/**
+ * TimeHelperTest class
+ *
+ * @package Cake.Test.Case.View.Helper
+ */
+class TimeHelperTest extends CakeTestCase {
+
+ public $Time = null;
+
+ public $CakeTime = null;
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->View = new View(null);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->View);
+ parent::tearDown();
+ }
+
+/**
+ * test CakeTime class methods are called correctly
+ */
+ public function testTimeHelperProxyMethodCalls() {
+ $methods = array(
+ 'convertSpecifiers', 'convert', 'serverOffset', 'fromString',
+ 'nice', 'niceShort', 'daysAsSql', 'dayAsSql',
+ 'isToday', 'isThisMonth', 'isThisYear', 'wasYesterday',
+ 'isTomorrow', 'toQuarter', 'toUnix', 'toAtom', 'toRSS',
+ 'timeAgoInWords', 'wasWithinLast', 'gmt', 'format', 'i18nFormat',
+ );
+ $CakeTime = $this->getMock('CakeTimeMock', $methods);
+ $Time = new TimeHelperTestObject($this->View, array('engine' => 'CakeTimeMock'));
+ $Time->attach($CakeTime);
+ foreach ($methods as $method) {
+ $CakeTime->expects($this->at(0))->method($method);
+ $Time->{$method}('who', 'what', 'when', 'where', 'how');
+ }
+ }
+
+/**
+ * test engine override
+ */
+ public function testEngineOverride() {
+ App::build(array(
+ 'Utility' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Utility' . DS)
+ ), App::REGISTER);
+ $Time = new TimeHelperTestObject($this->View, array('engine' => 'TestAppEngine'));
+ $this->assertInstanceOf('TestAppEngine', $Time->engine());
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ $Time = new TimeHelperTestObject($this->View, array('engine' => 'TestPlugin.TestPluginEngine'));
+ $this->assertInstanceOf('TestPluginEngine', $Time->engine());
+ CakePlugin::unload('TestPlugin');
+ }
+
+/**
+ * Test element wrapping in timeAgoInWords
+ *
+ * @return void
+ */
+ public function testTimeAgoInWords() {
+ $Time = new TimeHelper($this->View);
+ $timestamp = strtotime('+8 years, +4 months +2 weeks +3 days');
+ $result = $Time->timeAgoInWords($timestamp, array(
+ 'end' => '1 years',
+ 'element' => 'span'
+ ));
+ $expected = array(
+ 'span' => array(
+ 'title' => $timestamp,
+ 'class' => 'time-ago-in-words'
+ ),
+ 'on ' . date('j/n/y', $timestamp),
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $Time->timeAgoInWords($timestamp, array(
+ 'end' => '1 years',
+ 'element' => array(
+ 'title' => 'testing',
+ 'rel' => 'test'
+ )
+ ));
+ $expected = array(
+ 'span' => array(
+ 'title' => 'testing',
+ 'class' => 'time-ago-in-words',
+ 'rel' => 'test'
+ ),
+ 'on ' . date('j/n/y', $timestamp),
+ '/span'
+ );
+ $this->assertTags($result, $expected);
+
+ $timestamp = strtotime('+2 weeks');
+ $result = $Time->timeAgoInWords(
+ $timestamp,
+ array('end' => '1 years', 'element' => 'div')
+ );
+ $expected = array(
+ 'div' => array(
+ 'title' => $timestamp,
+ 'class' => 'time-ago-in-words'
+ ),
+ '2 weeks',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperCollectionTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperCollectionTest.php
new file mode 100644
index 0000000..eae0ce3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperCollectionTest.php
@@ -0,0 +1,188 @@
+<?php
+/**
+ * HelperCollectionTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HelperCollection', 'View');
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('View', 'View');
+
+/**
+ * Extended HtmlHelper
+ */
+class HtmlAliasHelper extends HtmlHelper {
+}
+
+class HelperCollectionTest extends CakeTestCase {
+
+/**
+ * setUp
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->View = $this->getMock('View', array(), array(null));
+ $this->Helpers = new HelperCollection($this->View);
+ }
+
+/**
+ * tearDown
+ *
+ * @return void
+ */
+ public function tearDown() {
+ CakePlugin::unload();
+ unset($this->Helpers, $this->View);
+ parent::tearDown();
+ }
+
+/**
+ * test triggering callbacks on loaded helpers
+ *
+ * @return void
+ */
+ public function testLoad() {
+ $result = $this->Helpers->load('Html');
+ $this->assertInstanceOf('HtmlHelper', $result);
+ $this->assertInstanceOf('HtmlHelper', $this->Helpers->Html);
+
+ $result = $this->Helpers->attached();
+ $this->assertEquals(array('Html'), $result, 'attached() results are wrong.');
+
+ $this->assertTrue($this->Helpers->enabled('Html'));
+ }
+
+/**
+ * test lazy loading of helpers
+ *
+ * @return void
+ */
+ public function testLazyLoad() {
+ $result = $this->Helpers->Html;
+ $this->assertInstanceOf('HtmlHelper', $result);
+
+ $result = $this->Helpers->Form;
+ $this->assertInstanceOf('FormHelper', $result);
+
+ App::build(array('Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
+ $this->View->plugin = 'TestPlugin';
+ CakePlugin::load(array('TestPlugin'));
+ $result = $this->Helpers->OtherHelper;
+ $this->assertInstanceOf('OtherHelperHelper', $result);
+ }
+
+/**
+ * test lazy loading of helpers
+ *
+ * @expectedException MissingHelperException
+ * @return void
+ */
+ public function testLazyLoadException() {
+ $result = $this->Helpers->NotAHelper;
+ }
+
+/**
+ * Tests loading as an alias
+ *
+ * @return void
+ */
+ public function testLoadWithAlias() {
+ $result = $this->Helpers->load('Html', array('className' => 'HtmlAlias'));
+ $this->assertInstanceOf('HtmlAliasHelper', $result);
+ $this->assertInstanceOf('HtmlAliasHelper', $this->Helpers->Html);
+
+ $result = $this->Helpers->attached();
+ $this->assertEquals(array('Html'), $result, 'attached() results are wrong.');
+
+ $this->assertTrue($this->Helpers->enabled('Html'));
+
+ $result = $this->Helpers->load('Html');
+ $this->assertInstanceOf('HtmlAliasHelper', $result);
+
+ App::build(array('Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)));
+ CakePlugin::load(array('TestPlugin'));
+ $result = $this->Helpers->load('SomeOther', array('className' => 'TestPlugin.OtherHelper'));
+ $this->assertInstanceOf('OtherHelperHelper', $result);
+ $this->assertInstanceOf('OtherHelperHelper', $this->Helpers->SomeOther);
+
+ $result = $this->Helpers->attached();
+ $this->assertEquals(array('Html', 'SomeOther'), $result, 'attached() results are wrong.');
+ App::build();
+ }
+
+/**
+ * test that the enabled setting disables the helper.
+ *
+ * @return void
+ */
+ public function testLoadWithEnabledFalse() {
+ $result = $this->Helpers->load('Html', array('enabled' => false));
+ $this->assertInstanceOf('HtmlHelper', $result);
+ $this->assertInstanceOf('HtmlHelper', $this->Helpers->Html);
+
+ $this->assertFalse($this->Helpers->enabled('Html'), 'Html should be disabled');
+ }
+
+/**
+ * test missinghelper exception
+ *
+ * @expectedException MissingHelperException
+ * @return void
+ */
+ public function testLoadMissingHelper() {
+ $result = $this->Helpers->load('ThisHelperShouldAlwaysBeMissing');
+ }
+
+/**
+ * test loading a plugin helper.
+ *
+ * @return void
+ */
+ public function testLoadPluginHelper() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ ));
+ CakePlugin::load(array('TestPlugin'));
+ $result = $this->Helpers->load('TestPlugin.OtherHelper');
+ $this->assertInstanceOf('OtherHelperHelper', $result, 'Helper class is wrong.');
+ $this->assertInstanceOf('OtherHelperHelper', $this->Helpers->OtherHelper, 'Class is wrong');
+
+ App::build();
+ }
+
+/**
+ * test unload()
+ *
+ * @return void
+ */
+ public function testUnload() {
+ $this->Helpers->load('Form');
+ $this->Helpers->load('Html');
+
+ $result = $this->Helpers->attached();
+ $this->assertEquals(array('Form', 'Html'), $result, 'loaded helpers is wrong');
+
+ $this->Helpers->unload('Html');
+ $this->assertNotContains('Html', $this->Helpers->attached());
+ $this->assertContains('Form', $this->Helpers->attached());
+
+ $result = $this->Helpers->attached();
+ $this->assertEquals(array('Form'), $result, 'loaded helpers is wrong');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperTest.php
new file mode 100644
index 0000000..65d9d8e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/HelperTest.php
@@ -0,0 +1,941 @@
+<?php
+/**
+ * HelperTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('Helper', 'View');
+App::uses('Model', 'Model');
+App::uses('Router', 'Routing');
+
+/**
+ * HelperTestPost class
+ *
+ * @package Cake.Test.Case.View
+ */
+class HelperTestPost extends Model {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ 'title' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'body' => array('type' => 'string', 'null' => true, 'default' => '', 'length' => ''),
+ 'number' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ 'date' => array('type' => 'date', 'null' => true, 'default' => '', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => true, 'default' => '', 'length' => ''),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null)
+ );
+ return $this->_schema;
+ }
+
+/**
+ * hasAndBelongsToMany property
+ *
+ * @var array
+ */
+ public $hasAndBelongsToMany = array('HelperTestTag' => array('with' => 'HelperTestPostsTag'));
+}
+
+/**
+ * HelperTestComment class
+ *
+ * @package Cake.Test.Case.View
+ */
+class HelperTestComment extends Model {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ 'author_id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ 'title' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'body' => array('type' => 'string', 'null' => true, 'default' => '', 'length' => ''),
+ 'BigField' => array('type' => 'string', 'null' => true, 'default' => '', 'length' => ''),
+ 'created' => array('type' => 'date', 'null' => true, 'default' => '', 'length' => ''),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null)
+ );
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * HelperTestTag class
+ *
+ * @package Cake.Test.Case.View
+ */
+class HelperTestTag extends Model {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ $this->_schema = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ 'name' => array('type' => 'string', 'null' => false, 'default' => '', 'length' => '255'),
+ 'created' => array('type' => 'date', 'null' => true, 'default' => '', 'length' => ''),
+ 'modified' => array('type' => 'datetime', 'null' => true, 'default' => '', 'length' => null)
+ );
+ return $this->_schema;
+ }
+
+}
+
+/**
+ * HelperTestPostsTag class
+ *
+ * @package Cake.Test.Case.View
+ */
+class HelperTestPostsTag extends Model {
+
+/**
+ * useTable property
+ *
+ * @var bool false
+ */
+ public $useTable = false;
+
+/**
+ * schema method
+ *
+ * @return void
+ */
+ public function schema($field = false) {
+ $this->_schema = array(
+ 'helper_test_post_id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ 'helper_test_tag_id' => array('type' => 'integer', 'null' => false, 'default' => '', 'length' => '8'),
+ );
+ return $this->_schema;
+ }
+
+}
+
+class TestHelper extends Helper {
+
+/**
+ * Helpers for this helper.
+ *
+ * @var string
+ */
+ public $helpers = array('Html', 'TestPlugin.OtherHelper');
+
+/**
+ * expose a method as public
+ *
+ * @param string $options
+ * @param string $exclude
+ * @param string $insertBefore
+ * @param string $insertAfter
+ * @return void
+ */
+ public function parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
+ return $this->_parseAttributes($options, $exclude, $insertBefore, $insertAfter);
+ }
+
+}
+
+/**
+ * HelperTest class
+ *
+ * @package Cake.Test.Case.View
+ */
+class HelperTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ ClassRegistry::flush();
+ Router::reload();
+ $null = null;
+ $this->View = new View($null);
+ $this->Helper = new Helper($this->View);
+ $this->Helper->request = new CakeRequest(null, false);
+
+ ClassRegistry::addObject('HelperTestPost', new HelperTestPost());
+ ClassRegistry::addObject('HelperTestComment', new HelperTestComment());
+ ClassRegistry::addObject('HelperTestTag', new HelperTestTag());
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ ));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ Configure::delete('Asset');
+
+ CakePlugin::unload();
+ unset($this->Helper, $this->View);
+ }
+
+/**
+ * Provider for setEntity test.
+ *
+ * @return array
+ */
+ public static function entityProvider() {
+ return array(
+ array(
+ 'HelperTestPost.id',
+ array('HelperTestPost', 'id'),
+ 'HelperTestPost',
+ 'id'
+ ),
+ array(
+ 'HelperTestComment.body',
+ array('HelperTestComment', 'body'),
+ 'HelperTestComment',
+ 'body'
+ ),
+ array(
+ 'HelperTest.1.Comment.body',
+ array('HelperTest', '1', 'Comment', 'body'),
+ 'Comment',
+ 'body'
+ ),
+ array(
+ 'HelperTestComment.BigField',
+ array('HelperTestComment', 'BigField'),
+ 'HelperTestComment',
+ 'BigField'
+ ),
+ array(
+ 'HelperTestComment.min',
+ array('HelperTestComment', 'min'),
+ 'HelperTestComment',
+ 'min'
+ )
+ );
+ }
+
+/**
+ * Test setting an entity and retrieving the entity, model and field.
+ *
+ * @dataProvider entityProvider
+ * @return void
+ */
+ public function testSetEntity($entity, $expected, $modelKey, $fieldKey) {
+ $this->Helper->setEntity($entity);
+ $this->assertEquals($expected, $this->Helper->entity());
+ $this->assertEquals($modelKey, $this->Helper->model());
+ $this->assertEquals($fieldKey, $this->Helper->field());
+ }
+
+/**
+ * test setEntity with setting a scope.
+ *
+ * @return
+ */
+ public function testSetEntityScoped() {
+ $this->Helper->setEntity('HelperTestPost', true);
+ $this->assertEquals(array('HelperTestPost'), $this->Helper->entity());
+
+ $this->Helper->setEntity('id');
+ $expected = array('HelperTestPost', 'id');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('HelperTestComment.body');
+ $expected = array('HelperTestComment', 'body');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('body');
+ $expected = array('HelperTestPost', 'body');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('2.body');
+ $expected = array('HelperTestPost', '2', 'body');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('Something.else');
+ $expected = array('Something', 'else');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('HelperTestComment.5.id');
+ $expected = array('HelperTestComment', 5, 'id');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('HelperTestComment.id.time');
+ $expected = array('HelperTestComment', 'id', 'time');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('HelperTestComment.created.year');
+ $expected = array('HelperTestComment', 'created', 'year');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity(null);
+ $this->Helper->setEntity('ModelThatDoesntExist.field_that_doesnt_exist');
+ $expected = array('ModelThatDoesntExist', 'field_that_doesnt_exist');
+ $this->assertEquals($expected, $this->Helper->entity());
+ }
+
+/**
+ * Test that setEntity() and model()/field() work with associated models.
+ *
+ * @return void
+ */
+ public function testSetEntityAssociated() {
+ $this->Helper->setEntity('HelperTestPost', true);
+
+ $this->Helper->setEntity('HelperTestPost.1.HelperTestComment.1.title');
+ $expected = array('HelperTestPost', '1', 'HelperTestComment', '1', 'title');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->assertEquals('HelperTestComment', $this->Helper->model());
+ }
+
+/**
+ * Test creating saveMany() compatible entities
+ *
+ * @return void
+ */
+ public function testSetEntitySaveMany() {
+ $this->Helper->setEntity('HelperTestPost', true);
+
+ $this->Helper->setEntity('0.HelperTestPost.id');
+ $expected = array('0', 'HelperTestPost', 'id');
+ $this->assertEquals($expected, $this->Helper->entity());
+ }
+
+/**
+ * Test that setEntity doesn't make CamelCase fields that are not associations an
+ * associated model.
+ *
+ * @return void
+ */
+ public function testSetEntityAssociatedCamelCaseField() {
+ $this->Helper->fieldset = array(
+ 'HelperTestComment' => array(
+ 'fields' => array('BigField' => array('type' => 'integer'))
+ )
+ );
+ $this->Helper->setEntity('HelperTestComment', true);
+ $this->Helper->setEntity('HelperTestComment.BigField');
+
+ $this->assertEquals('HelperTestComment', $this->Helper->model());
+ $this->assertEquals('BigField', $this->Helper->field());
+ }
+
+/**
+ * Test that multiple fields work when they are camelcase and in fieldset
+ *
+ * @return void
+ */
+ public function testSetEntityAssociatedCamelCaseFieldHabtmMultiple() {
+ $this->Helper->fieldset = array(
+ 'HelperTestComment' => array(
+ 'fields' => array('Tag' => array('type' => 'multiple'))
+ )
+ );
+ $this->Helper->setEntity('HelperTestComment', true);
+ $this->Helper->setEntity('Tag');
+
+ $this->assertEquals('Tag', $this->Helper->model());
+ $this->assertEquals('Tag', $this->Helper->field());
+ $this->assertEquals(array('Tag', 'Tag'), $this->Helper->entity());
+ }
+
+/**
+ * Test that habtm associations can have property fields created.
+ *
+ * @return void
+ */
+ public function testSetEntityHabtmPropertyFieldNames() {
+ $this->Helper->fieldset = array(
+ 'HelperTestComment' => array(
+ 'fields' => array('Tag' => array('type' => 'multiple'))
+ )
+ );
+ $this->Helper->setEntity('HelperTestComment', true);
+
+ $this->Helper->setEntity('Tag.name');
+ $this->assertEquals('Tag', $this->Helper->model());
+ $this->assertEquals('name', $this->Helper->field());
+ $this->assertEquals(array('Tag', 'name'), $this->Helper->entity());
+ }
+
+/**
+ * test that 'view' doesn't break things.
+ *
+ * @return void
+ */
+ public function testSetEntityWithView() {
+ $this->assertNull($this->Helper->setEntity('Allow.view.group_id'));
+ $this->assertNull($this->Helper->setEntity('Allow.view'));
+ $this->assertNull($this->Helper->setEntity('View.view'));
+ }
+
+/**
+ * test getting values from Helper
+ *
+ * @return void
+ */
+ public function testValue() {
+ $this->Helper->request->data = array('fullname' => 'This is me');
+ $this->Helper->setEntity('fullname');
+ $result = $this->Helper->value('fullname');
+ $this->assertEquals('This is me', $result);
+
+ $this->Helper->request->data = array(
+ 'Post' => array('name' => 'First Post')
+ );
+ $this->Helper->setEntity('Post.name');
+ $result = $this->Helper->value('Post.name');
+ $this->assertEquals('First Post', $result);
+
+ $this->Helper->request->data = array(
+ 'Post' => array(2 => array('name' => 'First Post'))
+ );
+ $this->Helper->setEntity('Post.2.name');
+ $result = $this->Helper->value('Post.2.name');
+ $this->assertEquals('First Post', $result);
+
+ $this->Helper->request->data = array(
+ 'Post' => array(
+ 2 => array('created' => array('year' => '2008'))
+ )
+ );
+ $this->Helper->setEntity('Post.2.created');
+ $result = $this->Helper->value('Post.2.created');
+ $this->assertEquals(array('year' => '2008'), $result);
+
+ $this->Helper->request->data = array(
+ 'Post' => array(
+ 2 => array('created' => array('year' => '2008'))
+ )
+ );
+ $this->Helper->setEntity('Post.2.created.year');
+ $result = $this->Helper->value('Post.2.created.year');
+ $this->assertEquals('2008', $result);
+ }
+
+/**
+ * Test default values with value()
+ *
+ * @return void
+ */
+ public function testValueWithDefault() {
+ $this->Helper->request->data = array('zero' => 0);
+ $this->Helper->setEntity('zero');
+ $result = $this->Helper->value(array('default' => 'something'), 'zero');
+ $this->assertEquals(array('value' => 0), $result);
+
+ $this->Helper->request->data = array('zero' => '0');
+ $result = $this->Helper->value(array('default' => 'something'), 'zero');
+ $this->assertEquals(array('value' => '0'), $result);
+
+ $this->Helper->setEntity('inexistent');
+ $result = $this->Helper->value(array('default' => 'something'), 'inexistent');
+ $this->assertEquals(array('value' => 'something'), $result);
+ }
+
+/**
+ * Test habtm data fetching and ensure no pollution happens.
+ *
+ * @return void
+ */
+ public function testValueHabtmKeys() {
+ $this->Helper->request->data = array(
+ 'HelperTestTag' => array('HelperTestTag' => '')
+ );
+ $this->Helper->setEntity('HelperTestTag.HelperTestTag');
+ $result = $this->Helper->value('HelperTestTag.HelperTestTag');
+ $this->assertEquals('', $result);
+
+ $this->Helper->request->data = array(
+ 'HelperTestTag' => array(
+ 'HelperTestTag' => array(2, 3, 4)
+ )
+ );
+ $this->Helper->setEntity('HelperTestTag.HelperTestTag');
+ $result = $this->Helper->value('HelperTestTag.HelperTestTag');
+ $this->assertEquals(array(2, 3, 4), $result);
+
+ $this->Helper->request->data = array(
+ 'HelperTestTag' => array(
+ array('id' => 3),
+ array('id' => 5)
+ )
+ );
+ $this->Helper->setEntity('HelperTestTag.HelperTestTag');
+ $result = $this->Helper->value('HelperTestTag.HelperTestTag');
+ $this->assertEquals(array(3 => 3, 5 => 5), $result);
+
+ $this->Helper->request->data = array(
+ 'HelperTestTag' => array(
+ 'body' => '',
+ 'title' => 'winning'
+ ),
+ );
+ $this->Helper->setEntity('HelperTestTag.body');
+ $result = $this->Helper->value('HelperTestTag.body');
+ $this->assertEquals('', $result);
+ }
+
+/**
+ * Ensure HTML escaping of url params. So link addresses are valid and not exploited
+ *
+ * @return void
+ */
+ public function testUrlConversion() {
+ $result = $this->Helper->url('/controller/action/1');
+ $this->assertEquals('/controller/action/1', $result);
+
+ $result = $this->Helper->url('/controller/action/1?one=1&two=2');
+ $this->assertEquals('/controller/action/1?one=1&amp;two=2', $result);
+
+ $result = $this->Helper->url(array('controller' => 'posts', 'action' => 'index', 'page' => '1" onclick="alert(\'XSS\');"'));
+ $this->assertEquals("/posts/index/page:1%22%20onclick%3D%22alert%28%27XSS%27%29%3B%22", $result);
+
+ $result = $this->Helper->url('/controller/action/1/param:this+one+more');
+ $this->assertEquals('/controller/action/1/param:this+one+more', $result);
+
+ $result = $this->Helper->url('/controller/action/1/param:this%20one%20more');
+ $this->assertEquals('/controller/action/1/param:this%20one%20more', $result);
+
+ $result = $this->Helper->url('/controller/action/1/param:%7Baround%20here%7D%5Bthings%5D%5Bare%5D%24%24');
+ $this->assertEquals('/controller/action/1/param:%7Baround%20here%7D%5Bthings%5D%5Bare%5D%24%24', $result);
+
+ $result = $this->Helper->url(array(
+ 'controller' => 'posts', 'action' => 'index', 'param' => '%7Baround%20here%7D%5Bthings%5D%5Bare%5D%24%24'
+ ));
+ $this->assertEquals("/posts/index/param:%257Baround%2520here%257D%255Bthings%255D%255Bare%255D%2524%2524", $result);
+
+ $result = $this->Helper->url(array(
+ 'controller' => 'posts', 'action' => 'index', 'page' => '1',
+ '?' => array('one' => 'value', 'two' => 'value', 'three' => 'purple')
+ ));
+ $this->assertEquals("/posts/index/page:1?one=value&amp;two=value&amp;three=purple", $result);
+ }
+
+/**
+ * test assetTimestamp application
+ *
+ * @return void
+ */
+ public function testAssetTimestamp() {
+ Configure::write('Foo.bar', 'test');
+ Configure::write('Asset.timestamp', false);
+ $result = $this->Helper->assetTimestamp(CSS_URL . 'cake.generic.css');
+ $this->assertEquals(CSS_URL . 'cake.generic.css', $result);
+
+ Configure::write('Asset.timestamp', true);
+ Configure::write('debug', 0);
+ $result = $this->Helper->assetTimestamp(CSS_URL . 'cake.generic.css');
+ $this->assertEquals(CSS_URL . 'cake.generic.css', $result);
+
+ Configure::write('Asset.timestamp', true);
+ Configure::write('debug', 2);
+ $result = $this->Helper->assetTimestamp(CSS_URL . 'cake.generic.css');
+ $this->assertRegExp('/' . preg_quote(CSS_URL . 'cake.generic.css?', '/') . '[0-9]+/', $result);
+
+ Configure::write('Asset.timestamp', 'force');
+ Configure::write('debug', 0);
+ $result = $this->Helper->assetTimestamp(CSS_URL . 'cake.generic.css');
+ $this->assertRegExp('/' . preg_quote(CSS_URL . 'cake.generic.css?', '/') . '[0-9]+/', $result);
+
+ $result = $this->Helper->assetTimestamp(CSS_URL . 'cake.generic.css?someparam');
+ $this->assertEquals(CSS_URL . 'cake.generic.css?someparam', $result);
+
+ $this->Helper->request->webroot = '/some/dir/';
+ $result = $this->Helper->assetTimestamp('/some/dir/' . CSS_URL . 'cake.generic.css');
+ $this->assertRegExp('/' . preg_quote(CSS_URL . 'cake.generic.css?', '/') . '[0-9]+/', $result);
+ }
+
+/**
+ * test assetUrl application
+ *
+ * @return void
+ */
+ public function testAssetUrl() {
+ $this->Helper->webroot = '';
+ $result = $this->Helper->assetUrl(array(
+ 'controller' => 'js',
+ 'action' => 'post',
+ 'ext' => 'js'
+ ),
+ array('fullBase' => true)
+ );
+ $this->assertEquals(FULL_BASE_URL . '/js/post.js', $result);
+
+ $result = $this->Helper->assetUrl('foo.jpg', array('pathPrefix' => 'img/'));
+ $this->assertEquals('img/foo.jpg', $result);
+
+ $result = $this->Helper->assetUrl('foo.jpg', array('fullBase' => true));
+ $this->assertEquals(FULL_BASE_URL . '/foo.jpg', $result);
+
+ $result = $this->Helper->assetUrl('style', array('ext' => '.css'));
+ $this->assertEquals('style.css', $result);
+
+ $result = $this->Helper->assetUrl('foo.jpg?one=two&three=four');
+ $this->assertEquals('foo.jpg?one=two&amp;three=four', $result);
+ }
+
+/**
+ * Test assetUrl with plugins.
+ *
+ * @return void
+ */
+ public function testAssetUrlPlugin() {
+ $this->Helper->webroot = '';
+ CakePlugin::load('TestPlugin');
+
+ $result = $this->Helper->assetUrl('TestPlugin.style', array('ext' => '.css'));
+ $this->assertEquals('test_plugin/style.css', $result);
+
+ $result = $this->Helper->assetUrl('TestPlugin.style', array('ext' => '.css', 'plugin' => false));
+ $this->assertEquals('TestPlugin.style.css', $result);
+
+ CakePlugin::unload('TestPlugin');
+ }
+
+/**
+ * test assetUrl and Asset.timestamp = force
+ *
+ * @return void
+ */
+ public function testAssetUrlTimestampForce() {
+ $this->Helper->webroot = '';
+ Configure::write('Asset.timestamp', 'force');
+
+ $result = $this->Helper->assetUrl('cake.generic.css', array('pathPrefix' => CSS_URL));
+ $this->assertRegExp('/' . preg_quote(CSS_URL . 'cake.generic.css?', '/') . '[0-9]+/', $result);
+ }
+
+/**
+ * test assetTimestamp with plugins and themes
+ *
+ * @return void
+ */
+ public function testAssetTimestampPluginsAndThemes() {
+ Configure::write('Asset.timestamp', 'force');
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
+ ));
+ CakePlugin::load(array('TestPlugin'));
+
+ $result = $this->Helper->assetTimestamp('/test_plugin/css/test_plugin_asset.css');
+ $this->assertRegExp('#/test_plugin/css/test_plugin_asset.css\?[0-9]+$#', $result, 'Missing timestamp plugin');
+
+ $result = $this->Helper->assetTimestamp('/test_plugin/css/i_dont_exist.css');
+ $this->assertRegExp('#/test_plugin/css/i_dont_exist.css\?$#', $result, 'No error on missing file');
+
+ $result = $this->Helper->assetTimestamp('/theme/test_theme/js/theme.js');
+ $this->assertRegExp('#/theme/test_theme/js/theme.js\?[0-9]+$#', $result, 'Missing timestamp theme');
+
+ $result = $this->Helper->assetTimestamp('/theme/test_theme/js/non_existant.js');
+ $this->assertRegExp('#/theme/test_theme/js/non_existant.js\?$#', $result, 'No error on missing file');
+ }
+
+/**
+ * testFieldsWithSameName method
+ *
+ * @return void
+ */
+ public function testFieldsWithSameName() {
+ $this->Helper->setEntity('HelperTestTag', true);
+
+ $this->Helper->setEntity('HelperTestTag.id');
+ $expected = array('HelperTestTag', 'id');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('My.id');
+ $expected = array('My', 'id');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('MyOther.id');
+ $expected = array('MyOther', 'id');
+ $this->assertEquals($expected, $this->Helper->entity());
+ }
+
+/**
+ * testFieldSameAsModel method
+ *
+ * @return void
+ */
+ public function testFieldSameAsModel() {
+ $this->Helper->setEntity('HelperTestTag', true);
+
+ $this->Helper->setEntity('helper_test_post');
+ $expected = array('HelperTestTag', 'helper_test_post');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $this->Helper->setEntity('HelperTestTag');
+ $expected = array('HelperTestTag', 'HelperTestTag');
+ $this->assertEquals($expected, $this->Helper->entity());
+ }
+
+/**
+ * testFieldSuffixForDate method
+ *
+ * @return void
+ */
+ public function testFieldSuffixForDate() {
+ $this->Helper->setEntity('HelperTestPost', true);
+ $expected = array('HelperTestPost');
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ foreach (array('year', 'month', 'day', 'hour', 'min', 'meridian') as $d) {
+ $this->Helper->setEntity('date.' . $d);
+ $expected = array('HelperTestPost', 'date', $d);
+ $this->assertEquals($expected, $this->Helper->entity());
+ }
+ }
+
+/**
+ * testMulitDimensionValue method
+ *
+ * @return void
+ */
+ public function testMultiDimensionValue() {
+ $this->Helper->data = array();
+ for ($i = 0; $i < 2; $i++) {
+ $this->Helper->request->data['Model'][$i] = 'what';
+ $result[] = $this->Helper->value("Model.{$i}");
+ $this->Helper->request->data['Model'][$i] = array();
+ for ($j = 0; $j < 2; $j++) {
+ $this->Helper->request->data['Model'][$i][$j] = 'how';
+ $result[] = $this->Helper->value("Model.{$i}.{$j}");
+ }
+ }
+ $expected = array('what', 'how', 'how', 'what', 'how', 'how');
+ $this->assertEquals($expected, $result);
+
+ $this->Helper->request->data['HelperTestComment']['5']['id'] = 'ok';
+ $result = $this->Helper->value('HelperTestComment.5.id');
+ $this->assertEquals('ok', $result);
+
+ $this->Helper->setEntity('HelperTestPost', true);
+ $this->Helper->request->data['HelperTestPost']['5']['created']['month'] = '10';
+ $result = $this->Helper->value('5.created.month');
+ $this->assertEquals(10, $result);
+
+ $this->Helper->request->data['HelperTestPost']['0']['id'] = 100;
+ $result = $this->Helper->value('HelperTestPost.0.id');
+ $this->assertEquals(100, $result);
+ }
+
+/**
+ * testClean method
+ *
+ * @return void
+ */
+ public function testClean() {
+ $result = $this->Helper->clean(array());
+ $this->assertEquals(null, $result);
+
+ $result = $this->Helper->clean(array('<script>with something</script>', '<applet>something else</applet>'));
+ $this->assertEquals(array('with something', 'something else'), $result);
+
+ $result = $this->Helper->clean('<script>with something</script>');
+ $this->assertEquals('with something', $result);
+
+ $result = $this->Helper->clean('<script type="text/javascript">alert("ruined");</script>');
+ $this->assertNotRegExp('#</*script#', $result);
+
+ $result = $this->Helper->clean("<script \ntype=\"text/javascript\">\n\talert('ruined');\n\n\t\t</script>");
+ $this->assertNotRegExp('#</*script#', $result);
+
+ $result = $this->Helper->clean('<body/onload=do(/something/)>');
+ $this->assertEquals('<body/>', $result);
+
+ $result = $this->Helper->clean('&lt;script&gt;alert(document.cookie)&lt;/script&gt;');
+ $this->assertEquals('&amp;lt;script&amp;gt;alert(document.cookie)&amp;lt;/script&amp;gt;', $result);
+ }
+
+/**
+ * testMultiDimensionalField method
+ *
+ * @return void
+ */
+ public function testMultiDimensionalField() {
+ $this->Helper->setEntity('HelperTestPost', true);
+
+ $entity = 'HelperTestPost.2.HelperTestComment.1.title';
+ $this->Helper->setEntity($entity);
+ $expected = array(
+ 'HelperTestPost', '2', 'HelperTestComment', '1', 'title'
+ );
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $entity = 'HelperTestPost.1.HelperTestComment.1.HelperTestTag.1.created';
+ $this->Helper->setEntity($entity);
+ $expected = array(
+ 'HelperTestPost', '1', 'HelperTestComment', '1',
+ 'HelperTestTag', '1', 'created'
+ );
+ $this->assertEquals($expected, $this->Helper->entity());
+
+ $entity = 'HelperTestPost.0.HelperTestComment.1.HelperTestTag.1.fake';
+ $expected = array(
+ 'HelperTestPost', '0', 'HelperTestComment', '1',
+ 'HelperTestTag', '1', 'fake'
+ );
+ $this->Helper->setEntity($entity);
+
+ $entity = '1.HelperTestComment.1.HelperTestTag.created.year';
+ $this->Helper->setEntity($entity);
+
+ $this->Helper->request->data['HelperTestPost'][2]['HelperTestComment'][1]['title'] = 'My Title';
+ $result = $this->Helper->value('HelperTestPost.2.HelperTestComment.1.title');
+ $this->assertEquals('My Title', $result);
+
+ $this->Helper->request->data['HelperTestPost'][2]['HelperTestComment'][1]['created']['year'] = 2008;
+ $result = $this->Helper->value('HelperTestPost.2.HelperTestComment.1.created.year');
+ $this->assertEquals(2008, $result);
+
+ $this->Helper->request->data[2]['HelperTestComment'][1]['created']['year'] = 2008;
+ $result = $this->Helper->value('HelperTestPost.2.HelperTestComment.1.created.year');
+ $this->assertEquals(2008, $result);
+
+ $this->Helper->request->data['HelperTestPost']['title'] = 'My Title';
+ $result = $this->Helper->value('title');
+ $this->assertEquals('My Title', $result);
+
+ $this->Helper->request->data['My']['title'] = 'My Title';
+ $result = $this->Helper->value('My.title');
+ $this->assertEquals('My Title', $result);
+ }
+
+ public function testWebrootPaths() {
+ $this->Helper->request->webroot = '/';
+ $result = $this->Helper->webroot('/img/cake.power.gif');
+ $expected = '/img/cake.power.gif';
+ $this->assertEquals($expected, $result);
+
+ $this->Helper->theme = 'test_theme';
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+
+ $result = $this->Helper->webroot('/img/cake.power.gif');
+ $expected = '/theme/test_theme/img/cake.power.gif';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Helper->webroot('/img/test.jpg');
+ $expected = '/theme/test_theme/img/test.jpg';
+ $this->assertEquals($expected, $result);
+
+ $webRoot = Configure::read('App.www_root');
+ Configure::write('App.www_root', CAKE . 'Test' . DS . 'test_app' . DS . 'webroot' . DS);
+
+ $result = $this->Helper->webroot('/img/cake.power.gif');
+ $expected = '/theme/test_theme/img/cake.power.gif';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Helper->webroot('/img/test.jpg');
+ $expected = '/theme/test_theme/img/test.jpg';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Helper->webroot('/img/cake.icon.gif');
+ $expected = '/img/cake.icon.gif';
+ $this->assertEquals($expected, $result);
+
+ $result = $this->Helper->webroot('/img/cake.icon.gif?some=param');
+ $expected = '/img/cake.icon.gif?some=param';
+ $this->assertEquals($expected, $result);
+
+ Configure::write('App.www_root', $webRoot);
+ }
+
+/**
+ * test lazy loading helpers is seamless
+ *
+ * @return void
+ */
+ public function testLazyLoadingHelpers() {
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ ));
+ CakePlugin::load(array('TestPlugin'));
+ $Helper = new TestHelper($this->View);
+ $this->assertInstanceOf('OtherHelperHelper', $Helper->OtherHelper);
+ $this->assertInstanceOf('HtmlHelper', $Helper->Html);
+ App::build();
+ }
+
+/**
+ * test that a helpers Helper is not 'attached' to the collection
+ *
+ * @return void
+ */
+ public function testThatHelperHelpersAreNotAttached() {
+ $Helper = new TestHelper($this->View);
+ $Helper->OtherHelper;
+
+ $result = $this->View->Helpers->enabled();
+ $expected = array();
+ $this->assertEquals($expected, $result, 'Helper helpers were attached to the collection.');
+ }
+
+/**
+ * test that the lazy loader doesn't duplicate objects on each access.
+ *
+ * @return void
+ */
+ public function testLazyLoadingUsesReferences() {
+ $Helper = new TestHelper($this->View);
+ $resultA = $Helper->Html;
+ $resultB = $Helper->Html;
+
+ $resultA->testprop = 1;
+ $this->assertEquals($resultA->testprop, $resultB->testprop);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/JsonViewTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/JsonViewTest.php
new file mode 100644
index 0000000..39a3e7a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/JsonViewTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * JsonViewTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View
+ * @since CakePHP(tm) v 2.1.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+App::uses('JsonView', 'View');
+
+/**
+ * JsonViewTest
+ *
+ * @package Cake.Test.Case.View
+ */
+class JsonViewTest extends CakeTestCase {
+
+/**
+ * testRenderWithoutView method
+ *
+ * @return void
+ */
+ public function testRenderWithoutView() {
+ $Request = new CakeRequest();
+ $Response = new CakeResponse();
+ $Controller = new Controller($Request, $Response);
+ $data = array('user' => 'fake', 'list' => array('item1', 'item2'));
+ $Controller->set(array('data' => $data, '_serialize' => 'data'));
+ $View = new JsonView($Controller);
+ $output = $View->render(false);
+
+ $this->assertSame(json_encode($data), $output);
+ $this->assertSame('application/json', $Response->type());
+ }
+
+/**
+ * Test render with an array in _serialize
+ *
+ * @return void
+ */
+ public function testRenderWithoutViewMultiple() {
+ $Request = new CakeRequest();
+ $Response = new CakeResponse();
+ $Controller = new Controller($Request, $Response);
+ $data = array('no' => 'nope', 'user' => 'fake', 'list' => array('item1', 'item2'));
+ $Controller->set($data);
+ $Controller->set('_serialize', array('no', 'user'));
+ $View = new JsonView($Controller);
+ $output = $View->render(false);
+
+ $this->assertSame(json_encode(array('no' => $data['no'], 'user' => $data['user'])), $output);
+ $this->assertSame('application/json', $Response->type());
+ }
+
+/**
+ * testRenderWithView method
+ *
+ * @return void
+ */
+ public function testRenderWithView() {
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ $Request = new CakeRequest();
+ $Response = new CakeResponse();
+ $Controller = new Controller($Request, $Response);
+ $Controller->name = $Controller->viewPath = 'Posts';
+
+ $data = array(
+ 'User' => array(
+ 'username' => 'fake'
+ ),
+ 'Item' => array(
+ array('name' => 'item1'),
+ array('name' => 'item2')
+ )
+ );
+ $Controller->set('user', $data);
+ $View = new JsonView($Controller);
+ $output = $View->render('index');
+
+ $expected = json_encode(array('user' => 'fake', 'list' => array('item1', 'item2')));
+ $this->assertSame($expected, $output);
+ $this->assertSame('application/json', $Response->type());
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/MediaViewTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/MediaViewTest.php
new file mode 100644
index 0000000..3b723c0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/MediaViewTest.php
@@ -0,0 +1,402 @@
+<?php
+/**
+ * MediaViewTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('MediaView', 'View');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * MediaViewTest class
+ *
+ * @package Cake.Test.Case.View
+ */
+class MediaViewTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->MediaView = $this->getMock('MediaView', array('_isActive', '_clearBuffer', '_flushBuffer'));
+ $this->MediaView->response = $this->getMock('CakeResponse');
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->MediaView);
+ }
+
+/**
+ * tests that rendering a file that does not exists throws an exception
+ *
+ * @expectedException NotFoundException
+ * @return void
+ */
+ public function testRenderNotFound() {
+ $this->MediaView->viewVars = array(
+ 'path' => '/some/missing/folder',
+ 'id' => 'file.jpg'
+ );
+ $this->MediaView->render();
+ }
+
+/**
+ * testRender method
+ *
+ * @return void
+ */
+ public function testRender() {
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS,
+ 'id' => 'test_asset.css',
+ 'extension' => 'css',
+ );
+ $this->MediaView->expects($this->exactly(2))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->response->expects($this->exactly(1))
+ ->method('type')
+ ->with('css')
+ ->will($this->returnArgument(0));
+
+ $this->MediaView->response->expects($this->at(1))
+ ->method('header')
+ ->with(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+
+ $this->MediaView->response->expects($this->at(2))
+ ->method('header')
+ ->with(array(
+ 'Content-Length' => 31
+ ));
+ $this->MediaView->response->expects($this->once())->method('send');
+ $this->MediaView->expects($this->once())->method('_clearBuffer');
+ $this->MediaView->expects($this->once())->method('_flushBuffer');
+
+ ob_start();
+ $result = $this->MediaView->render();
+ $output = ob_get_clean();
+ $this->assertEquals('this is the test asset css file', $output);
+ $this->assertTrue($result !== false);
+ }
+
+/**
+ * testRenderWithUnknownFileTypeGeneric method
+ *
+ * @return void
+ */
+ public function testRenderWithUnknownFileTypeGeneric() {
+ $currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
+ $_SERVER['HTTP_USER_AGENT'] = 'Some generic browser';
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS,
+ 'id' => 'no_section.ini',
+ 'extension' => 'ini',
+ );
+ $this->MediaView->expects($this->exactly(2))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->response->expects($this->exactly(1))
+ ->method('type')
+ ->with('ini')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->at(1))
+ ->method('header')
+ ->with(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+
+ $this->MediaView->response->expects($this->once())
+ ->method('download')
+ ->with('no_section.ini');
+
+ $this->MediaView->response->expects($this->at(3))
+ ->method('header')
+ ->with(array(
+ 'Accept-Ranges' => 'bytes'
+ ));
+
+ $this->MediaView->response->expects($this->at(4))
+ ->method('header')
+ ->with('Content-Length', 35);
+
+ $this->MediaView->response->expects($this->once())->method('send');
+ $this->MediaView->expects($this->once())->method('_clearBuffer');
+ $this->MediaView->expects($this->once())->method('_flushBuffer');
+
+ ob_start();
+ $result = $this->MediaView->render();
+ $output = ob_get_clean();
+ $this->assertEquals("some_key = some_value\nbool_key = 1\n", $output);
+ $this->assertTrue($result !== false);
+ if ($currentUserAgent !== null) {
+ $_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
+ }
+ }
+
+/**
+ * testRenderWithUnknownFileTypeOpera method
+ *
+ * @return void
+ */
+ public function testRenderWithUnknownFileTypeOpera() {
+ $currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
+ $_SERVER['HTTP_USER_AGENT'] = 'Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10';
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS,
+ 'id' => 'no_section.ini',
+ 'extension' => 'ini',
+ );
+ $this->MediaView->expects($this->exactly(2))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->response->expects($this->at(0))
+ ->method('type')
+ ->with('ini')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->at(1))
+ ->method('header')
+ ->with(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+
+ $this->MediaView->response->expects($this->at(2))
+ ->method('type')
+ ->with('application/octetstream')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->once())
+ ->method('download')
+ ->with('no_section.ini');
+
+ $this->MediaView->response->expects($this->at(4))
+ ->method('header')
+ ->with(array(
+ 'Accept-Ranges' => 'bytes'
+ ));
+
+ $this->MediaView->response->expects($this->at(5))
+ ->method('header')
+ ->with('Content-Length', 35);
+
+ $this->MediaView->response->expects($this->once())->method('send');
+ $this->MediaView->expects($this->once())->method('_clearBuffer');
+ $this->MediaView->expects($this->once())->method('_flushBuffer');
+
+ ob_start();
+ $result = $this->MediaView->render();
+ $output = ob_get_clean();
+ $this->assertEquals("some_key = some_value\nbool_key = 1\n", $output);
+ $this->assertTrue($result !== false);
+ if ($currentUserAgent !== null) {
+ $_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
+ }
+ }
+
+/**
+ * testRenderWithUnknownFileTypeIE method
+ *
+ * @return void
+ */
+ public function testRenderWithUnknownFileTypeIE() {
+ $currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
+ $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)';
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS,
+ 'id' => 'no_section.ini',
+ 'extension' => 'ini',
+ 'name' => 'config'
+ );
+ $this->MediaView->expects($this->exactly(2))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->response->expects($this->at(0))
+ ->method('type')
+ ->with('ini')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->at(1))
+ ->method('header')
+ ->with(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+
+ $this->MediaView->response->expects($this->at(2))
+ ->method('type')
+ ->with('application/force-download')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->once())
+ ->method('download')
+ ->with('config.ini');
+
+ $this->MediaView->response->expects($this->at(4))
+ ->method('header')
+ ->with(array(
+ 'Accept-Ranges' => 'bytes'
+ ));
+
+ $this->MediaView->response->expects($this->at(5))
+ ->method('header')
+ ->with('Content-Length', 35);
+
+ $this->MediaView->response->expects($this->once())->method('send');
+ $this->MediaView->expects($this->once())->method('_clearBuffer');
+ $this->MediaView->expects($this->once())->method('_flushBuffer');
+
+ ob_start();
+ $result = $this->MediaView->render();
+ $output = ob_get_clean();
+ $this->assertEquals("some_key = some_value\nbool_key = 1\n", $output);
+ $this->assertTrue($result !== false);
+ if ($currentUserAgent !== null) {
+ $_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
+ }
+ }
+
+/**
+ * testConnectionAborted method
+ *
+ * @return void
+ */
+ public function testConnectionAborted() {
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS,
+ 'id' => 'test_asset.css',
+ 'extension' => 'css',
+ );
+
+ $this->MediaView->expects($this->once())
+ ->method('_isActive')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->never())
+ ->method('type');
+
+ $result = $this->MediaView->render();
+ $this->assertFalse($result);
+ }
+
+/**
+ * testConnectionAbortedOnBuffering method
+ *
+ * @return void
+ */
+ public function testConnectionAbortedOnBuffering() {
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS,
+ 'id' => 'test_asset.css',
+ 'extension' => 'css',
+ );
+
+ $this->MediaView->expects($this->at(0))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->response->expects($this->any())
+ ->method('type')
+ ->with('css')
+ ->will($this->returnArgument(0));
+
+ $this->MediaView->expects($this->at(1))
+ ->method('_isActive')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->once())->method('send');
+ $this->MediaView->expects($this->once())->method('_clearBuffer');
+ $this->MediaView->expects($this->never())->method('_flushBuffer');
+
+ $result = $this->MediaView->render();
+ $this->assertFalse($result);
+ }
+
+/**
+ * Test downloading files with UPPERCASE extensions.
+ *
+ * @return void
+ */
+ public function testRenderUpperExtension() {
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'img' . DS,
+ 'id' => 'test_2.JPG',
+ 'extension' => 'JPG',
+ );
+
+ $this->MediaView->response->expects($this->any())
+ ->method('type')
+ ->with('jpg')
+ ->will($this->returnArgument(0));
+
+ $this->MediaView->expects($this->at(0))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->render();
+ }
+
+/**
+ * Test downloading files with extension not explicitly set.
+ *
+ * @return void
+ */
+ public function testRenderExtensionNotSet() {
+ $this->MediaView->viewVars = array(
+ 'path' => CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'img' . DS,
+ 'id' => 'test_2.JPG',
+ );
+
+ $this->MediaView->response->expects($this->any())
+ ->method('type')
+ ->with('jpg')
+ ->will($this->returnArgument(0));
+
+ $this->MediaView->expects($this->at(0))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->render();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ScaffoldViewTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ScaffoldViewTest.php
new file mode 100644
index 0000000..a5f2d85
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ScaffoldViewTest.php
@@ -0,0 +1,463 @@
+<?php
+/**
+ * ScaffoldViewTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.Controller
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Controller', 'Controller');
+App::uses('Scaffold', 'Controller');
+App::uses('ScaffoldView', 'View');
+App::uses('AppModel', 'Model');
+
+require_once dirname(dirname(__FILE__)) . DS . 'Model' . DS . 'models.php';
+
+/**
+ * TestScaffoldView class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class TestScaffoldView extends ScaffoldView {
+
+/**
+ * testGetFilename method
+ *
+ * @param string $action
+ * @return void
+ */
+ public function testGetFilename($action) {
+ return $this->_getViewFileName($action);
+ }
+
+}
+
+/**
+ * ScaffoldViewMockController class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldViewMockController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'ScaffoldMock'
+ */
+ public $name = 'ScaffoldMock';
+
+/**
+ * scaffold property
+ *
+ * @var mixed
+ */
+ public $scaffold;
+}
+
+/**
+ * ScaffoldViewTest class
+ *
+ * @package Cake.Test.Case.Controller
+ */
+class ScaffoldViewTest extends CakeTestCase {
+
+/**
+ * fixtures property
+ *
+ * @var array
+ */
+ public $fixtures = array('core.article', 'core.user', 'core.comment', 'core.join_thing', 'core.tag');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->request = new CakeRequest(null, false);
+ $this->Controller = new ScaffoldViewMockController($this->request);
+ $this->Controller->response = $this->getMock('CakeResponse', array('_sendHeader'));
+
+ App::build(array(
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
+ ));
+ CakePlugin::load('TestPlugin');
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ unset($this->Controller, $this->request);
+ parent::tearDown();
+ }
+
+/**
+ * testGetViewFilename method
+ *
+ * @return void
+ */
+ public function testGetViewFilename() {
+ $_admin = Configure::read('Routing.prefixes');
+ Configure::write('Routing.prefixes', array('admin'));
+
+ $this->Controller->request->params['action'] = 'index';
+ $ScaffoldView = new TestScaffoldView($this->Controller);
+ $result = $ScaffoldView->testGetFilename('index');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'index.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('edit');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'form.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('add');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'form.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('view');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'view.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('admin_index');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'index.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('admin_view');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'view.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('admin_edit');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'form.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('admin_add');
+ $expected = CAKE . 'View' . DS . 'Scaffolds' . DS . 'form.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('error');
+ $expected = CAKE . 'View' . DS . 'Errors' . DS . 'scaffold_error.ctp';
+ $this->assertEquals($expected, $result);
+
+ $Controller = new ScaffoldViewMockController($this->request);
+ $Controller->scaffold = 'admin';
+ $Controller->viewPath = 'Posts';
+ $Controller->request['action'] = 'admin_edit';
+
+ $ScaffoldView = new TestScaffoldView($Controller);
+ $result = $ScaffoldView->testGetFilename('admin_edit');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Posts' . DS . 'scaffold.form.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('edit');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Posts' . DS . 'scaffold.form.ctp';
+ $this->assertEquals($expected, $result);
+
+ $Controller = new ScaffoldViewMockController($this->request);
+ $Controller->scaffold = 'admin';
+ $Controller->viewPath = 'Tests';
+ $Controller->request->addParams(array(
+ 'plugin' => 'test_plugin',
+ 'action' => 'admin_add',
+ 'admin' => true
+ ));
+ $Controller->plugin = 'TestPlugin';
+
+ $ScaffoldView = new TestScaffoldView($Controller);
+ $result = $ScaffoldView->testGetFilename('admin_add');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' .
+ DS . 'TestPlugin' . DS . 'View' . DS . 'Tests' . DS . 'scaffold.form.ctp';
+ $this->assertEquals($expected, $result);
+
+ $result = $ScaffoldView->testGetFilename('add');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' .
+ DS . 'TestPlugin' . DS . 'View' . DS . 'Tests' . DS . 'scaffold.form.ctp';
+ $this->assertEquals($expected, $result);
+
+ Configure::write('Routing.prefixes', $_admin);
+ }
+
+/**
+ * test getting the view file name for themed scaffolds.
+ *
+ * @return void
+ */
+ public function testGetViewFileNameWithTheme() {
+ $this->Controller->request['action'] = 'index';
+ $this->Controller->viewPath = 'Posts';
+ $this->Controller->theme = 'TestTheme';
+ $ScaffoldView = new TestScaffoldView($this->Controller);
+
+ $result = $ScaffoldView->testGetFilename('index');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS .
+ 'Themed' . DS . 'TestTheme' . DS . 'Posts' . DS . 'scaffold.index.ctp';
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test default index scaffold generation
+ *
+ * @return void
+ */
+ public function testIndexScaffold() {
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'scaffold_mock'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'index',
+ );
+ $this->Controller->request->addParams($params);
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->base = '';
+ $this->Controller->request->here = '/scaffold_mock/index';
+
+ //set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->constructClasses();
+ ob_start();
+ new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('#<h2>Scaffold Mock</h2>#', $result);
+ $this->assertRegExp('#<table cellpadding="0" cellspacing="0">#', $result);
+
+ $this->assertRegExp('#<a href="/scaffold_users/view/1">1</a>#', $result); //belongsTo links
+ $this->assertRegExp('#<li><a href="/scaffold_mock/add">New Scaffold Mock</a></li>#', $result);
+ $this->assertRegExp('#<li><a href="/scaffold_users">List Scaffold Users</a></li>#', $result);
+ $this->assertRegExp('#<li><a href="/scaffold_comments/add">New Comment</a></li>#', $result);
+ }
+
+/**
+ * test default view scaffold generation
+ *
+ * @return void
+ */
+ public function testViewScaffold() {
+ $this->Controller->request->base = '';
+ $this->Controller->request->here = '/scaffold_mock';
+ $this->Controller->request->webroot = '/';
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(1),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'scaffold_mock/view/1'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'view',
+ );
+ $this->Controller->request->addParams($params);
+
+ //set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+ $this->Controller->constructClasses();
+
+ ob_start();
+ new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/<h2>View Scaffold Mock<\/h2>/', $result);
+ $this->assertRegExp('/<dl>/', $result);
+ //TODO: add specific tests for fields.
+ $this->assertRegExp('/<a href="\/scaffold_users\/view\/1">1<\/a>/', $result); //belongsTo links
+ $this->assertRegExp('/<li><a href="\/scaffold_mock\/edit\/1">Edit Scaffold Mock<\/a>\s<\/li>/', $result);
+ $this->assertRegExp('/<a href="\#" onclick="if[^>]*>Delete Scaffold Mock<\/a>\s<\/li>/', $result);
+ //check related table
+ $this->assertRegExp('/<div class="related">\s*<h3>Related Scaffold Comments<\/h3>\s*<table cellpadding="0" cellspacing="0">/', $result);
+ $this->assertRegExp('/<li><a href="\/scaffold_comments\/add">New Comment<\/a><\/li>/', $result);
+ $this->assertNotRegExp('/<th>JoinThing<\/th>/', $result);
+ }
+
+/**
+ * test default view scaffold generation
+ *
+ * @return void
+ */
+ public function testEditScaffold() {
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/scaffold_mock/edit/1';
+
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(1),
+ 'form' => array(),
+ 'named' => array(),
+ 'url' => array('url' => 'scaffold_mock'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'edit',
+ );
+ $this->Controller->request->addParams($params);
+
+ //set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+ $this->Controller->constructClasses();
+
+ ob_start();
+ new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+
+ $this->assertContains('<form action="/scaffold_mock/edit/1" id="ScaffoldMockEditForm" method="post"', $result);
+ $this->assertContains('<legend>Edit Scaffold Mock</legend>', $result);
+
+ $this->assertContains('input type="hidden" name="data[ScaffoldMock][id]" value="1" id="ScaffoldMockId"', $result);
+ $this->assertContains('select name="data[ScaffoldMock][user_id]" id="ScaffoldMockUserId"', $result);
+ $this->assertContains('input name="data[ScaffoldMock][title]" maxlength="255" type="text" value="First Article" id="ScaffoldMockTitle"', $result);
+ $this->assertContains('input name="data[ScaffoldMock][published]" maxlength="1" type="text" value="Y" id="ScaffoldMockPublished"', $result);
+ $this->assertContains('textarea name="data[ScaffoldMock][body]" cols="30" rows="6" id="ScaffoldMockBody"', $result);
+ $this->assertRegExp('/<a href="\#" onclick="if[^>]*>Delete<\/a><\/li>/', $result);
+ }
+
+/**
+ * Test Admin Index Scaffolding.
+ *
+ * @return void
+ */
+ public function testAdminIndexScaffold() {
+ $_backAdmin = Configure::read('Routing.prefixes');
+
+ Configure::write('Routing.prefixes', array('admin'));
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(),
+ 'form' => array(),
+ 'named' => array(),
+ 'prefix' => 'admin',
+ 'url' => array('url' => 'admin/scaffold_mock'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'admin_index',
+ 'admin' => 1,
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/admin/scaffold_mock';
+ $this->Controller->request->addParams($params);
+
+ //reset, and set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->scaffold = 'admin';
+ $this->Controller->constructClasses();
+
+ ob_start();
+ $Scaffold = new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/<h2>Scaffold Mock<\/h2>/', $result);
+ $this->assertRegExp('/<table cellpadding="0" cellspacing="0">/', $result);
+ //TODO: add testing for table generation
+ $this->assertRegExp('/<li><a href="\/admin\/scaffold_mock\/add">New Scaffold Mock<\/a><\/li>/', $result);
+
+ Configure::write('Routing.prefixes', $_backAdmin);
+ }
+
+/**
+ * Test Admin Index Scaffolding.
+ *
+ * @return void
+ */
+ public function testAdminEditScaffold() {
+ Configure::write('Routing.prefixes', array('admin'));
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(1),
+ 'form' => array(),
+ 'named' => array(),
+ 'prefix' => 'admin',
+ 'url' => array('url' => 'admin/scaffold_mock/edit/1'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'admin_edit',
+ 'admin' => 1,
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/admin/scaffold_mock/edit/1';
+ $this->Controller->request->addParams($params);
+
+ //reset, and set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->scaffold = 'admin';
+ $this->Controller->constructClasses();
+
+ ob_start();
+ $Scaffold = new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('#admin/scaffold_mock/edit/1#', $result);
+ $this->assertRegExp('#Scaffold Mock#', $result);
+ }
+
+/**
+ * Test Admin Index Scaffolding.
+ *
+ * @return void
+ */
+ public function testMultiplePrefixScaffold() {
+ $_backAdmin = Configure::read('Routing.prefixes');
+
+ Configure::write('Routing.prefixes', array('admin', 'member'));
+ $params = array(
+ 'plugin' => null,
+ 'pass' => array(),
+ 'form' => array(),
+ 'named' => array(),
+ 'prefix' => 'member',
+ 'url' => array('url' => 'member/scaffold_mock'),
+ 'controller' => 'scaffold_mock',
+ 'action' => 'member_index',
+ 'member' => 1,
+ );
+ $this->Controller->request->base = '';
+ $this->Controller->request->webroot = '/';
+ $this->Controller->request->here = '/member/scaffold_mock';
+ $this->Controller->request->addParams($params);
+
+ //reset, and set router.
+ Router::reload();
+ Router::setRequestInfo($this->Controller->request);
+
+ $this->Controller->scaffold = 'member';
+ $this->Controller->constructClasses();
+
+ ob_start();
+ $Scaffold = new Scaffold($this->Controller, $this->Controller->request);
+ $this->Controller->response->send();
+ $result = ob_get_clean();
+
+ $this->assertRegExp('/<h2>Scaffold Mock<\/h2>/', $result);
+ $this->assertRegExp('/<table cellpadding="0" cellspacing="0">/', $result);
+ //TODO: add testing for table generation
+ $this->assertRegExp('/<li><a href="\/member\/scaffold_mock\/add">New Scaffold Mock<\/a><\/li>/', $result);
+
+ Configure::write('Routing.prefixes', $_backAdmin);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ThemeViewTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ThemeViewTest.php
new file mode 100644
index 0000000..ec78383
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ThemeViewTest.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * ThemeViewTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('View', 'View');
+App::uses('ThemeView', 'View');
+App::uses('Controller', 'Controller');
+
+
+/**
+ * ThemePosts2Controller class
+ *
+ * @package Cake.Test.Case.View
+ */
+class ThemePosts2Controller extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'ThemePosts'
+ */
+ public $name = 'ThemePosts';
+
+ public $theme = null;
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ $this->set(array(
+ 'testData' => 'Some test data',
+ 'test2' => 'more data',
+ 'test3' => 'even more data',
+ ));
+ }
+
+}
+
+/**
+ * TestTheme2View class
+ *
+ * @package Cake.Test.Case.View
+ */
+class TestTheme2View extends ThemeView {
+
+/**
+ * renderElement method
+ *
+ * @param string $name
+ * @param array $params
+ * @return void
+ */
+ public function renderElement($name, $params = array()) {
+ return $name;
+ }
+
+/**
+ * getViewFileName method
+ *
+ * @param string $name
+ * @return void
+ */
+ public function getViewFileName($name = null) {
+ return $this->_getViewFileName($name);
+ }
+
+/**
+ * getLayoutFileName method
+ *
+ * @param string $name
+ * @return void
+ */
+ public function getLayoutFileName($name = null) {
+ return $this->_getLayoutFileName($name);
+ }
+
+}
+
+/**
+ * ThemeViewTest class
+ *
+ * @package Cake.Test.Case.View
+ */
+class ThemeViewTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+ $request = new CakeRequest('posts/index');
+ $this->Controller = new Controller($request);
+ $this->PostsController = new ThemePosts2Controller($request);
+ $this->PostsController->viewPath = 'posts';
+ $this->PostsController->index();
+ $this->ThemeView = new ThemeView($this->PostsController);
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+ App::objects('plugins', null, false);
+ CakePlugin::load(array('TestPlugin'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ unset($this->ThemeView);
+ unset($this->PostsController);
+ unset($this->Controller);
+ CakePlugin::unload();
+ }
+
+/**
+ * testPluginGetTemplate method
+ *
+ * @return void
+ */
+ public function testPluginThemedGetTemplate() {
+ $this->Controller->plugin = 'TestPlugin';
+ $this->Controller->name = 'TestPlugin';
+ $this->Controller->viewPath = 'Tests';
+ $this->Controller->action = 'index';
+ $this->Controller->theme = 'TestTheme';
+
+ $ThemeView = new TestTheme2View($this->Controller);
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'Tests' . DS . 'index.ctp';
+ $result = $ThemeView->getViewFileName('index');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'Layouts' . DS . 'plugin_default.ctp';
+ $result = $ThemeView->getLayoutFileName('plugin_default');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName('default');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testGetTemplate method
+ *
+ * @return void
+ */
+ public function testGetTemplate() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Pages';
+ $this->Controller->viewPath = 'Pages';
+ $this->Controller->action = 'display';
+ $this->Controller->params['pass'] = array('home');
+
+ $ThemeView = new TestTheme2View($this->Controller);
+ $ThemeView->theme = 'TestTheme';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages' . DS . 'home.ctp';
+ $result = $ThemeView->getViewFileName('home');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Posts' . DS . 'index.ctp';
+ $result = $ThemeView->getViewFileName('/Posts/index');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+
+ $ThemeView->layoutPath = 'rss';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Layouts' . DS . 'rss' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+
+ $ThemeView->layoutPath = 'Emails' . DS . 'html';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Layouts' . DS . 'Emails' . DS . 'html' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMissingView method
+ *
+ * @expectedException MissingViewException
+ * @return void
+ */
+ public function testMissingView() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Pages';
+ $this->Controller->viewPath = 'Pages';
+ $this->Controller->action = 'display';
+ $this->Controller->theme = 'my_theme';
+
+ $this->Controller->params['pass'] = array('home');
+
+ $View = new TestTheme2View($this->Controller);
+ ob_start();
+ $result = $View->getViewFileName('does_not_exist');
+ $expected = ob_get_clean();
+ $this->assertRegExp("/PagesController::/", $expected);
+ $this->assertRegExp("/views(\/|\\\)themed(\/|\\\)my_theme(\/|\\\)pages(\/|\\\)does_not_exist.ctp/", $expected);
+ }
+
+/**
+ * testMissingLayout method
+ *
+ * @expectedException MissingLayoutException
+ * @return void
+ */
+ public function testMissingLayout() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Posts';
+ $this->Controller->viewPath = 'posts';
+ $this->Controller->layout = 'whatever';
+ $this->Controller->theme = 'my_theme';
+
+ $View = new TestTheme2View($this->Controller);
+ ob_start();
+ $result = $View->getLayoutFileName();
+ $expected = ob_get_clean();
+ $this->assertRegExp("/Missing Layout/", $expected);
+ $this->assertRegExp("/views(\/|\\\)themed(\/|\\\)my_theme(\/|\\\)layouts(\/|\\\)whatever.ctp/", $expected);
+ }
+
+/**
+ * test memory leaks that existed in _paths at one point.
+ *
+ * @return void
+ */
+ public function testMemoryLeakInPaths() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Posts';
+ $this->Controller->viewPath = 'posts';
+ $this->Controller->layout = 'whatever';
+ $this->Controller->theme = 'TestTheme';
+
+ $View = new ThemeView($this->Controller);
+ $View->element('test_element');
+
+ $start = memory_get_usage();
+ for ($i = 0; $i < 10; $i++) {
+ $View->element('test_element');
+ }
+ $end = memory_get_usage();
+ $this->assertLessThanOrEqual($start + 5000, $end);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ViewTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ViewTest.php
new file mode 100644
index 0000000..33c0ceb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/ViewTest.php
@@ -0,0 +1,1448 @@
+<?php
+/**
+ * ViewTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('Helper', 'View');
+App::uses('Controller', 'Controller');
+App::uses('CacheHelper', 'View/Helper');
+App::uses('ErrorHandler', 'Error');
+
+
+/**
+ * ViewPostsController class
+ *
+ * @package Cake.Test.Case.View
+ */
+class ViewPostsController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'Posts'
+ */
+ public $name = 'Posts';
+
+/**
+ * uses property
+ *
+ * @var mixed null
+ */
+ public $uses = null;
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ $this->set(array(
+ 'testData' => 'Some test data',
+ 'test2' => 'more data',
+ 'test3' => 'even more data',
+ ));
+ }
+
+/**
+ * nocache_tags_with_element method
+ *
+ * @return void
+ */
+ public function nocache_multiple_element() {
+ $this->set('foo', 'this is foo var');
+ $this->set('bar', 'this is bar var');
+ }
+
+}
+
+/**
+ * ThemePostsController class
+ *
+ * @package Cake.Test.Case.View
+ */
+class ThemePostsController extends Controller {
+
+/**
+ * name property
+ *
+ * @var string 'ThemePosts'
+ */
+ public $name = 'ThemePosts';
+
+ public $theme = null;
+
+/**
+ * index method
+ *
+ * @return void
+ */
+ public function index() {
+ $this->set('testData', 'Some test data');
+ $test2 = 'more data';
+ $test3 = 'even more data';
+ $this->set(compact('test2', 'test3'));
+ }
+
+}
+
+/**
+ * TestThemeView class
+ *
+ * @package Cake.Test.Case.View
+ */
+class TestThemeView extends View {
+
+/**
+ * renderElement method
+ *
+ * @param string $name
+ * @param array $params
+ * @return void
+ */
+ public function renderElement($name, $params = array()) {
+ return $name;
+ }
+
+/**
+ * getViewFileName method
+ *
+ * @param string $name
+ * @return void
+ */
+ public function getViewFileName($name = null) {
+ return $this->_getViewFileName($name);
+ }
+
+/**
+ * getLayoutFileName method
+ *
+ * @param string $name
+ * @return void
+ */
+ public function getLayoutFileName($name = null) {
+ return $this->_getLayoutFileName($name);
+ }
+
+}
+
+/**
+ * TestView class
+ *
+ * @package Cake.Test.Case.View
+ */
+class TestView extends View {
+
+/**
+ * getViewFileName method
+ *
+ * @param string $name
+ * @return void
+ */
+ public function getViewFileName($name = null) {
+ return $this->_getViewFileName($name);
+ }
+
+/**
+ * getLayoutFileName method
+ *
+ * @param string $name
+ * @return void
+ */
+ public function getLayoutFileName($name = null) {
+ return $this->_getLayoutFileName($name);
+ }
+
+/**
+ * paths method
+ *
+ * @param string $plugin
+ * @param boolean $cached
+ * @return void
+ */
+ public function paths($plugin = null, $cached = true) {
+ return $this->_paths($plugin, $cached);
+ }
+
+/**
+ * Test only function to return instance scripts.
+ *
+ * @return array Scripts
+ */
+ public function scripts() {
+ return $this->_scripts;
+ }
+
+}
+
+/**
+ * TestAfterHelper class
+ *
+ * @package Cake.Test.Case.View
+ */
+class TestAfterHelper extends Helper {
+
+/**
+ * property property
+ *
+ * @var string ''
+ */
+ public $property = '';
+
+/**
+ * beforeLayout method
+ *
+ * @return void
+ */
+ public function beforeLayout($viewFile) {
+ $this->property = 'Valuation';
+ }
+
+/**
+ * afterLayout method
+ *
+ * @return void
+ */
+ public function afterLayout($layoutFile) {
+ $this->_View->output .= 'modified in the afterlife';
+ }
+
+}
+
+
+/**
+ * ViewTest class
+ *
+ * @package Cake.Test.Case.View
+ */
+class ViewTest extends CakeTestCase {
+
+/**
+ * Fixtures used in this test.
+ *
+ * @var array
+ */
+ public $fixtures = array('core.user', 'core.post');
+
+/**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ $request = $this->getMock('CakeRequest');
+ $this->Controller = new Controller($request);
+ $this->PostsController = new ViewPostsController($request);
+ $this->PostsController->viewPath = 'Posts';
+ $this->PostsController->index();
+ $this->View = new View($this->PostsController);
+
+ $themeRequest = new CakeRequest('posts/index');
+ $this->ThemeController = new Controller($themeRequest);
+ $this->ThemePostsController = new ThemePostsController($themeRequest);
+ $this->ThemePostsController->viewPath = 'posts';
+ $this->ThemePostsController->index();
+ $this->ThemeView = new View($this->ThemePostsController);
+
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ), App::RESET);
+ App::objects('plugins', null, false);
+
+ CakePlugin::load(array('TestPlugin', 'TestPlugin', 'PluginJs'));
+ Configure::write('debug', 2);
+ }
+
+/**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ CakePlugin::unload();
+ unset($this->View);
+ unset($this->PostsController);
+ unset($this->Controller);
+ unset($this->ThemeView);
+ unset($this->ThemePostsController);
+ unset($this->ThemeController);
+ }
+
+/**
+ * testGetTemplate method
+ *
+ * @return void
+ */
+ public function testGetTemplate() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Pages';
+ $this->Controller->viewPath = 'Pages';
+ $this->Controller->action = 'display';
+ $this->Controller->params['pass'] = array('home');
+
+ $ThemeView = new TestThemeView($this->Controller);
+ $ThemeView->theme = 'TestTheme';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages' . DS . 'home.ctp';
+ $result = $ThemeView->getViewFileName('home');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Posts' . DS . 'index.ctp';
+ $result = $ThemeView->getViewFileName('/Posts/index');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+
+ $ThemeView->layoutPath = 'rss';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Layouts' . DS . 'rss' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+
+ $ThemeView->layoutPath = 'Emails' . DS . 'html';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Layouts' . DS . 'Emails' . DS . 'html' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testPluginGetTemplate method
+ *
+ * @return void
+ */
+ public function testPluginGetTemplate() {
+ $this->Controller->plugin = 'TestPlugin';
+ $this->Controller->name = 'TestPlugin';
+ $this->Controller->viewPath = 'Tests';
+ $this->Controller->action = 'index';
+
+ $View = new TestView($this->Controller);
+
+ $expected = CakePlugin::path('TestPlugin') . 'View' . DS . 'Tests' . DS . 'index.ctp';
+ $result = $View->getViewFileName('index');
+ $this->assertEquals($expected, $result);
+
+ $expected = CakePlugin::path('TestPlugin') . 'View' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $View->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testPluginGetTemplate method
+ *
+ * @return void
+ */
+ public function testPluginThemedGetTemplate() {
+ $this->Controller->plugin = 'TestPlugin';
+ $this->Controller->name = 'TestPlugin';
+ $this->Controller->viewPath = 'Tests';
+ $this->Controller->action = 'index';
+ $this->Controller->theme = 'TestTheme';
+
+ $ThemeView = new TestThemeView($this->Controller);
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'Tests' . DS . 'index.ctp';
+ $result = $ThemeView->getViewFileName('index');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'Layouts' . DS . 'plugin_default.ctp';
+ $result = $ThemeView->getLayoutFileName('plugin_default');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Themed' . DS . 'TestTheme' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $ThemeView->getLayoutFileName('default');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * test that plugin/$plugin_name is only appended to the paths it should be.
+ *
+ * @return void
+ */
+ public function testPluginPathGeneration() {
+ $this->Controller->plugin = 'TestPlugin';
+ $this->Controller->name = 'TestPlugin';
+ $this->Controller->viewPath = 'Tests';
+ $this->Controller->action = 'index';
+
+ $View = new TestView($this->Controller);
+ $paths = $View->paths();
+ $expected = array_merge(App::path('View'), App::core('View'), App::core('Console/Templates/skel/View'));
+ $this->assertEquals($expected, $paths);
+
+ $paths = $View->paths('TestPlugin');
+ $pluginPath = CakePlugin::path('TestPlugin');
+ $expected = array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Plugin' . DS . 'TestPlugin' . DS,
+ $pluginPath . 'View' . DS,
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS,
+ CAKE . 'View' . DS,
+ CAKE . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'View' . DS
+ );
+ $this->assertEquals($expected, $paths);
+ }
+
+/**
+ * test that CamelCase plugins still find their view files.
+ *
+ * @return void
+ */
+ public function testCamelCasePluginGetTemplate() {
+ $this->Controller->plugin = 'TestPlugin';
+ $this->Controller->name = 'TestPlugin';
+ $this->Controller->viewPath = 'Tests';
+ $this->Controller->action = 'index';
+
+ $View = new TestView($this->Controller);
+ App::build(array(
+ 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS),
+ 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+ ));
+
+ $pluginPath = CakePlugin::path('TestPlugin');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'View' . DS . 'Tests' . DS . 'index.ctp';
+ $result = $View->getViewFileName('index');
+ $this->assertEquals($expected, $result);
+
+ $expected = $pluginPath . 'View' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $View->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testGetTemplate method
+ *
+ * @return void
+ */
+ public function testGetViewFileNames() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Pages';
+ $this->Controller->viewPath = 'Pages';
+ $this->Controller->action = 'display';
+ $this->Controller->params['pass'] = array('home');
+
+ $View = new TestView($this->Controller);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages' . DS . 'home.ctp';
+ $result = $View->getViewFileName('home');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Posts' . DS . 'index.ctp';
+ $result = $View->getViewFileName('/Posts/index');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Posts' . DS . 'index.ctp';
+ $result = $View->getViewFileName('../Posts/index');
+ $this->assertEquals($expected, $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages' . DS . 'page.home.ctp';
+ $result = $View->getViewFileName('page.home');
+ $this->assertEquals($expected, $result, 'Should not ruin files with dots.');
+
+ CakePlugin::load('TestPlugin');
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Pages' . DS . 'home.ctp';
+ $result = $View->getViewFileName('TestPlugin.home');
+ $this->assertEquals($expected, $result, 'Plugin is missing the view, cascade to app.');
+
+ $View->viewPath = 'Tests';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'View' . DS . 'Tests' . DS . 'index.ctp';
+ $result = $View->getViewFileName('TestPlugin.index');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test getting layout filenames
+ *
+ * @return void
+ */
+ public function testGetLayoutFileName() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Pages';
+ $this->Controller->viewPath = 'Pages';
+ $this->Controller->action = 'display';
+
+ $View = new TestView($this->Controller);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $View->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+
+ $View->layoutPath = 'rss';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Layouts' . DS . 'rss' . DS . 'default.ctp';
+ $result = $View->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+
+ $View->layoutPath = 'Emails' . DS . 'html';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Layouts' . DS . 'Emails' . DS . 'html' . DS . 'default.ctp';
+ $result = $View->getLayoutFileName();
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * Test getting layout filenames for plugins.
+ *
+ * @return void
+ */
+ public function testGetLayoutFileNamePlugin() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Pages';
+ $this->Controller->viewPath = 'Pages';
+ $this->Controller->action = 'display';
+
+ $View = new TestView($this->Controller);
+ CakePlugin::load('TestPlugin');
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'View' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $View->getLayoutFileName('TestPlugin.default');
+ $this->assertEquals($expected, $result);
+
+ $View->plugin = 'TestPlugin';
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' . DS . 'View' . DS . 'Layouts' . DS . 'default.ctp';
+ $result = $View->getLayoutFileName('default');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testMissingView method
+ *
+ * @expectedException MissingViewException
+ * @return void
+ */
+ public function testMissingView() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Pages';
+ $this->Controller->viewPath = 'Pages';
+ $this->Controller->action = 'display';
+ $this->Controller->params['pass'] = array('home');
+
+ $View = new TestView($this->Controller);
+ ob_start();
+ $result = $View->getViewFileName('does_not_exist');
+
+ $this->ThemeController->plugin = null;
+ $this->ThemeController->name = 'Pages';
+ $this->ThemeController->viewPath = 'Pages';
+ $this->ThemeController->action = 'display';
+ $this->ThemeController->theme = 'my_theme';
+
+ $this->ThemeController->params['pass'] = array('home');
+
+ $View = new TestThemeView($this->ThemeController);
+ ob_start();
+ $result = $View->getViewFileName('does_not_exist');
+ $expected = ob_get_clean();
+ $this->assertRegExp("/PagesController::/", $expected);
+ $this->assertRegExp("/views(\/|\\\)themed(\/|\\\)my_theme(\/|\\\)pages(\/|\\\)does_not_exist.ctp/", $expected);
+ }
+
+/**
+ * testMissingLayout method
+ *
+ * @expectedException MissingLayoutException
+ * @return void
+ */
+ public function testMissingLayout() {
+ $this->Controller->plugin = null;
+ $this->Controller->name = 'Posts';
+ $this->Controller->viewPath = 'Posts';
+ $this->Controller->layout = 'whatever';
+
+ $View = new TestView($this->Controller);
+ ob_start();
+ $result = $View->getLayoutFileName();
+ $expected = ob_get_clean();
+
+ $this->ThemeController->plugin = null;
+ $this->ThemeController->name = 'Posts';
+ $this->ThemeController->viewPath = 'posts';
+ $this->ThemeController->layout = 'whatever';
+ $this->ThemeController->theme = 'my_theme';
+
+ $View = new TestThemeView($this->ThemeController);
+ ob_start();
+ $result = $View->getLayoutFileName();
+ $expected = ob_get_clean();
+ $this->assertRegExp("/Missing Layout/", $expected);
+ $this->assertRegExp("/views(\/|\\\)themed(\/|\\\)my_theme(\/|\\\)layouts(\/|\\\)whatever.ctp/", $expected);
+ }
+
+/**
+ * testViewVars method
+ *
+ * @return void
+ */
+ public function testViewVars() {
+ $this->assertEquals(array('testData' => 'Some test data', 'test2' => 'more data', 'test3' => 'even more data'), $this->View->viewVars);
+ }
+
+/**
+ * testUUIDGeneration method
+ *
+ * @return void
+ */
+ public function testUUIDGeneration() {
+ $result = $this->View->uuid('form', array('controller' => 'posts', 'action' => 'index'));
+ $this->assertEquals('form5988016017', $result);
+ $result = $this->View->uuid('form', array('controller' => 'posts', 'action' => 'index'));
+ $this->assertEquals('formc3dc6be854', $result);
+ $result = $this->View->uuid('form', array('controller' => 'posts', 'action' => 'index'));
+ $this->assertEquals('form28f92cc87f', $result);
+ }
+
+/**
+ * testAddInlineScripts method
+ *
+ * @return void
+ */
+ public function testAddInlineScripts() {
+ $View = new TestView($this->Controller);
+ $View->addScript('prototype.js');
+ $View->addScript('prototype.js');
+ $this->assertEquals(array('prototype.js'), $View->scripts());
+
+ $View->addScript('mainEvent', 'Event.observe(window, "load", function() { doSomething(); }, true);');
+ $this->assertEquals(array('prototype.js', 'mainEvent' => 'Event.observe(window, "load", function() { doSomething(); }, true);'), $View->scripts());
+ }
+
+/**
+ * testElement method
+ *
+ * @return void
+ */
+ public function testElement() {
+ $result = $this->View->element('test_element');
+ $this->assertEquals('this is the test element', $result);
+
+ $result = $this->View->element('plugin_element', array(), array('plugin' => 'TestPlugin'));
+ $this->assertEquals('this is the plugin element using params[plugin]', $result);
+
+ $result = $this->View->element('plugin_element', array(), array('plugin' => 'test_plugin'));
+ $this->assertEquals('this is the plugin element using params[plugin]', $result);
+
+ $result = $this->View->element('TestPlugin.plugin_element');
+ $this->assertEquals('this is the plugin element using params[plugin]', $result);
+
+ $result = $this->View->element('test_plugin.plugin_element');
+ $this->assertRegExp('/Not Found:/', $result);
+ $this->assertRegExp('/test_plugin.plugin_element/', $result);
+
+ $this->View->plugin = 'TestPlugin';
+ $result = $this->View->element('test_plugin_element');
+ $this->assertEquals('this is the test set using View::$plugin plugin element', $result);
+
+ $result = $this->View->element('non_existent_element');
+ $this->assertRegExp('/Not Found:/', $result);
+ $this->assertRegExp('/non_existent_element/', $result);
+
+ $result = $this->View->element('TestPlugin.plugin_element', array(), array('plugin' => 'test_plugin'));
+ $this->assertRegExp('/Not Found:/', $result);
+ $this->assertRegExp('/TestPlugin.plugin_element/', $result);
+ }
+
+/**
+ * test that elements can have callbacks
+ *
+ */
+ public function testElementCallbacks() {
+ $this->getMock('HtmlHelper', array(), array($this->View), 'ElementCallbackMockHtmlHelper');
+ $this->View->helpers = array('ElementCallbackMockHtml');
+ $this->View->loadHelpers();
+
+ $this->View->ElementCallbackMockHtml->expects($this->at(0))->method('beforeRender');
+ $this->View->ElementCallbackMockHtml->expects($this->at(1))->method('afterRender');
+
+ $this->View->element('test_element', array(), array('callbacks' => true));
+ $this->mockObjects[] = $this->View->ElementCallbackMockHtml;
+ }
+
+/**
+ * test that additional element viewVars don't get overwritten with helpers.
+ *
+ * @return void
+ */
+ public function testElementParamsDontOverwriteHelpers() {
+ $Controller = new ViewPostsController();
+ $Controller->helpers = array('Form');
+
+ $View = new View($Controller);
+ $result = $View->element('type_check', array('form' => 'string'), array('callbacks' => true));
+ $this->assertEquals('string', $result);
+
+ $View->set('form', 'string');
+ $result = $View->element('type_check', array(), array('callbacks' => true));
+ $this->assertEquals('string', $result);
+ }
+
+/**
+ * testElementCacheHelperNoCache method
+ *
+ * @return void
+ */
+ public function testElementCacheHelperNoCache() {
+ $Controller = new ViewPostsController();
+ $View = new TestView($Controller);
+ $helpers = $View->loadHelpers();
+ $result = $View->element('test_element', array('ram' => 'val', 'test' => array('foo', 'bar')));
+ $this->assertEquals('this is the test element', $result);
+ }
+
+/**
+ * testElementCache method
+ *
+ * @return void
+ */
+ public function testElementCache() {
+ Cache::drop('test_view');
+ Cache::config('test_view', array(
+ 'engine' => 'File',
+ 'duration' => '+1 day',
+ 'path' => CACHE . 'views' . DS,
+ 'prefix' => ''
+ ));
+ Cache::clear(true, 'test_view');
+
+ $View = new TestView($this->PostsController);
+ $View->elementCache = 'test_view';
+
+ $result = $View->element('test_element', array(), array('cache' => true));
+ $expected = 'this is the test element';
+ $this->assertEquals($expected, $result);
+
+ $result = Cache::read('element__test_element_cache', 'test_view');
+ $this->assertEquals($expected, $result);
+
+ $result = $View->element('test_element', array('param' => 'one', 'foo' => 'two'), array('cache' => true));
+ $this->assertEquals($expected, $result);
+
+ $result = Cache::read('element__test_element_cache_param_foo', 'test_view');
+ $this->assertEquals($expected, $result);
+
+ $result = $View->element('test_element', array(
+ 'param' => 'one',
+ 'foo' => 'two'
+ ), array(
+ 'cache' => array('key' => 'custom_key')
+ ));
+ $result = Cache::read('element_custom_key', 'test_view');
+ $this->assertEquals($expected, $result);
+
+ $View->elementCache = 'default';
+ $result = $View->element('test_element', array(
+ 'param' => 'one',
+ 'foo' => 'two'
+ ), array(
+ 'cache' => array('config' => 'test_view'),
+ ));
+ $result = Cache::read('element__test_element_cache_param_foo', 'test_view');
+ $this->assertEquals($expected, $result);
+
+ Cache::clear(true, 'test_view');
+ Cache::drop('test_view');
+ }
+
+/**
+ * test __get allowing access to helpers.
+ *
+ * @return void
+ */
+ public function testMagicGet() {
+ $View = new View($this->PostsController);
+ $View->loadHelper('Html');
+ $this->assertInstanceOf('HtmlHelper', $View->Html);
+ }
+
+/**
+ * test that ctp is used as a fallback file extension for elements
+ *
+ * @return void
+ */
+ public function testElementCtpFallback() {
+ $View = new TestView($this->PostsController);
+ $View->ext = '.missing';
+ $element = 'test_element';
+ $expected = 'this is the test element';
+ $result = $View->element($element);
+
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testLoadHelpers method
+ *
+ * @return void
+ */
+ public function testLoadHelpers() {
+ $View = new View($this->PostsController);
+
+ $View->helpers = array('Html', 'Form');
+ $View->loadHelpers();
+
+ $this->assertInstanceOf('HtmlHelper', $View->Html, 'Object type is wrong.');
+ $this->assertInstanceOf('FormHelper', $View->Form, 'Object type is wrong.');
+ }
+
+/**
+ * test lazy loading helpers
+ *
+ * @return void
+ */
+ public function testLazyLoadHelpers() {
+ $View = new View($this->PostsController);
+
+ $View->helpers = array();
+ $this->assertInstanceOf('HtmlHelper', $View->Html, 'Object type is wrong.');
+ $this->assertInstanceOf('FormHelper', $View->Form, 'Object type is wrong.');
+ }
+
+/**
+ * test the correct triggering of helper callbacks
+ *
+ * @return void
+ */
+ public function testHelperCallbackTriggering() {
+ $View = new View($this->PostsController);
+ $View->helpers = array();
+ $View->Helpers = $this->getMock('HelperCollection', array('trigger'), array($View));
+
+ $View->Helpers->expects($this->at(0))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.beforeRender'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+ $View->Helpers->expects($this->at(1))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.beforeRenderFile'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+
+ $View->Helpers->expects($this->at(2))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.afterRenderFile'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+ $View->Helpers->expects($this->at(3))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.afterRender'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+
+ $View->Helpers->expects($this->at(4))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.beforeLayout'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+
+ $View->Helpers->expects($this->at(5))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.beforeRenderFile'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+
+ $View->Helpers->expects($this->at(6))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.afterRenderFile'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+
+ $View->Helpers->expects($this->at(7))->method('trigger')
+ ->with(
+ $this->logicalAnd(
+ $this->isInstanceOf('CakeEvent'),
+ $this->attributeEqualTo('_name', 'View.afterLayout'),
+ $this->attributeEqualTo('_subject', $View)
+ )
+ );
+
+ $View->render('index');
+ }
+
+/**
+ * testBeforeLayout method
+ *
+ * @return void
+ */
+ public function testBeforeLayout() {
+ $this->PostsController->helpers = array('Session', 'TestAfter', 'Html');
+ $View = new View($this->PostsController);
+ $View->render('index');
+ $this->assertEquals('Valuation', $View->Helpers->TestAfter->property);
+ }
+
+/**
+ * testAfterLayout method
+ *
+ * @return void
+ */
+ public function testAfterLayout() {
+ $this->PostsController->helpers = array('Session', 'TestAfter', 'Html');
+ $this->PostsController->set('variable', 'values');
+
+ $View = new View($this->PostsController);
+ ClassRegistry::addObject('afterView', $View);
+
+ $content = 'This is my view output';
+ $result = $View->renderLayout($content, 'default');
+ $this->assertRegExp('/modified in the afterlife/', $result);
+ $this->assertRegExp('/This is my view output/', $result);
+ }
+
+/**
+ * testRenderLoadHelper method
+ *
+ * @return void
+ */
+ public function testRenderLoadHelper() {
+ $this->PostsController->helpers = array('Session', 'Html', 'Form', 'Number');
+ $View = new TestView($this->PostsController);
+
+ $result = $View->render('index', false);
+ $this->assertEquals('posts index', $result);
+
+ $attached = $View->Helpers->attached();
+ $this->assertEquals(array('Session', 'Html', 'Form', 'Number'), $attached);
+
+ $this->PostsController->helpers = array('Html', 'Form', 'Number', 'TestPlugin.PluggedHelper');
+ $View = new TestView($this->PostsController);
+
+ $result = $View->render('index', false);
+ $this->assertEquals('posts index', $result);
+
+ $attached = $View->Helpers->attached();
+ $expected = array('Html', 'Form', 'Number', 'PluggedHelper');
+ $this->assertEquals($expected, $attached, 'Attached helpers are wrong.');
+ }
+
+/**
+ * testRender method
+ *
+ * @return void
+ */
+ public function testRender() {
+ $View = new TestView($this->PostsController);
+ $result = $View->render('index');
+
+ $this->assertRegExp("/<meta http-equiv=\"Content-Type\" content=\"text\/html; charset=utf-8\" \/>\s*<title>/", $result);
+ $this->assertRegExp("/<div id=\"content\">\s*posts index\s*<\/div>/", $result);
+ $this->assertRegExp("/<div id=\"content\">\s*posts index\s*<\/div>/", $result);
+
+ $this->assertTrue(isset($View->viewVars['content_for_layout']), 'content_for_layout should be a view var');
+ $this->assertTrue(isset($View->viewVars['scripts_for_layout']), 'scripts_for_layout should be a view var');
+
+ $this->PostsController->set('url', 'flash');
+ $this->PostsController->set('message', 'yo what up');
+ $this->PostsController->set('pause', 3);
+ $this->PostsController->set('page_title', 'yo what up');
+
+ $View = new TestView($this->PostsController);
+ $result = $View->render(false, 'flash');
+
+ $this->assertRegExp("/<title>yo what up<\/title>/", $result);
+ $this->assertRegExp("/<p><a href=\"flash\">yo what up<\/a><\/p>/", $result);
+
+ $this->assertTrue($View->render(false, 'flash'));
+
+ $this->PostsController->helpers = array('Session', 'Cache', 'Html');
+ $this->PostsController->constructClasses();
+ $this->PostsController->cacheAction = array('index' => 3600);
+ $this->PostsController->request->params['action'] = 'index';
+ Configure::write('Cache.check', true);
+
+ $View = new TestView($this->PostsController);
+ $result = $View->render('index');
+
+ $this->assertRegExp("/<meta http-equiv=\"Content-Type\" content=\"text\/html; charset=utf-8\" \/>\s*<title>/", $result);
+ $this->assertRegExp("/<div id=\"content\">\s*posts index\s*<\/div>/", $result);
+ $this->assertRegExp("/<div id=\"content\">\s*posts index\s*<\/div>/", $result);
+ }
+
+/**
+ * test that View::$view works
+ *
+ * @return void
+ */
+ public function testRenderUsingViewProperty() {
+ $this->PostsController->view = 'cache_form';
+ $View = new TestView($this->PostsController);
+
+ $this->assertEquals('cache_form', $View->view);
+ $result = $View->render();
+ $this->assertRegExp('/Add User/', $result);
+ }
+
+/**
+ * Test render()ing a file in a subdir from a custom viewPath
+ * in a plugin.
+ *
+ * @return void
+ */
+ public function testGetViewFileNameSubdirWithPluginAndViewPath() {
+ $this->PostsController->plugin = 'TestPlugin';
+ $this->PostsController->viewPath = 'Elements';
+ $this->PostsController->name = 'Posts';
+ $View = new TestView($this->PostsController);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS . 'TestPlugin' .
+ DS . 'View' . DS . 'Elements' . DS . 'sub_dir' . DS . 'sub_element.ctp';
+ $this->assertEquals($expected, $View->getViewFileName('sub_dir/sub_element'));
+ }
+
+/**
+ * test that view vars can replace the local helper variables
+ * and not overwrite the $this->Helper references
+ *
+ * @return void
+ */
+ public function testViewVarOverwritingLocalHelperVar() {
+ $Controller = new ViewPostsController();
+ $Controller->helpers = array('Session', 'Html');
+ $Controller->set('html', 'I am some test html');
+ $View = new View($Controller);
+ $result = $View->render('helper_overwrite', false);
+
+ $this->assertRegExp('/I am some test html/', $result);
+ $this->assertRegExp('/Test link/', $result);
+ }
+
+/**
+ * testGetViewFileName method
+ *
+ * @return void
+ */
+ public function testViewFileName() {
+ $View = new TestView($this->PostsController);
+
+ $result = $View->getViewFileName('index');
+ $this->assertRegExp('/Posts(\/|\\\)index.ctp/', $result);
+
+ $result = $View->getViewFileName('TestPlugin.index');
+ $this->assertRegExp('/Posts(\/|\\\)index.ctp/', $result);
+
+ $result = $View->getViewFileName('/Pages/home');
+ $this->assertRegExp('/Pages(\/|\\\)home.ctp/', $result);
+
+ $result = $View->getViewFileName('../Elements/test_element');
+ $this->assertRegExp('/Elements(\/|\\\)test_element.ctp/', $result);
+
+ $result = $View->getViewFileName('../Themed/TestTheme/Posts/index');
+ $this->assertRegExp('/Themed(\/|\\\)TestTheme(\/|\\\)Posts(\/|\\\)index.ctp/', $result);
+
+ $expected = CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS . 'Posts' . DS . 'index.ctp';
+ $result = $View->getViewFileName('../Posts/index');
+ $this->assertEquals($expected, $result);
+ }
+
+/**
+ * testRenderCache method
+ *
+ * @return void
+ */
+ public function testRenderCache() {
+ $this->skipIf(!is_writable(CACHE . 'views' . DS), 'CACHE/views dir is not writable, cannot test renderCache.');
+
+ $view = 'test_view';
+ $View = new View($this->PostsController);
+ $path = CACHE . 'views' . DS . 'view_cache_' . $view;
+
+ $cacheText = '<!--cachetime:' . time() . '-->some cacheText';
+ $f = fopen($path, 'w+');
+ fwrite($f, $cacheText);
+ fclose($f);
+
+ $result = $View->renderCache($path, '+1 second');
+ $this->assertFalse($result);
+ if (file_exists($path)) {
+ unlink($path);
+ }
+
+ $cacheText = '<!--cachetime:' . (time() + 10) . '-->some cacheText';
+ $f = fopen($path, 'w+');
+ fwrite($f, $cacheText);
+ fclose($f);
+ $result = $View->renderCache($path, '+1 second');
+
+ $this->assertRegExp('/^some cacheText/', $result);
+
+ @unlink($path);
+ }
+
+/**
+ * Test that render() will remove the cake:nocache tags when only the cachehelper is present.
+ *
+ * @return void
+ */
+ public function testRenderStrippingNoCacheTagsOnlyCacheHelper() {
+ Configure::write('Cache.check', false);
+ $View = new View($this->PostsController);
+ $View->set(array('superman' => 'clark', 'variable' => 'var'));
+ $View->helpers = array('Html', 'Form', 'Cache');
+ $View->layout = 'cache_layout';
+ $result = $View->render('index');
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ }
+
+/**
+ * Test that render() will remove the cake:nocache tags when only the Cache.check is true.
+ *
+ * @return void
+ */
+ public function testRenderStrippingNoCacheTagsOnlyCacheCheck() {
+ Configure::write('Cache.check', true);
+ $View = new View($this->PostsController);
+ $View->set(array('superman' => 'clark', 'variable' => 'var'));
+ $View->helpers = array('Html', 'Form');
+ $View->layout = 'cache_layout';
+ $result = $View->render('index');
+ $this->assertNotRegExp('/cake:nocache/', $result);
+ }
+
+/**
+ * testSet method
+ *
+ * @return void
+ */
+ public function testSet() {
+ $View = new TestView($this->PostsController);
+ $View->viewVars = array();
+ $View->set('somekey', 'someValue');
+ $this->assertSame($View->viewVars, array('somekey' => 'someValue'));
+ $this->assertSame($View->getVars(), array('somekey'));
+
+ $View->viewVars = array();
+ $keys = array('key1', 'key2');
+ $values = array('value1', 'value2');
+ $View->set($keys, $values);
+ $this->assertSame($View->viewVars, array('key1' => 'value1', 'key2' => 'value2'));
+ $this->assertSame($View->getVars(), array('key1', 'key2'));
+ $this->assertSame($View->getVar('key1'), 'value1');
+ $this->assertNull($View->getVar('key3'));
+
+ $View->set(array('key3' => 'value3'));
+ $this->assertSame($View->getVar('key3'), 'value3');
+
+ $View->viewVars = array();
+ $View->set(array(3 => 'three', 4 => 'four'));
+ $View->set(array(1 => 'one', 2 => 'two'));
+ $expected = array(3 => 'three', 4 => 'four', 1 => 'one', 2 => 'two');
+ $this->assertEquals($expected, $View->viewVars);
+ }
+
+/**
+ * testBadExt method
+ *
+ * @expectedException MissingViewException
+ * @return void
+ */
+ public function testBadExt() {
+ $this->PostsController->action = 'something';
+ $this->PostsController->ext = '.whatever';
+
+ $View = new TestView($this->PostsController);
+ $View->render('this_is_missing');
+ }
+
+/**
+ * testAltExt method
+ *
+ * @return void
+ */
+ public function testAltExt() {
+ $this->PostsController->ext = '.alt';
+ $View = new TestView($this->PostsController);
+ $result = $View->render('alt_ext', false);
+ $this->assertEquals('alt ext', $result);
+ }
+
+/**
+ * testAltBadExt method
+ *
+ * @expectedException MissingViewException
+ * @return void
+ */
+ public function testAltBadExt() {
+ $View = new TestView($this->PostsController);
+ $View->render('alt_ext');
+ }
+
+/**
+ * Test creating a block with capturing output.
+ *
+ * @return void
+ */
+ public function testBlockCapture() {
+ $this->View->start('test');
+ echo 'Block content';
+ $this->View->end();
+
+ $result = $this->View->fetch('test');
+ $this->assertEquals('Block content', $result);
+ }
+
+/**
+ * Test appending to a block with capturing output.
+ *
+ * @return void
+ */
+ public function testBlockCaptureAppend() {
+ $this->View->start('test');
+ echo 'Block';
+ $this->View->end();
+
+ $this->View->append('test');
+ echo ' content';
+ $this->View->end();
+
+ $result = $this->View->fetch('test');
+ $this->assertEquals('Block content', $result);
+ }
+
+/**
+ * Test setting a block's content.
+ *
+ * @return void
+ */
+ public function testBlockSet() {
+ $this->View->assign('test', 'Block content');
+ $result = $this->View->fetch('test');
+ $this->assertEquals('Block content', $result);
+ }
+
+/**
+ * Test appending to a block with append.
+ *
+ * @return void
+ */
+ public function testBlockAppend() {
+ $this->View->assign('test', 'Block');
+ $this->View->append('test', ' content');
+
+ $result = $this->View->fetch('test');
+ $this->assertEquals('Block content', $result);
+ }
+
+/**
+ * You should be able to append to undefined blocks.
+ *
+ * @return void
+ */
+ public function testBlockAppendUndefined() {
+ $this->View->append('test', 'Unknown');
+ $result = $this->View->fetch('test');
+ $this->assertEquals('Unknown', $result);
+ }
+
+/**
+ * setting an array should cause an exception.
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testBlockSetArrayException() {
+ $this->View->assign('test', array(1, 2, 3));
+ }
+
+/**
+ * Appending an array should cause an exception.
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testBlockAppendArrayException() {
+ $this->View->append('test', array(1, 2, 3));
+ }
+
+/**
+ * Test getting block names
+ *
+ * @return void
+ */
+ public function testBlocks() {
+ $this->View->append('test', 'one');
+ $this->View->assign('test1', 'one');
+
+ $this->assertEquals(array('test', 'test1'), $this->View->blocks());
+ }
+
+/**
+ * Test that blocks can be nested.
+ *
+ * @return void
+ */
+ public function testNestedBlocks() {
+ $this->View->start('first');
+ echo 'In first ';
+ $this->View->start('second');
+ echo 'In second';
+ $this->View->end();
+ echo 'In first';
+ $this->View->end();
+
+ $this->assertEquals('In first In first', $this->View->fetch('first'));
+ $this->assertEquals('In second', $this->View->fetch('second'));
+ }
+
+/**
+ * Test that an exception gets thrown when you leave a block open at the end
+ * of a view.
+ *
+ * @expectedException CakeException
+ * @return void
+ */
+ public function testExceptionOnOpenBlock() {
+ $this->View->render('open_block');
+ }
+
+/**
+ * Test nested extended views.
+ *
+ * @return void
+ */
+ public function testExtendNested() {
+ $this->View->layout = false;
+ $content = $this->View->render('nested_extends');
+ $expected = <<<TEXT
+This is the second parent.
+This is the first parent.
+This is the first template.
+Sidebar Content.
+TEXT;
+ $this->assertEquals($expected, $content);
+ }
+
+/**
+ * Make sure that extending the current view with itself causes an exception
+ *
+ * @expectedException LogicException
+ * @return void
+ */
+ public function testExtendSelf() {
+ $this->View->layout = false;
+ $this->View->render('extend_self');
+ }
+
+/**
+ * Make sure that extending in a loop causes an exception
+ *
+ * @expectedException LogicException
+ * @return void
+ */
+ public function testExtendLoop() {
+ $this->View->layout = false;
+ $this->View->render('extend_loop');
+ }
+
+/**
+ * Test extend() in an element and a view.
+ *
+ * @return void
+ */
+ public function testExtendElement() {
+ $this->View->layout = false;
+ $content = $this->View->render('extend_element');
+ $expected = <<<TEXT
+Parent View.
+View content.
+Parent Element.
+Element content.
+
+TEXT;
+ $this->assertEquals($expected, $content);
+ }
+
+/**
+ * Extending an element which doesn't exist should throw a missing view exception
+ *
+ * @expectedException LogicException
+ * @return void
+ */
+ public function testExtendMissingElement() {
+ $this->View->layout = false;
+ $this->View->render('extend_missing_element');
+ }
+
+/**
+ * Test that setting arbitrary properties still works.
+ *
+ * @return void
+ */
+ public function testPropertySetting() {
+ $this->assertFalse(isset($this->View->pageTitle));
+ $this->View->pageTitle = 'test';
+ $this->assertTrue(isset($this->View->pageTitle));
+ $this->assertTrue(!empty($this->View->pageTitle));
+ $this->assertEquals('test', $this->View->pageTitle);
+ }
+
+/**
+ * Test that setting arbitrary properties still works.
+ *
+ * @return void
+ */
+ public function testPropertySettingMagicGet() {
+ $this->assertFalse(isset($this->View->action));
+ $this->View->request->params['action'] = 'login';
+ $this->assertEquals('login', $this->View->action);
+ $this->assertTrue(isset($this->View->action));
+ $this->assertTrue(!empty($this->View->action));
+ }
+
+/**
+ * test memory leaks that existed in _paths at one point.
+ *
+ * @return void
+ */
+ public function testMemoryLeakInPaths() {
+ $this->ThemeController->plugin = null;
+ $this->ThemeController->name = 'Posts';
+ $this->ThemeController->viewPath = 'posts';
+ $this->ThemeController->layout = 'whatever';
+ $this->ThemeController->theme = 'TestTheme';
+
+ $View = new View($this->ThemeController);
+ $View->element('test_element');
+
+ $start = memory_get_usage();
+ for ($i = 0; $i < 10; $i++) {
+ $View->element('test_element');
+ }
+ $end = memory_get_usage();
+ $this->assertLessThanOrEqual($start + 5000, $end);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/XmlViewTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/XmlViewTest.php
new file mode 100644
index 0000000..44582e7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Case/View/XmlViewTest.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * XmlViewTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Case.View
+ * @since CakePHP(tm) v 2.1.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+App::uses('XmlView', 'View');
+
+/**
+ * XmlViewTest
+ *
+ * @package Cake.Test.Case.View
+ */
+class XmlViewTest extends CakeTestCase {
+
+/**
+ * testRenderWithoutView method
+ *
+ * @return void
+ */
+ public function testRenderWithoutView() {
+ $Request = new CakeRequest();
+ $Response = new CakeResponse();
+ $Controller = new Controller($Request, $Response);
+ $data = array('users' => array('user' => array('user1', 'user2')));
+ $Controller->set(array('users' => $data, '_serialize' => 'users'));
+ $View = new XmlView($Controller);
+ $output = $View->render(false);
+
+ $this->assertSame(Xml::build($data)->asXML(), $output);
+ $this->assertSame('application/xml', $Response->type());
+
+ $data = array(
+ array(
+ 'User' => array(
+ 'username' => 'user1'
+ )
+ ),
+ array(
+ 'User' => array(
+ 'username' => 'user2'
+ )
+ )
+ );
+ $Controller->set(array('users' => $data, '_serialize' => 'users'));
+ $View = new XmlView($Controller);
+ $output = $View->render(false);
+
+ $expected = Xml::build(array('response' => array('users' => $data)))->asXML();
+ $this->assertSame($expected, $output);
+ }
+
+/**
+ * Test render with an array in _serialize
+ *
+ * @return void
+ */
+ public function testRenderWithoutViewMultiple() {
+ $Request = new CakeRequest();
+ $Response = new CakeResponse();
+ $Controller = new Controller($Request, $Response);
+ $data = array('no' => 'nope', 'user' => 'fake', 'list' => array('item1', 'item2'));
+ $Controller->set($data);
+ $Controller->set('_serialize', array('no', 'user'));
+ $View = new XmlView($Controller);
+ $output = $View->render(false);
+
+ $expected = array(
+ 'response' => array('no' => $data['no'], 'user' => $data['user'])
+ );
+ $this->assertSame(Xml::build($expected)->asXML(), $output);
+ $this->assertSame('application/xml', $Response->type());
+ }
+
+/**
+ * testRenderWithView method
+ *
+ * @return void
+ */
+ public function testRenderWithView() {
+ App::build(array('View' => array(
+ CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
+ )));
+ $Request = new CakeRequest();
+ $Response = new CakeResponse();
+ $Controller = new Controller($Request, $Response);
+ $Controller->name = $Controller->viewPath = 'Posts';
+
+ $data = array(
+ array(
+ 'User' => array(
+ 'username' => 'user1'
+ )
+ ),
+ array(
+ 'User' => array(
+ 'username' => 'user2'
+ )
+ )
+ );
+ $Controller->set('users', $data);
+ $View = new XmlView($Controller);
+ $output = $View->render('index');
+
+ $expected = array(
+ 'users' => array('user' => array('user1', 'user2'))
+ );
+ $expected = Xml::build($expected)->asXML();
+ $this->assertSame($expected, $output);
+ $this->assertSame('application/xml', $Response->type());
+ $this->assertInstanceOf('HelperCollection', $View->Helpers);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AccountFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AccountFixture.php
new file mode 100644
index 0000000..f461933
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AccountFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AccountFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Aco'
+ */
+ public $name = 'Account';
+
+ public $table = 'Accounts';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'iAccountId' => array('type' => 'integer', 'key' => 'primary'),
+ 'cDescription' => array('type' => 'string', 'length' => 10, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('cDescription' => 'gwoo'),
+ array('cDescription' => 'phpnut'),
+ array('cDescription' => 'schreck'),
+ array('cDescription' => 'dude')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoActionFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoActionFixture.php
new file mode 100644
index 0000000..df1bd22
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoActionFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AcoActionFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'AcoAction'
+ */
+ public $name = 'AcoAction';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'model' => array('type' => 'string', 'default' => ''),
+ 'foreign_key' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'alias' => array('type' => 'string', 'default' => ''),
+ 'lft' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'rght' => array('type' => 'integer', 'length' => 10, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoFixture.php
new file mode 100644
index 0000000..d80d3dd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoFixture.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AcoFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Aco'
+ */
+ public $name = 'Aco';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'alias' => array('type' => 'string', 'default' => ''),
+ 'lft' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'rght' => array('type' => 'integer', 'length' => 10, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'ROOT', 'lft' => 1, 'rght' => 24),
+ array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Controller1', 'lft' => 2, 'rght' => 9),
+ array('parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'action1', 'lft' => 3, 'rght' => 6),
+ array('parent_id' => 3, 'model' => null, 'foreign_key' => null, 'alias' => 'record1', 'lft' => 4, 'rght' => 5),
+ array('parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'action2', 'lft' => 7, 'rght' => 8),
+ array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Controller2', 'lft' => 10, 'rght' => 17),
+ array('parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'action1', 'lft' => 11, 'rght' => 14),
+ array('parent_id' => 7, 'model' => null, 'foreign_key' => null, 'alias' => 'record1', 'lft' => 12, 'rght' => 13),
+ array('parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'action2', 'lft' => 15, 'rght' => 16),
+ array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'Users', 'lft' => 18, 'rght' => 23),
+ array('parent_id' => 9, 'model' => null, 'foreign_key' => null, 'alias' => 'Users', 'lft' => 19, 'rght' => 22),
+ array('parent_id' => 10, 'model' => null, 'foreign_key' => null, 'alias' => 'view', 'lft' => 20, 'rght' => 21),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoTwoFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoTwoFixture.php
new file mode 100644
index 0000000..af399fa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AcoTwoFixture.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AcoTwoFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'AcoTwo'
+ */
+ public $name = 'AcoTwo';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'alias' => array('type' => 'string', 'default' => ''),
+ 'lft' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'rght' => array('type' => 'integer', 'length' => 10, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'ROOT', 'lft' => 1, 'rght' => 20),
+ array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'tpsReports','lft' => 2, 'rght' => 9),
+ array('parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'view', 'lft' => 3, 'rght' => 6),
+ array('parent_id' => 3, 'model' => null, 'foreign_key' => null, 'alias' => 'current', 'lft' => 4, 'rght' => 5),
+ array('parent_id' => 2, 'model' => null, 'foreign_key' => null, 'alias' => 'update', 'lft' => 7, 'rght' => 8),
+ array('parent_id' => 1, 'model' => null, 'foreign_key' => null, 'alias' => 'printers', 'lft' => 10, 'rght' => 19),
+ array('parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'print', 'lft' => 11, 'rght' => 14),
+ array('parent_id' => 7, 'model' => null, 'foreign_key' => null, 'alias' => 'lettersize','lft' => 12, 'rght' => 13),
+ array('parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'refill', 'lft' => 15, 'rght' => 16),
+ array('parent_id' => 6, 'model' => null, 'foreign_key' => null, 'alias' => 'smash', 'lft' => 17, 'rght' => 18),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdFixture.php
new file mode 100644
index 0000000..d7100c8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdFixture.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Short description for ad_fixture.php
+ *
+ * Long description for ad_fixture.php
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * @link http://www.cakephp.org
+ * @package Cake.Test.Fixture
+ * @since 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AdFixture class
+ *
+ * @package Cake.Test.Fixture
+ */
+class AdFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Ad'
+ */
+ public $name = 'Ad';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'campaign_id' => array('type' => 'integer'),
+ 'parent_id' => array('type' => 'integer'),
+ 'lft' => array('type' => 'integer'),
+ 'rght' => array('type' => 'integer'),
+ 'name' => array('type' => 'string', 'length' => 255, 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => null, 'lft' => 1, 'rght' => 2, 'campaign_id' => 1, 'name' => 'Nordover'),
+ array('parent_id' => null, 'lft' => 3, 'rght' => 4, 'campaign_id' => 1, 'name' => 'Statbergen'),
+ array('parent_id' => null, 'lft' => 5, 'rght' => 6, 'campaign_id' => 1, 'name' => 'Feroy'),
+ array('parent_id' => null, 'lft' => 7, 'rght' => 12, 'campaign_id' => 2, 'name' => 'Newcastle'),
+ array('parent_id' => null, 'lft' => 8, 'rght' => 9, 'campaign_id' => 2, 'name' => 'Dublin'),
+ array('parent_id' => null, 'lft' => 10, 'rght' => 11, 'campaign_id' => 2, 'name' => 'Alborg'),
+ array('parent_id' => null, 'lft' => 13, 'rght' => 14, 'campaign_id' => 3, 'name' => 'New York')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdvertisementFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdvertisementFixture.php
new file mode 100644
index 0000000..3d4f7cb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AdvertisementFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AdvertisementFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Advertisement'
+ */
+ public $name = 'Advertisement';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('title' => 'First Ad', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('title' => 'Second Ad', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AfterTreeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AfterTreeFixture.php
new file mode 100644
index 0000000..32766c9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AfterTreeFixture.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Short description for after_tree_fixture.php
+ *
+ * Long description for after_tree_fixture.php
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * @link http://www.cakephp.org
+ * @package Cake.Test.Fixture
+ * @since 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * AdFixture class
+ *
+ * @package Cake.Test.Fixture
+ */
+class AfterTreeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'AfterTree'
+ */
+ public $name = 'AfterTree';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer'),
+ 'lft' => array('type' => 'integer'),
+ 'rght' => array('type' => 'integer'),
+ 'name' => array('type' => 'string', 'length' => 255, 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => null, 'lft' => 1, 'rght' => 2, 'name' => 'One'),
+ array('parent_id' => null, 'lft' => 3, 'rght' => 4, 'name' => 'Two'),
+ array('parent_id' => null, 'lft' => 5, 'rght' => 6, 'name' => 'Three'),
+ array('parent_id' => null, 'lft' => 7, 'rght' => 12, 'name' => 'Four'),
+ array('parent_id' => null, 'lft' => 8, 'rght' => 9, 'name' => 'Five'),
+ array('parent_id' => null, 'lft' => 10, 'rght' => 11, 'name' => 'Six'),
+ array('parent_id' => null, 'lft' => 13, 'rght' => 14, 'name' => 'Seven')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AnotherArticleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AnotherArticleFixture.php
new file mode 100644
index 0000000..f580b20
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AnotherArticleFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AnotherArticleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'AnotherArticle'
+ */
+ public $name = 'AnotherArticle';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('title' => 'First Article', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('title' => 'Second Article', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('title' => 'Third Article', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AppleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AppleFixture.php
new file mode 100644
index 0000000..a63da6b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AppleFixture.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AppleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Apple'
+ */
+ public $name = 'Apple';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'apple_id' => array('type' => 'integer', 'null' => true),
+ 'color' => array('type' => 'string', 'length' => 40, 'null' => false),
+ 'name' => array('type' => 'string', 'length' => 40, 'null' => false),
+ 'created' => 'datetime',
+ 'date' => 'date',
+ 'modified' => 'datetime',
+ 'mytime' => 'time'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('apple_id' => 2, 'color' => 'Red 1', 'name' => 'Red Apple 1', 'created' => '2006-11-22 10:38:58', 'date' => '1951-01-04', 'modified' => '2006-12-01 13:31:26', 'mytime' => '22:57:17'),
+ array('apple_id' => 1, 'color' => 'Bright Red 1', 'name' => 'Bright Red Apple', 'created' => '2006-11-22 10:43:13', 'date' => '2014-01-01', 'modified' => '2006-11-30 18:38:10', 'mytime' => '22:57:17'),
+ array('apple_id' => 2, 'color' => 'blue green', 'name' => 'green blue', 'created' => '2006-12-25 05:13:36', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:24', 'mytime' => '22:57:17'),
+ array('apple_id' => 2, 'color' => 'Blue Green', 'name' => 'Test Name', 'created' => '2006-12-25 05:23:36', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:23:36', 'mytime' => '22:57:17'),
+ array('apple_id' => 5, 'color' => 'Green', 'name' => 'Blue Green', 'created' => '2006-12-25 05:24:06', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:16', 'mytime' => '22:57:17'),
+ array('apple_id' => 4, 'color' => 'My new appleOrange', 'name' => 'My new apple', 'created' => '2006-12-25 05:29:39', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:29:39', 'mytime' => '22:57:17'),
+ array('apple_id' => 6, 'color' => 'Some wierd color', 'name' => 'Some odd color', 'created' => '2006-12-25 05:34:21', 'date' => '2006-12-25', 'modified' => '2006-12-25 05:34:21', 'mytime' => '22:57:17')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorFixture.php
new file mode 100644
index 0000000..135087d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorFixture.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArmorFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Armor'
+ */
+ public $name = 'Armor';
+
+/**
+ * Datasource
+ *
+ * Used for Multi database fixture test
+ *
+ * @var string 'test2'
+ */
+ public $useDbConfig = 'test2';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Leather', 'created' => '2007-03-17 01:16:23'),
+ array('name' => 'Chainmail', 'created' => '2007-03-17 01:18:23'),
+ array('name' => 'Cloak', 'created' => '2007-03-17 01:20:23'),
+ array('name' => 'Bikini', 'created' => '2007-03-17 01:22:23'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorsPlayerFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorsPlayerFixture.php
new file mode 100644
index 0000000..bdd71c5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArmorsPlayerFixture.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArmorsPlayerFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ArmorsPlayer'
+ */
+ public $name = 'ArmorsPlayer';
+
+/**
+ * Datasource
+ *
+ * Used for Multi database fixture test
+ *
+ * @var string 'test_database_three'
+ */
+ public $useDbConfig = 'test_database_three';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'player_id' => array('type' => 'integer', 'null' => false),
+ 'armor_id' => array('type' => 'integer', 'null' => false),
+ 'broken' => array('type' => 'boolean', 'null' => false, 'default' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('player_id' => 1, 'armor_id' => 1, 'broken' => false),
+ array('player_id' => 2, 'armor_id' => 2, 'broken' => false),
+ array('player_id' => 3, 'armor_id' => 3, 'broken' => false),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroFixture.php
new file mode 100644
index 0000000..6d63c4d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroFixture.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AroFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Aro'
+ */
+ public $name = 'Aro';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'alias' => array('type' => 'string', 'default' => ''),
+ 'lft' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'rght' => array('type' => 'integer', 'length' => 10, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'ROOT', 'lft' => 1, 'rght' => 8),
+ array('parent_id' => '1', 'model' => 'Group', 'foreign_key' => '1', 'alias' => 'admins', 'lft' => 2, 'rght' => 7),
+ array('parent_id' => '2', 'model' => 'AuthUser', 'foreign_key' => '1', 'alias' => 'Gandalf', 'lft' => 3, 'rght' => 4),
+ array('parent_id' => '2', 'model' => 'AuthUser', 'foreign_key' => '2', 'alias' => 'Elrond', 'lft' => 5, 'rght' => 6)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroTwoFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroTwoFixture.php
new file mode 100644
index 0000000..306567a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AroTwoFixture.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AroTwoFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'AroTwo'
+ */
+ public $name = 'AroTwo';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'alias' => array('type' => 'string', 'default' => ''),
+ 'lft' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'rght' => array('type' => 'integer', 'length' => 10, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => null, 'model' => null, 'foreign_key' => null, 'alias' => 'root', 'lft' => '1', 'rght' => '20'),
+ array('parent_id' => 1, 'model' => 'Group', 'foreign_key' => '1', 'alias' => 'admin', 'lft' => '2', 'rght' => '5'),
+ array('parent_id' => 1, 'model' => 'Group', 'foreign_key' => '2', 'alias' => 'managers', 'lft' => '6', 'rght' => '9'),
+ array('parent_id' => 1, 'model' => 'Group', 'foreign_key' => '3', 'alias' => 'users', 'lft' => '10', 'rght' => '19'),
+ array('parent_id' => 2, 'model' => 'User', 'foreign_key' => '1', 'alias' => 'Bobs', 'lft' => '3', 'rght' => '4'),
+ array('parent_id' => 3, 'model' => 'User', 'foreign_key' => '2', 'alias' => 'Lumbergh', 'lft' => '7' , 'rght' => '8'),
+ array('parent_id' => 4, 'model' => 'User', 'foreign_key' => '3', 'alias' => 'Samir', 'lft' => '11' , 'rght' => '12'),
+ array('parent_id' => 4, 'model' => 'User', 'foreign_key' => '4', 'alias' => 'Micheal', 'lft' => '13', 'rght' => '14'),
+ array('parent_id' => 4, 'model' => 'User', 'foreign_key' => '5', 'alias' => 'Peter', 'lft' => '15', 'rght' => '16'),
+ array('parent_id' => 4, 'model' => 'User', 'foreign_key' => '6', 'alias' => 'Milton', 'lft' => '17', 'rght' => '18'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoFixture.php
new file mode 100644
index 0000000..0f2ec84
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArosAcoFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ArosAco'
+ */
+ public $name = 'ArosAco';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'aro_id' => array('type' => 'integer', 'length' => 10, 'null' => false),
+ 'aco_id' => array('type' => 'integer', 'length' => 10, 'null' => false),
+ '_create' => array('type' => 'string', 'length' => 2, 'default' => 0),
+ '_read' => array('type' => 'string', 'length' => 2, 'default' => 0),
+ '_update' => array('type' => 'string', 'length' => 2, 'default' => 0),
+ '_delete' => array('type' => 'string', 'length' => 2, 'default' => 0)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoTwoFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoTwoFixture.php
new file mode 100644
index 0000000..e852287
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArosAcoTwoFixture.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArosAcoTwoFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ArosAcoTwo'
+ */
+ public $name = 'ArosAcoTwo';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'aro_id' => array('type' => 'integer', 'length' => 10, 'null' => false),
+ 'aco_id' => array('type' => 'integer', 'length' => 10, 'null' => false),
+ '_create' => array('type' => 'string', 'length' => 2, 'default' => 0),
+ '_read' => array('type' => 'string', 'length' => 2, 'default' => 0),
+ '_update' => array('type' => 'string', 'length' => 2, 'default' => 0),
+ '_delete' => array('type' => 'string', 'length' => 2, 'default' => 0)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('aro_id' => '1', 'aco_id' => '1', '_create' => '-1', '_read' => '-1', '_update' => '-1', '_delete' => '-1'),
+ array('aro_id' => '2', 'aco_id' => '1', '_create' => '0', '_read' => '1', '_update' => '1', '_delete' => '1'),
+ array('aro_id' => '3', 'aco_id' => '2', '_create' => '0', '_read' => '1', '_update' => '0', '_delete' => '0'),
+ array('aro_id' => '4', 'aco_id' => '2', '_create' => '1', '_read' => '1', '_update' => '0', '_delete' => '-1'),
+ array('aro_id' => '4', 'aco_id' => '6', '_create' => '1', '_read' => '1', '_update' => '0', '_delete' => '0'),
+ array('aro_id' => '5', 'aco_id' => '1', '_create' => '1', '_read' => '1', '_update' => '1', '_delete' => '1'),
+ array('aro_id' => '6', 'aco_id' => '3', '_create' => '-1', '_read' => '1', '_update' => '-1', '_delete' => '-1'),
+ array('aro_id' => '6', 'aco_id' => '4', '_create' => '-1', '_read' => '1', '_update' => '-1', '_delete' => '1'),
+ array('aro_id' => '6', 'aco_id' => '6', '_create' => '-1', '_read' => '1', '_update' => '1', '_delete' => '-1'),
+ array('aro_id' => '7', 'aco_id' => '2', '_create' => '-1', '_read' => '-1', '_update' => '-1', '_delete' => '-1'),
+ array('aro_id' => '7', 'aco_id' => '7', '_create' => '1', '_read' => '1', '_update' => '1', '_delete' => '0'),
+ array('aro_id' => '7', 'aco_id' => '8', '_create' => '1', '_read' => '1', '_update' => '1', '_delete' => '0'),
+ array('aro_id' => '7', 'aco_id' => '9', '_create' => '1', '_read' => '1', '_update' => '1', '_delete' => '1'),
+ array('aro_id' => '7', 'aco_id' => '10', '_create' => '0', '_read' => '0', '_update' => '0', '_delete' => '1'),
+ array('aro_id' => '8', 'aco_id' => '10', '_create' => '1', '_read' => '1', '_update' => '1', '_delete' => '1'),
+ array('aro_id' => '8', 'aco_id' => '2', '_create' => '-1', '_read' => '-1', '_update' => '-1', '_delete' => '-1'),
+ array('aro_id' => '9', 'aco_id' => '4', '_create' => '1', '_read' => '1', '_update' => '1', '_delete' => '-1'),
+ array('aro_id' => '9', 'aco_id' => '9', '_create' => '0', '_read' => '0', '_update' => '1', '_delete' => '1'),
+ array('aro_id' => '10', 'aco_id' => '9', '_create' => '1', '_read' => '1', '_update' => '1', '_delete' => '1'),
+ array('aro_id' => '10', 'aco_id' => '10', '_create' => '-1', '_read' => '-1', '_update' => '-1', '_delete' => '-1'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedFixture.php
new file mode 100644
index 0000000..52831f4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedFixture.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArticleFeaturedFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ArticleFeatured'
+ */
+ public $name = 'ArticleFeatured';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'body' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedsTagsFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedsTagsFixture.php
new file mode 100644
index 0000000..3ae0acf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFeaturedsTagsFixture.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArticleFeaturedsTagsFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ArticleFeaturedsTags'
+ */
+ public $name = 'ArticleFeaturedsTags';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'article_featured_id' => array('type' => 'integer', 'null' => false),
+ 'tag_id' => array('type' => 'integer', 'null' => false),
+ 'indexes' => array('UNIQUE_FEATURED' => array('column' => array('article_featured_id', 'tag_id'), 'unique' => 1))
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFixture.php
new file mode 100644
index 0000000..617a3ad
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticleFixture.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArticleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Article'
+ */
+ public $name = 'Article';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user_id' => array('type' => 'integer', 'null' => true),
+ 'title' => array('type' => 'string', 'null' => true),
+ 'body' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticlesTagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticlesTagFixture.php
new file mode 100644
index 0000000..37908b5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ArticlesTagFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ArticlesTagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ArticlesTag'
+ */
+ public $name = 'ArticlesTag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'article_id' => array('type' => 'integer', 'null' => false),
+ 'tag_id' => array('type' => 'integer', 'null' => false),
+ 'indexes' => array('UNIQUE_TAG2' => array('column' => array('article_id', 'tag_id'), 'unique' => 1))
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('article_id' => 1, 'tag_id' => 1),
+ array('article_id' => 1, 'tag_id' => 2),
+ array('article_id' => 2, 'tag_id' => 1),
+ array('article_id' => 2, 'tag_id' => 3)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AssertTagsTestCase.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AssertTagsTestCase.php
new file mode 100644
index 0000000..42bebde
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AssertTagsTestCase.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * This class helpes in indirectly testing the functionaliteies of CakeTestCase::assertTags
+ *
+ * @package Cake.Test.Fixture
+ */
+class AssertTagsTestCase extends CakeTestCase {
+
+/**
+ * test that assertTags knows how to handle correct quoting.
+ *
+ * @return void
+ */
+ public function testAssertTagsQuotes() {
+ $input = '<a href="/test.html" class="active">My link</a>';
+ $pattern = array(
+ 'a' => array('href' => '/test.html', 'class' => 'active'),
+ 'My link',
+ '/a'
+ );
+ $this->assertTags($input, $pattern);
+
+ $input = "<a href='/test.html' class='active'>My link</a>";
+ $pattern = array(
+ 'a' => array('href' => '/test.html', 'class' => 'active'),
+ 'My link',
+ '/a'
+ );
+ $this->assertTags($input, $pattern);
+
+ $input = "<a href='/test.html' class='active'>My link</a>";
+ $pattern = array(
+ 'a' => array('href' => 'preg:/.*\.html/', 'class' => 'active'),
+ 'My link',
+ '/a'
+ );
+ $this->assertTags($input, $pattern);
+ }
+
+/**
+ * testNumericValuesInExpectationForAssertTags
+ *
+ * @return void
+ */
+ public function testNumericValuesInExpectationForAssertTags() {
+ $value = 220985;
+
+ $input = '<p><strong>' . $value . '</strong></p>';
+ $pattern = array(
+ '<p',
+ '<strong',
+ $value,
+ '/strong',
+ '/p'
+ );
+ $this->assertTags($input, $pattern);
+
+ $input = '<p><strong>' . $value . '</strong></p><p><strong>' . $value . '</strong></p>';
+ $pattern = array(
+ '<p',
+ '<strong',
+ $value,
+ '/strong',
+ '/p',
+ '<p',
+ '<strong',
+ $value,
+ '/strong',
+ '/p',
+ );
+ $this->assertTags($input, $pattern);
+
+ $input = '<p><strong>' . $value . '</strong></p><p id="' . $value . '"><strong>' . $value . '</strong></p>';
+ $pattern = array(
+ '<p',
+ '<strong',
+ $value,
+ '/strong',
+ '/p',
+ 'p' => array('id' => $value),
+ '<strong',
+ $value,
+ '/strong',
+ '/p',
+ );
+ $this->assertTags($input, $pattern);
+ }
+
+/**
+ * testBadAssertTags
+ *
+ * @return void
+ */
+ public function testBadAssertTags() {
+ $input = '<a href="/test.html" class="active">My link</a>';
+ $pattern = array(
+ 'a' => array('hRef' => '/test.html', 'clAss' => 'active'),
+ 'My link2',
+ '/a'
+ );
+ $this->assertTags($input, $pattern);
+ }
+
+/**
+ * testBadAssertTags
+ *
+ * @return void
+ */
+ public function testBadAssertTags2() {
+ $input = '<a href="/test.html" class="active">My link</a>';
+ $pattern = array(
+ '<a' => array('href' => '/test.html', 'class' => 'active'),
+ 'My link',
+ '/a'
+ );
+ $this->assertTags($input, $pattern);
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AttachmentFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AttachmentFixture.php
new file mode 100644
index 0000000..e322c1a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AttachmentFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AttachmentFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Attachment'
+ */
+ public $name = 'Attachment';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'comment_id' => array('type' => 'integer', 'null' => false),
+ 'attachment' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('comment_id' => 5, 'attachment' => 'attachment.zip', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserCustomFieldFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserCustomFieldFixture.php
new file mode 100644
index 0000000..88ec586
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserCustomFieldFixture.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.1.8013
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AuthUserCustomFieldFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'AuthUser'
+ */
+ public $name = 'AuthUserCustomField';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'email' => array('type' => 'string', 'null' => false),
+ 'password' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('email' => 'mariano@example.com', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('email' => 'nate@example.com', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('email' => 'larry@example.com', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'),
+ array('email' => 'garrett@example.com', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'),
+ array('email' => 'chartjes@example.com', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'),
+
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserFixture.php
new file mode 100644
index 0000000..eab2a39
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthUserFixture.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AuthUserFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'AuthUser'
+ */
+ public $name = 'AuthUser';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'username' => array('type' => 'string', 'null' => false),
+ 'password' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('username' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('username' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('username' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'),
+ array('username' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'),
+ array('username' => 'chartjes', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'),
+
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthorFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthorFixture.php
new file mode 100644
index 0000000..02a191f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/AuthorFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class AuthorFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Author'
+ */
+ public $name = 'Author';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user' => array('type' => 'string', 'default' => null),
+ 'password' => array('type' => 'string', 'default' => null),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'),
+ array('user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticleFixture.php
new file mode 100644
index 0000000..8b322fa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticleFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * BakeArticleFixture
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BakeArticleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string
+ */
+ public $name = 'BakeArticle';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'bake_user_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'body' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticlesBakeTagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticlesBakeTagFixture.php
new file mode 100644
index 0000000..b1351df
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeArticlesBakeTagFixture.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * BakeCommentFixture
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BakeArticlesBakeTagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ArticlesTag'
+ */
+ public $name = 'BakeArticlesBakeTag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'bake_article_id' => array('type' => 'integer', 'null' => false),
+ 'bake_tag_id' => array('type' => 'integer', 'null' => false),
+ 'indexes' => array('UNIQUE_TAG' => array('column' => array('bake_article_id', 'bake_tag_id'), 'unique' => 1))
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeCommentFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeCommentFixture.php
new file mode 100644
index 0000000..6224b10
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeCommentFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * BakeCommentFixture
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * BakeCommentFixture fixture for testing bake
+ *
+ * @package Cake.Test.Fixture
+ */
+class BakeCommentFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Comment'
+ */
+ public $name = 'BakeComment';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'otherid' => array('type' => 'integer', 'key' => 'primary'),
+ 'bake_article_id' => array('type' => 'integer', 'null' => false),
+ 'bake_user_id' => array('type' => 'integer', 'null' => false),
+ 'comment' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeTagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeTagFixture.php
new file mode 100644
index 0000000..8b82879
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BakeTagFixture.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * BakeTagFixture
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BakeTagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Tag'
+ */
+ public $name = 'BakeTag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'tag' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BasketFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BasketFixture.php
new file mode 100644
index 0000000..c709863
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BasketFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BasketFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Basket'
+ */
+ public $name = 'Basket';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'type' => array('type' => 'string', 'length' => 255),
+ 'name' => array('type' => 'string', 'length' => 255),
+ 'object_id' => array('type' => 'integer'),
+ 'user_id' => array('type' => 'integer'),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'type' => 'nonfile', 'name' => 'basket1', 'object_id' => 1, 'user_id' => 1),
+ array('id' => 2, 'type' => 'file', 'name' => 'basket2', 'object_id' => 2, 'user_id' => 1),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BidFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BidFixture.php
new file mode 100644
index 0000000..ef93dff
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BidFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BidFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Bid'
+ */
+ public $name = 'Bid';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'message_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('message_id' => 1, 'name' => 'Bid 1.1'),
+ array('message_id' => 1, 'name' => 'Bid 1.2'),
+ array('message_id' => 3, 'name' => 'Bid 3.1'),
+ array('message_id' => 2, 'name' => 'Bid 2.1'),
+ array('message_id' => 2, 'name' => 'Bid 2.2')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingFixture.php
new file mode 100644
index 0000000..12791a4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.3.14
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BiddingFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Bidding'
+ */
+ public $name = 'Bidding';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'bid' => array('type' => 'string', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('bid' => 'One', 'name' => 'Bid 1'),
+ array('bid' => 'Two', 'name' => 'Bid 2'),
+ array('bid' => 'Three', 'name' => 'Bid 3'),
+ array('bid' => 'Five', 'name' => 'Bid 5')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingMessageFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingMessageFixture.php
new file mode 100644
index 0000000..d19502a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BiddingMessageFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.3.14
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BiddingMessageFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'BiddingMessage'
+ */
+ public $name = 'BiddingMessage';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'bidding' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('bidding' => 'One', 'name' => 'Message 1'),
+ array('bidding' => 'Two', 'name' => 'Message 2'),
+ array('bidding' => 'Three', 'name' => 'Message 3'),
+ array('bidding' => 'Four', 'name' => 'Message 4')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BinaryTestFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BinaryTestFixture.php
new file mode 100644
index 0000000..df0ab66
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BinaryTestFixture.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6700
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BinaryTestFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'BinaryTest'
+ */
+ public $name = 'BinaryTest';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'data' => array('type' => 'binary', 'length' => 300)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BookFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BookFixture.php
new file mode 100644
index 0000000..6cfaf54
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/BookFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7198
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class BookFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Book'
+ */
+ public $name = 'Book';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'isbn' => array('type' => 'string', 'length' => 13),
+ 'title' => array('type' => 'string', 'length' => 255),
+ 'author' => array('type' => 'string', 'length' => 255),
+ 'year' => array('type' => 'integer', 'null' => true),
+ 'pages' => array('type' => 'integer', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'isbn' => '1234567890', 'title' => 'Faust', 'author' => 'Johann Wolfgang von Goethe')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CacheTestModelFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CacheTestModelFixture.php
new file mode 100644
index 0000000..ae6fbb4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CacheTestModelFixture.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CacheTestModelFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'CacheTestModel'
+ */
+ public $name = 'CacheTestModel';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 255, 'key' => 'primary'),
+ 'data' => array('type' => 'string', 'length' => 255, 'default' => ''),
+ 'expires' => array('type' => 'integer', 'length' => 10, 'default' => '0'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CallbackFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CallbackFixture.php
new file mode 100644
index 0000000..b53dd0a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CallbackFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CallbackFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Callback'
+ */
+ public $name = 'Callback';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user' => array('type' => 'string', 'null' => false),
+ 'password' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('user' => 'user1', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('user' => 'user2', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'),
+ array('user' => 'user3', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CampaignFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CampaignFixture.php
new file mode 100644
index 0000000..f737f05
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CampaignFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for campaign_fixture.php
+ *
+ * Long description for campaign_fixture.php
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * @link http://www.cakephp.org
+ * @package Cake.Test.Fixture
+ * @since 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * CampaignFixture class
+ *
+ * @package Cake.Test.Fixture
+ */
+class CampaignFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Campaign'
+ */
+ public $name = 'Campaign';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => 255, 'null' => false),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Hurtigruten'),
+ array('name' => 'Colorline'),
+ array('name' => 'Queen of Scandinavia')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryFixture.php
new file mode 100644
index 0000000..664bcf9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryFixture.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CategoryFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Category'
+ */
+ public $name = 'Category';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => 0, 'name' => 'Category 1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 1, 'name' => 'Category 1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 1, 'name' => 'Category 1.2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 0, 'name' => 'Category 2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 0, 'name' => 'Category 3', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 5, 'name' => 'Category 3.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 2, 'name' => 'Category 1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 2, 'name' => 'Category 1.1.2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryThreadFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryThreadFixture.php
new file mode 100644
index 0000000..d1b2d1f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CategoryThreadFixture.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CategoryThreadFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'CategoryThread'
+ */
+ public $name = 'CategoryThread';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('parent_id' => 0, 'name' => 'Category 1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 1, 'name' => 'Category 1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 2, 'name' => 'Category 1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 3, 'name' => 'Category 1.1.2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 4, 'name' => 'Category 1.1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 5, 'name' => 'Category 2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
+ array('parent_id' => 6, 'name' => 'Category 2.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CdFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CdFixture.php
new file mode 100644
index 0000000..5f93c56
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CdFixture.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7198
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CdFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Cd'
+ */
+ public $name = 'Cd';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'length' => 255),
+ 'artist' => array('type' => 'string', 'length' => 255, 'null' => true),
+ 'genre' => array('type' => 'string', 'length' => 255, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'title' => 'Grace', 'artist' => 'Jeff Buckley', 'genre' => 'awesome')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CommentFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CommentFixture.php
new file mode 100644
index 0000000..71ae13e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CommentFixture.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CommentFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Comment'
+ */
+ public $name = 'Comment';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'article_id' => array('type' => 'integer', 'null' => false),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'comment' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:45:23', 'updated' => '2007-03-18 10:47:31'),
+ array('article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'),
+ array('article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:49:23', 'updated' => '2007-03-18 10:51:31'),
+ array('article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Article', 'published' => 'N', 'created' => '2007-03-18 10:51:23', 'updated' => '2007-03-18 10:53:31'),
+ array('article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:53:23', 'updated' => '2007-03-18 10:55:31'),
+ array('article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Article', 'published' => 'Y', 'created' => '2007-03-18 10:55:23', 'updated' => '2007-03-18 10:57:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentAccountFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentAccountFixture.php
new file mode 100644
index 0000000..aa6e374
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentAccountFixture.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ContentAccountFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Aco'
+ */
+ public $name = 'ContentAccount';
+
+ public $table = 'ContentAccounts';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'iContentAccountsId' => array('type' => 'integer', 'key' => 'primary'),
+ 'iContentId' => array('type' => 'integer'),
+ 'iAccountId' => array('type' => 'integer')
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('iContentId' => 1, 'iAccountId' => 1),
+ array('iContentId' => 2, 'iAccountId' => 2),
+ array('iContentId' => 3, 'iAccountId' => 3),
+ array('iContentId' => 4, 'iAccountId' => 4),
+ array('iContentId' => 1, 'iAccountId' => 2),
+ array('iContentId' => 2, 'iAccountId' => 3),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentFixture.php
new file mode 100644
index 0000000..2ea7d92
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ContentFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ContentFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Aco'
+ */
+ public $name = 'Content';
+
+ public $table = 'Content';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'iContentId' => array('type' => 'integer', 'key' => 'primary'),
+ 'cDescription' => array('type' => 'string', 'length' => 50, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('cDescription' => 'Test Content 1'),
+ array('cDescription' => 'Test Content 2'),
+ array('cDescription' => 'Test Content 3'),
+ array('cDescription' => 'Test Content 4')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostFixture.php
new file mode 100644
index 0000000..0ba496b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostFixture.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Counter Cache Test Fixtures
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CounterCachePostFixture extends CakeTestFixture {
+
+ public $name = 'CounterCachePost';
+
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'length' => 255),
+ 'user_id' => array('type' => 'integer', 'null' => true),
+ 'published' => array('type' => 'boolean', 'null' => false, 'default' => 0)
+ );
+
+ public $records = array(
+ array('id' => 1, 'title' => 'Rock and Roll', 'user_id' => 66, 'published' => false),
+ array('id' => 2, 'title' => 'Music', 'user_id' => 66, 'published' => true),
+ array('id' => 3, 'title' => 'Food', 'user_id' => 301, 'published' => true),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostNonstandardPrimaryKeyFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostNonstandardPrimaryKeyFixture.php
new file mode 100644
index 0000000..911187a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCachePostNonstandardPrimaryKeyFixture.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CounterCachePostNonstandardPrimaryKeyFixture extends CakeTestFixture {
+
+ public $name = 'CounterCachePostNonstandardPrimaryKey';
+
+ public $fields = array(
+ 'pid' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'length' => 255, 'null' => false),
+ 'uid' => array('type' => 'integer', 'null' => true),
+ );
+
+ public $records = array(
+ array('pid' => 1, 'title' => 'Rock and Roll', 'uid' => 66),
+ array('pid' => 2, 'title' => 'Music', 'uid' => 66),
+ array('pid' => 3, 'title' => 'Food', 'uid' => 301),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserFixture.php
new file mode 100644
index 0000000..fd58834
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserFixture.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CounterCacheUserFixture extends CakeTestFixture {
+
+ public $name = 'CounterCacheUser';
+
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => 255, 'null' => false),
+ 'post_count' => array('type' => 'integer', 'null' => true),
+ 'posts_published' => array('type' => 'integer', 'null' => true)
+ );
+
+ public $records = array(
+ array('id' => 66, 'name' => 'Alexander', 'post_count' => 2, 'posts_published' => 1),
+ array('id' => 301, 'name' => 'Steven', 'post_count' => 1, 'posts_published' => 1),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserNonstandardPrimaryKeyFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserNonstandardPrimaryKeyFixture.php
new file mode 100644
index 0000000..74f07f7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/CounterCacheUserNonstandardPrimaryKeyFixture.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class CounterCacheUserNonstandardPrimaryKeyFixture extends CakeTestFixture {
+
+ public $name = 'CounterCacheUserNonstandardPrimaryKey';
+
+ public $fields = array(
+ 'uid' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => 255, 'null' => false),
+ 'post_count' => array('type' => 'integer', 'null' => true)
+ );
+
+ public $records = array(
+ array('uid' => 66, 'name' => 'Alexander', 'post_count' => 2),
+ array('uid' => 301, 'name' => 'Steven', 'post_count' => 1),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DataTestFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DataTestFixture.php
new file mode 100644
index 0000000..cb4937b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DataTestFixture.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6700
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class DataTestFixture extends CakeTestFixture {
+
+/**
+ * Name property
+ *
+ * @var string 'DataTest'
+ */
+ public $name = 'DataTest';
+
+/**
+ * Fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'count' => array('type' => 'integer', 'default' => 0),
+ 'float' => array('type' => 'float', 'default' => 0),
+ 'created' => array('type' => 'datetime', 'default' => null),
+ 'updated' => array('type' => 'datetime', 'default' => null)
+ );
+
+/**
+ * Records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array(
+ 'count' => 2,
+ 'float' => 2.4,
+ 'created' => '2010-09-06 12:28:00',
+ 'updated' => '2010-09-06 12:28:00'
+ )
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DatatypeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DatatypeFixture.php
new file mode 100644
index 0000000..0a9f2e0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DatatypeFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7026
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class DatatypeFixture extends CakeTestFixture {
+
+/**
+ * Name property
+ *
+ * @var string 'Datatype'
+ */
+ public $name = 'Datatype';
+
+/**
+ * Fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
+ 'float_field' => array('type' => 'float', 'length' => '5,2', 'null' => false, 'default' => null),
+ 'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
+ );
+
+/**
+ * Records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'float_field' => 42.23, 'bool' => 0),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DependencyFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DependencyFixture.php
new file mode 100644
index 0000000..e7e750c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DependencyFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6879//Correct version number as needed**
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for file.
+ *
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6879//Correct version number as needed**
+ */
+class DependencyFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Dependency'
+ */
+ public $name = 'Dependency';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'child_id' => 'integer',
+ 'parent_id' => 'integer'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('child_id' => 1, 'parent_id' => 2),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceFixture.php
new file mode 100644
index 0000000..5eb07a1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class DeviceFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Device'
+ */
+ public $name = 'Device';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'device_type_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'typ' => array('type' => 'integer', 'null' => false),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('device_type_id' => 1, 'name' => 'Device 1', 'typ' => 1),
+ array('device_type_id' => 1, 'name' => 'Device 2', 'typ' => 1),
+ array('device_type_id' => 1, 'name' => 'Device 3', 'typ' => 2)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeCategoryFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeCategoryFixture.php
new file mode 100644
index 0000000..fa56f50
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeCategoryFixture.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class DeviceTypeCategoryFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'DeviceTypeCategory'
+ */
+ public $name = 'DeviceTypeCategory';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'DeviceTypeCategory 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeFixture.php
new file mode 100644
index 0000000..a5271dd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DeviceTypeFixture.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class DeviceTypeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'DeviceType'
+ */
+ public $name = 'DeviceType';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'device_type_category_id' => array('type' => 'integer', 'null' => false),
+ 'feature_set_id' => array('type' => 'integer', 'null' => false),
+ 'exterior_type_category_id' => array('type' => 'integer', 'null' => false),
+ 'image_id' => array('type' => 'integer', 'null' => false),
+ 'extra1_id' => array('type' => 'integer', 'null' => false),
+ 'extra2_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'order' => array('type' => 'integer', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('device_type_category_id' => 1, 'feature_set_id' => 1, 'exterior_type_category_id' => 1, 'image_id' => 1, 'extra1_id' => 1, 'extra2_id' => 1, 'name' => 'DeviceType 1', 'order' => 0)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentDirectoryFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentDirectoryFixture.php
new file mode 100644
index 0000000..29bc89c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentDirectoryFixture.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class DocumentDirectoryFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'DocumentDirectory'
+ */
+ public $name = 'DocumentDirectory';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'DocumentDirectory 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentFixture.php
new file mode 100644
index 0000000..94d3960
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DocumentFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class DocumentFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Document'
+ */
+ public $name = 'Document';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'document_directory_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('document_directory_id' => 1, 'name' => 'Document 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainFixture.php
new file mode 100644
index 0000000..87dd35f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainFixture.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package cake
+ * @subpackage cake.tests.fixtures
+ * @since CakePHP(tm) v 2.1
+ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package cake
+ * @subpackage cake.tests.fixtures
+ */
+class DomainFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Domain'
+ * @access public
+ */
+ public $name = 'Domain';
+
+/**
+ * fields property
+ *
+ * @var array
+ * @access public
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'domain' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ * @access public
+ */
+ public $records = array(
+ array('domain' => 'cakephp.org', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('domain' => 'book.cakephp.org', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('domain' => 'api.cakephp.org', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('domain' => 'mark-story.com', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('domain' => 'tinadurocher.com', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('domain' => 'chavik.com', 'created' => '2001-02-03 00:01:02', 'updated' => '2007-03-17 01:22:31'),
+ array('domain' => 'xintesa.com', 'created' => '2001-02-03 00:01:02', 'updated' => '2007-03-17 01:22:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainsSiteFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainsSiteFixture.php
new file mode 100644
index 0000000..8ee1682
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/DomainsSiteFixture.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package cake
+ * @subpackage cake.tests.fixtures
+ * @since CakePHP(tm) v 2.1
+ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package cake
+ * @subpackage cake.tests.fixtures
+ */
+class DomainsSiteFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Domain'
+ * @access public
+ */
+ public $name = 'DomainsSite';
+
+/**
+ * fields property
+ *
+ * @var array
+ * @access public
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'domain_id' => array('type' => 'integer', 'null' => false),
+ 'site_id' => array('type' => 'integer', 'null' => false),
+ 'active' => array('type' => 'boolean', 'null' => false, 'default' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime',
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ * @access public
+ */
+ public $records = array(
+ array('site_id' => 1, 'domain_id' => 1, 'active' => true, 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('site_id' => 1, 'domain_id' => 2, 'active' => true, 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('site_id' => 2, 'domain_id' => 4, 'active' => true, 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('site_id' => 2, 'domain_id' => 5, 'active' => true, 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('site_id' => 3, 'domain_id' => 6, 'active' => true, 'created' => '2001-02-03 00:01:02', 'updated' => '2007-03-17 01:22:31'),
+ array('site_id' => 3, 'domain_id' => 7, 'active' => false, 'created' => '2001-02-03 00:01:02', 'updated' => '2007-03-17 01:22:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ExteriorTypeCategoryFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ExteriorTypeCategoryFixture.php
new file mode 100644
index 0000000..8ab3bbc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ExteriorTypeCategoryFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ExteriorTypeCategoryFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ExteriorTypeCategory'
+ */
+ public $name = 'ExteriorTypeCategory';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'image_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('image_id' => 1, 'name' => 'ExteriorTypeCategory 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeatureSetFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeatureSetFixture.php
new file mode 100644
index 0000000..5892799
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeatureSetFixture.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class FeatureSetFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'FeatureSet'
+ */
+ public $name = 'FeatureSet';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'FeatureSet 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeaturedFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeaturedFixture.php
new file mode 100644
index 0000000..d130373
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FeaturedFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class FeaturedFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Featured'
+ */
+ public $name = 'Featured';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'article_featured_id' => array('type' => 'integer', 'null' => false),
+ 'category_id' => array('type' => 'integer', 'null' => false),
+ 'published_date' => 'datetime',
+ 'end_date' => 'datetime',
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('article_featured_id' => 1, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23', 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('article_featured_id' => 2, 'category_id' => 1, 'published_date' => '2007-03-31 10:39:23', 'end_date' => '2007-05-15 10:39:23', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FilmFileFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FilmFileFixture.php
new file mode 100644
index 0000000..cc82fc6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FilmFileFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class FilmFileFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'FilmFile'
+ */
+ public $name = 'FilmFile';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => 255)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'name' => 'one'),
+ array('id' => 2, 'name' => 'two')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FixturizedTestCase.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FixturizedTestCase.php
new file mode 100644
index 0000000..f6077b8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FixturizedTestCase.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * This class helps in testing the life-cycle of fixtures inside a CakeTestCase
+ *
+ * @package Cake.Test.Fixture
+ */
+class FixturizedTestCase extends CakeTestCase {
+
+/**
+ * Fixtures to use in this thes
+ * @var array
+ */
+ public $fixtures = array('core.category');
+
+/**
+ * test that the shared fixture is correctly set
+ *
+ * @return void
+ */
+ public function testFixturePresent() {
+ $this->assertInstanceOf('CakeFixtureManager', $this->fixtureManager);
+ }
+
+/**
+ * test that it is possible to load fixtures on demand
+ *
+ * @return void
+ */
+ public function testFixtureLoadOnDemand() {
+ $this->loadFixtures('Category');
+ }
+
+/**
+ * test that a test is marked as skipped using skipIf and its first parameter evaluates to true
+ *
+ * @return void
+ */
+ public function testSkipIfTrue() {
+ $this->skipIf(true);
+ }
+
+/**
+ * test that a test is not marked as skipped using skipIf and its first parameter evaluates to false
+ *
+ * @return void
+ */
+ public function testSkipIfFalse() {
+ $this->skipIf(false);
+ }
+
+/**
+ * test that a fixtures are unoaded even if the test throws exceptions
+ *
+ * @return void
+ * @throws Exception
+ */
+ public function testThrowException() {
+ throw new Exception();
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FlagTreeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FlagTreeFixture.php
new file mode 100644
index 0000000..e775e8f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FlagTreeFixture.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Tree behavior class test fixture.
+ *
+ * Enables a model object to act as a node-based tree.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5331
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Flag Tree Test Fixture
+ *
+ * Like Number Tree, but uses a flag for testing scope parameters
+ *
+ * @package Cake.Test.Fixture
+ */
+class FlagTreeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'FlagTree'
+ */
+ public $name = 'FlagTree';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer','key' => 'primary'),
+ 'name' => array('type' => 'string','null' => false),
+ 'parent_id' => 'integer',
+ 'lft' => array('type' => 'integer','null' => false),
+ 'rght' => array('type' => 'integer','null' => false),
+ 'flag' => array('type' => 'integer','null' => false, 'length' => 1, 'default' => 0)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitFixture.php
new file mode 100644
index 0000000..41ce730
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7953
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class FruitFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Fruit'
+ */
+ public $name = 'Fruit';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => 255),
+ 'color' => array('type' => 'string', 'length' => 13),
+ 'shape' => array('type' => 'string', 'length' => 255),
+ 'taste' => array('type' => 'string', 'length' => 255)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array(
+ 'id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'name' => 'Orange',
+ 'color' => 'orange', 'shape' => 'Spherical', 'taste' => 'Tangy & Sweet'
+ )
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitsUuidTagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitsUuidTagFixture.php
new file mode 100644
index 0000000..aebb4a7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/FruitsUuidTagFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7953
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class FruitsUuidTagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'FruitsUuidTag'
+ */
+ public $name = 'FruitsUuidTag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'fruit_id' => array('type' => 'string', 'null' => false, 'length' => 36, 'key' => 'primary'),
+ 'uuid_tag_id' => array('type' => 'string', 'null' => false, 'length' => 36, 'key' => 'primary'),
+ 'indexes' => array(
+ 'unique_fruits_tags' => array('unique' => true, 'column' => array('fruit_id', 'uuid_tag_id')),
+ ),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('fruit_id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'uuid_tag_id' => '481fc6d0-b920-43e0-e50f-6d1740cf8569')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GroupUpdateAllFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GroupUpdateAllFixture.php
new file mode 100644
index 0000000..bcfc517
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GroupUpdateAllFixture.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class GroupUpdateAllFixture extends CakeTestFixture {
+
+ public $name = 'GroupUpdateAll';
+
+ public $table = 'group_update_all';
+
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 29),
+ 'code' => array('type' => 'integer', 'null' => false, 'length' => 4),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+ public $records = array(
+ array(
+ 'id' => 1,
+ 'name' => 'group one',
+ 'code' => 120
+ ),
+ array(
+ 'id' => 2,
+ 'name' => 'group two',
+ 'code' => 125
+ ),
+ array(
+ 'id' => 3,
+ 'name' => 'group three',
+ 'code' => 130
+ ),
+ array(
+ 'id' => 4,
+ 'name' => 'group four',
+ 'code' => 135
+ ),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildFixture.php
new file mode 100644
index 0000000..8f7d912
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildFixture.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class GuildFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Guild'
+ */
+ public $name = 'Guild';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Warriors'),
+ array('name' => 'Rangers'),
+ array('name' => 'Wizards'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildsPlayerFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildsPlayerFixture.php
new file mode 100644
index 0000000..c82d59a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/GuildsPlayerFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class GuildsPlayerFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'GuildsPlayer'
+ */
+ public $name = 'GuildsPlayer';
+
+ public $useDbConfig = 'test2';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'player_id' => array('type' => 'integer', 'null' => false),
+ 'guild_id' => array('type' => 'integer', 'null' => false),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('player_id' => 1, 'guild_id' => 1),
+ array('player_id' => 1, 'guild_id' => 2),
+ array('player_id' => 4, 'guild_id' => 3),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/HomeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/HomeFixture.php
new file mode 100644
index 0000000..8ed74c5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/HomeFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class HomeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Home'
+ */
+ public $name = 'Home';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'another_article_id' => array('type' => 'integer', 'null' => false),
+ 'advertisement_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('another_article_id' => 1, 'advertisement_id' => 1, 'title' => 'First Home', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('another_article_id' => 3, 'advertisement_id' => 1, 'title' => 'Second Home', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ImageFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ImageFixture.php
new file mode 100644
index 0000000..8a14847
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ImageFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ImageFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Image'
+ */
+ public $name = 'Image';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Image 1'),
+ array('name' => 'Image 2'),
+ array('name' => 'Image 3'),
+ array('name' => 'Image 4'),
+ array('name' => 'Image 5')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/InnoFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/InnoFixture.php
new file mode 100644
index 0000000..12403c3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/InnoFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Fixture to test be tested exclusively with InnoDB tables
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class InnoFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Article'
+ */
+ public $name = 'Inno';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => true),
+ 'tableParameters' => array(
+ 'engine' => 'InnoDB'
+ )
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Name 1'),
+ array('name' => 'Name 2'),
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemFixture.php
new file mode 100644
index 0000000..b1293d3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemFixture.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ItemFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Item'
+ */
+ public $name = 'Item';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'syfile_id' => array('type' => 'integer', 'null' => false),
+ 'published' => array('type' => 'boolean', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('syfile_id' => 1, 'published' => 0, 'name' => 'Item 1'),
+ array('syfile_id' => 2, 'published' => 0, 'name' => 'Item 2'),
+ array('syfile_id' => 3, 'published' => 0, 'name' => 'Item 3'),
+ array('syfile_id' => 4, 'published' => 0, 'name' => 'Item 4'),
+ array('syfile_id' => 5, 'published' => 0, 'name' => 'Item 5'),
+ array('syfile_id' => 6, 'published' => 0, 'name' => 'Item 6')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemsPortfolioFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemsPortfolioFixture.php
new file mode 100644
index 0000000..5c16e2e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ItemsPortfolioFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ItemsPortfolioFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ItemsPortfolio'
+ */
+ public $name = 'ItemsPortfolio';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'item_id' => array('type' => 'integer', 'null' => false),
+ 'portfolio_id' => array('type' => 'integer', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('item_id' => 1, 'portfolio_id' => 1),
+ array('item_id' => 2, 'portfolio_id' => 2),
+ array('item_id' => 3, 'portfolio_id' => 1),
+ array('item_id' => 4, 'portfolio_id' => 1),
+ array('item_id' => 5, 'portfolio_id' => 1),
+ array('item_id' => 6, 'portfolio_id' => 2)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinABFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinABFixture.php
new file mode 100644
index 0000000..641d36d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinABFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6317
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class JoinABFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'JoinAsJoinB'
+ */
+ public $name = 'JoinAsJoinB';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'join_a_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'join_b_id' => array('type' => 'integer', 'default' => null),
+ 'other' => array('type' => 'string', 'default' => ''),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('join_a_id' => 1, 'join_b_id' => 2, 'other' => 'Data for Join A 1 Join B 2', 'created' => '2008-01-03 10:56:33', 'updated' => '2008-01-03 10:56:33'),
+ array('join_a_id' => 2, 'join_b_id' => 3, 'other' => 'Data for Join A 2 Join B 3', 'created' => '2008-01-03 10:56:34', 'updated' => '2008-01-03 10:56:34'),
+ array('join_a_id' => 3, 'join_b_id' => 1, 'other' => 'Data for Join A 3 Join B 1', 'created' => '2008-01-03 10:56:35', 'updated' => '2008-01-03 10:56:35')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinACFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinACFixture.php
new file mode 100644
index 0000000..d698c32
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinACFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6317
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class JoinACFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'JoinAsJoinC'
+ */
+ public $name = 'JoinAsJoinC';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'join_a_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'join_c_id' => array('type' => 'integer', 'default' => null),
+ 'other' => array('type' => 'string', 'default' => ''),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('join_a_id' => 1, 'join_c_id' => 2, 'other' => 'Data for Join A 1 Join C 2', 'created' => '2008-01-03 10:57:22', 'updated' => '2008-01-03 10:57:22'),
+ array('join_a_id' => 2, 'join_c_id' => 3, 'other' => 'Data for Join A 2 Join C 3', 'created' => '2008-01-03 10:57:23', 'updated' => '2008-01-03 10:57:23'),
+ array('join_a_id' => 3, 'join_c_id' => 1, 'other' => 'Data for Join A 3 Join C 1', 'created' => '2008-01-03 10:57:24', 'updated' => '2008-01-03 10:57:24')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinAFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinAFixture.php
new file mode 100644
index 0000000..97b6958
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinAFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6317
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class JoinAFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'JoinA'
+ */
+ public $name = 'JoinA';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'default' => ''),
+ 'body' => array('type' => 'text'),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Join A 1', 'body' => 'Join A 1 Body', 'created' => '2008-01-03 10:54:23', 'updated' => '2008-01-03 10:54:23'),
+ array('name' => 'Join A 2', 'body' => 'Join A 2 Body', 'created' => '2008-01-03 10:54:24', 'updated' => '2008-01-03 10:54:24'),
+ array('name' => 'Join A 3', 'body' => 'Join A 2 Body', 'created' => '2008-01-03 10:54:25', 'updated' => '2008-01-03 10:54:24')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinBFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinBFixture.php
new file mode 100644
index 0000000..464b593
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinBFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6317
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class JoinBFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'JoinB'
+ */
+ public $name = 'JoinB';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'default' => ''),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Join B 1', 'created' => '2008-01-03 10:55:01', 'updated' => '2008-01-03 10:55:01'),
+ array('name' => 'Join B 2', 'created' => '2008-01-03 10:55:02', 'updated' => '2008-01-03 10:55:02'),
+ array('name' => 'Join B 3', 'created' => '2008-01-03 10:55:03', 'updated' => '2008-01-03 10:55:03')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinCFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinCFixture.php
new file mode 100644
index 0000000..100868c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinCFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6317
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class JoinCFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'JoinC'
+ */
+ public $name = 'JoinC';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'default' => ''),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Join C 1', 'created' => '2008-01-03 10:56:11', 'updated' => '2008-01-03 10:56:11'),
+ array('name' => 'Join C 2', 'created' => '2008-01-03 10:56:12', 'updated' => '2008-01-03 10:56:12'),
+ array('name' => 'Join C 3', 'created' => '2008-01-03 10:56:13', 'updated' => '2008-01-03 10:56:13')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinThingFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinThingFixture.php
new file mode 100644
index 0000000..72186cb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/JoinThingFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class JoinThingFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'JoinThing'
+ */
+ public $name = 'JoinThing';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'something_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'something_else_id' => array('type' => 'integer', 'default' => null),
+ 'doomed' => array('type' => 'boolean', 'default' => '0'),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('something_id' => 1, 'something_else_id' => 2, 'doomed' => '1', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('something_id' => 2, 'something_else_id' => 3, 'doomed' => '0', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('something_id' => 3, 'something_else_id' => 1, 'doomed' => '1', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MessageFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MessageFixture.php
new file mode 100644
index 0000000..3237260
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MessageFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class MessageFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Message'
+ */
+ public $name = 'Message';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'thread_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('thread_id' => 1, 'name' => 'Thread 1, Message 1'),
+ array('thread_id' => 2, 'name' => 'Thread 2, Message 1'),
+ array('thread_id' => 3, 'name' => 'Thread 3, Message 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyProductsFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyProductsFixture.php
new file mode 100644
index 0000000..b83a0d2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyProductsFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class MyCategoriesMyProductsFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'MyCategoriesMyProducts'
+ */
+ public $name = 'MyCategoriesMyProducts';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'my_category_id' => array('type' => 'integer'),
+ 'my_product_id' => array('type' => 'integer'),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('my_category_id' => 1, 'my_product_id' => 1),
+ array('my_category_id' => 2, 'my_product_id' => 1),
+ array('my_category_id' => 2, 'my_product_id' => 2),
+ array('my_category_id' => 3, 'my_product_id' => 2),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyUsersFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyUsersFixture.php
new file mode 100644
index 0000000..81c1615
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoriesMyUsersFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class MyCategoriesMyUsersFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'MyCategoriesMyUsers'
+ */
+ public $name = 'MyCategoriesMyUsers';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'my_category_id' => array('type' => 'integer'),
+ 'my_user_id' => array('type' => 'integer'),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('my_category_id' => 1, 'my_user_id' => 1),
+ array('my_category_id' => 3, 'my_user_id' => 1),
+ array('my_category_id' => 1, 'my_user_id' => 2),
+ array('my_category_id' => 2, 'my_user_id' => 2),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoryFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoryFixture.php
new file mode 100644
index 0000000..ea66687
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyCategoryFixture.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class MyCategoryFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'MyCategory'
+ */
+ public $name = 'MyCategory';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'name' => 'A'),
+ array('id' => 2, 'name' => 'B'),
+ array('id' => 3, 'name' => 'C'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyProductFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyProductFixture.php
new file mode 100644
index 0000000..ed47e27
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyProductFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class MyProductFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'MyProduct'
+ */
+ public $name = 'MyProduct';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'name' => 'book'),
+ array('id' => 2, 'name' => 'computer'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyUserFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyUserFixture.php
new file mode 100644
index 0000000..8a13bdd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/MyUserFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class MyUserFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'MyUser'
+ */
+ public $name = 'MyUser';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'firstname' => array('type' => 'string', 'null' => false),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'firstname' => 'userA'),
+ array('id' => 2, 'firstname' => 'userB')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NodeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NodeFixture.php
new file mode 100644
index 0000000..e7b84fc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NodeFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6879 //Correct version number as needed**
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for file.
+ *
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6879 //Correct version number as needed**
+ */
+class NodeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Node'
+ */
+ public $name = 'Node';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => 'string',
+ 'state' => 'integer'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'name' => 'First', 'state' => 50),
+ array('id' => 2, 'name' => 'Second', 'state' => 60),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeFixture.php
new file mode 100644
index 0000000..d831a72
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeFixture.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Tree behavior class.
+ *
+ * Enables a model object to act as a node-based tree.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5331
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Number Tree Test Fixture
+ *
+ * Generates a tree of data for use testing the tree behavior
+ *
+ * @package Cake.Test.Fixture
+ */
+class NumberTreeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'NumberTree'
+ */
+ public $name = 'NumberTree';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer','key' => 'primary'),
+ 'name' => array('type' => 'string','null' => false),
+ 'parent_id' => 'integer',
+ 'lft' => array('type' => 'integer','null' => false),
+ 'rght' => array('type' => 'integer','null' => false)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeTwoFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeTwoFixture.php
new file mode 100644
index 0000000..0ab4bd5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumberTreeTwoFixture.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Tree behavior class.
+ *
+ * Enables a model object to act as a node-based tree.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5331
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Number Tree Test Fixture
+ *
+ * Generates a tree of data for use testing the tree behavior
+ *
+ * @package Cake.Test.Fixture
+ */
+class NumberTreeTwoFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'NumberTree'
+ */
+ public $name = 'NumberTreeTwo';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer','key' => 'primary'),
+ 'name' => array('type' => 'string','null' => false),
+ 'number_tree_id' => array('type' => 'integer', 'null' => false),
+ 'parent_id' => 'integer',
+ 'lft' => array('type' => 'integer','null' => false),
+ 'rght' => array('type' => 'integer','null' => false)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumericArticleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumericArticleFixture.php
new file mode 100644
index 0000000..49d7593
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/NumericArticleFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class NumericArticleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'NumericArticle'
+ */
+ public $name = 'NumericArticle';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('title' => 'First Article', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('title' => '12345abcde', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/OverallFavoriteFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/OverallFavoriteFixture.php
new file mode 100644
index 0000000..1c8b83b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/OverallFavoriteFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7198
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class OverallFavoriteFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'OverallFavorite'
+ */
+ public $name = 'OverallFavorite';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'model_type' => array('type' => 'string', 'length' => 255),
+ 'model_id' => array('type' => 'integer'),
+ 'priority' => array('type' => 'integer')
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'model_type' => 'Cd', 'model_id' => '1', 'priority' => '1'),
+ array('id' => 2, 'model_type' => 'Book', 'model_id' => '1', 'priority' => '2')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PersonFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PersonFixture.php
new file mode 100644
index 0000000..a05575d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PersonFixture.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6700
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class PersonFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Person'
+ */
+ public $name = 'Person';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 32),
+ 'mother_id' => array('type' => 'integer', 'null' => false, 'key' => 'index'),
+ 'father_id' => array('type' => 'integer', 'null' => false),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'id', 'unique' => 1),
+ 'mother_id' => array('column' => array('mother_id', 'father_id'), 'unique' => 0)
+ )
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'person', 'mother_id' => 2, 'father_id' => 3),
+ array('name' => 'mother', 'mother_id' => 4, 'father_id' => 5),
+ array('name' => 'father', 'mother_id' => 6, 'father_id' => 7),
+ array('name' => 'mother - grand mother', 'mother_id' => 0, 'father_id' => 0),
+ array('name' => 'mother - grand father', 'mother_id' => 0, 'father_id' => 0),
+ array('name' => 'father - grand mother', 'mother_id' => 0, 'father_id' => 0),
+ array('name' => 'father - grand father', 'mother_id' => 0, 'father_id' => 0)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PlayerFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PlayerFixture.php
new file mode 100644
index 0000000..6e23eb0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PlayerFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class PlayerFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Player'
+ */
+ public $name = 'Player';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'mark', 'created' => '2007-03-17 01:16:23'),
+ array('name' => 'jack', 'created' => '2007-03-17 01:18:23'),
+ array('name' => 'larry', 'created' => '2007-03-17 01:20:23'),
+ array('name' => 'jose', 'created' => '2007-03-17 01:22:23'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PortfolioFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PortfolioFixture.php
new file mode 100644
index 0000000..3b43d87
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PortfolioFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class PortfolioFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Portfolio'
+ */
+ public $name = 'Portfolio';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'seller_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('seller_id' => 1, 'name' => 'Portfolio 1'),
+ array('seller_id' => 1, 'name' => 'Portfolio 2'),
+ array('seller_id' => 2, 'name' => 'Portfolio 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostFixture.php
new file mode 100644
index 0000000..a3badd8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostFixture.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class PostFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Post'
+ */
+ public $name = 'Post';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'author_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'body' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('author_id' => 1, 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('author_id' => 3, 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('author_id' => 1, 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostsTagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostsTagFixture.php
new file mode 100644
index 0000000..9d49f58
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PostsTagFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class PostsTagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'PostsTag'
+ */
+ public $name = 'PostsTag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'post_id' => array('type' => 'integer', 'null' => false),
+ 'tag_id' => array('type' => 'string', 'null' => false),
+ 'indexes' => array('posts_tag' => array('column' => array('tag_id', 'post_id'), 'unique' => 1))
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('post_id' => 1, 'tag_id' => 'tag1'),
+ array('post_id' => 1, 'tag_id' => 'tag2'),
+ array('post_id' => 2, 'tag_id' => 'tag1'),
+ array('post_id' => 2, 'tag_id' => 'tag3')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrefixTestFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrefixTestFixture.php
new file mode 100644
index 0000000..37073dc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrefixTestFixture.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @subpackage cake.tests.fixtures
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ * @subpackage cake.tests.fixtures
+ */
+class PrefixTestFixture extends CakeTestFixture {
+
+ public $name = 'PrefixTest';
+
+ public $table = 'prefix_prefix_tests';
+
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrimaryModelFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrimaryModelFixture.php
new file mode 100644
index 0000000..b9f1166
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/PrimaryModelFixture.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class PrimaryModelFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'PrimaryModel'
+ */
+ public $name = 'PrimaryModel';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'primary_name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('primary_name' => 'Primary Name Existing')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductFixture.php
new file mode 100644
index 0000000..8156bc7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductFixture.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ProductFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Product'
+ */
+ public $name = 'Product';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => 255, 'null' => false),
+ 'type' => array('type' => 'string', 'length' => 255, 'null' => false),
+ 'price' => array('type' => 'integer', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Park\'s Great Hits', 'type' => 'Music', 'price' => 19),
+ array('name' => 'Silly Puddy', 'type' => 'Toy', 'price' => 3),
+ array('name' => 'Playstation', 'type' => 'Toy', 'price' => 89),
+ array('name' => 'Men\'s T-Shirt', 'type' => 'Clothing', 'price' => 32),
+ array('name' => 'Blouse', 'type' => 'Clothing', 'price' => 34),
+ array('name' => 'Electronica 2002', 'type' => 'Music', 'price' => 4),
+ array('name' => 'Country Tunes', 'type' => 'Music', 'price' => 21),
+ array('name' => 'Watermelon', 'type' => 'Food', 'price' => 9)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductUpdateAllFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductUpdateAllFixture.php
new file mode 100644
index 0000000..243b2df
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProductUpdateAllFixture.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ProductUpdateAllFixture extends CakeTestFixture {
+
+ public $name = 'ProductUpdateAll';
+
+ public $table = 'product_update_all';
+
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false, 'length' => 29),
+ 'groupcode' => array('type' => 'integer', 'null' => false, 'length' => 4),
+ 'group_id' => array('type' => 'integer', 'null' => false, 'length' => 8),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+
+ public $records = array(
+ array(
+ 'id' => 1,
+ 'name' => 'product one',
+ 'groupcode' => 120,
+ 'group_id' => 1
+ ),
+ array(
+ 'id' => 2,
+ 'name' => 'product two',
+ 'groupcode' => 120,
+ 'group_id' => 1
+ ),
+ array(
+ 'id' => 3,
+ 'name' => 'product three',
+ 'groupcode' => 125,
+ 'group_id' => 2
+ ),
+ array(
+ 'id' => 4,
+ 'name' => 'product four',
+ 'groupcode' => 135,
+ 'group_id' => 4
+ ),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProjectFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProjectFixture.php
new file mode 100644
index 0000000..bbf98a4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ProjectFixture.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ProjectFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Project'
+ */
+ public $name = 'Project';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('name' => 'Project 1'),
+ array('name' => 'Project 2'),
+ array('name' => 'Project 3')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SampleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SampleFixture.php
new file mode 100644
index 0000000..a25b032
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SampleFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class SampleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Sample'
+ */
+ public $name = 'Sample';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'apple_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'length' => 40, 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('apple_id' => 3, 'name' => 'sample1'),
+ array('apple_id' => 2, 'name' => 'sample2'),
+ array('apple_id' => 4, 'name' => 'sample3'),
+ array('apple_id' => 5, 'name' => 'sample4')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SecondaryModelFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SecondaryModelFixture.php
new file mode 100644
index 0000000..8159c5b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SecondaryModelFixture.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class SecondaryModelFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'SecondaryModel'
+ */
+ public $name = 'SecondaryModel';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'secondary_name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('secondary_name' => 'Secondary Name Existing')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SessionFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SessionFixture.php
new file mode 100644
index 0000000..20fb517
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SessionFixture.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class SessionFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Session'
+ */
+ public $name = 'Session';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 128, 'key' => 'primary'),
+ 'data' => array('type' => 'text','null' => true),
+ 'expires' => array('type' => 'integer', 'length' => 11, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SiteFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SiteFixture.php
new file mode 100644
index 0000000..00458e5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SiteFixture.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package cake
+ * @subpackage cake.tests.fixtures
+ * @since CakePHP(tm) v 2.1
+ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package cake
+ * @subpackage cake.tests.fixtures
+ */
+class SiteFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Site'
+ * @access public
+ */
+ public $name = 'Site';
+
+/**
+ * fields property
+ *
+ * @var array
+ * @access public
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ * @access public
+ */
+ public $records = array(
+ array('name' => 'cakephp', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('name' => 'Mark Story\'s sites', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('name' => 'rchavik sites', 'created' => '2001-02-03 00:01:02', 'updated' => '2007-03-17 01:22:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingElseFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingElseFixture.php
new file mode 100644
index 0000000..b76ddcd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingElseFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class SomethingElseFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'SomethingElse'
+ */
+ public $name = 'SomethingElse';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'default' => ''),
+ 'body' => array('type' => 'text'),
+ 'published' => array('type' => 'string', 'default' => ''),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingFixture.php
new file mode 100644
index 0000000..156a117
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SomethingFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class SomethingFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Something'
+ */
+ public $name = 'Something';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'default' => ''),
+ 'body' => array('type' => 'text'),
+ 'published' => array('type' => 'string', 'default' => ''),
+ 'created' => array('type' => 'datetime', 'null' => true),
+ 'updated' => array('type' => 'datetime', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoriesTagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoriesTagFixture.php
new file mode 100644
index 0000000..7c09d0f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoriesTagFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class StoriesTagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'StoriesTag'
+ */
+ public $name = 'StoriesTag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'story' => array('type' => 'integer', 'null' => false),
+ 'tag_id' => array('type' => 'integer', 'null' => false),
+ 'indexes' => array('UNIQUE_STORY_TAG' => array('column' => array('story', 'tag_id'), 'unique' => 1))
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('story' => 1, 'tag_id' => 1)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoryFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoryFixture.php
new file mode 100644
index 0000000..13d6442
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/StoryFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class StoryFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Story'
+ */
+ public $name = 'Story';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'story' => array('type' => 'integer', 'key' => 'primary'),
+ 'title' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('title' => 'First Story'),
+ array('title' => 'Second Story')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SyfileFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SyfileFixture.php
new file mode 100644
index 0000000..8c18b3a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/SyfileFixture.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class SyfileFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Syfile'
+ */
+ public $name = 'Syfile';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'image_id' => array('type' => 'integer', 'null' => true),
+ 'name' => array('type' => 'string', 'null' => false),
+ 'item_count' => array('type' => 'integer', 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('image_id' => 1, 'name' => 'Syfile 1'),
+ array('image_id' => 2, 'name' => 'Syfile 2'),
+ array('image_id' => 5, 'name' => 'Syfile 3'),
+ array('image_id' => 3, 'name' => 'Syfile 4'),
+ array('image_id' => 4, 'name' => 'Syfile 5'),
+ array('image_id' => null, 'name' => 'Syfile 6')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TagFixture.php
new file mode 100644
index 0000000..11d0acc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TagFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Tag'
+ */
+ public $name = 'Tag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'tag' => array('type' => 'string', 'null' => false),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
+ array('tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31'),
+ array('tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginArticleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginArticleFixture.php
new file mode 100644
index 0000000..03d8872
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginArticleFixture.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 7660
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TestPluginArticleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Article'
+ */
+ public $name = 'TestPluginArticle';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'title' => array('type' => 'string', 'null' => false),
+ 'body' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('user_id' => 1, 'title' => 'First Plugin Article', 'body' => 'First Plugin Article Body', 'published' => 'Y', 'created' => '2008-09-24 10:39:23', 'updated' => '2008-09-24 10:41:31'),
+ array('user_id' => 3, 'title' => 'Second Plugin Article', 'body' => 'Second Plugin Article Body', 'published' => 'Y', 'created' => '2008-09-24 10:41:23', 'updated' => '2008-09-24 10:43:31'),
+ array('user_id' => 1, 'title' => 'Third Plugin Article', 'body' => 'Third Plugin Article Body', 'published' => 'Y', 'created' => '2008-09-24 10:43:23', 'updated' => '2008-09-24 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginCommentFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginCommentFixture.php
new file mode 100644
index 0000000..ed36009
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TestPluginCommentFixture.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 7660
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TestPluginCommentFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Comment'
+ */
+ public $name = 'TestPluginComment';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'article_id' => array('type' => 'integer', 'null' => false),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'comment' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'article_id' => 1, 'user_id' => 2, 'comment' => 'First Comment for First Plugin Article', 'published' => 'Y', 'created' => '2008-09-24 10:45:23', 'updated' => '2008-09-24 10:47:31'),
+ array('id' => 2, 'article_id' => 1, 'user_id' => 4, 'comment' => 'Second Comment for First Plugin Article', 'published' => 'Y', 'created' => '2008-09-24 10:47:23', 'updated' => '2008-09-24 10:49:31'),
+ array('id' => 3, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Third Comment for First Plugin Article', 'published' => 'Y', 'created' => '2008-09-24 10:49:23', 'updated' => '2008-09-24 10:51:31'),
+ array('id' => 4, 'article_id' => 1, 'user_id' => 1, 'comment' => 'Fourth Comment for First Plugin Article', 'published' => 'N', 'created' => '2008-09-24 10:51:23', 'updated' => '2008-09-24 10:53:31'),
+ array('id' => 5, 'article_id' => 2, 'user_id' => 1, 'comment' => 'First Comment for Second Plugin Article', 'published' => 'Y', 'created' => '2008-09-24 10:53:23', 'updated' => '2008-09-24 10:55:31'),
+ array('id' => 6, 'article_id' => 2, 'user_id' => 2, 'comment' => 'Second Comment for Second Plugin Article', 'published' => 'Y', 'created' => '2008-09-24 10:55:23', 'updated' => '2008-09-24 10:57:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThePaperMonkiesFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThePaperMonkiesFixture.php
new file mode 100644
index 0000000..6817bef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThePaperMonkiesFixture.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ThePaperMonkiesFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'ThePaperMonkies'
+ */
+ public $name = 'ThePaperMonkies';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'apple_id' => array('type' => 'integer', 'length' => 10, 'null' => true),
+ 'device_id' => array('type' => 'integer', 'length' => 10, 'null' => true)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array();
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThreadFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThreadFixture.php
new file mode 100644
index 0000000..5049c85
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/ThreadFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class ThreadFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Thread'
+ */
+ public $name = 'Thread';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'project_id' => array('type' => 'integer', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('project_id' => 1, 'name' => 'Project 1, Thread 1'),
+ array('project_id' => 1, 'name' => 'Project 1, Thread 2'),
+ array('project_id' => 2, 'name' => 'Project 2, Thread 1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateArticleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateArticleFixture.php
new file mode 100644
index 0000000..2fcfd96
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateArticleFixture.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TranslateArticleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Translate'
+ */
+ public $name = 'TranslateArticle';
+
+/**
+ * table property
+ *
+ * @var string 'i18n'
+ */
+ public $table = 'article_i18n';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'locale' => array('type' => 'string', 'length' => 6, 'null' => false),
+ 'model' => array('type' => 'string', 'null' => false),
+ 'foreign_key' => array('type' => 'integer', 'null' => false),
+ 'field' => array('type' => 'string', 'null' => false),
+ 'content' => array('type' => 'text')
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('locale' => 'eng', 'model' => 'TranslatedArticle', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title (eng) #1'),
+ array('locale' => 'eng', 'model' => 'TranslatedArticle', 'foreign_key' => 1, 'field' => 'body', 'content' => 'Body (eng) #1'),
+ array('locale' => 'deu', 'model' => 'TranslatedArticle', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title (deu) #1'),
+ array('locale' => 'deu', 'model' => 'TranslatedArticle', 'foreign_key' => 1, 'field' => 'body', 'content' => 'Body (deu) #1'),
+ array('locale' => 'cze', 'model' => 'TranslatedArticle', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title (cze) #1'),
+ array('locale' => 'cze', 'model' => 'TranslatedArticle', 'foreign_key' => 1, 'field' => 'body', 'content' => 'Body (cze) #1'),
+ array('locale' => 'eng', 'model' => 'TranslatedArticle', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title (eng) #2'),
+ array('locale' => 'eng', 'model' => 'TranslatedArticle', 'foreign_key' => 2, 'field' => 'body', 'content' => 'Body (eng) #2'),
+ array('locale' => 'deu', 'model' => 'TranslatedArticle', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title (deu) #2'),
+ array('locale' => 'deu', 'model' => 'TranslatedArticle', 'foreign_key' => 2, 'field' => 'body', 'content' => 'Body (deu) #2'),
+ array('locale' => 'cze', 'model' => 'TranslatedArticle', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title (cze) #2'),
+ array('locale' => 'cze', 'model' => 'TranslatedArticle', 'foreign_key' => 2, 'field' => 'body', 'content' => 'Body (cze) #2'),
+ array('locale' => 'eng', 'model' => 'TranslatedArticle', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title (eng) #3'),
+ array('locale' => 'eng', 'model' => 'TranslatedArticle', 'foreign_key' => 3, 'field' => 'body', 'content' => 'Body (eng) #3'),
+ array('locale' => 'deu', 'model' => 'TranslatedArticle', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title (deu) #3'),
+ array('locale' => 'deu', 'model' => 'TranslatedArticle', 'foreign_key' => 3, 'field' => 'body', 'content' => 'Body (deu) #3'),
+ array('locale' => 'cze', 'model' => 'TranslatedArticle', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title (cze) #3'),
+ array('locale' => 'cze', 'model' => 'TranslatedArticle', 'foreign_key' => 3, 'field' => 'body', 'content' => 'Body (cze) #3')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateFixture.php
new file mode 100644
index 0000000..ea3632c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateFixture.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TranslateFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Translate'
+ */
+ public $name = 'Translate';
+
+/**
+ * table property
+ *
+ * @var string 'i18n'
+ */
+ public $table = 'i18n';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'locale' => array('type' => 'string', 'length' => 6, 'null' => false),
+ 'model' => array('type' => 'string', 'null' => false),
+ 'foreign_key' => array('type' => 'integer', 'null' => false),
+ 'field' => array('type' => 'string', 'null' => false),
+ 'content' => array('type' => 'text')
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
+ array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
+ array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
+ array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
+ array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
+ array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Obsah #1'),
+ array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title #2'),
+ array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Content #2'),
+ array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titel #2'),
+ array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Inhalt #2'),
+ array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titulek #2'),
+ array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Obsah #2'),
+ array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title #3'),
+ array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Content #3'),
+ array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titel #3'),
+ array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Inhalt #3'),
+ array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titulek #3'),
+ array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Obsah #3')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateTableFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateTableFixture.php
new file mode 100644
index 0000000..c8f9a14
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateTableFixture.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TranslateTableFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'TranslateTable'
+ */
+ public $name = 'TranslateTable';
+
+/**
+ * table property
+ *
+ * @var string 'another_i18n'
+ */
+ public $table = 'another_i18n';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'locale' => array('type' => 'string', 'length' => 6, 'null' => false),
+ 'model' => array('type' => 'string', 'null' => false),
+ 'foreign_key' => array('type' => 'integer', 'null' => false),
+ 'field' => array('type' => 'string', 'null' => false),
+ 'content' => array('type' => 'text'));
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('locale' => 'eng', 'model' => 'TranslatedItemWithTable', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Another Title #1'),
+ array('locale' => 'eng', 'model' => 'TranslatedItemWithTable', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Another Content #1')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateWithPrefixFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateWithPrefixFixture.php
new file mode 100644
index 0000000..2d5d30d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslateWithPrefixFixture.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TranslateWithPrefixFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Translate'
+ */
+ public $name = 'TranslateWithPrefix';
+
+/**
+ * table property
+ *
+ * @var string 'i18n'
+ */
+ public $table = 'i18n_translate_with_prefixes';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'locale' => array('type' => 'string', 'length' => 6, 'null' => false),
+ 'model' => array('type' => 'string', 'null' => false),
+ 'foreign_key' => array('type' => 'integer', 'null' => false),
+ 'field' => array('type' => 'string', 'null' => false),
+ 'content' => array('type' => 'text')
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
+ array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
+ array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
+ array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
+ array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
+ array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Obsah #1'),
+ array('id' => 7, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title #2'),
+ array('id' => 8, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Content #2'),
+ array('id' => 9, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titel #2'),
+ array('id' => 10, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Inhalt #2'),
+ array('id' => 11, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titulek #2'),
+ array('id' => 12, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Obsah #2'),
+ array('id' => 13, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title #3'),
+ array('id' => 14, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Content #3'),
+ array('id' => 15, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titel #3'),
+ array('id' => 16, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Inhalt #3'),
+ array('id' => 17, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titulek #3'),
+ array('id' => 18, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Obsah #3')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedArticleFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedArticleFixture.php
new file mode 100644
index 0000000..7066486
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedArticleFixture.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TranslatedArticleFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'TranslatedItem'
+ */
+ public $name = 'TranslatedArticle';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => 1, 'user_id' => 1, 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
+ array('id' => 2, 'user_id' => 3, 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
+ array('id' => 3, 'user_id' => 1, 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedItemFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedItemFixture.php
new file mode 100644
index 0000000..3d54903
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/TranslatedItemFixture.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class TranslatedItemFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'TranslatedItem'
+ */
+ public $name = 'TranslatedItem';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'translated_article_id' => array('type' => 'integer'),
+ 'slug' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('translated_article_id' => 1, 'slug' => 'first_translated'),
+ array('translated_article_id' => 1, 'slug' => 'second_translated'),
+ array('translated_article_id' => 1, 'slug' => 'third_translated')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnconventionalTreeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnconventionalTreeFixture.php
new file mode 100644
index 0000000..7eb96f8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnconventionalTreeFixture.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Unconventional Tree behavior class test fixture.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7879
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * UnconventionalTreeFixture class
+ *
+ * Like Number tree, but doesn't use the default values for lft and rght or parent_id
+ *
+ * @uses CakeTestFixture
+ * @package Cake.Test.Fixture
+ */
+class UnconventionalTreeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'FlagTree'
+ */
+ public $name = 'UnconventionalTree';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer','key' => 'primary'),
+ 'name' => array('type' => 'string','null' => false),
+ 'join' => 'integer',
+ 'left' => array('type' => 'integer','null' => false),
+ 'right' => array('type' => 'integer','null' => false),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnderscoreFieldFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnderscoreFieldFixture.php
new file mode 100644
index 0000000..22bb315
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UnderscoreFieldFixture.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * UnderscoreFieldFixture class
+ *
+ * @package Cake.Test.Fixture
+ */
+class UnderscoreFieldFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'UnderscoreField'
+ */
+ public $name = 'UnderscoreField';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user_id' => array('type' => 'integer', 'null' => false),
+ 'my_model_has_a_field' => array('type' => 'string', 'null' => false),
+ 'body_field' => 'text',
+ 'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+ 'another_field' => array('type' => 'integer', 'length' => 3),
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('user_id' => 1, 'my_model_has_a_field' => 'First Article', 'body_field' => 'First Article Body', 'published' => 'Y', 'another_field' => 2),
+ array('user_id' => 3, 'my_model_has_a_field' => 'Second Article', 'body_field' => 'Second Article Body', 'published' => 'Y', 'another_field' => 3),
+ array('user_id' => 1, 'my_model_has_a_field' => 'Third Article', 'body_field' => 'Third Article Body', 'published' => 'Y', 'another_field' => 5),
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UserFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UserFixture.php
new file mode 100644
index 0000000..5a81876
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UserFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class UserFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'User'
+ */
+ public $name = 'User';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'user' => array('type' => 'string', 'null' => true),
+ 'password' => array('type' => 'string', 'null' => true),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('user' => 'mariano', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:16:23', 'updated' => '2007-03-17 01:18:31'),
+ array('user' => 'nate', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:18:23', 'updated' => '2007-03-17 01:20:31'),
+ array('user' => 'larry', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:20:23', 'updated' => '2007-03-17 01:22:31'),
+ array('user' => 'garrett', 'password' => '5f4dcc3b5aa765d61d8327deb882cf99', 'created' => '2007-03-17 01:22:23', 'updated' => '2007-03-17 01:24:31'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidFixture.php
new file mode 100644
index 0000000..cf7cdc3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.6700
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class UuidFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Uuid'
+ */
+ public $name = 'Uuid';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'title' => 'string',
+ 'count' => array('type' => 'integer', 'default' => 0),
+ 'created' => 'datetime',
+ 'updated' => 'datetime'
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => '47c36f9c-bc00-4d17-9626-4e183ca6822b', 'title' => 'Unique record 1', 'count' => 2, 'created' => '2008-03-13 01:16:23', 'updated' => '2008-03-13 01:18:31'),
+ array('id' => '47c36f9c-f2b0-43f5-b3f7-4e183ca6822b', 'title' => 'Unique record 2', 'count' => 4, 'created' => '2008-03-13 01:18:24', 'updated' => '2008-03-13 01:20:32'),
+ array('id' => '47c36f9c-0ffc-4084-9b03-4e183ca6822b', 'title' => 'Unique record 3', 'count' => 5, 'created' => '2008-03-13 01:20:25', 'updated' => '2008-03-13 01:22:33'),
+ array('id' => '47c36f9c-2578-4c2e-aeab-4e183ca6822b', 'title' => 'Unique record 4', 'count' => 3, 'created' => '2008-03-13 01:22:26', 'updated' => '2008-03-13 01:24:34'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTagFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTagFixture.php
new file mode 100644
index 0000000..744f117
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTagFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7953
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class UuidTagFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'UuidTag'
+ */
+ public $name = 'UuidTag';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => 255),
+ 'created' => array('type' => 'datetime')
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => '481fc6d0-b920-43e0-e50f-6d1740cf8569', 'name' => 'MyTag', 'created' => '2009-12-09 12:30:00')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTreeFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTreeFixture.php
new file mode 100644
index 0000000..2431f56
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidTreeFixture.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * UUID Tree behavior fixture.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.7984
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * UuidTreeFixture class
+ *
+ * @uses CakeTestFixture
+ * @package Cake.Test.Fixture
+ */
+class UuidTreeFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'UuidTree'
+ */
+ public $name = 'UuidTree';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'name' => array('type' => 'string','null' => false),
+ 'parent_id' => array('type' => 'string', 'length' => 36, 'null' => true),
+ 'lft' => array('type' => 'integer','null' => false),
+ 'rght' => array('type' => 'integer','null' => false)
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemFixture.php
new file mode 100644
index 0000000..fb04e3e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemFixture.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class UuiditemFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Uuiditem'
+ */
+ public $name = 'Uuiditem';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'published' => array('type' => 'boolean', 'null' => false),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'published' => 0, 'name' => 'Item 1'),
+ array('id' => '48298a29-81c0-4c26-a7fb-413140cf8569', 'published' => 0, 'name' => 'Item 2'),
+ array('id' => '482b7756-8da0-419a-b21f-27da40cf8569', 'published' => 0, 'name' => 'Item 3'),
+ array('id' => '482cfd4b-0e7c-4ea3-9582-4cec40cf8569', 'published' => 0, 'name' => 'Item 4'),
+ array('id' => '4831181b-4020-4983-a29b-131440cf8569', 'published' => 0, 'name' => 'Item 5'),
+ array('id' => '483798c8-c7cc-430e-8cf9-4fcc40cf8569', 'published' => 0, 'name' => 'Item 6')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioFixture.php
new file mode 100644
index 0000000..c2d8523
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class UuiditemsUuidportfolioFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'UuiditemsUuidportfolio'
+ */
+ public $name = 'UuiditemsUuidportfolio';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'uuiditem_id' => array('type' => 'string', 'length' => 36, 'null' => false),
+ 'uuidportfolio_id' => array('type' => 'string', 'length' => 36, 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => '4850fd8f-cc5c-449f-bf34-0c5240cf8569', 'uuiditem_id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'uuidportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
+ array('id' => '4850fee5-d24c-4ea0-9759-0c2e40cf8569', 'uuiditem_id' => '48298a29-81c0-4c26-a7fb-413140cf8569', 'uuidportfolio_id' => '480af662-eb8c-47d3-886b-230540cf8569'),
+ array('id' => '4851af6e-fa18-403d-b57e-437d40cf8569', 'uuiditem_id' => '482b7756-8da0-419a-b21f-27da40cf8569', 'uuidportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
+ array('id' => '4851b94c-9790-42dc-b760-4f9240cf8569', 'uuiditem_id' => '482cfd4b-0e7c-4ea3-9582-4cec40cf8569', 'uuidportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioNumericidFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioNumericidFixture.php
new file mode 100644
index 0000000..c3c7a2e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuiditemsUuidportfolioNumericidFixture.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class UuiditemsUuidportfolioNumericidFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'UuiditemsUuidportfolioNumericid'
+ */
+ public $name = 'UuiditemsUuidportfolioNumericid';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'integer', 'length' => 10, 'key' => 'primary'),
+ 'uuiditem_id' => array('type' => 'string', 'length' => 36, 'null' => false),
+ 'uuidportfolio_id' => array('type' => 'string', 'length' => 36, 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('uuiditem_id' => '481fc6d0-b920-43e0-a40d-6d1740cf8569', 'uuidportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
+ array('uuiditem_id' => '48298a29-81c0-4c26-a7fb-413140cf8569', 'uuidportfolio_id' => '480af662-eb8c-47d3-886b-230540cf8569'),
+ array('uuiditem_id' => '482b7756-8da0-419a-b21f-27da40cf8569', 'uuidportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569'),
+ array('uuiditem_id' => '482cfd4b-0e7c-4ea3-9582-4cec40cf8569', 'uuidportfolio_id' => '4806e091-6940-4d2b-b227-303740cf8569')
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidportfolioFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidportfolioFixture.php
new file mode 100644
index 0000000..fbb4d92
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/UuidportfolioFixture.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Short description for class.
+ *
+ * @package Cake.Test.Fixture
+ */
+class UuidportfolioFixture extends CakeTestFixture {
+
+/**
+ * name property
+ *
+ * @var string 'Uuidportfolio'
+ */
+ public $name = 'Uuidportfolio';
+
+/**
+ * fields property
+ *
+ * @var array
+ */
+ public $fields = array(
+ 'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'null' => false)
+ );
+
+/**
+ * records property
+ *
+ * @var array
+ */
+ public $records = array(
+ array('id' => '4806e091-6940-4d2b-b227-303740cf8569', 'name' => 'Portfolio 1'),
+ array('id' => '480af662-eb8c-47d3-886b-230540cf8569', 'name' => 'Portfolio 2'),
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/rss.xml b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/rss.xml
new file mode 100644
index 0000000..172649d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/rss.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <atom:link href="http://bakery.cakephp.org/articles/rss" rel="self" type="application/rss+xml" />
+ <title>The Bakery: </title>
+ <link>http://bakery.cakephp.org/</link>
+ <description>Recent Articles at The Bakery.</description>
+ <language>en-us</language>
+ <pubDate>Wed, 01 Sep 2010 12:09:25 -0500</pubDate>
+ <docs>http://validator.w3.org/feed/docs/rss2.html</docs>
+ <generator>CakePHP Bakery</generator>
+ <managingEditor>mariano@cricava.com (Mariano Iglesias)</managingEditor>
+ <webMaster>gwoo@cakephp.org (Garrett Woodworth)</webMaster>
+ <item>
+ <title>EpisodeCMS</title>
+ <link>http://bakery.cakephp.org/articles/view/episodecms</link>
+ <description>EpisodeCMS is CakePHP based content management system.
+Features: control panel, events API, module management, multilanguage and translations, themes
+http://episodecms.com/
+
+Please help me to improve it. Thanks.</description>
+ <pubDate>Tue, 31 Aug 2010 02:07:02 -0500</pubDate>
+ <guid>http://bakery.cakephp.org/articles/view/episodecms</guid>
+ </item>
+ <item>
+ <title>Alertpay automated sales via IPN</title>
+ <link>http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn</link>
+ <description>I&#039;m going to show you how I implemented a payment module via the Alertpay payment processor.</description>
+ <pubDate>Tue, 31 Aug 2010 01:42:00 -0500</pubDate>
+ <guid>http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn</guid>
+ </item>
+ </channel>
+</rss> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/sample.xml b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/sample.xml
new file mode 100644
index 0000000..0ab267d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/sample.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<tags>
+ <tag id="1">
+ <name>defect</name>
+ </tag>
+ <tag id="2">
+ <name>enhancement</name>
+ </tag>
+</tags> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_request.xml b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_request.xml
new file mode 100644
index 0000000..cd3a238
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_request.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<soap:Envelope
+xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
+soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
+
+<soap:Body xmlns:m="http://www.example.org/stock">
+ <m:GetStockPrice>
+ <m:StockName>IBM</m:StockName>
+ </m:GetStockPrice>
+</soap:Body>
+
+</soap:Envelope> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_response.xml b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_response.xml
new file mode 100644
index 0000000..c9e9de5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/Fixture/soap_response.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<soap:Envelope
+xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
+soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
+
+<soap:Body xmlns:m="http://www.example.org/stock">
+ <m:GetStockPriceResponse>
+ <m:Price>34.5</m:Price>
+ </m:GetStockPriceResponse>
+</soap:Body>
+
+</soap:Envelope> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.ini.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.ini.php
new file mode 100644
index 0000000..b9215b4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.ini.php
@@ -0,0 +1,60 @@
+;<?php exit() ?>
+; SVN FILE: $Id$
+;/**
+; * Test App Ini Based Acl Config File
+; *
+; *
+; * PHP 5
+; *
+; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+; * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+; *
+; * Licensed under The MIT License
+; * Redistributions of files must retain the above copyright notice.
+; *
+; * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+; * @link http://cakephp.org CakePHP(tm) Project
+;; * @package Cake.Test.test_app.Config
+; * @since CakePHP(tm) v 0.10.0.1076
+; * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+; */
+
+;-------------------------------------
+;Users
+;-------------------------------------
+
+[admin]
+groups = administrators
+allow =
+deny = ads
+
+[paul]
+groups = users
+allow =
+deny =
+
+[jenny]
+groups = users
+allow = ads
+deny = images, files
+
+[nobody]
+groups = anonymous
+allow =
+deny =
+
+;-------------------------------------
+;Groups
+;-------------------------------------
+
+[administrators]
+deny =
+allow = posts, comments, images, files, stats, ads
+
+[users]
+allow = posts, comments, images, files
+deny = stats, ads
+
+[anonymous]
+allow =
+deny = posts, comments, images, files, stats, ads
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.php
new file mode 100644
index 0000000..aeb8d1e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/acl.php
@@ -0,0 +1,74 @@
+<?php
+/*
+ * Test App PHP Based Acl Config File
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Config
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www/opensource/org/licenses/mit-license.php)
+ */
+
+
+// -------------------------------------
+// Roles
+// -------------------------------------
+$config['roles'] = array(
+ 'Role/admin' => null,
+ 'Role/data_acquirer' => null,
+ 'Role/accounting' => null,
+ 'Role/database_manager' => null,
+ 'Role/sales' => null,
+ 'Role/data_analyst' => 'Role/data_acquirer, Role/database_manager',
+ 'Role/reports' => 'Role/data_analyst',
+ // allow inherited roles to be defined as an array or comma separated list
+ 'Role/manager' => array(
+ 'Role/accounting',
+ 'Role/sales',
+ ),
+ 'Role/accounting_manager' => 'Role/accounting',
+ // managers
+ 'User/hardy' => 'Role/accounting_manager, Role/reports',
+ 'User/stan' => 'Role/manager',
+ // accountants
+ 'User/peter' => 'Role/accounting',
+ 'User/jeff' => 'Role/accounting',
+ // admins
+ 'User/jan' => 'Role/admin',
+ // database
+ 'User/db_manager_1' => 'Role/database_manager',
+ 'User/db_manager_2' => 'Role/database_manager',
+);
+
+//-------------------------------------
+// Rules
+//-------------------------------------
+$config['rules']['allow'] = array(
+ '/*' => 'Role/admin',
+ '/controllers/*/manager_*' => 'Role/manager',
+ '/controllers/reports/*' => 'Role/sales',
+ '/controllers/invoices/*' => 'Role/accounting',
+ '/controllers/invoices/edit' => 'User/db_manager_2',
+ '/controllers/db/*' => 'Role/database_manager',
+ '/controllers/*/(add|edit|publish)' => 'User/stan',
+ '/controllers/users/dashboard' => 'Role/default',
+ // test for case insensitivity
+ 'controllers/Forms/NEW' => 'Role/data_acquirer',
+);
+$config['rules']['deny'] = array(
+ // accountants and sales should not delete anything
+ '/controllers/*/delete' => array(
+ 'Role/sales',
+ 'Role/accounting'
+ ),
+ '/controllers/db/drop' => 'User/db_manager_2',
+);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/empty.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/empty.php
new file mode 100644
index 0000000..01d4f0a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/empty.php
@@ -0,0 +1,2 @@
+<?php
+//do nothing this is an empty file. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_minimized.ini b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_minimized.ini
new file mode 100644
index 0000000..e6a722d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_minimized.ini
@@ -0,0 +1,2 @@
+minimizedAttributeFormat = "format"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_tags.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_tags.php
new file mode 100644
index 0000000..abff9cd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/htmlhelper_tags.php
@@ -0,0 +1,8 @@
+<?php
+
+$config = array(
+ 'tags' => array(
+ 'form' => 'start form',
+ 'formend' => 'finish form'
+ )
+); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/nested.ini b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/nested.ini
new file mode 100644
index 0000000..f9832a2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/nested.ini
@@ -0,0 +1,17 @@
+; Test file for testing ini files with . syntax
+[database]
+db.username = mark
+db.password = secret
+
+[nesting]
+one.two.three = 3
+a.b.c.d = On
+
+[bools]
+test_on = on
+test_off = off
+test_yes = yes
+test_no = no
+test_true = true
+test_false = false
+test_null = null
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/no_section.ini b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/no_section.ini
new file mode 100644
index 0000000..6e6fbb7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/no_section.ini
@@ -0,0 +1,2 @@
+some_key = some_value
+bool_key = 1
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/routes.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/routes.php
new file mode 100644
index 0000000..2a6c03c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/routes.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Routes file
+ *
+ * Routes for test app
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.test_app.Config
+ * @since CakePHP v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+Router::parseExtensions('json');
+Router::connect('/some_alias', array('controller' => 'tests_apps', 'action' => 'some_method'));
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test.php
new file mode 100644
index 0000000..44c3455
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test.php
@@ -0,0 +1,12 @@
+<?php
+$config = array(
+ 'Read' => 'value',
+ 'Deep' => array(
+ 'Deeper' => array(
+ 'Deepest' => 'buried'
+ )
+ ),
+ 'TestAcl' => array(
+ 'classname' => 'Original'
+ )
+);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test2.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test2.php
new file mode 100644
index 0000000..745b75d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Config/var_test2.php
@@ -0,0 +1,13 @@
+<?php
+$config = array(
+ 'Read' => 'value2',
+ 'Deep' => array(
+ 'Second' => array(
+ 'SecondDeepest' => 'buried2'
+ )
+ ),
+ 'TestAcl' => array(
+ 'classname' => 'Overwrite',
+ 'custom' => 'one'
+ )
+);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/SampleShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/SampleShell.php
new file mode 100644
index 0000000..6af95ce
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/SampleShell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * SampleShell file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Console.Command
+ * @since CakePHP(tm) v 1.2.0.7871
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class SampleShell extends Shell {
+
+/**
+ * main method
+ *
+ * @return void
+ */
+ public function main() {
+ $this->out('This is the main method called from SampleShell');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/Task/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/Task/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Command/Task/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/classes/test_object.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/classes/test_object.ctp
new file mode 100644
index 0000000..c524b82
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/classes/test_object.ctp
@@ -0,0 +1,2 @@
+I got rendered
+<?php echo $test; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/views/admin_edit.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/views/admin_edit.ctp
new file mode 100644
index 0000000..0d7ec67
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Console/Templates/test/views/admin_edit.ctp
@@ -0,0 +1 @@
+admin_edit template \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/AppController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/AppController.php
new file mode 100644
index 0000000..0414cee
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/AppController.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Application level Controller
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Controller', 'Controller');
+
+/**
+ * This is a placeholder class.
+ * Create the same file in app/Controller/AppController.php
+ *
+ * Add your application-wide methods in the class below, your controllers
+ * will inherit them.
+ *
+ * @package Cake.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
+ */
+class AppController extends Controller {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/Component/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/Component/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/Component/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/PagesController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/PagesController.php
new file mode 100644
index 0000000..b1c6048
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/PagesController.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Static content controller.
+ *
+ * This file will render views from views/pages/
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Controller
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppController', 'Controller');
+
+/**
+ * Static content controller
+ *
+ * Override this controller by placing a copy in controllers directory of an application
+ *
+ * @package Cake.Controller
+ * @link http://book.cakephp.org/2.0/en/controllers/pages-controller.html
+ */
+class PagesController extends AppController {
+
+/**
+ * Default helper
+ *
+ * @var array
+ */
+ public $helpers = array('Html', 'Session');
+
+/**
+ * This controller does not use a model
+ *
+ * @var array
+ */
+ public $uses = array();
+
+/**
+ * Displays a view
+ *
+ * @param mixed What page to display
+ * @return void
+ */
+ public function display() {
+ $path = func_get_args();
+
+ $count = count($path);
+ if (!$count) {
+ $this->redirect('/');
+ }
+ $page = $subpage = $titleForLayout = null;
+
+ if (!empty($path[0])) {
+ $page = $path[0];
+ }
+ if (!empty($path[1])) {
+ $subpage = $path[1];
+ }
+ if (!empty($path[$count - 1])) {
+ $titleForLayout = Inflector::humanize($path[$count - 1]);
+ }
+ $this->set(array(
+ 'page' => $page,
+ 'subpage' => $subpage,
+ 'title_for_layout' => $titleForLayout
+ ));
+ $this->render(implode('/', $path));
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestAppsErrorController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestAppsErrorController.php
new file mode 100644
index 0000000..9ca1d7e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestAppsErrorController.php
@@ -0,0 +1,14 @@
+<?php
+
+App::uses('CakeErrorController', 'Controller');
+
+class TestAppsErrorController extends CakeErrorController {
+
+ public $helpers = array(
+ 'Html',
+ 'Session',
+ 'Form',
+ 'Banana',
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsController.php
new file mode 100644
index 0000000..2e8243c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsController.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * TestsAppsController file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Controller
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestsAppsController extends AppController {
+
+ public $name = 'TestsApps';
+
+ public $uses = array();
+
+ public $components = array('RequestHandler');
+
+ public function index() {
+ $var = '';
+ if (isset($this->request->query['var'])) {
+ $var = $this->request->query['var'];
+ }
+ $this->set('var', $var);
+ }
+
+ public function some_method() {
+ return 5;
+ }
+
+ public function set_action() {
+ $this->set('var', 'string');
+ $this->render('index');
+ }
+
+ public function redirect_to() {
+ $this->redirect('http://cakephp.org');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsPostsController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsPostsController.php
new file mode 100644
index 0000000..8ae0ae1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Controller/TestsAppsPostsController.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * TestsAppsPostsController file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Controller
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestsAppsPostsController extends AppController {
+
+ public $name = 'TestsAppsPosts';
+
+ public $uses = array('Post');
+
+ public $viewPath = 'TestsApps';
+
+ public function add() {
+ $data = array(
+ 'Post' => array(
+ 'title' => 'Test article',
+ 'body' => 'Body of article.',
+ 'author_id' => 1
+ )
+ );
+ $this->Post->save($data);
+
+ $this->set('posts', $this->Post->find('all'));
+ $this->render('index');
+ }
+
+/**
+ * check url params
+ *
+ */
+ public function url_var() {
+ $this->set('params', $this->request->params);
+ $this->render('index');
+ }
+
+/**
+ * post var testing
+ *
+ */
+ public function post_var() {
+ $this->set('data', $this->request->data);
+ $this->render('index');
+ }
+
+ public function input_data() {
+ $this->set('data', $this->request->input('json_decode', true));
+ $this->render('index');
+ }
+
+/**
+ * Fixturized action for testAction()
+ *
+ */
+ public function fixtured() {
+ $this->set('posts', $this->Post->find('all'));
+ $this->render('index');
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Error/TestAppsExceptionRenderer.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Error/TestAppsExceptionRenderer.php
new file mode 100644
index 0000000..e104a01
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Error/TestAppsExceptionRenderer.php
@@ -0,0 +1,21 @@
+<?php
+
+class TestAppsExceptionRenderer extends ExceptionRenderer {
+
+ protected function _getController($exception) {
+ App::uses('TestAppsErrorController', 'Controller');
+ if (!$request = Router::getRequest(true)) {
+ $request = new CakeRequest();
+ }
+ $response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ try {
+ $controller = new TestAppsErrorController($request, $response);
+ $controller->layout = 'banana';
+ } catch (Exception $e) {
+ $controller = new Controller($request, $response);
+ $controller->viewPath = 'Errors';
+ }
+ return $controller;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Cache/Engine/TestAppCacheEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Cache/Engine/TestAppCacheEngine.php
new file mode 100644
index 0000000..1eb4908
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Cache/Engine/TestAppCacheEngine.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Test Suite Test App Cache Engine class.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Lib.Cache.Engine
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestAppCacheEngine extends CacheEngine {
+
+ public function write($key, $value, $duration) {
+ if ($key == 'fail') {
+ return false;
+ }
+ }
+
+ public function read($key) {
+ }
+
+ public function increment($key, $offset = 1) {
+ }
+
+ public function decrement($key, $offset = 1) {
+ }
+
+ public function delete($key) {
+ }
+
+ public function clear($check) {
+ }
+
+ public function clearGroup($group) {
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Library.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Library.php
new file mode 100644
index 0000000..2618259
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Library.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Test Suite Library
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Lib
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class Library {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Log/Engine/TestAppLog.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Log/Engine/TestAppLog.php
new file mode 100644
index 0000000..8ccf3a7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Log/Engine/TestAppLog.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Test Suite Test App Logging stream class.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Lib.Log.Engine
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseLog', 'Log/Engine');
+
+class TestAppLog extends BaseLog {
+
+ public function write($type, $message) {
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Utility/TestUtilityClass.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Utility/TestUtilityClass.php
new file mode 100644
index 0000000..d2b3d2d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Lib/Utility/TestUtilityClass.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Test Suite TestUtilityClass Library
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Lib.Utility
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestUtilityClass {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..426b6f0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/default.po
@@ -0,0 +1,5 @@
+msgid "default.foo"
+msgstr "Default Foo"
+
+msgid "default.bar"
+msgstr "Default Bar"
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom1.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom1.po
new file mode 100644
index 0000000..86fbb7f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom1.po
@@ -0,0 +1,8 @@
+msgid ""
+msgstr "Test Domain 1"
+
+msgid "dom1.foo"
+msgstr "Dom 1 Foo"
+
+msgid "dom1.bar"
+msgstr "Dom 1 Bar"
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom2.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom2.po
new file mode 100644
index 0000000..40c017c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/cache_test_po/LC_MESSAGES/dom2.po
@@ -0,0 +1,8 @@
+msgid ""
+msgstr "Test Domain"
+
+msgid "dom2.foo"
+msgstr "Dom 2 Foo"
+
+msgid "dom2.bar"
+msgstr "Dom 2 Bar"
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/eng/LC_MESSAGES/validation_messages.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/eng/LC_MESSAGES/validation_messages.po
new file mode 100644
index 0000000..4559a2a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/eng/LC_MESSAGES/validation_messages.po
@@ -0,0 +1,5 @@
+msgid "Validation failed: %s"
+msgstr "Translated validation failed: %s"
+
+msgid "arg1"
+msgstr "Translated arg1" \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/ja_jp/LC_TIME b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/ja_jp/LC_TIME
new file mode 100644
index 0000000..f70592d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/ja_jp/LC_TIME
@@ -0,0 +1,48 @@
+escape_char /
+comment_char %
+abday "<U65E5>";"<U6708>";"<U706B>";"<U6C34>";"<U6728>";"<U91D1>";"<U571F>"
+
+day "<U65E5><U66DC><U65E5>";"<U6708><U66DC><U65E5>";/
+ "<U706B><U66DC><U65E5>";"<U6C34><U66DC><U65E5>";/
+ "<U6728><U66DC><U65E5>";"<U91D1><U66DC><U65E5>";/
+ "<U571F><U66DC><U65E5>"
+
+week 7;19971130;7
+first_weekday 1
+first_workday 2
+abmon "<U0020><U0031><U6708>";"<U0020><U0032><U6708>";/
+ "<U0020><U0033><U6708>";"<U0020><U0034><U6708>";/
+ "<U0020><U0035><U6708>";"<U0020><U0036><U6708>";/
+ "<U0020><U0037><U6708>";"<U0020><U0038><U6708>";/
+ "<U0020><U0039><U6708>";"<U0031><U0030><U6708>";/
+ "<U0031><U0031><U6708>";"<U0031><U0032><U6708>"
+mon "<U0031><U6708>";"<U0032><U6708>";/
+ "<U0033><U6708>";"<U0034><U6708>";/
+ "<U0035><U6708>";"<U0036><U6708>";/
+ "<U0037><U6708>";"<U0038><U6708>";/
+ "<U0039><U6708>";"<U0031><U0030><U6708>";/
+ "<U0031><U0031><U6708>";"<U0031><U0032><U6708>"
+% Appropriate date and time representation (%c)
+%
+d_t_fmt "<U0025><U0059><U5E74><U0025><U006D><U6708><U0025><U0064><U65E5><U0020><U0025><U0048><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
+%
+% Appropriate date representation (%x)
+% "%Y年%m月%d日"
+d_fmt "<U0025><U0059><U5E74><U0025><U006D><U6708><U0025><U0064><U65E5>"
+%
+% Appropriate time representation (%X)
+%
+t_fmt "<U0025><U0048><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
+%
+% Appropriate AM/PM time representation (%r)
+%
+t_fmt_ampm "<U0025><U0070><U0025><U0049><U6642><U0025><U004D><U5206><U0025><U0053><U79D2>"
+%
+% Strings for AM/PM
+%
+am_pm "<U5348><U524D>";"<U5348><U5F8C>"
+%
+% Appropriate date representation (date(1))
+date_fmt "<U0025><U0059><U5E74><U0020><U0025><U0062><U0020><U0025>/
+<U0065><U65E5><U0020><U0025><U0041><U0020><U0025><U0048><U003A><U0025>/
+<U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..2fcbdba
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MESSAGES/default.po
@@ -0,0 +1,76 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+msgid ""
+msgstr "header"
+
+msgid "Plural Rule 1"
+msgstr "Po (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d is 1 (po translated)"
+msgstr[1] "%d is 2-4 (po translated)"
+msgstr[2] "%d everything else (po translated)"
+
+msgid "This is a multiline translation\n"
+"broken up over multiple lines.\n"
+"This is the third line.\n"
+"This is the forth line."
+msgstr "This is a multiline translation\n"
+"broken up over multiple lines.\n"
+"This is the third line.\n"
+"This is the forth line. (translated)"
+
+msgid "No Translation needed"
+msgstr ""
+
+msgid "test"
+msgid_plural "tests"
+msgstr[0] "test translated"
+msgstr[1] "test translated"
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "valid\n"
+"second line"
+msgid_plural "valids\n"
+"second line"
+msgstr[0] "v\n"
+"second line"
+msgstr[1] "vs\n"
+"second line"
+
+msgid "%d = 1\n"
+"This is a multiline translation\n"
+"broken up over multiple lines.\n"
+"This is the third line.\n"
+"This is the forth line."
+msgid_plural "%d = 0 or > 1\n"
+"This is a multiline translation\n"
+"broken up over multiple lines.\n"
+"This is the third line.\n"
+"This is the forth line."
+msgstr[0] "%d is 1\n"
+"This is a multiline translation\n"
+"broken up over multiple lines.\n"
+"This is the third line.\n"
+"This is the forth line."
+msgstr[1] "%d is 2-4\n"
+"This is a multiline translation\n"
+"broken up over multiple lines.\n"
+"This is the third line.\n"
+"This is the forth line."
+
+msgid "this is a \"quoted string\""
+msgstr "this is a \"quoted string\" (translated)" \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MONETARY/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MONETARY/default.po
new file mode 100644
index 0000000..e2a3c3a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_MONETARY/default.po
@@ -0,0 +1,18 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+msgid ""
+msgstr "header"
+
+msgid "Plural Rule 1"
+msgstr "Monetary Po (translated)" \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_TIME b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_TIME
new file mode 100644
index 0000000..fe9f566
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/po/LC_TIME
@@ -0,0 +1,60 @@
+escape_char /
+comment_char %
+abday "<U0053><U0075><U006E>";"<U004D><U006F><U006E>";/
+ "<U0054><U0075><U0065>";"<U0057><U0065><U0064>";/
+ "<U0054><U0068><U0075>";"<U0046><U0072><U0069>";/
+ "<U0053><U0061><U0074>"
+day "<U0053><U0075><U006E><U0064><U0061><U0079>";/
+ "<U004D><U006F><U006E><U0064><U0061><U0079>";/
+ "<U0054><U0075><U0065><U0073><U0064><U0061><U0079>";/
+ "<U0057><U0065><U0064><U006E><U0065><U0073><U0064><U0061><U0079>";/
+ "<U0054><U0068><U0075><U0072><U0073><U0064><U0061><U0079>";/
+ "<U0046><U0072><U0069><U0064><U0061><U0079>";/
+ "<U0053><U0061><U0074><U0075><U0072><U0064><U0061><U0079>"
+
+week 7;19971130;7
+first_weekday 1
+first_workday 2
+abmon "<U004A><U0061><U006E>";"<U0046><U0065><U0062>";/
+ "<U004D><U0061><U0072>";"<U0041><U0070><U0072>";/
+ "<U004D><U0061><U0079>";"<U004A><U0075><U006E>";/
+ "<U004A><U0075><U006C>";"<U0041><U0075><U0067>";/
+ "<U0053><U0065><U0070>";"<U004F><U0063><U0074>";/
+ "<U004E><U006F><U0076>";"<U0044><U0065><U0063>"
+mon "<U004A><U0061><U006E><U0075><U0061><U0072><U0079>";/
+ "<U0046><U0065><U0062><U0072><U0075><U0061><U0072><U0079>";/
+ "<U004D><U0061><U0072><U0063><U0068>";/
+ "<U0041><U0070><U0072><U0069><U006C>";/
+ "<U004D><U0061><U0079>";/
+ "<U004A><U0075><U006E><U0065>";/
+ "<U004A><U0075><U006C><U0079>";/
+ "<U0041><U0075><U0067><U0075><U0073><U0074>";/
+ "<U0053><U0065><U0070><U0074><U0065><U006D><U0062><U0065><U0072>";/
+ "<U004F><U0063><U0074><U006F><U0062><U0065><U0072>";/
+ "<U004E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
+ "<U0044><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
+% Appropriate date and time representation (%c)
+% "%a %d %b %Y %r %Z"
+d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0072><U0020><U0025><U005A>"
+%
+% Appropriate date representation (%x)
+% "%m/%d/%Y"
+d_fmt "<U0025><U006D><U002F><U0025><U0064><U002F><U0025><U0059>"
+%
+% Appropriate time representation (%X)
+% "%r"
+t_fmt "<U0025><U0072>"
+%
+% Appropriate AM/PM time representation (%r)
+% "%I:%M:%S %p"
+t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
+<U0025><U0070>"
+%
+% Strings for AM/PM
+%
+am_pm "<U0041><U004D>";"<U0050><U004D>"
+%
+% Appropriate date representation (date(1)) "%a %b %e %H:%M:%S %Z %Y"
+date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065>/
+<U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
+<U0025><U005A><U0020><U0025><U0059>"
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..b82a5ea
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..356da71
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..f8aeb73
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/core.po
@@ -0,0 +1,21 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-Language: Single Form Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 0 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d ends with any # (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..a790a8f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_0_po/LC_MESSAGES/default.po
@@ -0,0 +1,24 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-Language: Single Form Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 0 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d ends with any # (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 0"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..ae0822e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..1a722b8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..9e69464
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/core.po
@@ -0,0 +1,24 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
+"X-Poedit-Language: Four Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 10 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d ends in 1 (from core translated)"
+msgstr[1] "%d ends in 2 (from core translated)"
+msgstr[2] "%d ends in 03-04 (from core translated)"
+msgstr[3] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..f59b901
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_10_po/LC_MESSAGES/default.po
@@ -0,0 +1,27 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
+"X-Poedit-Language: Four Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 10 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d ends in 1 (translated)"
+msgstr[1] "%d ends in 2 (translated)"
+msgstr[2] "%d ends in 03-04 (translated)"
+msgstr[3] "%d everything else (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..6fb6c7d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..181a67f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..7fa6e8f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/core.po
@@ -0,0 +1,25 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4;\n"
+"X-Poedit-Language: Five Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 11 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d is 1 (from core translated)"
+msgstr[1] "%d is 2 (from core translated)"
+msgstr[2] "%d is 3-6 (from core translated)"
+msgstr[3] "%d is 7-10 (from core translated)"
+msgstr[4] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..bd2c38b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_11_po/LC_MESSAGES/default.po
@@ -0,0 +1,25 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4;\n"
+"X-Poedit-Language: Five Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 11 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d is 1 (translated)"
+msgstr[1] "%d is 2 (translated)"
+msgstr[2] "%d is 3-6 (translated)"
+msgstr[3] "%d is 7-10 (translated)"
+msgstr[4] "%d everything else (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..b6b9133
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..0edb5a9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..54f7e18
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/core.po
@@ -0,0 +1,24 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==2 ? 1 : n==0 || (n>=3 && n<=10) ? 2 : 3;\n"
+"X-Poedit-Language: Four Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 12 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d is 1 (from core translated)"
+msgstr[1] "%d is 2 (from core translated)"
+msgstr[2] "%d is 0 or 3-10 (from core translated)"
+msgstr[3] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..ad49ef8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_12_po/LC_MESSAGES/default.po
@@ -0,0 +1,24 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==2 ? 1 : n==0 || (n>=3 && n<=10) ? 2 : 3;\n"
+"X-Poedit-Language: Four Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 12 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d is 1 (translated)"
+msgstr[1] "%d is 2 (translated)"
+msgstr[2] "%d is 0 or 3-10 (translated)"
+msgstr[3] "%d everything else (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..162034a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..65225e7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..fde2995
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/core.po
@@ -0,0 +1,24 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==0 || (n%100>=1 && n%100<=10) ? 1 : n%100>=11 && n%100<=20 ? 2 : 3;\n"
+"X-Poedit-Language: Four Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 13 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d is 1 (from core translated)"
+msgstr[1] "%d is 0 or ends in 01-10 (from core translated)"
+msgstr[2] "%d ends in 11-20 (from core translated)"
+msgstr[3] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..ceb723f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_13_po/LC_MESSAGES/default.po
@@ -0,0 +1,24 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=n==1 ? 0 : n==0 || (n%100>=1 && n%100<=10) ? 1 : n%100>=11 && n%100<=20 ? 2 : 3;\n"
+"X-Poedit-Language: Four Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 13 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d is 1 (translated)"
+msgstr[1] "%d is 0 or ends in 01-10 (translated)"
+msgstr[2] "%d ends in 11-20 (translated)"
+msgstr[3] "%d everything else (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..37f32aa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..35ce089
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..fd23d23
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 ? 0 : n%10==2 ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 14 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d ends in 1 (from core translated)"
+msgstr[1] "%d ends in 2 (from core translated)"
+msgstr[2] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..deea59f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_14_po/LC_MESSAGES/default.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-10-09 19:20-0300\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Renan Gonçalves <renan.saddam@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 ? 0 : n%10==2 ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 14 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d ends in 1 (translated)"
+msgstr[1] "%d ends in 2 (translated)"
+msgstr[2] "%d everything else (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..4084818
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..19b7f5b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..5c5aaa9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/core.po
@@ -0,0 +1,22 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Language: Two Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 1 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d = 1 (from core translated)"
+msgstr[1] "%d = 0 or > 1 (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..6667c96
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_1_po/LC_MESSAGES/default.po
@@ -0,0 +1,25 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Language: Two Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 1 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d = 1 (translated)"
+msgstr[1] "%d = 0 or > 1 (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..fa0e4e6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..b5f1af7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..a9cb17c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/core.po
@@ -0,0 +1,22 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
+"X-Poedit-Language: Two Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 2 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d = 0 or 1 (from core translated)"
+msgstr[1] "%d > 1 (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..24d5c6e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_2_po/LC_MESSAGES/default.po
@@ -0,0 +1,25 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
+"X-Poedit-Language: Two Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 2 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d = 0 or 1 (translated)"
+msgstr[1] "%d > 1 (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..05c300a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..9c72964
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..38621d0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 3 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d ends 1 but not 11 (from core translated)"
+msgstr[1] "%d everything else (from core translated)"
+msgstr[2] "%d = 0 (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..81d98d4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_3_po/LC_MESSAGES/default.po
@@ -0,0 +1,26 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 3 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d ends 1 but not 11 (translated)"
+msgstr[1] "%d everything else (translated)"
+msgstr[2] "%d = 0 (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..d3faf1c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..a752620
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..17124c2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 4 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d = 1 (from core translated)"
+msgstr[1] "%d = 2 (from core translated)"
+msgstr[2] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..87cdbb6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_4_po/LC_MESSAGES/default.po
@@ -0,0 +1,26 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 4 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d = 1 (translated)"
+msgstr[1] "%d = 2 (translated)"
+msgstr[2] "%d everything else (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..835de9c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..ab2d1cc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..dccbeae
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 5 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d = 1 (from core translated)"
+msgstr[1] "%d = 0 or ends in 01-19 (from core translated)"
+msgstr[2] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..b6dd7ec
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_5_po/LC_MESSAGES/default.po
@@ -0,0 +1,24 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 5 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d = 1 (translated)"
+msgstr[1] "%d = 0 or ends in 01-19 (translated)"
+msgstr[2] "%d everything else (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..698ae1d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..4617861
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..6fa429f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 6 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d ends in 1, not 11 (from core translated)"
+msgstr[1] "%d everything else (from core translated)"
+msgstr[2] "%d ends in 0 or ends in 10-20 (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..b294c00
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_6_po/LC_MESSAGES/default.po
@@ -0,0 +1,26 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 6 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d ends in 1, not 11 (translated)"
+msgstr[1] "%d everything else (translated)"
+msgstr[2] "%d ends in 0 or ends in 10-20 (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..767a751
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..9964362
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..9426b75
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 7 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d ends in 1, not 11 (from core translated)"
+msgstr[1] "%d ends in 2-4, not 12-14 (from core translated)"
+msgstr[2] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..c0e0417
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_7_po/LC_MESSAGES/default.po
@@ -0,0 +1,26 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 7 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d ends in 1, not 11 (translated)"
+msgstr[1] "%d ends in 2-4, not 12-14 (translated)"
+msgstr[2] "%d everything else (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..98ffe96
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..6e88264
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..de69dde
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 8 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d is 1 (from core translated)"
+msgstr[1] "%d is 2-4 (from core translated)"
+msgstr[2] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..bfbe2f6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_8_po/LC_MESSAGES/default.po
@@ -0,0 +1,26 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 8 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d is 1 (translated)"
+msgstr[1] "%d is 2-4 (translated)"
+msgstr[2] "%d everything else (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/core.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/core.mo
new file mode 100644
index 0000000..d9e1f47
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/core.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/default.mo b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/default.mo
new file mode 100644
index 0000000..fc1f36c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_mo/LC_MESSAGES/default.mo
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/core.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/core.po
new file mode 100644
index 0000000..aa2c93c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/core.po
@@ -0,0 +1,23 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1 (from core)"
+msgstr "Plural Rule 9 (from core translated)"
+
+msgid "%d = 1 (from core)"
+msgid_plural "%d = 0 or > 1 (from core)"
+msgstr[0] "%d is 1 (from core translated)"
+msgstr[1] "%d ends in 2-4, not 12-14 (from core translated)"
+msgstr[2] "%d everything else (from core translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/default.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/default.po
new file mode 100644
index 0000000..48f93bc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/rule_9_po/LC_MESSAGES/default.po
@@ -0,0 +1,26 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Poedit-Language: Three Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 9 (translated)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d is 1 (translated)"
+msgstr[1] "%d ends in 2-4, not 12-14 (translated)"
+msgstr[2] "%d everything else (translated)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (translated)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/time_test/LC_TIME b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/time_test/LC_TIME
new file mode 100644
index 0000000..63c105f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Locale/time_test/LC_TIME
@@ -0,0 +1,42 @@
+escape_char /
+comment_char %
+abday "<U0064><U006F><U006D>";"<U006C><U0075><U006E>";/
+ "<U006D><U0061><U0072>";"<U006D><U0069><U00E9>";/
+ "<U006A><U0075><U0065>";"<U0076><U0069><U0065>";/
+ "<U0073><U00E1><U0062>"
+day "<U0064><U006F><U006D><U0069><U006E><U0067><U006F>";/
+ "<U006C><U0075><U006E><U0065><U0073>";/
+ "<U006D><U0061><U0072><U0074><U0065><U0073>";/
+ "<U006D><U0069><U00E9><U0072><U0063><U006F><U006C><U0065><U0073>";/
+ "<U006A><U0075><U0065><U0076><U0065><U0073>";/
+ "<U0076><U0069><U0065><U0072><U006E><U0065><U0073>";/
+ "<U0073><U00E1><U0062><U0061><U0064><U006F>"
+abmon "<U0065><U006E><U0065>";"<U0066><U0065><U0062>";/
+ "<U006D><U0061><U0072>";"<U0061><U0062><U0072>";/
+ "<U006D><U0061><U0079>";"<U006A><U0075><U006E>";/
+ "<U006A><U0075><U006C>";"<U0061><U0067><U006F>";/
+ "<U0073><U0065><U0070>";"<U006F><U0063><U0074>";/
+ "<U006E><U006F><U0076>";"<U0064><U0069><U0063>"
+mon "<U0065><U006E><U0065><U0072><U006F>";/
+ "<U0066><U0065><U0062><U0072><U0065><U0072><U006F>";/
+ "<U006D><U0061><U0072><U007A><U006F>";/
+ "<U0061><U0062><U0072><U0069><U006C>";/
+ "<U006D><U0061><U0079><U006F>";/
+ "<U006A><U0075><U006E><U0069><U006F>";/
+ "<U006A><U0075><U006C><U0069><U006F>";/
+ "<U0061><U0067><U006F><U0073><U0074><U006F>";/
+ "<U0073><U0065><U0070><U0074><U0069><U0065><U006D><U0062><U0072><U0065>";/
+ "<U006F><U0063><U0074><U0075><U0062><U0072><U0065>";/
+ "<U006E><U006F><U0076><U0069><U0065><U006D><U0062><U0072><U0065>";/
+ "<U0064><U0069><U0063><U0069><U0065><U006D><U0062><U0072><U0065>"
+d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
+d_fmt "<U0025><U0064><U002F><U0025><U006D><U002F><U0025><U0079>"
+t_fmt "<U0025><U0054>"
+am_pm "<U0061><U006D>";"<U0070><U006D>"
+t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
+<U0025><U0070>"
+date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065>/
+<U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020>/
+<U0025><U005A><U0020><U0025><U0059>"
+% FIXME: found in CLDR
+first_weekday 2
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/AppModel.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/AppModel.php
new file mode 100644
index 0000000..174de2d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/AppModel.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Application model for Cake.
+ *
+ * This file is application-wide model file. You can put all
+ * application-wide model-related methods here.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Model
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+
+/**
+ * Application model for Cake.
+ *
+ * This is a placeholder class.
+ * Create the same file in app/Model/AppModel.php
+ * Add your application-wide methods to the class, your models will inherit them.
+ *
+ * @package Cake.Model
+ */
+class AppModel extends Model {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterOneBehaviorBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterOneBehaviorBehavior.php
new file mode 100644
index 0000000..f45fadc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterOneBehaviorBehavior.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Behavior for binding management.
+ *
+ * Behavior to simplify manipulating a model's bindings when doing a find operation
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Behavior to allow for dynamic and atomic manipulation of a Model's associations used for a find call. Most useful for limiting
+ * the amount of associations and data returned.
+ *
+ * @package Cake.Test.test_app.Model.Behavior
+ */
+class PersisterOneBehaviorBehavior extends ModelBehavior {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterTwoBehaviorBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterTwoBehaviorBehavior.php
new file mode 100644
index 0000000..964588d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Behavior/PersisterTwoBehaviorBehavior.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Behavior for binding management.
+ *
+ * Behavior to simplify manipulating a model's bindings when doing a find operation
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Behavior to allow for dynamic and atomic manipulation of a Model's associations used for a find call. Most useful for limiting
+ * the amount of associations and data returned.
+ *
+ * @package Cake.Test.test_app.Model.Behavior
+ */
+class PersisterTwoBehaviorBehavior extends ModelBehavior {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Comment.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Comment.php
new file mode 100644
index 0000000..653aa7c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Comment.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Test App Comment Model
+ *
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.test_app.Model
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class Comment extends AppModel {
+
+ public $useTable = 'comments';
+
+ public $name = 'Comment';
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Database/TestLocalDriver.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Database/TestLocalDriver.php
new file mode 100644
index 0000000..8375702
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Database/TestLocalDriver.php
@@ -0,0 +1,5 @@
+<?php
+App::uses('TestSource', 'TestPlugin.Model/Datasource');
+class TestLocalDriver extends TestSource {
+}
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php
new file mode 100644
index 0000000..e7b5f9f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Session/TestAppLibSession.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Test suite app/Model/Datasource/Session session handler
+ *
+ */
+
+App::uses('CakeSessionHandlerInterface', 'Model/Datasource/Session');
+
+class TestAppLibSession implements CakeSessionHandlerInterface {
+
+ public function open() {
+ return true;
+ }
+
+ public function close() {
+ }
+
+ public function read($id) {
+ }
+
+ public function write($id, $data) {
+ }
+
+ public function destroy($id) {
+ }
+
+ public function gc($expires = null) {
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2OtherSource.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2OtherSource.php
new file mode 100644
index 0000000..8816822
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2OtherSource.php
@@ -0,0 +1,27 @@
+<?php
+class Test2OtherSource extends DataSource {
+
+ public function describe($model) {
+ return compact('model');
+ }
+
+ public function listSources($data = null) {
+ return array('test_source');
+ }
+
+ public function create(Model $model, $fields = null, $values = null) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function read(Model $model, $queryData = array()) {
+ return compact('model', 'queryData');
+ }
+
+ public function update(Model $model, $fields = array(), $values = array()) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function delete(Model $model, $id = null) {
+ return compact('model', 'id');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2Source.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2Source.php
new file mode 100644
index 0000000..bb9f1dc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Datasource/Test2Source.php
@@ -0,0 +1,27 @@
+<?php
+class Test2Source extends DataSource {
+
+ public function describe($model) {
+ return compact('model');
+ }
+
+ public function listSources($data = null) {
+ return array('test_source');
+ }
+
+ public function create(Model $model, $fields = null, $values = null) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function read(Model $model, $queryData = array()) {
+ return compact('model', 'queryData');
+ }
+
+ public function update(Model $model, $fields = array(), $values = array()) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function delete(Model $model, $id = null) {
+ return compact('model', 'id');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterOne.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterOne.php
new file mode 100644
index 0000000..7fc260d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterOne.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Test App Comment Model
+ *
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.test_app.Model
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class PersisterOne extends AppModel {
+
+ public $useTable = 'posts';
+
+ public $name = 'PersisterOne';
+
+ public $actsAs = array('PersisterOneBehavior', 'TestPlugin.TestPluginPersisterOne');
+
+ public $hasMany = array('Comment', 'TestPlugin.TestPluginComment');
+
+ public $validate = array(
+ 'title' => array(
+ 'custom' => array(
+ 'rule' => array('custom', '.*'),
+ 'allowEmpty' => true,
+ 'required' => false,
+ 'message' => 'Post title is required'
+ ),
+ 'between' => array(
+ 'rule' => array('between', 5, 15),
+ 'message' => array('You may enter up to %s chars (minimum is %s chars)', 14, 6)
+ )
+ ),
+ 'body' => array(
+ 'first_rule' => array(
+ 'rule' => array('custom', '.*'),
+ 'allowEmpty' => true,
+ 'required' => false,
+ 'message' => 'Post body is required'
+ ),
+ 'second_rule' => array(
+ 'rule' => array('custom', '.*'),
+ 'allowEmpty' => true,
+ 'required' => false,
+ 'message' => 'Post body is super required'
+ )
+ ),
+ );
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterTwo.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterTwo.php
new file mode 100644
index 0000000..ef9d418
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/PersisterTwo.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Test App Comment Model
+ *
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.test_app.Model
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class PersisterTwo extends AppModel {
+
+ public $useTable = 'posts';
+
+ public $name = 'PersisterTwo';
+
+ public $actsAs = array('PersisterOneBehavior', 'TestPlugin.TestPluginPersisterOne');
+
+ public $hasMany = array('Comment', 'TestPlugin.TestPluginComment');
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Post.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Post.php
new file mode 100644
index 0000000..0ebbaad
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Model/Post.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Test App Comment Model
+ *
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.test_app.Model
+ * @since CakePHP v 1.2.0.7726
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class Post extends AppModel {
+
+ public $useTable = 'posts';
+
+ public $name = 'Post';
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/Config/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/Config/bootstrap.php
new file mode 100644
index 0000000..d4469c9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/Config/bootstrap.php
@@ -0,0 +1,2 @@
+<?php
+Configure::write('CakePluginTest.js_plugin.bootstrap', 'loaded js plugin bootstrap'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/one/plugin_one.js b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/one/plugin_one.js
new file mode 100644
index 0000000..03e21bb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/one/plugin_one.js
@@ -0,0 +1 @@
+alert('plugin one nested js file'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/plugin_js.js b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/plugin_js.js
new file mode 100644
index 0000000..ac52468
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/PluginJs/webroot/js/plugin_js.js
@@ -0,0 +1 @@
+alert('win sauce'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/Schema/schema.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/Schema/schema.php
new file mode 100644
index 0000000..f810d02
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/Schema/schema.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * TestAppSchema file
+ *
+ * Use for testing the loading of schema files from plugins.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Config.Schema
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginAppSchema extends CakeSchema {
+
+ public $name = 'TestPluginApp';
+
+ public $test_plugin_acos = array(
+ 'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
+ 'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'model' => array('type' => 'string', 'null' => true),
+ 'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'alias' => array('type' => 'string', 'null' => true),
+ 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
+ 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+ );
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/bootstrap.php
new file mode 100644
index 0000000..25b87f1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/bootstrap.php
@@ -0,0 +1,2 @@
+<?php
+Configure::write('CakePluginTest.test_plugin.bootstrap', 'loaded plugin bootstrap'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/custom_config.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/custom_config.php
new file mode 100644
index 0000000..86c82c9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/custom_config.php
@@ -0,0 +1,2 @@
+<?php
+Configure::write('CakePluginTest.test_plugin.custom', 'loaded plugin custom config'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/load.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/load.php
new file mode 100644
index 0000000..efe50c2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/load.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Test Suite TestPlugin config file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Config
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$config['plugin_load'] = '/test_app/plugins/test_plugin/config/load.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/more.load.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/more.load.php
new file mode 100644
index 0000000..1485353
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/more.load.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Test Suite TestPlugin config file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Config
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$config['plugin_more_load'] = '/test_app/plugins/test_plugin/config/more.load.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/routes.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/routes.php
new file mode 100644
index 0000000..2bd2971
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Config/routes.php
@@ -0,0 +1,2 @@
+<?php
+Configure::write('CakePluginTest.test_plugin.routes', 'loaded plugin routes'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/ExampleShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/ExampleShell.php
new file mode 100644
index 0000000..67c6021
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/ExampleShell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Console.Command
+ * @since CakePHP(tm) v 1.2.0.7871
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class ExampleShell extends Shell {
+
+/**
+ * main method
+ *
+ * @return void
+ */
+ public function main() {
+ $this->out('This is the main method called from TestPlugin.ExampleShell');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/Task/OtherTaskTask.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/Task/OtherTaskTask.php
new file mode 100644
index 0000000..26b5025
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Command/Task/OtherTaskTask.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Testing task in a plugin
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Console.Command.Task
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class OtherTaskTask extends Shell {
+
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Templates/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Templates/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Console/Templates/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/OtherComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/OtherComponent.php
new file mode 100644
index 0000000..69d93b2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/OtherComponent.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class OtherComponent extends Object {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/PluginsComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/PluginsComponent.php
new file mode 100644
index 0000000..ffd5cf7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/PluginsComponent.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class PluginsComponent extends Component {
+
+ public $components = array('TestPlugin.Other');
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginComponent.php
new file mode 100644
index 0000000..1c7bc36
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginComponent.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginComponentComponent extends Object {
+
+ public $components = array('TestPlugin.TestPluginOtherComponent');
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginOtherComponent.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginOtherComponent.php
new file mode 100644
index 0000000..2fb4a3b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/Component/TestPluginOtherComponent.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Controller.Component
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginOtherComponentComponent extends Object {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginAppController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginAppController.php
new file mode 100644
index 0000000..93a4981
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginAppController.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Test Suite TestPlugin AppController
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Controller
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginAppController extends AppController {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginController.php
new file mode 100644
index 0000000..097caca
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestPluginController.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * TestPluginController used by Dispatcher test to test plugin shortcut urls.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Controller
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginController extends TestPluginAppController {
+
+ public $uses = array();
+
+ public function index() {
+ $this->autoRender = false;
+ }
+
+ public function add() {
+ $this->autoRender = false;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestsController.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestsController.php
new file mode 100644
index 0000000..0d25196
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Controller/TestsController.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Controller
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestsController extends TestPluginAppController {
+
+ public $name = 'Tests';
+
+ public $uses = array();
+
+ public $helpers = array('TestPlugin.OtherHelper', 'Html');
+
+ public $components = array('TestPlugin.Plugins');
+
+ public function index() {
+ $this->set('test_value', 'It is a variable');
+ }
+
+ public function some_method() {
+ return 25;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Cache/Engine/TestPluginCacheEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Cache/Engine/TestPluginCacheEngine.php
new file mode 100644
index 0000000..76cac13
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Cache/Engine/TestPluginCacheEngine.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Test Suite Test Plugin Cache Engine class.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Lib.Cache.Engine
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginCacheEngine extends CacheEngine {
+
+ public function write($key, $value, $duration) {
+ }
+
+ public function read($key) {
+ }
+
+ public function increment($key, $offset = 1) {
+ }
+
+ public function decrement($key, $offset = 1) {
+ }
+
+ public function delete($key) {
+ }
+
+ public function clear($check) {
+ }
+
+ public function clearGroup($group) {
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Custom/Package/CustomLibClass.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Custom/Package/CustomLibClass.php
new file mode 100644
index 0000000..a339825
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Custom/Package/CustomLibClass.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Test Suite CustomLibClass Library
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Lib.Custom.Package
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class CustomLibClass {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Error/TestPluginExceptionRenderer.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Error/TestPluginExceptionRenderer.php
new file mode 100644
index 0000000..785dc2b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Error/TestPluginExceptionRenderer.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Exception Renderer
+ *
+ * Provides Exception rendering features. Which allow exceptions to be rendered
+ * as HTML pages.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Lib.Error
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ExceptionRenderer', 'Error');
+
+class TestPluginExceptionRenderer extends ExceptionRenderer {
+
+/**
+ * Renders the response for the exception.
+ *
+ * @return void
+ */
+ public function render() {
+ echo 'Rendered by test plugin';
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Log/Engine/TestPluginLog.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Log/Engine/TestPluginLog.php
new file mode 100644
index 0000000..753720d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Log/Engine/TestPluginLog.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Test Suite Test Plugin Logging stream class.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Lib.Log.Engine
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeLogInterface', 'Log');
+
+class TestPluginLog implements CakeLogInterface
+{
+
+ public function write($type, $message) {
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/Test2DispatcherFilter.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/Test2DispatcherFilter.php
new file mode 100644
index 0000000..85ede80
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/Test2DispatcherFilter.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Routing.Filter
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DispatcherFilter', 'Routing');
+
+class Test2DispatcherFilter extends DispatcherFilter {
+
+ public function beforeDispatch($event) {
+ $event->data['response']->statusCode(500);
+ $event->stopPropagation();
+ return $event->data['response'];
+ }
+
+ public function afterDispatch($event) {
+ $event->data['response']->statusCode(200);
+ }
+
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/TestDispatcherFilter.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/TestDispatcherFilter.php
new file mode 100644
index 0000000..6fdb617
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/Routing/Filter/TestDispatcherFilter.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Routing.Filter
+ * @since CakePHP(tm) v 2.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('DispatcherFilter', 'Routing');
+
+class TestDispatcherFilter extends DispatcherFilter {
+
+ public function beforeDispatch($event) {
+ $event->data['request']->params['altered'] = true;
+ }
+
+ public function afterDispatch($event) {
+ $event->data['response']->statusCode(304);
+ }
+
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginLibrary.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginLibrary.php
new file mode 100644
index 0000000..3111e64
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginLibrary.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Test Suite TestPlugin Library
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Lib
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginLibrary {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginOtherLibrary.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginOtherLibrary.php
new file mode 100644
index 0000000..1fa6b84
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Lib/TestPluginOtherLibrary.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Test Suite TestPlugin Other Library
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Lib
+ * @since CakePHP(tm) v 2.0.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginOtherLibrary {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MESSAGES/test_plugin.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MESSAGES/test_plugin.po
new file mode 100644
index 0000000..9228591
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MESSAGES/test_plugin.po
@@ -0,0 +1,50 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Language: Two Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 1 (from plugin)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d = 1 (from plugin)"
+msgstr[1] "%d = 0 or > 1 (from plugin)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (from plugin)"
+
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Language: Two Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Plural Rule 1 (from plugin)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "%d = 1 (from plugin)"
+msgstr[1] "%d = 0 or > 1 (from plugin)"
+
+#~ msgid "Plural-Forms 1"
+#~ msgstr "Plural-Forms 1 (from plugin)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MONETARY/test_plugin.po b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MONETARY/test_plugin.po
new file mode 100644
index 0000000..d1079d3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Locale/po/LC_MONETARY/test_plugin.po
@@ -0,0 +1,22 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: CakePHP Testsuite\n"
+"POT-Creation-Date: 2008-05-15 02:51-0700\n"
+"PO-Revision-Date: \n"
+"Last-Translator: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"Language-Team: CakePHP I18N & I10N Team <i10n.cakephp@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Language: Two Forms of Plurals\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "Plural Rule 1"
+msgstr "Monetary Plural Rule 1 (from plugin)"
+
+msgid "%d = 1"
+msgid_plural "%d = 0 or > 1"
+msgstr[0] "Monetary %d = 1 (from plugin)"
+msgstr[1] "Monetary %d = 0 or > 1 (from plugin)"
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterOneBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterOneBehavior.php
new file mode 100644
index 0000000..36ea3ff
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterOneBehavior.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Behavior for binding management.
+ *
+ * Behavior to simplify manipulating a model's bindings when doing a find operation
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Behavior to allow for dynamic and atomic manipulation of a Model's associations used for a find call. Most useful for limiting
+ * the amount of associations and data returned.
+ *
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model.Behavior
+ */
+class TestPluginPersisterOneBehavior extends ModelBehavior {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterTwoBehavior.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterTwoBehavior.php
new file mode 100644
index 0000000..b18580c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Behavior/TestPluginPersisterTwoBehavior.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Behavior for binding management.
+ *
+ * Behavior to simplify manipulating a model's bindings when doing a find operation
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model.Behavior
+ * @since CakePHP(tm) v 1.2.0.5669
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Behavior to allow for dynamic and atomic manipulation of a Model's associations used for a find call. Most useful for limiting
+ * the amount of associations and data returned.
+ *
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model.Behavior
+ */
+class TestPluginPersisterTwoBehavior extends ModelBehavior {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/DboDummy.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/DboDummy.php
new file mode 100644
index 0000000..348e40a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/DboDummy.php
@@ -0,0 +1,10 @@
+<?php
+App::uses('DboSource', 'Model/Datasource');
+
+class DboDummy extends DboSource {
+
+ public function connect() {
+ return true;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/TestDriver.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/TestDriver.php
new file mode 100644
index 0000000..91a1d3f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Database/TestDriver.php
@@ -0,0 +1,3 @@
+<?php
+class TestDriver extends TestSource {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php
new file mode 100644
index 0000000..acad188
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/Session/TestPluginSession.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Test suite plugin session handler
+ */
+
+App::uses('CakeSessionHandlerInterface', 'Model/Datasource/Session');
+
+class TestPluginSession implements CakeSessionHandlerInterface {
+
+ public function open() {
+ return true;
+ }
+
+ public function close() {
+ }
+
+ public function read($id) {
+ }
+
+ public function write($id, $data) {
+ }
+
+ public function destroy($id) {
+ }
+
+ public function gc($expires = null) {
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestOtherSource.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestOtherSource.php
new file mode 100644
index 0000000..7ab6feb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestOtherSource.php
@@ -0,0 +1,27 @@
+<?php
+class TestOtherSource extends DataSource {
+
+ public function describe($model) {
+ return compact('model');
+ }
+
+ public function listSources($data = null) {
+ return array('test_source');
+ }
+
+ public function create(Model $model, $fields = null, $values = array()) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function read(Model $model, $queryData = array()) {
+ return compact('model', 'queryData');
+ }
+
+ public function update(Model $model, $fields = array(), $values = array()) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function delete(Model $model, $id = null) {
+ return compact('model', 'id');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestSource.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestSource.php
new file mode 100644
index 0000000..371d86a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/Datasource/TestSource.php
@@ -0,0 +1,29 @@
+<?php
+App::uses('DataSource', 'Model/Datasource');
+
+class TestSource extends DataSource {
+
+ public function describe($model) {
+ return compact('model');
+ }
+
+ public function listSources($data = null) {
+ return array('test_source');
+ }
+
+ public function create(Model $model, $fields = array(), $values = array()) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function read(Model $model, $queryData = array()) {
+ return compact('model', 'queryData');
+ }
+
+ public function update(Model $model, $fields = array(), $values = array()) {
+ return compact('model', 'fields', 'values');
+ }
+
+ public function delete(Model $model, $id = null) {
+ return compact('model', 'id');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAppModel.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAppModel.php
new file mode 100644
index 0000000..057da37
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAppModel.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Test Suite TestPlugin AppModel
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model
+ * @since CakePHP(tm) v 1.2.0.5432
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginAppModel extends CakeTestModel {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthUser.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthUser.php
new file mode 100644
index 0000000..35ab049
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthUser.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Test Plugin Auth User Model
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model
+ * @since CakePHP v 1.2.0.4487
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginAuthUser extends TestPluginAppModel {
+
+/**
+ * Name property
+ *
+ * @var string
+ */
+ public $name = 'TestPluginAuthUser';
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = 'auth_users';
+
+/**
+ * useDbConfig property
+ *
+ * @var string 'test'
+ */
+ public $useDbConfig = 'test';
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthors.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthors.php
new file mode 100644
index 0000000..52c65bb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginAuthors.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Test App Comment Model
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model
+ * @since CakePHP v 1.2.0.7726
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+class TestPluginAuthors extends TestPluginAppModel {
+
+ public $useTable = 'authors';
+
+ public $name = 'TestPluginAuthors';
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginComment.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginComment.php
new file mode 100644
index 0000000..d469320
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginComment.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Test App Comment Model
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model
+ * @since CakePHP v 1.2.0.7726
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+class TestPluginComment extends TestPluginAppModel {
+
+ public $useTable = 'test_plugin_comments';
+
+ public $name = 'TestPluginComment';
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginPost.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginPost.php
new file mode 100644
index 0000000..abc6eb4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Model/TestPluginPost.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Test Plugin Post Model
+ *
+ *
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc.
+ * @link http://cakephp.org CakePHP Project
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Model
+ * @since CakePHP v 1.2.0.4487
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class TestPluginPost extends TestPluginAppModel {
+
+/**
+ * Name property
+ *
+ * @var string
+ */
+ public $name = 'Post';
+
+/**
+ * useTable property
+ *
+ * @var string
+ */
+ public $useTable = 'posts';
+
+/**
+ * Validation rules
+ *
+ * @var array
+ */
+ public $validate = array(
+ 'title' => array(
+ 'rule' => array('custom', '.*'),
+ 'allowEmpty' => true,
+ 'required' => false,
+ 'message' => 'Post title is required'
+ ),
+ 'body' => array(
+ 'first_rule' => array(
+ 'rule' => array('custom', '.*'),
+ 'allowEmpty' => true,
+ 'required' => false,
+ 'message' => 'Post body is required'
+ ),
+ 'Post body is super required' => array(
+ 'rule' => array('custom', '.*'),
+ 'allowEmpty' => true,
+ 'required' => false,
+ )
+ ),
+ );
+
+/**
+ * Translation domain to use for validation messages
+ *
+ * @var string
+ */
+ public $validationDomain = 'test_plugin';
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Utility/TestPluginEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Utility/TestPluginEngine.php
new file mode 100644
index 0000000..67fc231
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Utility/TestPluginEngine.php
@@ -0,0 +1,5 @@
+<?php
+
+class TestPluginEngine {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/Example/ExampleExample.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/Example/ExampleExample.php
new file mode 100644
index 0000000..1a5392d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/Example/ExampleExample.php
@@ -0,0 +1,4 @@
+<?php
+class ExampleExample {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/sample/sample_plugin.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/sample/sample_plugin.php
new file mode 100644
index 0000000..cd4c9cf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/sample/sample_plugin.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Vendor.sample
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class SamplePluginClassTestName {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/welcome.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/welcome.php
new file mode 100644
index 0000000..998ed49
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/Vendor/welcome.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.Vendor
+ * @since CakePHP(tm) v 1.2.0.7629
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+This is the welcome.php file in test_plugin/vendors directory \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/plugin_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/plugin_element.ctp
new file mode 100644
index 0000000..a050892
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/plugin_element.ctp
@@ -0,0 +1 @@
+<?php echo 'this is the plugin element using params[plugin]'; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/sub_dir/sub_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/sub_dir/sub_element.ctp
new file mode 100644
index 0000000..8764d25
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/sub_dir/sub_element.ctp
@@ -0,0 +1 @@
+Content from TestPlugin.Elements/sub_dir/sub_element
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/test_plugin_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/test_plugin_element.ctp
new file mode 100644
index 0000000..3e65a67
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/test_plugin_element.ctp
@@ -0,0 +1 @@
+<?php echo 'this is the test set using View::$plugin plugin element'; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/translate.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/translate.ctp
new file mode 100644
index 0000000..75b0eab
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Elements/translate.ctp
@@ -0,0 +1 @@
+<?php __('This is a translatable string'); ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Emails/text/test_plugin_tpl.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Emails/text/test_plugin_tpl.ctp
new file mode 100644
index 0000000..8a663d0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Emails/text/test_plugin_tpl.ctp
@@ -0,0 +1 @@
+Into TestPlugin.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/OtherHelperHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/OtherHelperHelper.php
new file mode 100644
index 0000000..abee3dd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/OtherHelperHelper.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('AppHelper', 'View/Helper');
+class OtherHelperHelper extends AppHelper {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/PluggedHelperHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/PluggedHelperHelper.php
new file mode 100644
index 0000000..53f17f6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/PluggedHelperHelper.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPlugin.View.Helper
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class PluggedHelperHelper extends AppHelper {
+
+ public $helpers = array('TestPlugin.OtherHelper');
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/TestPluginAppHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/TestPluginAppHelper.php
new file mode 100644
index 0000000..6712da0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Helper/TestPluginAppHelper.php
@@ -0,0 +1,4 @@
+<?php
+class TestPluginAppHelper extends AppHelper {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/Emails/text/plug_default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/Emails/text/plug_default.ctp
new file mode 100644
index 0000000..39908fd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/Emails/text/plug_default.ctp
@@ -0,0 +1,4 @@
+
+<?php echo $content_for_layout; ?>
+
+This email was sent using the TestPlugin.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/default.ctp
new file mode 100644
index 0000000..0437f2c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Layouts/default.ctp
@@ -0,0 +1 @@
+test plugin default layout \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/index.ctp
new file mode 100644
index 0000000..6260ece
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/index.ctp
@@ -0,0 +1 @@
+test plugin index \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/scaffold.form.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/scaffold.form.ctp
new file mode 100644
index 0000000..2aef3c7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Tests/scaffold.form.ctp
@@ -0,0 +1 @@
+test_plugin add/edit scaffold view \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/test_plugin_asset.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/test_plugin_asset.css
new file mode 100644
index 0000000..f3b6b53
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/test_plugin_asset.css
@@ -0,0 +1 @@
+this is the test plugin asset css file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/theme_one.htc b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/theme_one.htc
new file mode 100644
index 0000000..636fb51
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/theme_one.htc
@@ -0,0 +1 @@
+htc file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/unknown.extension b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/unknown.extension
new file mode 100644
index 0000000..602e227
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/css/unknown.extension
@@ -0,0 +1 @@
+Testing a file with unknown extension to mime mapping. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/flash/plugin_test.swf b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/flash/plugin_test.swf
new file mode 100644
index 0000000..02a920c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/flash/plugin_test.swf
@@ -0,0 +1 @@
+this is just a test to load swf file from the plugin. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/img/cake.icon.gif b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/img/cake.icon.gif
new file mode 100644
index 0000000..f29f72e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/img/cake.icon.gif
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/js/test_plugin/test.js b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/js/test_plugin/test.js
new file mode 100644
index 0000000..6db1d7d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/js/test_plugin/test.js
@@ -0,0 +1 @@
+alert("Test App"); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf
new file mode 100644
index 0000000..f38d751
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/pdfs/plugin_test.pdf
@@ -0,0 +1 @@
+this is just a test to load pdf file from the plugin. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/root.js b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/root.js
new file mode 100644
index 0000000..529e1c1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPlugin/webroot/root.js
@@ -0,0 +1 @@
+alert('I am a root level file!'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Config/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Config/bootstrap.php
new file mode 100644
index 0000000..0d1b8a4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Config/bootstrap.php
@@ -0,0 +1,2 @@
+<?php
+Configure::write('CakePluginTest.test_plugin_two.bootstrap', 'loaded plugin two bootstrap'); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/ExampleShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/ExampleShell.php
new file mode 100644
index 0000000..066b5be
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/ExampleShell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPluginTwo.Console.Command
+ * @since CakePHP(tm) v 1.2.0.7871
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class ExampleShell extends Shell {
+
+/**
+ * main method
+ *
+ * @return void
+ */
+ public function main() {
+ $this->out('This is the main method called from TestPluginTwo.ExampleShell');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/Task/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/Task/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/Task/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/WelcomeShell.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/WelcomeShell.php
new file mode 100644
index 0000000..dd38dca
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Command/WelcomeShell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Plugin.TestPluginTwo.Console.Command
+ * @since CakePHP(tm) v 1.2.0.7871
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class WelcomeShell extends Shell {
+
+/**
+ * say_hello method
+ *
+ * @return void
+ */
+ public function say_hello() {
+ $this->out('This is the say_hello method called from TestPluginTwo.WelcomeShell');
+ }
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Templates/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Templates/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Plugin/TestPluginTwo/Console/Templates/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Utility/TestAppEngine.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Utility/TestAppEngine.php
new file mode 100644
index 0000000..490dc8d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Utility/TestAppEngine.php
@@ -0,0 +1,5 @@
+<?php
+
+class TestAppEngine {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/MyTest.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/MyTest.php
new file mode 100644
index 0000000..d65342e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/MyTest.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Vendor.Test
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+This is the MyTest.php file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/hello.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/hello.php
new file mode 100644
index 0000000..5e835e9
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/Test/hello.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Vendor.Test
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+This is the hello.php file in Test directory \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/css/test_asset.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/css/test_asset.css
new file mode 100644
index 0000000..e8b09dd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/css/test_asset.css
@@ -0,0 +1 @@
+this is the test asset css file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test.jpg b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test.jpg
new file mode 100644
index 0000000..ca5197a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test.jpg
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test_2.JPG b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test_2.JPG
new file mode 100644
index 0000000..ca5197a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/img/test_2.JPG
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/sample/configure_test_vendor_sample.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/sample/configure_test_vendor_sample.php
new file mode 100644
index 0000000..634027d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/sample/configure_test_vendor_sample.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Vendor.sample
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+class ConfigureTestVendorSample {
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/somename/some.name.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/somename/some.name.php
new file mode 100644
index 0000000..6e79546
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/somename/some.name.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Vendor.somename
+ * @since CakePHP(tm) v 1.2.0.4206
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+This is a file with dot in file name \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/welcome.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/welcome.php
new file mode 100644
index 0000000..91b019a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/Vendor/welcome.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.Test.test_app.Vendor
+ * @since CakePHP(tm) v 1.2.0.7629
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+This is the welcome.php file in vendors directory \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_element.ctp
new file mode 100644
index 0000000..6dd4142
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_element.ctp
@@ -0,0 +1,2 @@
+<?php $this->extend('parent_element'); ?>
+Element content.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp
new file mode 100644
index 0000000..dd106ce
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp
@@ -0,0 +1,2 @@
+<?php $this->extend('noneexistent_parent_element'); ?>
+Element content.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/html_call.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/html_call.ctp
new file mode 100644
index 0000000..8c2c089
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/html_call.ctp
@@ -0,0 +1,3 @@
+<?php
+echo $this->Html->link('Test', 'http://example.com');
+?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/contains_nocache.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/contains_nocache.ctp
new file mode 100644
index 0000000..cf5a42a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/contains_nocache.ctp
@@ -0,0 +1,5 @@
+<h2>Cache Me</h2>
+<!--nocache-->
+ <p>F. In Element With No Cache Tags</p>
+ <?php $this->log('6. in element with no cache tags') ?>
+<!--/nocache-->
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/plain.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/plain.ctp
new file mode 100644
index 0000000..29b8083
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/plain.ctp
@@ -0,0 +1,4 @@
+<h2>Cache Me</h2>
+ <p>B. In Plain Element</p>
+ <?php $this->log('2. in plain element') ?>
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub1.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub1.ctp
new file mode 100644
index 0000000..8557e05
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub1.ctp
@@ -0,0 +1,8 @@
+<?php echo $this->element('nocache/sub2'); ?>
+
+<!--nocache-->
+ <?php $foobar = 'in sub1'; ?>
+ <?php echo $foobar; ?>
+<!--/nocache-->
+
+<?php echo 'printing: "' . $foobar . '"'; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub2.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub2.ctp
new file mode 100644
index 0000000..991e3b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/nocache/sub2.ctp
@@ -0,0 +1,6 @@
+<!--nocache-->
+ <?php $barfoo = 'in sub2'; ?>
+ <?php echo $barfoo; ?>
+<!--/nocache-->
+
+<?php echo 'printing: "' . $barfoo . '"'; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/parent_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/parent_element.ctp
new file mode 100644
index 0000000..86e68f6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/parent_element.ctp
@@ -0,0 +1,2 @@
+Parent Element.
+<?php echo $this->fetch('content'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/session_helper.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/session_helper.ctp
new file mode 100644
index 0000000..109c9a1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/session_helper.ctp
@@ -0,0 +1,5 @@
+<div id="notificationLayout">
+ <h1><?php echo $name; ?></h1>
+ <h3><?php echo $title; ?></h3>
+ <p><?php echo $message; ?></p>
+</div> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.ctp
new file mode 100644
index 0000000..08f1d67
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.ctp
@@ -0,0 +1 @@
+<?php echo 'this is the test element'; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.xml b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.xml
new file mode 100644
index 0000000..f7f3cbe
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/test_element.xml
@@ -0,0 +1 @@
+<p>test element</p>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/type_check.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/type_check.ctp
new file mode 100644
index 0000000..a863c2b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Elements/type_check.ctp
@@ -0,0 +1 @@
+<?php echo gettype($form); ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/custom.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/custom.ctp
new file mode 100644
index 0000000..d83a64d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/custom.ctp
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake.libs.view.templates.elements.email.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<p>Here is your value: <b><?php echo $value; ?></b></p>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/default.ctp
new file mode 100644
index 0000000..9f6924f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/default.ctp
@@ -0,0 +1,25 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.elements.email.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php
+$content = explode("\n", $content);
+
+foreach ($content as $line):
+ echo '<p> ' . $line . '</p>';
+endforeach;
+?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/image.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/image.ctp
new file mode 100644
index 0000000..073d58a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/image.ctp
@@ -0,0 +1,23 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.1
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+echo $this->Html->image('image.gif', array(
+ 'alt' => 'cool image',
+ 'width' => 100,
+ 'height' => 100,
+ 'fullBase' => true,
+ ));
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/japanese.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/japanese.ctp
new file mode 100644
index 0000000..fa883c7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/japanese.ctp
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake.libs.view.templates.elements.email.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<p>ここにあなたの設定した値が入ります: <b><?php echo $value; ?></b></p>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/nested_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/nested_element.ctp
new file mode 100644
index 0000000..4985820
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/html/nested_element.ctp
@@ -0,0 +1,3 @@
+Before the element.
+<?php echo $this->element('html_call'); ?>
+After the element. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom.ctp
new file mode 100644
index 0000000..268eb91
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom.ctp
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake.libs.view.templates.elements.email.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+Here is your value: <?php echo $value; ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom_helper.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom_helper.ctp
new file mode 100644
index 0000000..4b672bf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/custom_helper.ctp
@@ -0,0 +1,19 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.pages
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+Right now: <?php echo $this->Time->toAtom($time); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/default.ctp
new file mode 100644
index 0000000..8ddd9f6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/default.ctp
@@ -0,0 +1,19 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.elements.email.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo $content; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/japanese.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/japanese.ctp
new file mode 100644
index 0000000..c81821e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/japanese.ctp
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake.libs.view.templates.elements.email.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision$
+ * @modifiedby $LastChangedBy$
+ * @lastmodified $Date$
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+ここにあなたの設定した値が入ります: <?php echo $value; ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/wide.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/wide.ctp
new file mode 100644
index 0000000..2c824f4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Emails/text/wide.ctp
@@ -0,0 +1,20 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.elements.email.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+This element has some text that is just too wide to comply with email standards.
+<?php echo $content; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error400.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error400.ctp
new file mode 100644
index 0000000..6d50860
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error400.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo $name; ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake', 'Error'); ?>: </strong>
+ <?php printf(
+ __d('cake', 'The requested address %s was not found on this server.'),
+ "<strong>'{$url}'</strong>"
+ ); ?>
+</p>
+<?php
+if (Configure::read('debug') > 0 ):
+ echo $this->element('exception_stack_trace');
+endif;
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error500.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error500.ctp
new file mode 100644
index 0000000..4e1f36e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Errors/error500.ctp
@@ -0,0 +1,28 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo $name; ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake', 'Error'); ?>: </strong>
+ <?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
+</p>
+<?php
+if (Configure::read('debug') > 0 ):
+ echo $this->element('exception_stack_trace');
+endif;
+?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Helper/BananaHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Helper/BananaHelper.php
new file mode 100644
index 0000000..57759ac
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Helper/BananaHelper.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Helper', 'View');
+
+class BananaHelper extends Helper {
+
+ public function peel() {
+ return '<b>peeled</b>';
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/default.ctp
new file mode 100644
index 0000000..31a9281
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/default.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts.email.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+
+<html>
+<head>
+ <title><?php echo $title_for_layout; ?></title>
+</head>
+
+<body>
+ <?php echo $content_for_layout; ?>
+
+ <p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/japanese.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/japanese.ctp
new file mode 100644
index 0000000..caca09b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/japanese.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts.email.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+
+<html>
+<head>
+ <title><?php echo $title_for_layout; ?></title>
+</head>
+
+<body>
+ <?php echo $content_for_layout; ?>
+
+ <p>このメールは <a href="http://cakephp.org">CakePHP Framework</a> を利用して送信しました。</p>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/thin.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/thin.ctp
new file mode 100644
index 0000000..09d0e32
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/html/thin.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts.email.html
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+
+<html>
+<head>
+ <title><?php echo $title_for_layout; ?></title>
+</head>
+
+<body>
+ <?php echo $content_for_layout; ?>
+
+ <p>This email was sent using the CakePHP Framework</p>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/default.ctp
new file mode 100644
index 0000000..21fd9e2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/default.ctp
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts.email.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+
+<?php echo $content_for_layout; ?>
+
+This email was sent using the CakePHP Framework, http://cakephp.org. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/japanese.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/japanese.ctp
new file mode 100644
index 0000000..53a0d22
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/Emails/text/japanese.ctp
@@ -0,0 +1,22 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts.email.text
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+
+<?php echo $content_for_layout; ?>
+
+CakePHP Framework を使って送信したメールです。 http://cakephp.org. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax.ctp
new file mode 100644
index 0000000..2400b59
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax.ctp
@@ -0,0 +1,19 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php echo $content_for_layout; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax2.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax2.ctp
new file mode 100644
index 0000000..f233daa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/ajax2.ctp
@@ -0,0 +1,22 @@
+<?php
+/* SVN FILE: $Id: ajax2.ctp 7062 2008-05-30 11:29:53Z nate $ */
+
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+Ajax!
+<?php echo $content_for_layout; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/banana.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/banana.ctp
new file mode 100644
index 0000000..b44e3aa
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/banana.ctp
@@ -0,0 +1,5 @@
+<body>
+<?php
+ echo $this->Banana->peel();
+?>
+</body> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_empty_sections.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_empty_sections.ctp
new file mode 100644
index 0000000..dae25af
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_empty_sections.ctp
@@ -0,0 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title><?php echo $title_for_layout; ?></title>
+ <!--nocache--><?php $x = 1; ?><!--/nocache-->
+</head>
+<body>
+ <!--nocache--><?php $x++; ?><!--/nocache-->
+ <!--nocache--><?php $x++; ?><!--/nocache-->
+ <?php echo $content_for_layout; ?>
+ <!--nocache--><?php echo 'cached count is: ' . $x; ?><!--/nocache-->
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_layout.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_layout.ctp
new file mode 100644
index 0000000..2677f1a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/cache_layout.ctp
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<p>This is regular text</p>
+<!--nocache-->
+ <?php echo microtime(); ?>
+<!--/nocache-->
+
+<?php echo $content_for_layout; ?>
+
+<?php echo $superman; ?>
+
+<!--nocache-->
+ <?php echo $variable; ?>
+<!--/nocache-->
+<p>Additional regular text.</p> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/default.ctp
new file mode 100644
index 0000000..21b25e1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/default.ctp
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$this->loadHelper('Html');
+
+$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <?php echo $this->Html->charset(); ?>
+ <title>
+ <?php echo $cakeDescription ?>:
+ <?php echo $title_for_layout; ?>
+ </title>
+ <?php
+ echo $this->Html->meta('icon');
+
+ echo $this->Html->css('cake.generic');
+
+ echo $scripts_for_layout;
+ ?>
+</head>
+<body>
+ <div id="container">
+ <div id="header">
+ <h1><?php echo $this->Html->link($cakeDescription, 'http://cakephp.org'); ?></h1>
+ </div>
+ <div id="content">
+
+ <?php echo $content_for_layout; ?>
+
+ </div>
+ <div id="footer">
+ <?php echo $this->Html->link(
+ $this->Html->image('cake.power.gif', array('alt' => $cakeDescription, 'border' => '0')),
+ 'http://www.cakephp.org/',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/flash.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/flash.ctp
new file mode 100644
index 0000000..2a0c34f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/flash.ctp
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><?php echo $page_title?></title>
+<?php echo $this->Html->charset(); ?>
+
+<?php if (Configure::read('debug') == 0) { ?>
+<meta http-equiv="Refresh" content="<?php echo $pause?>;url=<?php echo $url?>"/>
+<?php } ?>
+<style><!--
+P { text-align:center; font:bold 1.1em sans-serif }
+A { color:#444; text-decoration:none }
+A:HOVER { text-decoration: underline; color:#44E }
+--></style>
+</head>
+<body>
+<p><a href="<?php echo $url?>"><?php echo $message?></a></p>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/js/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/js/default.ctp
new file mode 100644
index 0000000..d94dc90
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/js/default.ctp
@@ -0,0 +1,2 @@
+<?php echo $scripts_for_layout; ?>
+<script type="text/javascript"><?php echo $content_for_layout; ?></script> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/json/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/json/default.ctp
new file mode 100644
index 0000000..3f29013
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/json/default.ctp
@@ -0,0 +1 @@
+<?php echo $content_for_layout; ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/multi_cache.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/multi_cache.ctp
new file mode 100644
index 0000000..573574c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/multi_cache.ctp
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<p>This is regular text</p>
+<!--nocache-->
+ <p>A. Layout Before Content</p>
+ <?php $this->log('1. layout before content') ?>
+<!--/nocache-->
+<!--nocache--><?php echo $this->element('nocache/plain'); ?><!--/nocache-->
+<!--nocache-->
+ <p>C. Layout After Test Element But Before Content</p>
+ <?php $this->log('3. layout after test element but before content') ?>
+<!--/nocache-->
+<?php echo $content_for_layout; ?>
+<!--nocache-->
+ <p>E. Layout After Content</p>
+ <?php $this->log('5. layout after content') ?>
+<!--/nocache-->
+<p>Additional regular text.</p>
+<?php echo $this->element('nocache/contains_nocache'); ?>
+<!--nocache-->
+ <p>G. Layout After Content And After Element With No Cache Tags</p>
+ <?php $this->log('7. layout after content and after element with no cache tags') ?>
+<!--/nocache-->
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/rss/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/rss/default.ctp
new file mode 100644
index 0000000..94067f2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/rss/default.ctp
@@ -0,0 +1,17 @@
+<?php
+echo $rss->header();
+
+if (!isset($channel)) {
+ $channel = array();
+}
+if (!isset($channel['title'])) {
+ $channel['title'] = $title_for_layout;
+}
+
+echo $rss->document(
+ $rss->channel(
+ array(), $channel, $content_for_layout
+ )
+);
+
+?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/xml/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/xml/default.ctp
new file mode 100644
index 0000000..1025a55
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Layouts/xml/default.ctp
@@ -0,0 +1,2 @@
+<?php echo '<?xml version="1.0" encoding="' . Configure::read('App.encoding') . '"?>'; ?>
+<?php echo $content_for_layout; ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/extract.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/extract.ctp
new file mode 100644
index 0000000..cba9b01
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/extract.ctp
@@ -0,0 +1,24 @@
+<?php
+$count = 10;
+$messages = array('count' => 10);
+
+// Plural
+echo __n('You have %d new message.', 'You have %d new messages.', $count);
+echo __n('You deleted %d message.', 'You deleted %d messages.', $messages['count']);
+
+// Domain Plural
+echo __dn('domain', 'You have %d new message (domain).', 'You have %d new messages (domain).', '10');
+echo __dn('domain', 'You deleted %d message (domain).', 'You deleted %d messages (domain).', $messages['count']);
+
+// Duplicated Message
+echo __('Editing this Page');
+echo __('You have %d new message.');
+
+// Multiline
+__('Hot features!'
+ . "\n - No Configuration:"
+ . ' Set-up the database and let the magic begin'
+ . "\n - Extremely Simple:"
+ . ' Just look at the name...It\'s Cake'
+ . "\n - Active, Friendly Community:"
+ . ' Join us #cakephp on IRC. We\'d love to help you get started');
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/home.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/home.ctp
new file mode 100644
index 0000000..bc71459
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/home.ctp
@@ -0,0 +1,163 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.pages
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Debugger', 'Utility');
+?>
+<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
+<a href="http://cakephp.org/changelogs/1.3.6"><?php echo __d('cake_dev', 'Read the changelog'); ?> </a>
+<p>
+ <?php
+ if (is_writable(TMP)):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your tmp directory is writable.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your tmp directory is NOT writable.');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<p>
+ <?php
+ $settings = Cache::settings();
+ if (!empty($settings)):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'The %s is being used for caching. To change the config edit APP/config/core.php ', '<em>'. $settings['engine'] . 'Engine</em>');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in APP/config/core.php');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<p>
+ <?php
+ $filePresent = null;
+ if (file_exists(APP . 'Config' . DS . 'database.php')):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Your database configuration file is present.');
+ $filePresent = true;
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Your database configuration file is NOT present.');
+ echo '<br/>';
+ echo __d('cake_dev', 'Rename config/database.php.default to config/database.php');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<?php
+if (isset($filePresent)):
+ App::uses('ConnectionManager', 'Model');
+ try {
+ $connected = ConnectionManager::getDataSource('default');
+ } catch (Exception $e) {
+ $connected = false;
+ }
+?>
+<p>
+ <?php
+ if ($connected && $connected->isConnected()):
+ echo '<span class="notice success">';
+ echo __d('cake_dev', 'Cake is able to connect to the database.');
+ echo '</span>';
+ else:
+ echo '<span class="notice">';
+ echo __d('cake_dev', 'Cake is NOT able to connect to the database.');
+ echo '</span>';
+ endif;
+ ?>
+</p>
+<?php endif; ?>
+<?php
+ App::uses('Validation', 'Utility');
+ if (!Validation::alphaNumeric('cakephp')) {
+ echo '<p><span class="notice">';
+ __('PCRE has not been compiled with Unicode support.');
+ echo '<br/>';
+ __('Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
+ echo '</span></p>';
+ }
+?>
+<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
+<p>
+<?php
+echo __d('cake_dev', 'To change the content of this page, create: APP/views/pages/home.ctp.<br />
+To change its layout, create: APP/views/layouts/default.ctp.<br />
+You can also add some CSS styles for your pages at: APP/webroot/css.');
+?>
+</p>
+
+<h3><?php echo __d('cake_dev', 'Getting Started'); ?></h3>
+<p>
+ <?php
+ echo $this->Html->link(
+ sprintf('<strong>%s</strong> %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 1.3 Docs')),
+ 'http://book.cakephp.org/view/875/x1-3-Collection',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+</p>
+<p>
+ <?php
+ echo $this->Html->link(
+ __d('cake_dev', 'The 15 min Blog Tutorial'),
+ 'http://book.cakephp.org/view/1528/Blog',
+ array('target' => '_blank', 'escape' => false)
+ );
+ ?>
+</p>
+
+<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3>
+<p>
+<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
+</p>
+<p>
+<?php echo __d('cake_dev', 'Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.'); ?>
+</p>
+
+<ul>
+ <li><a href="http://cakefoundation.org/"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
+ <li><a href="http://www.cakephp.org"><?php echo __d('cake_dev', 'CakePHP'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li>
+ <li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li>
+ <li><a href="http://api.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li>
+ <li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
+ <li><a href="http://live.cakephp.org"><?php echo __d('cake_dev', 'The Show'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'The Show is a live and archived internet radio broadcast CakePHP-related topics and answer questions live via IRC, Skype, and telephone.'); ?></li></ul></li>
+ <li><a href="http://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
+ <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
+ <ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li>
+ <li><a href="http://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'For the Development of CakePHP Git repository, Downloads'); ?></li></ul></li>
+ <li><a href="http://cakephp.lighthouseapp.com/"><?php echo __d('cake_dev', 'CakePHP Lighthouse'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'CakePHP Tickets, Wiki pages, Roadmap'); ?></li></ul></li>
+ <li><a href="http://www.cakeforge.org"><?php echo __d('cake_dev', 'CakeForge'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Open Development for CakePHP'); ?></li></ul></li>
+ <li><a href="http://astore.amazon.com/cakesoftwaref-20/"><?php echo __d('cake_dev', 'Book Store'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Recommended Software Books'); ?></li></ul></li>
+ <li><a href="http://www.cafepress.com/cakefoundation"><?php echo __d('cake_dev', 'CakePHP gear'); ?> </a>
+ <ul><li><?php echo __d('cake_dev', 'Get your own CakePHP gear - Doughnate to Cake'); ?></li></ul></li>
+</ul>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/page.home.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/page.home.ctp
new file mode 100644
index 0000000..46f877f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Pages/page.home.ctp
@@ -0,0 +1,2 @@
+Empty page with a dot in the filename.
+Used to test plugin.view and missing plugins.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/alt_ext.alt b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/alt_ext.alt
new file mode 100644
index 0000000..5d26c81
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/alt_ext.alt
@@ -0,0 +1 @@
+alt ext \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_empty_sections.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_empty_sections.ctp
new file mode 100644
index 0000000..0bb2bc4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_empty_sections.ctp
@@ -0,0 +1,2 @@
+View Content
+ <!--nocache--><?php $y = 1; ?><!--/nocache-->
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_form.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_form.ctp
new file mode 100644
index 0000000..7f335e1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/cache_form.ctp
@@ -0,0 +1,14 @@
+<div class="users form">
+<!--nocache-->
+ <?php echo $this->Form->create('User'); ?>
+ <fieldset>
+ <legend><?php echo __('Add User'); ?></legend>
+ <?php
+ echo $this->Form->input('username');
+ echo $this->Form->input('email');
+ echo $this->Form->input('password');
+ ?>
+ </fieldset>
+ <?php echo $this->Form->end('Submit'); ?>
+<!--/nocache-->
+</div> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_element.ctp
new file mode 100644
index 0000000..a76c961
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_element.ctp
@@ -0,0 +1,3 @@
+<?php $this->extend('parent_view'); ?>
+View content.
+<?php echo $this->element('extended_element'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop.ctp
new file mode 100644
index 0000000..f7a07ae
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop.ctp
@@ -0,0 +1,2 @@
+<?php $this->extend('extend_loop_inner'); ?>
+Outer element.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop_inner.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop_inner.ctp
new file mode 100644
index 0000000..efde058
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_loop_inner.ctp
@@ -0,0 +1,2 @@
+<?php $this->extend('extend_loop'); ?>
+Inner loop element.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp
new file mode 100644
index 0000000..7d5a6ac
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp
@@ -0,0 +1 @@
+<?php echo $this->element('extended_missing_element'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_self.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_self.ctp
new file mode 100644
index 0000000..3515819
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/extend_self.ctp
@@ -0,0 +1,2 @@
+<?php $this->extend('extend_self'); ?>
+To infinifty and beyond.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/helper_overwrite.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/helper_overwrite.ctp
new file mode 100644
index 0000000..100c5f5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/helper_overwrite.ctp
@@ -0,0 +1,4 @@
+<?php
+echo $html;
+echo $this->Html->link('Test link', '#');
+?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/index.ctp
new file mode 100644
index 0000000..ff145ee
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/index.ctp
@@ -0,0 +1 @@
+posts index \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/json/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/json/index.ctp
new file mode 100644
index 0000000..433162d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/json/index.ctp
@@ -0,0 +1,27 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Test.test_app.View.Json
+ * @since CakePHP(tm) v 2.1.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+$formatted = array(
+ 'user' => $user['User']['username'],
+ 'list' => array()
+);
+foreach ($user['Item'] as $item) {
+ $formatted['list'][] = $item['name'];
+}
+
+echo json_encode($formatted);
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/multiple_nocache.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/multiple_nocache.ctp
new file mode 100644
index 0000000..4ee095b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/multiple_nocache.ctp
@@ -0,0 +1,15 @@
+--view start--
+<!--nocache-->
+ <?php echo $batman ?>
+<!--/nocache-->
+
+this view has 3 nocache blocks
+
+<!--nocache-->
+ <?php echo $spiderman; ?>
+<!--/nocache-->
+
+<!--nocache-->
+ <?php echo 'some string'; ?>
+<!--/nocache-->
+--view end-- \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nested_extends.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nested_extends.ctp
new file mode 100644
index 0000000..d032106
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nested_extends.ctp
@@ -0,0 +1,5 @@
+<?php
+$this->extend('parent_1');
+$this->assign('sidebar', 'Sidebar Content.');
+?>
+This is the first template.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nocache_multiple_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nocache_multiple_element.ctp
new file mode 100644
index 0000000..d6770e2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/nocache_multiple_element.ctp
@@ -0,0 +1,9 @@
+<!--nocache-->
+ <?php echo $foo; ?>
+<!--/nocache-->
+
+<!--nocache-->
+ <?php echo $bar; ?>
+<!--/nocache-->
+
+<?php echo $this->element('nocache/sub1'); ?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/open_block.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/open_block.ctp
new file mode 100644
index 0000000..edd595f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/open_block.ctp
@@ -0,0 +1,3 @@
+<?php
+$this->start('no_close');
+echo 'This block has no close :(';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_1.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_1.ctp
new file mode 100644
index 0000000..e41dfa5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_1.ctp
@@ -0,0 +1,5 @@
+<?php
+$this->extend('parent_2');
+?>
+This is the first parent.
+<?php echo $this->fetch('content'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_2.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_2.ctp
new file mode 100644
index 0000000..aedb0f2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_2.ctp
@@ -0,0 +1,3 @@
+This is the second parent.
+<?php echo $this->fetch('content'); ?>
+<?php echo $this->fetch('sidebar'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_view.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_view.ctp
new file mode 100644
index 0000000..e338b78
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/parent_view.ctp
@@ -0,0 +1,2 @@
+Parent View.
+<?php echo $this->fetch('content') ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/scaffold.form.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/scaffold.form.ctp
new file mode 100644
index 0000000..ff82390
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/scaffold.form.ctp
@@ -0,0 +1 @@
+test_app posts add/edit scaffold view \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/sequencial_nocache.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/sequencial_nocache.ctp
new file mode 100644
index 0000000..92f5ad8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/sequencial_nocache.ctp
@@ -0,0 +1,23 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.pages
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h1>Content</h1>
+<!--nocache-->
+ <p>D. In View File</p>
+ <?php $this->log('4. in view file') ?>
+<!--/nocache-->
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/test_nocache_tags.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/test_nocache_tags.ctp
new file mode 100644
index 0000000..0933f2f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/test_nocache_tags.ctp
@@ -0,0 +1,142 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.view.templates.pages
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<p>
+ <!--nocache-->
+ <span class="notice">
+ <?php
+ echo __d('cake', 'Your tmp directory is ');
+ if (is_writable(TMP)):
+ echo __d('cake', 'writable.');
+ else:
+ echo __d('cake', 'NOT writable.');
+ endif;
+ ?>
+ </span>
+ <!--/nocache-->
+</p>
+<p>
+ <span class="notice">
+ <?php
+ echo __d('cake', 'Your cache is ');
+ if (Cache::isInitialized('default')):
+ echo __d('cake', 'set up and initialized properly.');
+ $settings = Cache::settings();
+ echo '<p>' . $settings['engine'];
+ echo __d('cake', ' is being used to cache, to change this edit config/core.php ');
+ echo '</p>';
+
+ echo 'Settings: <ul>';
+ foreach ($settings as $name => $value):
+ if (is_array($value)):
+ $value = join(',', $value);
+ endif;
+ echo '<li>' . $name . ': ' . $value . '</li>';
+ endforeach;
+ echo '</ul>';
+
+ else:
+ echo __d('cake', 'NOT working.');
+ echo '<br />';
+ if (is_writable(TMP)):
+ echo __d('cake', 'Edit: config/core.php to insure you have the newset version of this file and the variable $cakeCache set properly');
+ endif;
+ endif;
+ ?>
+ </span>
+</p>
+<p>
+ <span class="notice">
+ <?php
+ echo __d('cake', 'Your database configuration file is ');
+ $filePresent = null;
+ if (file_exists(APP . 'Config'.'database.php')):
+ echo __d('cake', 'present.');
+ $filePresent = true;
+ else:
+ echo __d('cake', 'NOT present.');
+ echo '<br/>';
+ echo __d('cake', 'Rename config/database.php.default to config/database.php');
+ endif;
+ ?>
+ </span>
+</p>
+<?php
+if (!empty($filePresent)):
+ App::uses('ConnectionManager', 'Model');
+ $connected = ConnectionManager::getDataSource('default');
+?>
+<p>
+ <span class="notice">
+ <?php echo __d('cake', 'Cake');
+ if ($connected->isConnected()):
+ __d('cake', ' is able to ');
+ else:
+ __d('cake', ' is NOT able to ');
+ endif;
+ __d('cake', 'connect to the database.');
+ ?>
+ </span>
+</p>
+<?php endif; ?>
+<h2><?php echo __d('cake', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
+<a href="https://trac.cakephp.org/wiki/notes/1.2.x.x"><?php echo __d('cake', 'Read the release notes and get the latest version'); ?> </a>
+<h2><?php echo __d('cake', 'Editing this Page'); ?></h2>
+<p>
+<?php echo __d('cake', 'To change the content of this page, create: /app/View/Pages/home.ctp.'); ?><br />
+<?php echo __d('cake', 'To change its layout, create: /app/View/Layouts/default.ctp.'); ?><br />
+<a href="http://manual.cakephp.org/"><?php echo __d('cake', 'See the views section of the manual for more info.'); ?> </a><br />
+<?php echo __d('cake', 'You can also add some CSS styles for your pages at: app/webroot/css/.'); ?>
+</p>
+<h2><?php echo __d('cake', 'Getting Started'); ?></h2>
+<p>
+<a href="http://manual.cakephp.org/appendix/blog_tutorial"><?php echo __d('cake', 'The 15 min Blog Tutorial'); ?></a><br />
+<a href="http://www-128.ibm.com/developerworks/edu/os-dw-os-php-cake1.html"><?php echo __d('cake', 'Cook up Web sites fast with CakePHP'); ?></a><br />
+<a href="http://www-128.ibm.com/developerworks/edu/os-dw-os-php-wiki1.html"><?php echo __d('cake', 'Create an interactive production wiki using PHP'); ?></a>
+</p>
+<h2><?php echo __d('cake', 'More about Cake'); ?></h2>
+<p>
+<?php echo __d('cake', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
+</p>
+<p>
+<?php echo __d('cake', 'Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.'); ?>
+</p>
+<ul>
+ <li><a href="http://cakefoundation.org/"><?php echo __d('cake', 'Cake Software Foundation'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Promoting development related to CakePHP'); ?></li></ul></li>
+ <li><a href="http://bakery.cakephp.org"><?php echo __d('cake', 'The Bakery'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Everything CakePHP'); ?></li></ul></li>
+ <li><a href="http://astore.amazon.com/cakesoftwaref-20/"><?php echo __d('cake', 'Book Store'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Recommended Software Books'); ?></li></ul></li>
+ <li><a href="http://www.cafepress.com/cakefoundation"><?php echo __d('cake', 'CakeSchwag'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Get your own CakePHP gear - Doughnate to Cake'); ?></li></ul></li>
+ <li><a href="http://www.cakephp.org"><?php echo __d('cake', 'CakePHP'); ?> </a>
+ <ul><li><?php echo __d('cake', 'The Rapid Development Framework'); ?></li></ul></li>
+ <li><a href="http://manual.cakephp.org"><?php echo __d('cake', 'CakePHP Manual'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Your Rapid Development Cookbook'); ?></li></ul></li>
+ <li><a href="http://api.cakephp.org"><?php echo __d('cake', 'CakePHP API'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Docblock Your Best Friend'); ?></li></ul></li>
+ <li><a href="http://www.cakeforge.org"><?php echo __d('cake', 'CakeForge'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Open Development for CakePHP'); ?></li></ul></li>
+ <li><a href="https://trac.cakephp.org/"><?php echo __d('cake', 'CakePHP Trac'); ?> </a>
+ <ul><li><?php echo __d('cake', 'For the Development of CakePHP (Tickets, SVN browser, Roadmap, Changelogs)'); ?></li></ul></li>
+ <li><a href="http://groups-beta.google.com/group/cake-php"><?php echo __d('cake', 'CakePHP Google Group'); ?> </a>
+ <ul><li><?php echo __d('cake', 'Community mailing list'); ?></li></ul></li>
+ <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
+ <ul><li><?php echo __d('cake', 'Live chat about CakePHP'); ?></li></ul></li>
+</ul>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/xml/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/xml/index.ctp
new file mode 100644
index 0000000..7d49b03
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Posts/xml/index.ctp
@@ -0,0 +1,6 @@
+<?php
+$data = array('users' => array('user' => array()));
+foreach ($users as $user) {
+ $data['users']['user'][] = array('@' => $user['User']['username']);
+}
+echo Xml::fromArray($data)->saveXml();
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Scaffolds/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Scaffolds/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Scaffolds/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/index.ctp
new file mode 100644
index 0000000..dc1d03e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/index.ctp
@@ -0,0 +1 @@
+This is the TestsAppsController index view <?php echo isset($var) ? $var : ''; ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/json/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/json/index.ctp
new file mode 100644
index 0000000..49236e7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/TestsApps/json/index.ctp
@@ -0,0 +1 @@
+{"cakephp":"cool"} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Elements/test_element.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Elements/test_element.ctp
new file mode 100644
index 0000000..745dddb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Elements/test_element.ctp
@@ -0,0 +1 @@
+Hi, I'm the test element. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Emails/text/themed.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Emails/text/themed.ctp
new file mode 100644
index 0000000..5ea24fb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Emails/text/themed.ctp
@@ -0,0 +1 @@
+In TestTheme
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Layouts/default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Layouts/default.ctp
new file mode 100644
index 0000000..f055297
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Layouts/default.ctp
@@ -0,0 +1,2 @@
+default test_theme layout
+<?php echo $content_for_layout ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Emails/text/test_plugin_tpl.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Emails/text/test_plugin_tpl.ctp
new file mode 100644
index 0000000..74a205d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Emails/text/test_plugin_tpl.ctp
@@ -0,0 +1 @@
+Into TestPlugin. (themed)
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Layouts/plugin_default.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Layouts/plugin_default.ctp
new file mode 100644
index 0000000..9e1e449
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Layouts/plugin_default.ctp
@@ -0,0 +1 @@
+test_plugin test_plugin_theme default layout \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Tests/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Tests/index.ctp
new file mode 100644
index 0000000..edf7ab4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Plugin/TestPlugin/Tests/index.ctp
@@ -0,0 +1 @@
+test plugin index theme view \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/index.ctp
new file mode 100644
index 0000000..3ec978c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/index.ctp
@@ -0,0 +1 @@
+posts index themed view \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/scaffold.index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/scaffold.index.ctp
new file mode 100644
index 0000000..a782987
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/scaffold.index.ctp
@@ -0,0 +1 @@
+I'm a themed scaffold file. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/themed.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/themed.ctp
new file mode 100644
index 0000000..b8492b1
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/Posts/themed.ctp
@@ -0,0 +1,4 @@
+posts themed themed file.
+<!--nocache-->
+<?php echo $this->element('test_element'); ?>
+<!--/nocache-->
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/test_asset.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/test_asset.css
new file mode 100644
index 0000000..e8b09dd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/test_asset.css
@@ -0,0 +1 @@
+this is the test asset css file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/theme_webroot.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/theme_webroot.css
new file mode 100644
index 0000000..12e29a5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/css/theme_webroot.css
@@ -0,0 +1 @@
+theme webroot css file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/flash/theme_test.swf b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/flash/theme_test.swf
new file mode 100644
index 0000000..cfe782b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/flash/theme_test.swf
@@ -0,0 +1 @@
+this is just a test to load swf file from the theme. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/cake.power.gif b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/cake.power.gif
new file mode 100644
index 0000000..8f8d570
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/cake.power.gif
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/test.jpg b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/test.jpg
new file mode 100644
index 0000000..ca5197a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/img/test.jpg
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/one/theme_one.js b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/one/theme_one.js
new file mode 100644
index 0000000..d29bcbc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/one/theme_one.js
@@ -0,0 +1 @@
+nested theme js file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/theme.js b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/theme.js
new file mode 100644
index 0000000..ec17940
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/js/theme.js
@@ -0,0 +1 @@
+root theme js file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/pdfs/theme_test.pdf b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/pdfs/theme_test.pdf
new file mode 100644
index 0000000..9c1dcbc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/pdfs/theme_test.pdf
@@ -0,0 +1 @@
+this is just a test to load pdf file from the theme. \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/space image.text b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/space image.text
new file mode 100644
index 0000000..7ba4f07
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/View/Themed/TestTheme/webroot/space image.text
@@ -0,0 +1 @@
+This is not an image.
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/tmp/dir_map b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/tmp/dir_map
new file mode 100644
index 0000000..1f8b2ba
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/tmp/dir_map
@@ -0,0 +1,2 @@
+1845415352
+a:4:{s:27:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs";a:24:{i:0;s:27:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs";i:1;s:32:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view";i:2;s:42:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\scaffolds";i:3;s:38:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\pages";i:4;s:40:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\layouts";i:5;s:44:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\layouts\\\\xml";i:6;s:44:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\layouts\\\\rss";i:7;s:43:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\layouts\\\\js";i:8;s:46:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\layouts\\\\email";i:9;s:51:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\layouts\\\\email\\\\text";i:10;s:51:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\layouts\\\\email\\\\html";i:11;s:40:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\helpers";i:12;s:39:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\errors";i:13;s:41:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\elements";i:14;s:47:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\elements\\\\email";i:15;s:52:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\elements\\\\email\\\\text";i:16;s:52:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\view\\\\elements\\\\email\\\\html";i:17;s:33:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\model";i:18;s:45:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\model\\\\datasources";i:19;s:49:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\model\\\\datasources\\\\dbo";i:20;s:43:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\model\\\\behaviors";i:21;s:38:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\controller";i:22;s:49:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\controller\\\\components";i:23;s:33:"C:\\\\dev\\\\prj2\\\\sites\\\\cake\\\\libs\\\\cache";}s:35:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors";a:7:{i:0;s:35:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors";i:1;s:42:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors\\\\shells";i:2;s:52:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors\\\\shells\\\\templates";i:3;s:64:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors\\\\shells\\\\templates\\\\cdc_project";i:4;s:48:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors\\\\shells\\\\tasks";i:5;s:38:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors\\\\js";i:6;s:39:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\vendors\\\\css";}s:25:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors";a:10:{i:0;s:25:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors";i:1;s:36:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest";i:2;s:41:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\test";i:3;s:49:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\test\\\\support";i:4;s:59:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\test\\\\support\\\\collector";i:5;s:47:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\extensions";i:6;s:55:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\extensions\\\\testdox";i:7;s:41:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\docs";i:8;s:44:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\docs\\\\fr";i:9;s:44:"C:\\\\dev\\\\prj2\\\\sites\\\\vendors\\\\simpletest\\\\docs\\\\en";}s:41:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\views\\\\helpers";a:1:{i:0;s:41:"C:\\\\dev\\\\prj2\\\\sites\\\\main_site\\\\views\\\\helpers";}}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/img/cake.power.gif b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/img/cake.power.gif
new file mode 100644
index 0000000..8f8d570
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/img/cake.power.gif
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/theme_webroot.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/theme_webroot.css
new file mode 100644
index 0000000..f65d3e0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/theme_webroot.css
@@ -0,0 +1 @@
+override the theme webroot css file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/webroot_test.css b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/webroot_test.css
new file mode 100644
index 0000000..83c3bc4
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/css/webroot_test.css
@@ -0,0 +1 @@
+this is the webroot test asset css file \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/cake.power.gif b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/cake.power.gif
new file mode 100644
index 0000000..8f8d570
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/cake.power.gif
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/test.jpg b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/test.jpg
new file mode 100644
index 0000000..ca5197a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Test/test_app/webroot/theme/test_theme/img/test.jpg
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestCase.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestCase.php
new file mode 100644
index 0000000..3509243
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestCase.php
@@ -0,0 +1,679 @@
+<?php
+/**
+ * CakeTestCase file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeFixtureManager', 'TestSuite/Fixture');
+App::uses('CakeTestFixture', 'TestSuite/Fixture');
+
+/**
+ * CakeTestCase class
+ *
+ * @package Cake.TestSuite
+ */
+abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
+
+/**
+ * The class responsible for managing the creation, loading and removing of fixtures
+ *
+ * @var CakeFixtureManager
+ */
+ public $fixtureManager = null;
+
+/**
+ * By default, all fixtures attached to this class will be truncated and reloaded after each test.
+ * Set this to false to handle manually
+ *
+ * @var array
+ */
+ public $autoFixtures = true;
+
+/**
+ * Set this to false to avoid tables to be dropped if they already exist
+ *
+ * @var boolean
+ */
+ public $dropTables = true;
+
+/**
+ * Configure values to restore at end of test.
+ *
+ * @var array
+ */
+ protected $_configure = array();
+
+/**
+ * Path settings to restore at the end of the test.
+ *
+ * @var array
+ */
+ protected $_pathRestore = array();
+
+/**
+ * Runs the test case and collects the results in a TestResult object.
+ * If no TestResult object is passed a new one will be created.
+ * This method is run for each test method in this class
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ * @return PHPUnit_Framework_TestResult
+ * @throws InvalidArgumentException
+ */
+ public function run(PHPUnit_Framework_TestResult $result = null) {
+ if (!empty($this->fixtureManager)) {
+ $this->fixtureManager->load($this);
+ }
+ $result = parent::run($result);
+ if (!empty($this->fixtureManager)) {
+ $this->fixtureManager->unload($this);
+ }
+ return $result;
+ }
+
+/**
+ * Called when a test case method is about to start (to be overridden when needed.)
+ *
+ * @param string $method Test method about to get executed.
+ * @return void
+ */
+ public function startTest($method) {
+ }
+
+/**
+ * Called when a test case method has been executed (to be overridden when needed.)
+ *
+ * @param string $method Test method about that was executed.
+ * @return void
+ */
+ public function endTest($method) {
+ }
+
+/**
+ * Overrides SimpleTestCase::skipIf to provide a boolean return value
+ *
+ * @param boolean $shouldSkip
+ * @param string $message
+ * @return boolean
+ */
+ public function skipIf($shouldSkip, $message = '') {
+ if ($shouldSkip) {
+ $this->markTestSkipped($message);
+ }
+ return $shouldSkip;
+ }
+
+/**
+ * Setup the test case, backup the static object values so they can be restored.
+ * Specifically backs up the contents of Configure and paths in App if they have
+ * not already been backed up.
+ *
+ * @return void
+ */
+ public function setUp() {
+ parent::setUp();
+
+ if (empty($this->_configure)) {
+ $this->_configure = Configure::read();
+ }
+ if (empty($this->_pathRestore)) {
+ $this->_pathRestore = App::paths();
+ }
+ if (class_exists('Router', false)) {
+ Router::reload();
+ }
+ }
+
+/**
+ * teardown any static object changes and restore them.
+ *
+ * @return void
+ */
+ public function tearDown() {
+ parent::tearDown();
+ App::build($this->_pathRestore, App::RESET);
+ if (class_exists('ClassRegistry', false)) {
+ ClassRegistry::flush();
+ }
+ if (!empty($this->_configure)) {
+ Configure::clear();
+ Configure::write($this->_configure);
+ }
+ if (isset($_GET['debug']) && $_GET['debug']) {
+ ob_flush();
+ }
+ }
+
+/**
+ * See CakeTestSuiteDispatcher::date()
+ *
+ * @param string $format format to be used.
+ * @return string
+ */
+ public static function date($format = 'Y-m-d H:i:s') {
+ return CakeTestSuiteDispatcher::date($format);
+ }
+
+// @codingStandardsIgnoreStart PHPUnit overrides don't match CakePHP
+
+/**
+ * Announces the start of a test.
+ *
+ * @param string $method Test method just started.
+ * @return void
+ */
+ protected function assertPreConditions() {
+ parent::assertPreConditions();
+ $this->startTest($this->getName());
+ }
+
+/**
+ * Announces the end of a test.
+ *
+ * @param string $method Test method just finished.
+ * @return void
+ */
+ protected function assertPostConditions() {
+ parent::assertPostConditions();
+ $this->endTest($this->getName());
+ }
+
+// @codingStandardsIgnoreEnd
+
+/**
+ * Chooses which fixtures to load for a given test
+ *
+ * @param string $fixture Each parameter is a model name that corresponds to a
+ * fixture, i.e. 'Post', 'Author', etc.
+ * @return void
+ * @see CakeTestCase::$autoFixtures
+ * @throws Exception when no fixture manager is available.
+ */
+ public function loadFixtures() {
+ if (empty($this->fixtureManager)) {
+ throw new Exception(__d('cake_dev', 'No fixture manager to load the test fixture'));
+ }
+ $args = func_get_args();
+ foreach ($args as $class) {
+ $this->fixtureManager->loadSingle($class);
+ }
+ }
+
+/**
+ * Assert text equality, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $expected The expected value.
+ * @param string $result The actual value.
+ * @param message The message to use for failure.
+ * @return boolean
+ */
+ public function assertTextNotEquals($expected, $result, $message = '') {
+ $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
+ $result = str_replace(array("\r\n", "\r"), "\n", $result);
+ return $this->assertNotEquals($expected, $result, $message);
+ }
+
+/**
+ * Assert text equality, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $expected The expected value.
+ * @param string $result The actual value.
+ * @param message The message to use for failure.
+ * @return boolean
+ */
+ public function assertTextEquals($expected, $result, $message = '') {
+ $expected = str_replace(array("\r\n", "\r"), "\n", $expected);
+ $result = str_replace(array("\r\n", "\r"), "\n", $result);
+ return $this->assertEquals($expected, $result, $message);
+ }
+
+/**
+ * Asserts that a string starts with a given prefix, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $prefix
+ * @param string $string
+ * @param string $message
+ * @return boolean
+ */
+ public function assertTextStartsWith($prefix, $string, $message = '') {
+ $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
+ $string = str_replace(array("\r\n", "\r"), "\n", $string);
+ return $this->assertStringStartsWith($prefix, $string, $message);
+ }
+
+/**
+ * Asserts that a string starts not with a given prefix, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $prefix
+ * @param string $string
+ * @param string $message
+ * @return boolean
+ */
+ public function assertTextStartsNotWith($prefix, $string, $message = '') {
+ $prefix = str_replace(array("\r\n", "\r"), "\n", $prefix);
+ $string = str_replace(array("\r\n", "\r"), "\n", $string);
+ return $this->assertStringStartsNotWith($prefix, $string, $message);
+ }
+
+/**
+ * Asserts that a string ends with a given prefix, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $suffix
+ * @param string $string
+ * @param string $message
+ * @return boolean
+ */
+ public function assertTextEndsWith($suffix, $string, $message = '') {
+ $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
+ $string = str_replace(array("\r\n", "\r"), "\n", $string);
+ return $this->assertStringEndsWith($suffix, $string, $message);
+ }
+
+/**
+ * Asserts that a string ends not with a given prefix, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $suffix
+ * @param string $string
+ * @param string $message
+ * @return boolean
+ */
+ public function assertTextEndsNotWith($suffix, $string, $message = '') {
+ $suffix = str_replace(array("\r\n", "\r"), "\n", $suffix);
+ $string = str_replace(array("\r\n", "\r"), "\n", $string);
+ return $this->assertStringEndsNotWith($suffix, $string, $message);
+ }
+
+/**
+ * Assert that a string contains another string, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $needle
+ * @param string $haystack
+ * @param string $message
+ * @param boolean $ignoreCase
+ * @return boolean
+ */
+ public function assertTextContains($needle, $haystack, $message = '', $ignoreCase = false) {
+ $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
+ $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
+ return $this->assertContains($needle, $haystack, $message, $ignoreCase);
+ }
+
+/**
+ * Assert that a text doesn't contain another text, ignoring differences in newlines.
+ * Helpful for doing cross platform tests of blocks of text.
+ *
+ * @param string $needle
+ * @param string $haystack
+ * @param string $message
+ * @param boolean $ignoreCase
+ * @return boolean
+ */
+ public function assertTextNotContains($needle, $haystack, $message = '', $ignoreCase = false) {
+ $needle = str_replace(array("\r\n", "\r"), "\n", $needle);
+ $haystack = str_replace(array("\r\n", "\r"), "\n", $haystack);
+ return $this->assertNotContains($needle, $haystack, $message, $ignoreCase);
+ }
+
+/**
+ * Takes an array $expected and generates a regex from it to match the provided $string.
+ * Samples for $expected:
+ *
+ * Checks for an input tag with a name attribute (contains any non-empty value) and an id
+ * attribute that contains 'my-input':
+ * array('input' => array('name', 'id' => 'my-input'))
+ *
+ * Checks for two p elements with some text in them:
+ * array(
+ * array('p' => true),
+ * 'textA',
+ * '/p',
+ * array('p' => true),
+ * 'textB',
+ * '/p'
+ * )
+ *
+ * You can also specify a pattern expression as part of the attribute values, or the tag
+ * being defined, if you prepend the value with preg: and enclose it with slashes, like so:
+ * array(
+ * array('input' => array('name', 'id' => 'preg:/FieldName\d+/')),
+ * 'preg:/My\s+field/'
+ * )
+ *
+ * Important: This function is very forgiving about whitespace and also accepts any
+ * permutation of attribute order. It will also allow whitespace between specified tags.
+ *
+ * @param string $string An HTML/XHTML/XML string
+ * @param array $expected An array, see above
+ * @param string $message SimpleTest failure output string
+ * @return boolean
+ */
+ public function assertTags($string, $expected, $fullDebug = false) {
+ $regex = array();
+ $normalized = array();
+ foreach ((array)$expected as $key => $val) {
+ if (!is_numeric($key)) {
+ $normalized[] = array($key => $val);
+ } else {
+ $normalized[] = $val;
+ }
+ }
+ $i = 0;
+ foreach ($normalized as $tags) {
+ if (!is_array($tags)) {
+ $tags = (string)$tags;
+ }
+ $i++;
+ if (is_string($tags) && $tags{0} == '<') {
+ $tags = array(substr($tags, 1) => array());
+ } elseif (is_string($tags)) {
+ $tagsTrimmed = preg_replace('/\s+/m', '', $tags);
+
+ if (preg_match('/^\*?\//', $tags, $match) && $tagsTrimmed !== '//') {
+ $prefix = array(null, null);
+
+ if ($match[0] == '*/') {
+ $prefix = array('Anything, ', '.*?');
+ }
+ $regex[] = array(
+ sprintf('%sClose %s tag', $prefix[0], substr($tags, strlen($match[0]))),
+ sprintf('%s<[\s]*\/[\s]*%s[\s]*>[\n\r]*', $prefix[1], substr($tags, strlen($match[0]))),
+ $i,
+ );
+ continue;
+ }
+ if (!empty($tags) && preg_match('/^preg\:\/(.+)\/$/i', $tags, $matches)) {
+ $tags = $matches[1];
+ $type = 'Regex matches';
+ } else {
+ $tags = preg_quote($tags, '/');
+ $type = 'Text equals';
+ }
+ $regex[] = array(
+ sprintf('%s "%s"', $type, $tags),
+ $tags,
+ $i,
+ );
+ continue;
+ }
+ foreach ($tags as $tag => $attributes) {
+ $regex[] = array(
+ sprintf('Open %s tag', $tag),
+ sprintf('[\s]*<%s', preg_quote($tag, '/')),
+ $i,
+ );
+ if ($attributes === true) {
+ $attributes = array();
+ }
+ $attrs = array();
+ $explanations = array();
+ $i = 1;
+ foreach ($attributes as $attr => $val) {
+ if (is_numeric($attr) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
+ $attrs[] = $matches[1];
+ $explanations[] = sprintf('Regex "%s" matches', $matches[1]);
+ continue;
+ } else {
+ $quotes = '["\']';
+ if (is_numeric($attr)) {
+ $attr = $val;
+ $val = '.+?';
+ $explanations[] = sprintf('Attribute "%s" present', $attr);
+ } elseif (!empty($val) && preg_match('/^preg\:\/(.+)\/$/i', $val, $matches)) {
+ $quotes = '["\']?';
+ $val = $matches[1];
+ $explanations[] = sprintf('Attribute "%s" matches "%s"', $attr, $val);
+ } else {
+ $explanations[] = sprintf('Attribute "%s" == "%s"', $attr, $val);
+ $val = preg_quote($val, '/');
+ }
+ $attrs[] = '[\s]+' . preg_quote($attr, '/') . '=' . $quotes . $val . $quotes;
+ }
+ $i++;
+ }
+ if ($attrs) {
+ $permutations = $this->_arrayPermute($attrs);
+
+ $permutationTokens = array();
+ foreach ($permutations as $permutation) {
+ $permutationTokens[] = implode('', $permutation);
+ }
+ $regex[] = array(
+ sprintf('%s', implode(', ', $explanations)),
+ $permutationTokens,
+ $i,
+ );
+ }
+ $regex[] = array(
+ sprintf('End %s tag', $tag),
+ '[\s]*\/?[\s]*>[\n\r]*',
+ $i,
+ );
+ }
+ }
+ foreach ($regex as $i => $assertation) {
+ list($description, $expressions, $itemNum) = $assertation;
+ $matches = false;
+ foreach ((array)$expressions as $expression) {
+ if (preg_match(sprintf('/^%s/s', $expression), $string, $match)) {
+ $matches = true;
+ $string = substr($string, strlen($match[0]));
+ break;
+ }
+ }
+ if (!$matches) {
+ $this->assertTrue(false, sprintf('Item #%d / regex #%d failed: %s', $itemNum, $i, $description));
+ if ($fullDebug) {
+ debug($string, true);
+ debug($regex, true);
+ }
+ return false;
+ }
+ }
+
+ $this->assertTrue(true, '%s');
+ return true;
+ }
+
+/**
+ * Generates all permutation of an array $items and returns them in a new array.
+ *
+ * @param array $items An array of items
+ * @return array
+ */
+ protected function _arrayPermute($items, $perms = array()) {
+ static $permuted;
+ if (empty($perms)) {
+ $permuted = array();
+ }
+
+ if (empty($items)) {
+ $permuted[] = $perms;
+ } else {
+ $numItems = count($items) - 1;
+ for ($i = $numItems; $i >= 0; --$i) {
+ $newItems = $items;
+ $newPerms = $perms;
+ list($tmp) = array_splice($newItems, $i, 1);
+ array_unshift($newPerms, $tmp);
+ $this->_arrayPermute($newItems, $newPerms);
+ }
+ return $permuted;
+ }
+ }
+
+// @codingStandardsIgnoreStart
+
+/**
+ * Compatibility wrapper function for assertEquals
+ *
+ *
+ * @param mixed $result
+ * @param mixed $expected
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertEqual($result, $expected, $message = '') {
+ return self::assertEquals($expected, $result, $message);
+ }
+
+/**
+ * Compatibility wrapper function for assertNotEquals
+ *
+ * @param mixed $result
+ * @param mixed $expected
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertNotEqual($result, $expected, $message = '') {
+ return self::assertNotEquals($expected, $result, $message);
+ }
+
+/**
+ * Compatibility wrapper function for assertRegexp
+ *
+ * @param mixed $pattern a regular expression
+ * @param string $string the text to be matched
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertPattern($pattern, $string, $message = '') {
+ return self::assertRegExp($pattern, $string, $message);
+ }
+
+/**
+ * Compatibility wrapper function for assertEquals
+ *
+ * @param mixed $actual
+ * @param mixed $expected
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertIdentical($actual, $expected, $message = '') {
+ return self::assertSame($expected, $actual, $message);
+ }
+
+/**
+ * Compatibility wrapper function for assertNotEquals
+ *
+ * @param mixed $actual
+ * @param mixed $expected
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertNotIdentical($actual, $expected, $message = '') {
+ return self::assertNotSame($expected, $actual, $message);
+ }
+
+/**
+ * Compatibility wrapper function for assertNotRegExp
+ *
+ * @param mixed $pattern a regular expression
+ * @param string $string the text to be matched
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertNoPattern($pattern, $string, $message = '') {
+ return self::assertNotRegExp($pattern, $string, $message);
+ }
+
+ protected function assertNoErrors() {
+ }
+
+/**
+ * Compatibility wrapper function for setExpectedException
+ *
+ * @param mixed $expected the name of the Exception or error
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected function expectError($expected = false, $message = '') {
+ if (!$expected) {
+ $expected = 'Exception';
+ }
+ $this->setExpectedException($expected, $message);
+ }
+
+/**
+ * Compatibility wrapper function for setExpectedException
+ *
+ * @param mixed $expected the name of the Exception
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected function expectException($name = 'Exception', $message = '') {
+ $this->setExpectedException($name, $message);
+ }
+
+/**
+ * Compatibility wrapper function for assertSame
+ *
+ * @param mixed $first
+ * @param mixed $second
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertReference(&$first, &$second, $message = '') {
+ return self::assertSame($first, $second, $message);
+ }
+
+/**
+ * Compatibility wrapper for assertIsA
+ *
+ * @param string $object
+ * @param string $type
+ * @param string $message
+ * @return void
+ */
+ protected static function assertIsA($object, $type, $message = '') {
+ return self::assertInstanceOf($type, $object, $message);
+ }
+
+/**
+ * Compatibility function to test if value is between an acceptable range
+ *
+ * @param mixed $result
+ * @param mixed $expected
+ * @param mixed $margin the rage of acceptation
+ * @param string $message the text to display if the assertion is not correct
+ * @return void
+ */
+ protected static function assertWithinMargin($result, $expected, $margin, $message = '') {
+ $upper = $result + $margin;
+ $lower = $result - $margin;
+ return self::assertTrue((($expected <= $upper) && ($expected >= $lower)), $message);
+ }
+
+/**
+ * Compatibility function for skipping.
+ *
+ * @param boolean $condition Condition to trigger skipping
+ * @param string $message Message for skip
+ * @return boolean
+ */
+ protected function skipUnless($condition, $message = '') {
+ if (!$condition) {
+ $this->markTestSkipped($message);
+ }
+ return $condition;
+ }
+ // @codingStandardsIgnoreStop
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestLoader.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestLoader.php
new file mode 100644
index 0000000..83a3607
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestLoader.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * TestLoader for CakePHP Test suite.
+ *
+ * Turns partial paths used on the testsuite console and web UI into full file paths.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ * @package Cake.TestSuite
+ */
+
+/**
+ * TestLoader for CakePHP Test suite.
+ *
+ * Turns partial paths used on the testsuite console and web UI into full file paths.
+ *
+ * @package Cake.TestSuite
+ */
+class CakeTestLoader extends PHPUnit_Runner_StandardTestSuiteLoader {
+
+/**
+ * Load a file and find the first test case / suite in that file.
+ *
+ * @param string $filePath
+ * @param string $params
+ * @return ReflectionClass
+ */
+ public function load($filePath, $params = '') {
+ $file = $this->_resolveTestFile($filePath, $params);
+ return parent::load('', $file);
+ }
+
+/**
+ * Convert path fragments used by Cake's test runner to absolute paths that can be fed to PHPUnit.
+ *
+ * @return void
+ */
+ protected function _resolveTestFile($filePath, $params) {
+ $basePath = $this->_basePath($params) . DS . $filePath;
+ $ending = 'Test.php';
+ return (strpos($basePath, $ending) === (strlen($basePath) - strlen($ending))) ? $basePath : $basePath . $ending;
+ }
+
+/**
+ * Generates the base path to a set of tests based on the parameters.
+ *
+ * @param array $params
+ * @return string The base path.
+ */
+ protected static function _basePath($params) {
+ $result = null;
+ if (!empty($params['core'])) {
+ $result = CORE_TEST_CASES;
+ } elseif (!empty($params['plugin'])) {
+ if (!CakePlugin::loaded($params['plugin'])) {
+ try {
+ CakePlugin::load($params['plugin']);
+ $result = CakePlugin::path($params['plugin']) . 'Test' . DS . 'Case';
+ } catch (MissingPluginException $e) {
+ }
+ } else {
+ $result = CakePlugin::path($params['plugin']) . 'Test' . DS . 'Case';
+ }
+ } elseif (!empty($params['app'])) {
+ $result = APP_TEST_CASES;
+ }
+ return $result;
+ }
+
+/**
+ * Get the list of files for the test listing.
+ *
+ * @return void
+ */
+ public static function generateTestList($params) {
+ $directory = self::_basePath($params);
+ $fileList = self::_getRecursiveFileList($directory);
+
+ $testCases = array();
+ foreach ($fileList as $testCaseFile) {
+ $case = str_replace($directory . DS, '', $testCaseFile);
+ $case = str_replace('Test.php', '', $case);
+ $testCases[$testCaseFile] = $case;
+ }
+ sort($testCases);
+ return $testCases;
+ }
+
+/**
+ * Gets a recursive list of files from a given directory and matches then against
+ * a given fileTestFunction, like isTestCaseFile()
+ *
+ * @param string $directory The directory to scan for files.
+ * @param mixed $fileTestFunction
+ */
+ protected static function _getRecursiveFileList($directory = '.') {
+ $fileList = array();
+ if (!is_dir($directory)) {
+ return $fileList;
+ }
+
+ $files = new RegexIterator(
+ new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)),
+ '/.*Test.php$/'
+ );
+
+ foreach ($files as $file) {
+ $fileList[] = $file->getPathname();
+ }
+ return $fileList;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestRunner.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestRunner.php
new file mode 100644
index 0000000..e2f39cd
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestRunner.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * TestRunner for CakePHP Test suite.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+/**
+ * A custom test runner for Cake's use of PHPUnit.
+ *
+ * @package Cake.TestSuite
+ */
+class CakeTestRunner extends PHPUnit_TextUI_TestRunner {
+
+/**
+ * Lets us pass in some options needed for cake's webrunner.
+ *
+ * @return void
+ */
+ public function __construct($loader, $params) {
+ parent::__construct($loader);
+ $this->_params = $params;
+ }
+
+/**
+ * Actually run a suite of tests. Cake initializes fixtures here using the chosen fixture manager
+ *
+ * @param PHPUnit_Framework_Test $suite
+ * @param array $arguments
+ * @return void
+ */
+ public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array()) {
+ if (isset($arguments['printer'])) {
+ self::$versionStringPrinted = true;
+ }
+
+ $fixture = $this->_getFixtureManager($arguments);
+ foreach ($suite->getIterator() as $test) {
+ if ($test instanceof CakeTestCase) {
+ $fixture->fixturize($test);
+ $test->fixtureManager = $fixture;
+ }
+ }
+
+ $return = parent::doRun($suite, $arguments);
+ $fixture->shutdown();
+ return $return;
+ }
+
+// @codingStandardsIgnoreStart PHPUnit overrides don't match CakePHP
+/**
+ * Create the test result and splice on our code coverage reports.
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ protected function createTestResult() {
+ $result = new PHPUnit_Framework_TestResult;
+ if (!empty($this->_params['codeCoverage'])) {
+ if (method_exists($result, 'collectCodeCoverageInformation')) {
+ $result->collectCodeCoverageInformation(true);
+ }
+ if (method_exists($result, 'setCodeCoverage')) {
+ $result->setCodeCoverage(new PHP_CodeCoverage());
+ }
+ }
+ return $result;
+ }
+// @codingStandardsIgnoreEnd
+
+/**
+ * Get the fixture manager class specified or use the default one.
+ *
+ * @return instance of a fixture manager.
+ * @throws RuntimeException When fixture manager class cannot be loaded.
+ */
+ protected function _getFixtureManager($arguments) {
+ if (isset($arguments['fixtureManager'])) {
+ App::uses($arguments['fixtureManager'], 'TestSuite');
+ if (class_exists($arguments['fixtureManager'])) {
+ return new $arguments['fixtureManager'];
+ }
+ throw new RuntimeException(__d('cake_dev', 'Could not find fixture manager %s.', $arguments['fixtureManager']));
+ }
+ App::uses('AppFixtureManager', 'TestSuite');
+ if (class_exists('AppFixtureManager')) {
+ return new AppFixtureManager();
+ }
+ return new CakeFixtureManager();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuite.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuite.php
new file mode 100644
index 0000000..ca478a0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuite.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * A class to contain test cases and run them with shared fixtures
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.TestSuite
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Folder', 'Utility');
+
+/**
+ * A class to contain test cases and run them with shared fixtures
+ *
+ * @package Cake.TestSuite
+ */
+class CakeTestSuite extends PHPUnit_Framework_TestSuite {
+
+/**
+ * Adds all the files in a directory to the test suite. Does not recurse through directories.
+ *
+ * @param string $directory The directory to add tests from.
+ * @return void
+ */
+ public function addTestDirectory($directory = '.') {
+ $Folder = new Folder($directory);
+ list($dirs, $files) = $Folder->read(true, true, true);
+
+ foreach ($files as $file) {
+ if (substr($file, -4) === '.php') {
+ $this->addTestFile($file);
+ }
+ }
+ }
+
+/**
+ * Recursively adds all the files in a directory to the test suite.
+ *
+ * @param string $directory The directory subtree to add tests from.
+ * @return void
+ */
+ public function addTestDirectoryRecursive($directory = '.') {
+ $Folder = new Folder($directory);
+ $files = $Folder->tree(null, true, 'files');
+
+ foreach ($files as $file) {
+ if (substr($file, -4) === '.php') {
+ $this->addTestFile($file);
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteCommand.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteCommand.php
new file mode 100644
index 0000000..6d410ec
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteCommand.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * TestRunner for CakePHP Test suite.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.TestSuite
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+require_once 'PHPUnit/TextUI/Command.php';
+
+App::uses('CakeTestRunner', 'TestSuite');
+App::uses('CakeTestLoader', 'TestSuite');
+App::uses('CakeTestSuite', 'TestSuite');
+App::uses('CakeTestCase', 'TestSuite');
+App::uses('ControllerTestCase', 'TestSuite');
+App::uses('CakeTestModel', 'TestSuite/Fixture');
+
+/**
+ * Class to customize loading of test suites from CLI
+ *
+ * @package Cake.TestSuite
+ */
+class CakeTestSuiteCommand extends PHPUnit_TextUI_Command {
+
+/**
+ * Construct method
+ *
+ * @param array $params list of options to be used for this run
+ * @throws MissingTestLoaderException When a loader class could not be found.
+ */
+ public function __construct($loader, $params = array()) {
+ if ($loader && !class_exists($loader)) {
+ throw new MissingTestLoaderException(array('class' => $loader));
+ }
+ $this->arguments['loader'] = $loader;
+ $this->arguments['test'] = $params['case'];
+ $this->arguments['testFile'] = $params;
+ $this->_params = $params;
+
+ $this->longOptions['fixture='] = 'handleFixture';
+ $this->longOptions['output='] = 'handleReporter';
+ }
+
+/**
+ * Ugly hack to get around PHPUnit having a hard coded classname for the Runner. :(
+ *
+ * @param array $argv
+ * @param boolean $exit
+ */
+ public function run(array $argv, $exit = true) {
+ $this->handleArguments($argv);
+
+ $runner = $this->getRunner($this->arguments['loader']);
+
+ if (is_object($this->arguments['test']) &&
+ $this->arguments['test'] instanceof PHPUnit_Framework_Test) {
+ $suite = $this->arguments['test'];
+ } else {
+ $suite = $runner->getTest(
+ $this->arguments['test'],
+ $this->arguments['testFile']
+ );
+ }
+
+ if (count($suite) == 0) {
+ $skeleton = new PHPUnit_Util_Skeleton_Test(
+ $suite->getName(),
+ $this->arguments['testFile']
+ );
+
+ $result = $skeleton->generate(true);
+
+ if (!$result['incomplete']) {
+ eval(str_replace(array('<?php', '?>'), '', $result['code']));
+ $suite = new PHPUnit_Framework_TestSuite(
+ $this->arguments['test'] . 'Test'
+ );
+ }
+ }
+
+ if ($this->arguments['listGroups']) {
+ PHPUnit_TextUI_TestRunner::printVersionString();
+
+ print "Available test group(s):\n";
+
+ $groups = $suite->getGroups();
+ sort($groups);
+
+ foreach ($groups as $group) {
+ print " - $group\n";
+ }
+
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ }
+
+ unset($this->arguments['test']);
+ unset($this->arguments['testFile']);
+
+ try {
+ $result = $runner->doRun($suite, $this->arguments);
+ } catch (PHPUnit_Framework_Exception $e) {
+ print $e->getMessage() . "\n";
+ }
+
+ if ($exit) {
+ if (isset($result) && $result->wasSuccessful()) {
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ } elseif (!isset($result) || $result->errorCount() > 0) {
+ exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
+ } else {
+ exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
+ }
+ }
+ }
+
+/**
+ * Create a runner for the command.
+ *
+ * @param $loader The loader to be used for the test run.
+ * @return CakeTestRunner
+ */
+ public function getRunner($loader) {
+ return new CakeTestRunner($loader, $this->_params);
+ }
+
+/**
+ * Handler for customizing the FixtureManager class/
+ *
+ * @param string $class Name of the class that will be the fixture manager
+ * @return void
+ */
+ public function handleFixture($class) {
+ $this->arguments['fixtureManager'] = $class;
+ }
+
+/**
+ * Handles output flag used to change printing on webrunner.
+ *
+ * @return void
+ */
+ public function handleReporter($reporter) {
+ $object = null;
+
+ $type = strtolower($reporter);
+ $reporter = ucwords($reporter);
+ $coreClass = 'Cake' . $reporter . 'Reporter';
+ App::uses($coreClass, 'TestSuite/Reporter');
+
+ $appClass = $reporter . 'Reporter';
+ App::uses($appClass, 'TestSuite/Reporter');
+
+ if (!class_exists($appClass)) {
+ $object = new $coreClass(null, $this->_params);
+ } else {
+ $object = new $appClass(null, $this->_params);
+ }
+ return $this->arguments['printer'] = $object;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php
new file mode 100644
index 0000000..20adfbf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/CakeTestSuiteDispatcher.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ * CakeTestSuiteDispatcher controls dispatching TestSuite web based requests.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.TestSuite
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+define('CORE_TEST_CASES', CAKE . 'Test' . DS . 'Case');
+define('APP_TEST_CASES', TESTS . 'Case');
+
+App::uses('CakeTestSuiteCommand', 'TestSuite');
+
+/**
+ * CakeTestSuiteDispatcher handles web requests to the test suite and runs the correct action.
+ *
+ * @package Cake.TestSuite
+ */
+class CakeTestSuiteDispatcher {
+
+/**
+ * 'Request' parameters
+ *
+ * @var array
+ */
+ public $params = array(
+ 'codeCoverage' => false,
+ 'case' => null,
+ 'core' => false,
+ 'app' => true,
+ 'plugin' => null,
+ 'output' => 'html',
+ 'show' => 'groups',
+ 'show_passes' => false,
+ 'filter' => false,
+ 'fixture' => null
+ );
+
+/**
+ * Baseurl for the request
+ *
+ * @var string
+ */
+ protected $_baseUrl;
+
+/**
+ * Base dir of the request. Used for accessing assets.
+ *
+ * @var string
+ */
+ protected $_baseDir;
+
+/**
+ * boolean to set auto parsing of params.
+ *
+ * @var boolean
+ */
+ protected $_paramsParsed = false;
+
+/**
+ * reporter instance used for the request
+ *
+ * @var CakeBaseReporter
+ */
+ protected static $_Reporter = null;
+
+/**
+ * constructor
+ *
+ * @return void
+ */
+ public function __construct() {
+ $this->_baseUrl = $_SERVER['PHP_SELF'];
+ $dir = rtrim(dirname($this->_baseUrl), '\\');
+ $this->_baseDir = ($dir === '/') ? $dir : $dir . '/';
+ }
+
+/**
+ * Runs the actions required by the URL parameters.
+ *
+ * @return void
+ */
+ public function dispatch() {
+ $this->_checkPHPUnit();
+ $this->_parseParams();
+
+ if ($this->params['case']) {
+ $value = $this->_runTestCase();
+ } else {
+ $value = $this->_testCaseList();
+ }
+
+ $output = ob_get_clean();
+ echo $output;
+ return $value;
+ }
+
+/**
+ * Static method to initialize the test runner, keeps global space clean
+ *
+ * @return void
+ */
+ public static function run() {
+ $dispatcher = new CakeTestSuiteDispatcher();
+ $dispatcher->dispatch();
+ }
+
+/**
+ * Checks that PHPUnit is installed. Will exit if it doesn't
+ *
+ * @return void
+ */
+ protected function _checkPHPUnit() {
+ $found = $this->loadTestFramework();
+ if (!$found) {
+ $baseDir = $this->_baseDir;
+ include CAKE . 'TestSuite' . DS . 'templates' . DS . 'phpunit.php';
+ exit();
+ }
+ }
+
+/**
+ * Checks for the existence of the test framework files
+ *
+ * @return boolean true if found, false otherwise
+ */
+ public function loadTestFramework() {
+ foreach (App::path('vendors') as $vendor) {
+ if (is_dir($vendor . 'PHPUnit')) {
+ ini_set('include_path', $vendor . PATH_SEPARATOR . ini_get('include_path'));
+ break;
+ }
+ }
+
+ return include 'PHPUnit' . DS . 'Autoload.php';
+ }
+
+/**
+ * Checks for the xdebug extension required to do code coverage. Displays an error
+ * if xdebug isn't installed.
+ *
+ * @return void
+ */
+ protected function _checkXdebug() {
+ if (!extension_loaded('xdebug')) {
+ $baseDir = $this->_baseDir;
+ include CAKE . 'TestSuite' . DS . 'templates' . DS . 'xdebug.php';
+ exit();
+ }
+ }
+
+/**
+ * Generates a page containing the a list of test cases that could be run.
+ *
+ * @return void
+ */
+ protected function _testCaseList() {
+ $command = new CakeTestSuiteCommand('', $this->params);
+ $Reporter = $command->handleReporter($this->params['output']);
+ $Reporter->paintDocumentStart();
+ $Reporter->paintTestMenu();
+ $Reporter->testCaseList();
+ $Reporter->paintDocumentEnd();
+ }
+
+/**
+ * Sets the params, calling this will bypass the auto parameter parsing.
+ *
+ * @param array $params Array of parameters for the dispatcher
+ * @return void
+ */
+ public function setParams($params) {
+ $this->params = $params;
+ $this->_paramsParsed = true;
+ }
+
+/**
+ * Parse url params into a 'request'
+ *
+ * @return void
+ */
+ protected function _parseParams() {
+ if (!$this->_paramsParsed) {
+ if (!isset($_SERVER['SERVER_NAME'])) {
+ $_SERVER['SERVER_NAME'] = '';
+ }
+ foreach ($this->params as $key => $value) {
+ if (isset($_GET[$key])) {
+ $this->params[$key] = $_GET[$key];
+ }
+ }
+ if (isset($_GET['code_coverage'])) {
+ $this->params['codeCoverage'] = true;
+ $this->_checkXdebug();
+ }
+ }
+ if (empty($this->params['plugin']) && empty($this->params['core'])) {
+ $this->params['app'] = true;
+ }
+ $this->params['baseUrl'] = $this->_baseUrl;
+ $this->params['baseDir'] = $this->_baseDir;
+ }
+
+/**
+ * Runs a test case file.
+ *
+ * @return void
+ */
+ protected function _runTestCase() {
+ $commandArgs = array(
+ 'case' => $this->params['case'],
+ 'core' => $this->params['core'],
+ 'app' => $this->params['app'],
+ 'plugin' => $this->params['plugin'],
+ 'codeCoverage' => $this->params['codeCoverage'],
+ 'showPasses' => !empty($this->params['show_passes']),
+ 'baseUrl' => $this->_baseUrl,
+ 'baseDir' => $this->_baseDir,
+ );
+
+ $options = array(
+ '--filter', $this->params['filter'],
+ '--output', $this->params['output'],
+ '--fixture', $this->params['fixture']
+ );
+ restore_error_handler();
+
+ try {
+ self::time();
+ $command = new CakeTestSuiteCommand('CakeTestLoader', $commandArgs);
+ $result = $command->run($options);
+ } catch (MissingConnectionException $exception) {
+ ob_end_clean();
+ $baseDir = $this->_baseDir;
+ include CAKE . 'TestSuite' . DS . 'templates' . DS . 'missing_connection.php';
+ exit();
+ }
+ }
+
+/**
+ * Sets a static timestamp
+ *
+ * @param boolean $reset to set new static timestamp.
+ * @return integer timestamp
+ */
+ public static function time($reset = false) {
+ static $now;
+ if ($reset || !$now) {
+ $now = time();
+ }
+ return $now;
+ }
+
+/**
+ * Returns formatted date string using static time
+ * This method is being used as formatter for created, modified and updated fields in Model::save()
+ *
+ * @param string $format format to be used.
+ * @return string formatted date
+ */
+ public static function date($format) {
+ return date($format, self::time());
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/ControllerTestCase.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/ControllerTestCase.php
new file mode 100644
index 0000000..d6002f0
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/ControllerTestCase.php
@@ -0,0 +1,378 @@
+<?php
+/**
+ * ControllerTestCase file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Dispatcher', 'Routing');
+App::uses('CakeTestCase', 'TestSuite');
+App::uses('Router', 'Routing');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+App::uses('Helper', 'View');
+App::uses('CakeEvent', 'Event');
+
+/**
+ * ControllerTestDispatcher class
+ *
+ * @package Cake.TestSuite
+ */
+class ControllerTestDispatcher extends Dispatcher {
+
+/**
+ * The controller to use in the dispatch process
+ *
+ * @var Controller
+ */
+ public $testController = null;
+
+/**
+ * Use custom routes during tests
+ *
+ * @var boolean
+ */
+ public $loadRoutes = true;
+
+/**
+ * Returns the test controller
+ *
+ * @return Controller
+ */
+ protected function _getController($request, $response) {
+ if ($this->testController === null) {
+ $this->testController = parent::_getController($request, $response);
+ }
+ $this->testController->helpers = array_merge(array('InterceptContent'), $this->testController->helpers);
+ $this->testController->setRequest($request);
+ $this->testController->response = $this->response;
+ foreach ($this->testController->Components->attached() as $component) {
+ $object = $this->testController->Components->{$component};
+ if (isset($object->response)) {
+ $object->response = $response;
+ }
+ if (isset($object->request)) {
+ $object->request = $request;
+ }
+ }
+ return $this->testController;
+ }
+
+/**
+ * Loads routes and resets if the test case dictates it should
+ *
+ * @return void
+ */
+ protected function _loadRoutes() {
+ parent::_loadRoutes();
+ if (!$this->loadRoutes) {
+ Router::reload();
+ }
+ }
+
+}
+
+/**
+ * InterceptContentHelper class
+ *
+ * @package Cake.TestSuite
+ */
+class InterceptContentHelper extends Helper {
+
+/**
+ * Intercepts and stores the contents of the view before the layout is rendered
+ *
+ * @param string $viewFile The view file
+ */
+ public function afterRender($viewFile) {
+ $this->_View->assign('__view_no_layout__', $this->_View->fetch('content'));
+ $this->_View->Helpers->unload('InterceptContent');
+ }
+
+}
+
+/**
+ * ControllerTestCase class
+ *
+ * @package Cake.TestSuite
+ */
+abstract class ControllerTestCase extends CakeTestCase {
+
+/**
+ * The controller to test in testAction
+ *
+ * @var Controller
+ */
+ public $controller = null;
+
+/**
+ * Automatically mock controllers that aren't mocked
+ *
+ * @var boolean
+ */
+ public $autoMock = true;
+
+/**
+ * Use custom routes during tests
+ *
+ * @var boolean
+ */
+ public $loadRoutes = true;
+
+/**
+ * The resulting view vars of the last testAction call
+ *
+ * @var array
+ */
+ public $vars = null;
+
+/**
+ * The resulting rendered view of the last testAction call
+ *
+ * @var string
+ */
+ public $view = null;
+
+/**
+ * The resulting rendered layout+view of the last testAction call
+ *
+ * @var string
+ */
+ public $contents = null;
+
+/**
+ * The returned result of the dispatch (requestAction), if any
+ *
+ * @var string
+ */
+ public $result = null;
+
+/**
+ * The headers that would have been sent by the action
+ *
+ * @var string
+ */
+ public $headers = null;
+
+/**
+ * Flag for checking if the controller instance is dirty.
+ * Once a test has been run on a controller it should be rebuilt
+ * to clean up properties.
+ *
+ * @var boolean
+ */
+ private $__dirtyController = false;
+
+/**
+ * Used to enable calling ControllerTestCase::testAction() without the testing
+ * framework thinking that it's a test case
+ *
+ * @param string $name The name of the function
+ * @param array $arguments Array of arguments
+ * @return Function
+ */
+ public function __call($name, $arguments) {
+ if ($name == 'testAction') {
+ return call_user_func_array(array($this, '_testAction'), $arguments);
+ }
+ }
+
+/**
+ * Lets you do functional tests of a controller action.
+ *
+ * ### Options:
+ *
+ * - `data` Will be used as the request data. If the `method` is GET,
+ * data will be used a GET params. If the `method` is POST, it will be used
+ * as POST data. By setting `$options['data']` to a string, you can simulate XML or JSON
+ * payloads to your controllers allowing you to test REST webservices.
+ * - `method` POST or GET. Defaults to POST.
+ * - `return` Specify the return type you want. Choose from:
+ * - `vars` Get the set view variables.
+ * - `view` Get the rendered view, without a layout.
+ * - `contents` Get the rendered view including the layout.
+ * - `result` Get the return value of the controller action. Useful
+ * for testing requestAction methods.
+ *
+ * @param string $url The url to test
+ * @param array $options See options
+ */
+ protected function _testAction($url = '', $options = array()) {
+ $this->vars = $this->result = $this->view = $this->contents = $this->headers = null;
+
+ $options = array_merge(array(
+ 'data' => array(),
+ 'method' => 'POST',
+ 'return' => 'result'
+ ), $options);
+
+ $restore = array('get' => $_GET, 'post' => $_POST);
+
+ $_SERVER['REQUEST_METHOD'] = strtoupper($options['method']);
+ if (is_array($options['data'])) {
+ if (strtoupper($options['method']) == 'GET') {
+ $_GET = $options['data'];
+ $_POST = array();
+ } else {
+ $_POST = $options['data'];
+ $_GET = array();
+ }
+ }
+ $request = $this->getMock('CakeRequest', array('_readInput'), array($url));
+
+ if (is_string($options['data'])) {
+ $request->expects($this->any())
+ ->method('_readInput')
+ ->will($this->returnValue($options['data']));
+ }
+
+ $Dispatch = new ControllerTestDispatcher();
+ foreach (Router::$routes as $route) {
+ if ($route instanceof RedirectRoute) {
+ $route->response = $this->getMock('CakeResponse', array('send'));
+ }
+ }
+ $Dispatch->loadRoutes = $this->loadRoutes;
+ $Dispatch->parseParams(new CakeEvent('ControllerTestCase', $Dispatch, array('request' => $request)));
+ if (!isset($request->params['controller'])) {
+ $this->headers = Router::currentRoute()->response->header();
+ return;
+ }
+ if ($this->__dirtyController) {
+ $this->controller = null;
+ }
+
+ $plugin = empty($request->params['plugin']) ? '' : Inflector::camelize($request->params['plugin']) . '.';
+ if ($this->controller === null && $this->autoMock) {
+ $this->generate($plugin . Inflector::camelize($request->params['controller']));
+ }
+ $params = array();
+ if ($options['return'] == 'result') {
+ $params['return'] = 1;
+ $params['bare'] = 1;
+ $params['requested'] = 1;
+ }
+ $Dispatch->testController = $this->controller;
+ $Dispatch->response = $this->getMock('CakeResponse', array('send'));
+ $this->result = $Dispatch->dispatch($request, $Dispatch->response, $params);
+ $this->controller = $Dispatch->testController;
+ $this->vars = $this->controller->viewVars;
+ $this->contents = $this->controller->response->body();
+ if (isset($this->controller->View)) {
+ $this->view = $this->controller->View->fetch('__view_no_layout__');
+ }
+ $this->__dirtyController = true;
+ $this->headers = $Dispatch->response->header();
+
+ $_GET = $restore['get'];
+ $_POST = $restore['post'];
+
+ return $this->{$options['return']};
+ }
+
+/**
+ * Generates a mocked controller and mocks any classes passed to `$mocks`. By
+ * default, `_stop()` is stubbed as is sending the response headers, so to not
+ * interfere with testing.
+ *
+ * ### Mocks:
+ *
+ * - `methods` Methods to mock on the controller. `_stop()` is mocked by default
+ * - `models` Models to mock. Models are added to the ClassRegistry so they any
+ * time they are instantiated the mock will be created. Pass as key value pairs
+ * with the value being specific methods on the model to mock. If `true` or
+ * no value is passed, the entire model will be mocked.
+ * - `components` Components to mock. Components are only mocked on this controller
+ * and not within each other (i.e., components on components)
+ *
+ * @param string $controller Controller name
+ * @param array $mocks List of classes and methods to mock
+ * @return Controller Mocked controller
+ * @throws MissingControllerException When controllers could not be created.
+ * @throws MissingComponentException When components could not be created.
+ */
+ public function generate($controller, $mocks = array()) {
+ list($plugin, $controller) = pluginSplit($controller);
+ if ($plugin) {
+ App::uses($plugin . 'AppController', $plugin . '.Controller');
+ $plugin .= '.';
+ }
+ App::uses($controller . 'Controller', $plugin . 'Controller');
+ if (!class_exists($controller . 'Controller')) {
+ throw new MissingControllerException(array(
+ 'class' => $controller . 'Controller',
+ 'plugin' => substr($plugin, 0, -1)
+ ));
+ }
+ ClassRegistry::flush();
+
+ $mocks = array_merge_recursive(array(
+ 'methods' => array('_stop'),
+ 'models' => array(),
+ 'components' => array()
+ ), (array)$mocks);
+
+ list($plugin, $name) = pluginSplit($controller);
+ $_controller = $this->getMock($name . 'Controller', $mocks['methods'], array(), '', false);
+ $_controller->name = $name;
+ $request = $this->getMock('CakeRequest');
+ $response = $this->getMock('CakeResponse', array('_sendHeader'));
+ $_controller->__construct($request, $response);
+
+ $config = ClassRegistry::config('Model');
+ foreach ($mocks['models'] as $model => $methods) {
+ if (is_string($methods)) {
+ $model = $methods;
+ $methods = true;
+ }
+ if ($methods === true) {
+ $methods = array();
+ }
+ ClassRegistry::init($model);
+ list($plugin, $name) = pluginSplit($model);
+ $config = array_merge((array)$config, array('name' => $model));
+ $_model = $this->getMock($name, $methods, array($config));
+ ClassRegistry::removeObject($name);
+ ClassRegistry::addObject($name, $_model);
+ }
+
+ foreach ($mocks['components'] as $component => $methods) {
+ if (is_string($methods)) {
+ $component = $methods;
+ $methods = true;
+ }
+ if ($methods === true) {
+ $methods = array();
+ }
+ list($plugin, $name) = pluginSplit($component, true);
+ $componentClass = $name . 'Component';
+ App::uses($componentClass, $plugin . 'Controller/Component');
+ if (!class_exists($componentClass)) {
+ throw new MissingComponentException(array(
+ 'class' => $componentClass
+ ));
+ }
+ $_component = $this->getMock($componentClass, $methods, array(), '', false);
+ $_controller->Components->set($name, $_component);
+ }
+
+ $_controller->constructClasses();
+ $this->__dirtyController = false;
+
+ $this->controller = $_controller;
+ return $this->controller;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/BaseCoverageReport.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/BaseCoverageReport.php
new file mode 100644
index 0000000..0cf23e8
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/BaseCoverageReport.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ * Abstract class for common CoverageReport methods.
+ * Provides several template methods for custom output.
+ *
+ * PHP5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.TestSuite.Coverage
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Abstract class for common CoverageReport methods.
+ * Provides several template methods for custom output.
+ *
+ * @package Cake.TestSuite.Coverage
+ */
+abstract class BaseCoverageReport {
+
+/**
+ * coverage data
+ *
+ * @var string
+ */
+ protected $_rawCoverage;
+
+/**
+ * is the test an app test
+ *
+ * @var string
+ */
+ public $appTest = false;
+
+/**
+ * is the test a plugin test
+ *
+ * @var string
+ */
+ public $pluginTest = false;
+
+/**
+ * Array of test case file names. Used to do basename() matching with
+ * files that have coverage to decide which results to show on page load.
+ *
+ * @var array
+ */
+ protected $_testNames = array();
+
+/**
+ * Constructor
+ *
+ * @param array $coverage Array of coverage data from PHPUnit_Test_Result
+ * @param CakeBaseReporter $reporter A reporter to use for the coverage report.
+ * @return void
+ */
+ public function __construct($coverage, CakeBaseReporter $reporter) {
+ $this->_rawCoverage = $coverage;
+ $this->_setParams($reporter);
+ }
+
+/**
+ * Pulls params out of the reporter.
+ *
+ * @param CakeBaseReporter $reporter Reporter to suck params out of.
+ * @return void
+ */
+ protected function _setParams(CakeBaseReporter $reporter) {
+ if ($reporter->params['app']) {
+ $this->appTest = true;
+ }
+ if ($reporter->params['plugin']) {
+ $this->pluginTest = Inflector::camelize($reporter->params['plugin']);
+ }
+ }
+
+/**
+ * Set the coverage data array
+ *
+ * @param array $coverage Coverage data to use.
+ * @return void
+ */
+ public function setCoverage($coverage) {
+ $this->_rawCoverage = $coverage;
+ }
+
+/**
+ * Gets the base path that the files we are interested in live in.
+ *
+ * @return void
+ */
+ public function getPathFilter() {
+ $path = ROOT . DS;
+ if ($this->appTest) {
+ $path .= APP_DIR . DS;
+ } elseif ($this->pluginTest) {
+ $path = App::pluginPath($this->pluginTest);
+ } else {
+ $path = CAKE;
+ }
+ return $path;
+ }
+
+/**
+ * Filters the coverage data by path. Files not in the provided path will be removed.
+ *
+ * @param string $path Path to filter files by.
+ * @return array Array of coverage data for files that match the given path.
+ */
+ public function filterCoverageDataByPath($path) {
+ $files = array();
+ foreach ($this->_rawCoverage as $fileName => $fileCoverage) {
+ if (strpos($fileName, $path) !== 0) {
+ continue;
+ }
+ $files[$fileName] = $fileCoverage;
+ }
+ return $files;
+ }
+
+/**
+ * Calculates how many lines are covered and what the total number of executable lines is.
+ *
+ * Handles both PHPUnit3.5 and 3.6 formats.
+ *
+ * 3.5 uses -1 for uncovered, and -2 for dead.
+ * 3.6 uses array() for uncovered and null for dead.
+ *
+ * @param array $fileLines
+ * @param array $coverageData
+ * @return array. Array of covered, total lines.
+ */
+ protected function _calculateCoveredLines($fileLines, $coverageData) {
+ $covered = $total = 0;
+
+ //shift line numbers forward one
+ array_unshift($fileLines, ' ');
+ unset($fileLines[0]);
+
+ foreach ($fileLines as $lineno => $line) {
+ if (!isset($coverageData[$lineno])) {
+ continue;
+ }
+ if (is_array($coverageData[$lineno]) && !empty($coverageData[$lineno])) {
+ $covered++;
+ $total++;
+ } elseif ($coverageData[$lineno] === -1 || $coverageData[$lineno] === array()) {
+ $total++;
+ }
+ }
+ return array($covered, $total);
+ }
+
+/**
+ * Generates report to display.
+ *
+ * @return string compiled html report.
+ */
+ abstract public function report();
+
+/**
+ * Generates an coverage 'diff' for $file based on $coverageData.
+ *
+ * @param string $filename Name of the file having coverage generated
+ * @param array $fileLines File data as an array. See file() for how to get one of these.
+ * @param array $coverageData Array of coverage data to use to generate HTML diffs with
+ * @return string prepared report for a single file.
+ */
+ abstract public function generateDiff($filename, $fileLines, $coverageData);
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/HtmlCoverageReport.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/HtmlCoverageReport.php
new file mode 100644
index 0000000..8706888
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/HtmlCoverageReport.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * Generates code coverage reports in HTML from data obtained from PHPUnit
+ *
+ * PHP5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.TestSuite.Coverage
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseCoverageReport', 'TestSuite/Coverage');
+
+/**
+ * Generates code coverage reports in HTML from data obtained from PHPUnit
+ *
+ * @package Cake.TestSuite.Coverage
+ */
+class HtmlCoverageReport extends BaseCoverageReport {
+
+/**
+ * Generates report html to display.
+ *
+ * @return string compiled html report.
+ */
+ public function report() {
+ $pathFilter = $this->getPathFilter();
+ $coverageData = $this->filterCoverageDataByPath($pathFilter);
+ if (empty($coverageData)) {
+ return '<h3>No files to generate coverage for</h3>';
+ }
+ $output = $this->coverageScript();
+ $output .= <<<HTML
+ <h3>Code coverage results
+ <a href="#" onclick="coverage_toggle_all()" class="coverage-toggle">Toggle all files</a>
+ </h3>
+HTML;
+ foreach ($coverageData as $file => $coverageData) {
+ $fileData = file($file);
+ $output .= $this->generateDiff($file, $fileData, $coverageData);
+ }
+ return $output;
+ }
+
+/**
+ * Generates an HTML diff for $file based on $coverageData.
+ *
+ * Handles both PHPUnit3.5 and 3.6 formats.
+ *
+ * 3.5 uses -1 for uncovered, and -2 for dead.
+ * 3.6 uses array() for uncovered and null for dead.
+ *
+ * @param string $filename Name of the file having coverage generated
+ * @param array $fileLines File data as an array. See file() for how to get one of these.
+ * @param array $coverageData Array of coverage data to use to generate HTML diffs with
+ * @return string HTML diff.
+ */
+ public function generateDiff($filename, $fileLines, $coverageData) {
+ $output = '';
+ $diff = array();
+
+ list($covered, $total) = $this->_calculateCoveredLines($fileLines, $coverageData);
+
+ //shift line numbers forward one;
+ array_unshift($fileLines, ' ');
+ unset($fileLines[0]);
+
+ foreach ($fileLines as $lineno => $line) {
+ $class = 'ignored';
+ $coveringTests = array();
+ if (!empty($coverageData[$lineno]) && is_array($coverageData[$lineno])) {
+ $coveringTests = array();
+ foreach ($coverageData[$lineno] as $test) {
+ $class = (is_array($test) && isset($test['id'])) ? $test['id'] : $test;
+ $testReflection = new ReflectionClass(current(explode('::', $class)));
+ $this->_testNames[] = $this->_guessSubjectName($testReflection);
+ $coveringTests[] = $class;
+ }
+ $class = 'covered';
+ } elseif (isset($coverageData[$lineno]) && ($coverageData[$lineno] === -1 || $coverageData[$lineno] === array())) {
+ $class = 'uncovered';
+ } elseif (array_key_exists($lineno, $coverageData) && ($coverageData[$lineno] === -2 || $coverageData[$lineno] === null)) {
+ $class .= ' dead';
+ }
+ $diff[] = $this->_paintLine($line, $lineno, $class, $coveringTests);
+ }
+
+ $percentCovered = 100;
+ if ($total > 0) {
+ $percentCovered = round(100 * $covered / $total, 2);
+ }
+ $output .= $this->coverageHeader($filename, $percentCovered);
+ $output .= implode("", $diff);
+ $output .= $this->coverageFooter();
+ return $output;
+ }
+
+/**
+ * Guess the classname the test was for based on the test case filename.
+ *
+ * @param ReflectionClass $testReflection.
+ * @return string Possible test subject name.
+ */
+ protected function _guessSubjectName($testReflection) {
+ $basename = basename($testReflection->getFilename());
+ if (strpos($basename, '.test') !== false) {
+ list($subject, ) = explode('.', $basename, 2);
+ return $subject;
+ }
+ $subject = str_replace('Test.php', '', $basename);
+ return $subject;
+ }
+
+/**
+ * Renders the html for a single line in the html diff.
+ *
+ * @return void
+ */
+ protected function _paintLine($line, $linenumber, $class, $coveringTests) {
+ $coveredBy = '';
+ if (!empty($coveringTests)) {
+ $coveredBy = "Covered by:\n";
+ foreach ($coveringTests as $test) {
+ $coveredBy .= $test . "\n";
+ }
+ }
+
+ return sprintf(
+ '<div class="code-line %s" title="%s"><span class="line-num">%s</span><span class="content">%s</span></div>',
+ $class,
+ $coveredBy,
+ $linenumber,
+ htmlspecialchars($line)
+ );
+ }
+
+/**
+ * generate some javascript for the coverage report.
+ *
+ * @return void
+ */
+ public function coverageScript() {
+ return <<<HTML
+ <script type="text/javascript">
+ function coverage_show_hide(selector) {
+ var element = document.getElementById(selector);
+ element.style.display = (element.style.display == 'none') ? '' : 'none';
+ }
+ function coverage_toggle_all() {
+ var divs = document.querySelectorAll('div.coverage-container');
+ var i = divs.length;
+ while (i--) {
+ if (divs[i] && divs[i].className.indexOf('primary') == -1) {
+ divs[i].style.display = (divs[i].style.display == 'none') ? '' : 'none';
+ }
+ }
+ }
+ </script>
+HTML;
+ }
+
+/**
+ * Generate an HTML snippet for coverage headers
+ *
+ * @return void
+ */
+ public function coverageHeader($filename, $percent) {
+ $filename = basename($filename);
+ list($file, $ext) = explode('.', $filename);
+ $display = in_array($file, $this->_testNames) ? 'block' : 'none';
+ $primary = $display == 'block' ? 'primary' : '';
+ return <<<HTML
+ <div class="coverage-container $primary" style="display:$display;">
+ <h4>
+ <a href="#coverage-$filename" onclick="coverage_show_hide('coverage-$filename');">
+ $filename Code coverage: $percent%
+ </a>
+ </h4>
+ <div class="code-coverage-results" id="coverage-$filename" style="display:none;">
+ <pre>
+HTML;
+ }
+
+/**
+ * Generate an HTML snippet for coverage footers
+ *
+ * @return void
+ */
+ public function coverageFooter() {
+ return "</pre></div></div>";
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/TextCoverageReport.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/TextCoverageReport.php
new file mode 100644
index 0000000..e258214
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Coverage/TextCoverageReport.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Generates code coverage reports in Simple plain text from data obtained from PHPUnit
+ *
+ * PHP5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.TestSuite.Coverage
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('BaseCoverageReport', 'TestSuite/Coverage');
+
+/**
+ * Generates code coverage reports in Simple plain text from data obtained from PHPUnit
+ *
+ * @package Cake.TestSuite.Coverage
+ */
+class TextCoverageReport extends BaseCoverageReport {
+
+/**
+ * Generates report text to display.
+ *
+ * @return string compiled plain text report.
+ */
+ public function report() {
+ $pathFilter = $this->getPathFilter();
+ $coverageData = $this->filterCoverageDataByPath($pathFilter);
+ if (empty($coverageData)) {
+ return 'No files to generate coverage for';
+ }
+ $output = "\nCoverage Report:\n\n";
+ foreach ($coverageData as $file => $coverageData) {
+ $fileData = file($file);
+ $output .= $this->generateDiff($file, $fileData, $coverageData);
+ }
+ return $output;
+ }
+
+/**
+ * Generates a 'diff' report for a file.
+ * Since diffs are too big for plain text reports a simple file => % covered is done.
+ *
+ * @param string $filename Name of the file having coverage generated
+ * @param array $fileLines File data as an array. See file() for how to get one of these.
+ * @param array $coverageData Array of coverage data to use to generate HTML diffs with
+ * @return string
+ */
+ public function generateDiff($filename, $fileLines, $coverageData) {
+ list($covered, $total) = $this->_calculateCoveredLines($fileLines, $coverageData);
+ $percentCovered = round(100 * $covered / $total, 2);
+ return "$filename : $percentCovered%\n";
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php
new file mode 100644
index 0000000..d5998ec
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * A factory class to manage the life cycle of test fixtures
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.TestSuite.Fixture
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ConnectionManager', 'Model');
+App::uses('ClassRegistry', 'Utility');
+
+/**
+ * A factory class to manage the life cycle of test fixtures
+ *
+ * @package Cake.TestSuite.Fixture
+ */
+class CakeFixtureManager {
+
+/**
+ * Was this class already initialized?
+ *
+ * @var boolean
+ */
+ protected $_initialized = false;
+
+/**
+ * Default datasource to use
+ *
+ * @var DataSource
+ */
+ protected $_db = null;
+
+/**
+ * Holds the fixture classes that where instantiated
+ *
+ * @var array
+ */
+ protected $_loaded = array();
+
+/**
+ * Holds the fixture classes that where instantiated indexed by class name
+ *
+ * @var array
+ */
+ protected $_fixtureMap = array();
+
+/**
+ * Inspects the test to look for unloaded fixtures and loads them
+ *
+ * @param CakeTestCase $test the test case to inspect
+ * @return void
+ */
+ public function fixturize($test) {
+ if (!$this->_initialized) {
+ ClassRegistry::config(array('ds' => 'test', 'testing' => true));
+ }
+ if (empty($test->fixtures) || !empty($this->_processed[get_class($test)])) {
+ $test->db = $this->_db;
+ return;
+ }
+ $this->_initDb();
+ $test->db = $this->_db;
+ if (!is_array($test->fixtures)) {
+ $test->fixtures = array_map('trim', explode(',', $test->fixtures));
+ }
+ if (isset($test->fixtures)) {
+ $this->_loadFixtures($test->fixtures);
+ }
+
+ $this->_processed[get_class($test)] = true;
+ }
+
+/**
+ * Initializes this class with a DataSource object to use as default for all fixtures
+ *
+ * @return void
+ */
+ protected function _initDb() {
+ if ($this->_initialized) {
+ return;
+ }
+ $db = ConnectionManager::getDataSource('test');
+ $db->cacheSources = false;
+ $this->_db = $db;
+ $this->_initialized = true;
+ }
+
+/**
+ * Looks for fixture files and instantiates the classes accordingly
+ *
+ * @param array $fixtures the fixture names to load using the notation {type}.{name}
+ * @return void
+ * @throws UnexpectedValueException when a referenced fixture does not exist.
+ */
+ protected function _loadFixtures($fixtures) {
+ foreach ($fixtures as $index => $fixture) {
+ $fixtureFile = null;
+ $fixtureIndex = $fixture;
+ if (isset($this->_loaded[$fixture])) {
+ continue;
+ }
+
+ if (strpos($fixture, 'core.') === 0) {
+ $fixture = substr($fixture, strlen('core.'));
+ $fixturePaths[] = CAKE . 'Test' . DS . 'Fixture';
+ } elseif (strpos($fixture, 'app.') === 0) {
+ $fixture = substr($fixture, strlen('app.'));
+ $fixturePaths = array(
+ TESTS . 'Fixture'
+ );
+ } elseif (strpos($fixture, 'plugin.') === 0) {
+ $parts = explode('.', $fixture, 3);
+ $pluginName = $parts[1];
+ $fixture = $parts[2];
+ $fixturePaths = array(
+ CakePlugin::path(Inflector::camelize($pluginName)) . 'Test' . DS . 'Fixture',
+ TESTS . 'Fixture'
+ );
+ } else {
+ $fixturePaths = array(
+ TESTS . 'Fixture',
+ CAKE . 'Test' . DS . 'Fixture'
+ );
+ }
+
+ $loaded = false;
+ foreach ($fixturePaths as $path) {
+ $className = Inflector::camelize($fixture);
+ if (is_readable($path . DS . $className . 'Fixture.php')) {
+ $fixtureFile = $path . DS . $className . 'Fixture.php';
+ require_once $fixtureFile;
+ $fixtureClass = $className . 'Fixture';
+ $this->_loaded[$fixtureIndex] = new $fixtureClass();
+ $this->_fixtureMap[$fixtureClass] = $this->_loaded[$fixtureIndex];
+ $loaded = true;
+ break;
+ }
+ }
+
+ if (!$loaded) {
+ $firstPath = str_replace(array(APP, CAKE_CORE_INCLUDE_PATH, ROOT), '', $fixturePaths[0] . DS . $className . 'Fixture.php');
+ throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s (%s) not found', $className, $firstPath));
+ }
+ }
+ }
+
+/**
+ * Runs the drop and create commands on the fixtures if necessary.
+ *
+ * @param CakeTestFixture $fixture the fixture object to create
+ * @param DataSource $db the datasource instance to use
+ * @param boolean $drop whether drop the fixture if it is already created or not
+ * @return void
+ */
+ protected function _setupTable($fixture, $db = null, $drop = true) {
+ if (!$db) {
+ if (!empty($fixture->useDbConfig)) {
+ $db = ConnectionManager::getDataSource($fixture->useDbConfig);
+ } else {
+ $db = $this->_db;
+ }
+ }
+ if (!empty($fixture->created) && in_array($db->configKeyName, $fixture->created)) {
+ return;
+ }
+
+ $sources = $db->listSources();
+ $table = $db->config['prefix'] . $fixture->table;
+ $exists = in_array($table, $sources);
+
+ if ($drop && $exists) {
+ $fixture->drop($db);
+ $fixture->create($db);
+ } elseif (!$exists) {
+ $fixture->create($db);
+ } else {
+ $fixture->created[] = $db->configKeyName;
+ }
+ }
+
+/**
+ * Creates the fixtures tables and inserts data on them.
+ *
+ * @param CakeTestCase $test the test to inspect for fixture loading
+ * @return void
+ */
+ public function load(CakeTestCase $test) {
+ if (empty($test->fixtures)) {
+ return;
+ }
+ $fixtures = $test->fixtures;
+ if (empty($fixtures) || $test->autoFixtures == false) {
+ return;
+ }
+
+ $nested = $test->db->useNestedTransactions;
+ $test->db->useNestedTransactions = false;
+ $test->db->begin();
+ foreach ($fixtures as $f) {
+ if (!empty($this->_loaded[$f])) {
+ $fixture = $this->_loaded[$f];
+ $db = ConnectionManager::getDataSource($fixture->useDbConfig);
+ $this->_setupTable($fixture, $db, $test->dropTables);
+ $fixture->insert($db);
+ }
+ }
+ $test->db->commit();
+ $test->db->useNestedTransactions = $nested;
+ }
+
+/**
+ * Truncates the fixtures tables
+ *
+ * @param CakeTestCase $test the test to inspect for fixture unloading
+ * @return void
+ */
+ public function unload(CakeTestCase $test) {
+ $fixtures = !empty($test->fixtures) ? $test->fixtures : array();
+ foreach (array_reverse($fixtures) as $f) {
+ if (isset($this->_loaded[$f])) {
+ $fixture = $this->_loaded[$f];
+ if (!empty($fixture->created)) {
+ foreach ($fixture->created as $ds) {
+ $db = ConnectionManager::getDataSource($ds);
+ $fixture->truncate($db);
+ }
+ }
+ }
+ }
+ }
+
+/**
+ * Creates a single fixture table and loads data into it.
+ *
+ * @param string $name of the fixture
+ * @param DataSource $db DataSource instance or leave null to get DataSource from the fixture
+ * @return void
+ * @throws UnexpectedValueException if $name is not a previously loaded class
+ */
+ public function loadSingle($name, $db = null) {
+ $name .= 'Fixture';
+ if (isset($this->_fixtureMap[$name])) {
+ $fixture = $this->_fixtureMap[$name];
+ if (!$db) {
+ $db = ConnectionManager::getDataSource($fixture->useDbConfig);
+ }
+ $this->_setupTable($fixture, $db);
+ $fixture->truncate($db);
+ $fixture->insert($db);
+ } else {
+ throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s not found', $name));
+ }
+ }
+
+/**
+ * Drop all fixture tables loaded by this class
+ *
+ * @return void
+ */
+ public function shutDown() {
+ foreach ($this->_loaded as $fixture) {
+ if (!empty($fixture->created)) {
+ foreach ($fixture->created as $ds) {
+ $db = ConnectionManager::getDataSource($ds);
+ $fixture->drop($db);
+ }
+ }
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestFixture.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestFixture.php
new file mode 100644
index 0000000..359d57f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestFixture.php
@@ -0,0 +1,269 @@
+<?php
+/**
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeSchema', 'Model');
+
+/**
+ * CakeTestFixture is responsible for building and destroying tables to be used
+ * during testing.
+ *
+ * @package Cake.TestSuite.Fixture
+ */
+class CakeTestFixture {
+
+/**
+ * Name of the object
+ *
+ * @var string
+ */
+ public $name = null;
+
+/**
+ * Cake's DBO driver (e.g: DboMysql).
+ *
+ * @var object
+ */
+ public $db = null;
+
+/**
+ * Fixture Datasource
+ *
+ * @var string
+ */
+ public $useDbConfig = 'test';
+
+/**
+ * Full Table Name
+ *
+ * @var string
+ */
+ public $table = null;
+
+/**
+ * List of datasources where this fixture has been created
+ *
+ * @var array
+ */
+ public $created = array();
+
+/**
+ * Instantiate the fixture.
+ *
+ * @throws CakeException on invalid datasource usage.
+ */
+ public function __construct() {
+ if ($this->name === null) {
+ if (preg_match('/^(.*)Fixture$/', get_class($this), $matches)) {
+ $this->name = $matches[1];
+ } else {
+ $this->name = get_class($this);
+ }
+ }
+ $connection = 'test';
+ if (!empty($this->useDbConfig)) {
+ $connection = $this->useDbConfig;
+ if (strpos($connection, 'test') !== 0) {
+ throw new CakeException(__d('cake_dev', 'Invalid datasource %s for object %s', $connection, $this->name));
+ }
+ }
+ $this->Schema = new CakeSchema(array('name' => 'TestSuite', 'connection' => $connection));
+ $this->init();
+ }
+
+/**
+ * Initialize the fixture.
+ *
+ * @return void
+ * @throws MissingModelException Whe importing from a model that does not exist.
+ */
+ public function init() {
+ if (isset($this->import) && (is_string($this->import) || is_array($this->import))) {
+ $import = array_merge(
+ array('connection' => 'default', 'records' => false),
+ is_array($this->import) ? $this->import : array('model' => $this->import)
+ );
+
+ $this->Schema->connection = $import['connection'];
+ if (isset($import['model'])) {
+ list($plugin, $modelClass) = pluginSplit($import['model'], true);
+ App::uses($modelClass, $plugin . 'Model');
+ if (!class_exists($modelClass)) {
+ throw new MissingModelException(array('class' => $modelClass));
+ }
+ $model = new $modelClass(null, null, $import['connection']);
+ $db = $model->getDataSource();
+ if (empty($model->tablePrefix)) {
+ $model->tablePrefix = $db->config['prefix'];
+ }
+ $this->fields = $model->schema(true);
+ $this->fields[$model->primaryKey]['key'] = 'primary';
+ $this->table = $db->fullTableName($model, false, false);
+ ClassRegistry::config(array('ds' => 'test'));
+ ClassRegistry::flush();
+ } elseif (isset($import['table'])) {
+ $model = new Model(null, $import['table'], $import['connection']);
+ $db = ConnectionManager::getDataSource($import['connection']);
+ $db->cacheSources = false;
+ $model->useDbConfig = $import['connection'];
+ $model->name = Inflector::camelize(Inflector::singularize($import['table']));
+ $model->table = $import['table'];
+ $model->tablePrefix = $db->config['prefix'];
+ $this->fields = $model->schema(true);
+ ClassRegistry::flush();
+ }
+
+ if (!empty($db->config['prefix']) && strpos($this->table, $db->config['prefix']) === 0) {
+ $this->table = str_replace($db->config['prefix'], '', $this->table);
+ }
+
+ if (isset($import['records']) && $import['records'] !== false && isset($model) && isset($db)) {
+ $this->records = array();
+ $query = array(
+ 'fields' => $db->fields($model, null, array_keys($this->fields)),
+ 'table' => $db->fullTableName($model),
+ 'alias' => $model->alias,
+ 'conditions' => array(),
+ 'order' => null,
+ 'limit' => null,
+ 'group' => null
+ );
+ $records = $db->fetchAll($db->buildStatement($query, $model), false, $model->alias);
+
+ if ($records !== false && !empty($records)) {
+ $this->records = Hash::extract($records, '{n}.' . $model->alias);
+ }
+ }
+ }
+
+ if (!isset($this->table)) {
+ $this->table = Inflector::underscore(Inflector::pluralize($this->name));
+ }
+
+ if (!isset($this->primaryKey) && isset($this->fields['id'])) {
+ $this->primaryKey = 'id';
+ }
+ }
+
+/**
+ * Run before all tests execute, should return SQL statement to create table for this fixture could be executed successfully.
+ *
+ * @param object $db An instance of the database object used to create the fixture table
+ * @return boolean True on success, false on failure
+ */
+ public function create($db) {
+ if (!isset($this->fields) || empty($this->fields)) {
+ return false;
+ }
+
+ if (empty($this->fields['tableParameters']['engine'])) {
+ $canUseMemory = true;
+ foreach ($this->fields as $field => $args) {
+
+ if (is_string($args)) {
+ $type = $args;
+ } elseif (!empty($args['type'])) {
+ $type = $args['type'];
+ } else {
+ continue;
+ }
+
+ if (in_array($type, array('blob', 'text', 'binary'))) {
+ $canUseMemory = false;
+ break;
+ }
+ }
+
+ if ($canUseMemory) {
+ $this->fields['tableParameters']['engine'] = 'MEMORY';
+ }
+ }
+ $this->Schema->build(array($this->table => $this->fields));
+ try {
+ $db->execute($db->createSchema($this->Schema), array('log' => false));
+ $this->created[] = $db->configKeyName;
+ } catch (Exception $e) {
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Run after all tests executed, should return SQL statement to drop table for this fixture.
+ *
+ * @param object $db An instance of the database object used to create the fixture table
+ * @return boolean True on success, false on failure
+ */
+ public function drop($db) {
+ if (empty($this->fields)) {
+ return false;
+ }
+ $this->Schema->build(array($this->table => $this->fields));
+ try {
+
+ $db->execute($db->dropSchema($this->Schema), array('log' => false));
+ $this->created = array_diff($this->created, array($db->configKeyName));
+ } catch (Exception $e) {
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Run before each tests is executed, should return a set of SQL statements to insert records for the table
+ * of this fixture could be executed successfully.
+ *
+ * @param object $db An instance of the database into which the records will be inserted
+ * @return boolean on success or if there are no records to insert, or false on failure
+ */
+ public function insert($db) {
+ if (!isset($this->_insert)) {
+ $values = array();
+ if (isset($this->records) && !empty($this->records)) {
+ $fields = array();
+ foreach ($this->records as $record) {
+ $fields = array_merge($fields, array_keys(array_intersect_key($record, $this->fields)));
+ }
+ $fields = array_unique($fields);
+ $default = array_fill_keys($fields, null);
+ foreach ($this->records as $record) {
+ $fields = array_keys($record);
+ $values[] = array_values(array_merge($default, $record));
+ }
+ $nested = $db->useNestedTransactions;
+ $db->useNestedTransactions = false;
+ $result = $db->insertMulti($this->table, $fields, $values);
+ $db->useNestedTransactions = $nested;
+ return $result;
+ }
+ return true;
+ }
+ }
+
+/**
+ * Truncates the current fixture. Can be overwritten by classes extending CakeFixture to trigger other events before / after
+ * truncate.
+ *
+ * @param object $db A reference to a db instance
+ * @return boolean
+ */
+ public function truncate($db) {
+ $fullDebug = $db->fullDebug;
+ $db->fullDebug = false;
+ $return = $db->truncate($this->table);
+ $db->fullDebug = $fullDebug;
+ return $return;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestModel.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestModel.php
new file mode 100644
index 0000000..22add85
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Fixture/CakeTestModel.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.Fixture
+ * @since CakePHP(tm) v 1.2.0.4667
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Model', 'Model');
+
+/**
+ * A model to extend from to help you during testing.
+ *
+ * @package Cake.TestSuite.Fixture
+ */
+class CakeTestModel extends Model {
+
+ public $useDbConfig = 'test';
+
+ public $cacheSources = false;
+
+/**
+ * Sets default order for the model to avoid failing tests caused by
+ * incorrect order when no order has been defined in the finds.
+ * Postgres can return the results in any order it considers appropriate if none is specified
+ *
+ * @param array $queryData
+ * @return array $queryData
+ */
+ public function beforeFind($queryData) {
+ $pk = $this->primaryKey;
+ $aliasedPk = $this->alias . '.' . $this->primaryKey;
+ switch (true) {
+ case !$pk:
+ case !$this->useTable:
+ case !$this->schema('id'):
+ case !empty($queryData['order'][0]):
+ case !empty($queryData['group']):
+ case
+ (is_string($queryData['fields']) && !($queryData['fields'] == $pk || $queryData['fields'] == $aliasedPk)) ||
+ (is_array($queryData['fields']) && !(array_key_exists($pk, $queryData['fields']) || array_key_exists($aliasedPk, $queryData['fields']))):
+ break;
+ default:
+ $queryData['order'] = array($this->alias . '.' . $this->primaryKey => 'ASC');
+ break;
+ }
+ return $queryData;
+ }
+/**
+ * Overriding save() to set CakeTestSuiteDispatcher::date() as formatter for created, modified and updated fields
+ *
+ * @param array $data
+ * @param boolean|array $validate
+ * @param array $fieldList
+ */
+
+ public function save($data = null, $validate = true, $fieldList = array()) {
+ $db = $this->getDataSource();
+ $db->columns['datetime']['formatter'] = 'CakeTestSuiteDispatcher::date';
+ return parent::save($data, $validate, $fieldList);
+ }
+
+} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php
new file mode 100644
index 0000000..27dfbd7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeBaseReporter.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * CakeBaseReporter contains common functionality to all cake test suite reporters.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+require_once 'PHPUnit/TextUI/ResultPrinter.php';
+
+/**
+ * CakeBaseReporter contains common reporting features used in the CakePHP Test suite
+ *
+ * @package Cake.TestSuite.Reporter
+ */
+class CakeBaseReporter extends PHPUnit_TextUI_ResultPrinter {
+
+ protected $_headerSent = false;
+
+/**
+ * Array of request parameters. Usually parsed GET params.
+ *
+ * @var array
+ */
+ public $params = array();
+
+/**
+ * Character set for the output of test reporting.
+ *
+ * @var string
+ */
+ protected $_characterSet;
+
+/**
+ * Does nothing yet. The first output will
+ * be sent on the first test start.
+ *
+ * ### Params
+ *
+ * - show_passes - Should passes be shown
+ * - plugin - Plugin test being run?
+ * - core - Core test being run.
+ * - case - The case being run
+ * - codeCoverage - Whether the case/group being run is being code covered.
+ *
+ * @param string $charset The character set to output with. Defaults to UTF-8
+ * @param array $params Array of request parameters the reporter should use. See above.
+ */
+ public function __construct($charset = 'utf-8', $params = array()) {
+ if (!$charset) {
+ $charset = 'utf-8';
+ }
+ $this->_characterSet = $charset;
+ $this->params = $params;
+ }
+
+/**
+ * Retrieves a list of test cases from the active Manager class,
+ * displaying it in the correct format for the reporter subclass
+ *
+ * @return mixed
+ */
+ public function testCaseList() {
+ $testList = CakeTestLoader::generateTestList($this->params);
+ return $testList;
+ }
+
+/**
+ * Paints the start of the response from the test suite.
+ * Used to paint things like head elements in an html page.
+ *
+ * @return void
+ */
+ public function paintDocumentStart() {
+ }
+
+/**
+ * Paints the end of the response from the test suite.
+ * Used to paint things like </body> in an html page.
+ *
+ * @return void
+ */
+ public function paintDocumentEnd() {
+ }
+
+/**
+ * Paint a list of test sets, core, app, and plugin test sets
+ * available.
+ *
+ * @return void
+ */
+ public function paintTestMenu() {
+ }
+
+/**
+ * Get the baseUrl if one is available.
+ *
+ * @return string The base url for the request.
+ */
+ public function baseUrl() {
+ if (!empty($_SERVER['PHP_SELF'])) {
+ return $_SERVER['PHP_SELF'];
+ }
+ return '';
+ }
+
+ public function printResult(PHPUnit_Framework_TestResult $result) {
+ $this->paintFooter($result);
+ }
+
+ public function paintResult(PHPUnit_Framework_TestResult $result) {
+ $this->paintFooter($result);
+ }
+
+/**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {
+ $this->paintException($e, $test);
+ }
+
+/**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {
+ $this->paintFail($e, $test);
+ }
+
+/**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
+ $this->paintSkip($e, $test);
+ }
+
+/**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
+ $this->paintSkip($e, $test);
+ }
+
+/**
+ * A test suite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
+ if (!$this->_headerSent) {
+ echo $this->paintHeader();
+ }
+ echo __d('cake_dev', 'Running %s', $suite->getName()) . "\n";
+ }
+
+/**
+ * A test suite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {
+ }
+
+/**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test) {
+ }
+
+/**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time) {
+ $this->numAssertions += $test->getNumAssertions();
+ if ($test->hasFailed()) {
+ return;
+ }
+ $this->paintPass($test, $time);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php
new file mode 100644
index 0000000..5bd2695
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php
@@ -0,0 +1,377 @@
+<?php
+/**
+ * CakeHtmlReporter
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeBaseReporter', 'TestSuite/Reporter');
+
+/**
+ * CakeHtmlReporter Reports Results of TestSuites and Test Cases
+ * in an HTML format / context.
+ *
+ * @package Cake.TestSuite.Reporter
+ */
+class CakeHtmlReporter extends CakeBaseReporter {
+
+/**
+ * Paints the top of the web page setting the
+ * title to the name of the starting test.
+ *
+ * @return void
+ */
+ public function paintHeader() {
+ $this->_headerSent = true;
+ $this->sendContentType();
+ $this->sendNoCacheHeaders();
+ $this->paintDocumentStart();
+ $this->paintTestMenu();
+ echo "<ul class='tests'>\n";
+ }
+
+/**
+ * Set the content-type header so it is in the correct encoding.
+ *
+ * @return void
+ */
+ public function sendContentType() {
+ if (!headers_sent()) {
+ header('Content-Type: text/html; charset=' . Configure::read('App.encoding'));
+ }
+ }
+
+/**
+ * Paints the document start content contained in header.php
+ *
+ * @return void
+ */
+ public function paintDocumentStart() {
+ ob_start();
+ $baseDir = $this->params['baseDir'];
+ include CAKE . 'TestSuite' . DS . 'templates' . DS . 'header.php';
+ }
+
+/**
+ * Paints the menu on the left side of the test suite interface.
+ * Contains all of the various plugin, core, and app buttons.
+ *
+ * @return void
+ */
+ public function paintTestMenu() {
+ $cases = $this->baseUrl() . '?show=cases';
+ $plugins = App::objects('plugin', null, false);
+ sort($plugins);
+ include CAKE . 'TestSuite' . DS . 'templates' . DS . 'menu.php';
+ }
+
+/**
+ * Retrieves and paints the list of tests cases in an HTML format.
+ *
+ * @return void
+ */
+ public function testCaseList() {
+ $testCases = parent::testCaseList();
+ $core = $this->params['core'];
+ $plugin = $this->params['plugin'];
+
+ $buffer = "<h3>App Test Cases:</h3>\n<ul>";
+ $urlExtra = null;
+ if ($core) {
+ $buffer = "<h3>Core Test Cases:</h3>\n<ul>";
+ $urlExtra = '&core=true';
+ } elseif ($plugin) {
+ $buffer = "<h3>" . Inflector::humanize($plugin) . " Test Cases:</h3>\n<ul>";
+ $urlExtra = '&plugin=' . $plugin;
+ }
+
+ if (1 > count($testCases)) {
+ $buffer .= "<strong>EMPTY</strong>";
+ }
+
+ foreach ($testCases as $testCaseFile => $testCase) {
+ $title = explode(DS, str_replace('.test.php', '', $testCase));
+ $title[count($title) - 1] = Inflector::camelize($title[count($title) - 1]);
+ $title = implode(' / ', $title);
+ $buffer .= "<li><a href='" . $this->baseUrl() . "?case=" . urlencode($testCase) . $urlExtra . "'>" . $title . "</a></li>\n";
+ }
+ $buffer .= "</ul>\n";
+ echo $buffer;
+ }
+
+/**
+ * Send the headers necessary to ensure the page is
+ * reloaded on every request. Otherwise you could be
+ * scratching your head over out of date test data.
+ *
+ * @return void
+ */
+ public function sendNoCacheHeaders() {
+ if (!headers_sent()) {
+ header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: post-check=0, pre-check=0", false);
+ header("Pragma: no-cache");
+ }
+ }
+
+/**
+ * Paints the end of the test with a summary of
+ * the passes and failures.
+ *
+ * @param PHPUnit_Framework_TestResult $result Result object
+ * @return void
+ */
+ public function paintFooter($result) {
+ ob_end_flush();
+ $colour = ($result->failureCount() + $result->errorCount() > 0 ? "red" : "green");
+ echo "</ul>\n";
+ echo "<div style=\"";
+ echo "padding: 8px; margin: 1em 0; background-color: $colour; color: white;";
+ echo "\">";
+ echo ($result->count() - $result->skippedCount()) . "/" . $result->count();
+ echo " test methods complete:\n";
+ echo "<strong>" . count($result->passed()) . "</strong> passes, ";
+ echo "<strong>" . $result->failureCount() . "</strong> fails, ";
+ echo "<strong>" . $this->numAssertions . "</strong> assertions and ";
+ echo "<strong>" . $result->errorCount() . "</strong> exceptions.";
+ echo "</div>\n";
+ echo '<div style="padding:0 0 5px;">';
+ echo '<p><strong>Time:</strong> ' . $result->time() . ' seconds</p>';
+ echo '<p><strong>Peak memory:</strong> ' . number_format(memory_get_peak_usage()) . ' bytes</p>';
+ echo $this->_paintLinks();
+ echo '</div>';
+ if (isset($this->params['codeCoverage']) && $this->params['codeCoverage']) {
+ $coverage = $result->getCodeCoverage();
+ if (method_exists($coverage, 'getSummary')) {
+ $report = $coverage->getSummary();
+ echo $this->paintCoverage($report);
+ }
+ if (method_exists($coverage, 'getData')) {
+ $report = $coverage->getData();
+ echo $this->paintCoverage($report);
+ }
+ }
+ $this->paintDocumentEnd();
+ }
+
+/**
+ * Paints a code coverage report.
+ *
+ * @return void
+ */
+ public function paintCoverage(array $coverage) {
+ App::uses('HtmlCoverageReport', 'TestSuite/Coverage');
+
+ $reporter = new HtmlCoverageReport($coverage, $this);
+ echo $reporter->report();
+ }
+
+/**
+ * Renders the links that for accessing things in the test suite.
+ *
+ * @return void
+ */
+ protected function _paintLinks() {
+ $show = $query = array();
+ if (!empty($this->params['case'])) {
+ $show['show'] = 'cases';
+ }
+
+ if (!empty($this->params['core'])) {
+ $show['core'] = $query['core'] = 'true';
+ }
+ if (!empty($this->params['plugin'])) {
+ $show['plugin'] = $query['plugin'] = $this->params['plugin'];
+ }
+ if (!empty($this->params['case'])) {
+ $query['case'] = $this->params['case'];
+ }
+ $show = $this->_queryString($show);
+ $query = $this->_queryString($query);
+
+ echo "<p><a href='" . $this->baseUrl() . $show . "'>Run more tests</a> | <a href='" . $this->baseUrl() . $query . "&show_passes=1'>Show Passes</a> | \n";
+ echo "<a href='" . $this->baseUrl() . $query . "&debug=1'>Enable Debug Output</a> | \n";
+ echo "<a href='" . $this->baseUrl() . $query . "&amp;code_coverage=true'>Analyze Code Coverage</a></p>\n";
+ }
+
+/**
+ * Convert an array of parameters into a query string url
+ *
+ * @param array $url Url hash to be converted
+ * @return string Converted url query string
+ */
+ protected function _queryString($url) {
+ $out = '?';
+ $params = array();
+ foreach ($url as $key => $value) {
+ $params[] = "$key=$value";
+ }
+ $out .= implode('&amp;', $params);
+ return $out;
+ }
+
+/**
+ * Paints the end of the document html.
+ *
+ * @return void
+ */
+ public function paintDocumentEnd() {
+ $baseDir = $this->params['baseDir'];
+ include CAKE . 'TestSuite' . DS . 'templates' . DS . 'footer.php';
+ if (ob_get_length()) {
+ ob_end_flush();
+ }
+ }
+
+/**
+ * Paints the test failure with a breadcrumbs
+ * trail of the nesting test suites below the
+ * top level test.
+ *
+ * @param PHPUnit_Framework_AssertionFailedError $message Failure object displayed in
+ * the context of the other tests.
+ * @return void
+ */
+ public function paintFail($message, $test) {
+ $trace = $this->_getStackTrace($message);
+ $testName = get_class($test) . '(' . $test->getName() . ')';
+
+ $actualMsg = $expectedMsg = null;
+ $failure = $message->getComparisonFailure();
+ if (is_object($failure)) {
+ $actualMsg = $message->getComparisonFailure()->getActualAsString();
+ $expectedMsg = $message->getComparisonFailure()->getExpectedAsString();
+ }
+
+ echo "<li class='fail'>\n";
+ echo "<span>Failed</span>";
+ echo "<div class='msg'><pre>" . $this->_htmlEntities($message->toString());
+
+ if ((is_string($actualMsg) && is_string($expectedMsg)) || (is_array($actualMsg) && is_array($expectedMsg))) {
+ echo "<br />" . PHPUnit_Util_Diff::diff($expectedMsg, $actualMsg);
+ }
+
+ echo "</pre></div>\n";
+ echo "<div class='msg'>" . __d('cake_dev', 'Test case: %s', $testName) . "</div>\n";
+ echo "<div class='msg'>" . __d('cake_dev', 'Stack trace:') . '<br />' . $trace . "</div>\n";
+ echo "</li>\n";
+ }
+
+/**
+ * Paints the test pass with a breadcrumbs
+ * trail of the nesting test suites below the
+ * top level test.
+ *
+ * @param PHPUnit_Framework_Test test method that just passed
+ * @param float $time time spent to run the test method
+ * @return void
+ */
+ public function paintPass(PHPUnit_Framework_Test $test, $time = null) {
+ if (isset($this->params['showPasses']) && $this->params['showPasses']) {
+ echo "<li class='pass'>\n";
+ echo "<span>Passed</span> ";
+
+ echo "<br />" . $this->_htmlEntities($test->getName()) . " ($time seconds)\n";
+ echo "</li>\n";
+ }
+ }
+
+/**
+ * Paints a PHP exception.
+ *
+ * @param Exception $exception Exception to display.
+ * @return void
+ */
+ public function paintException($message, $test) {
+ $trace = $this->_getStackTrace($message);
+ $testName = get_class($test) . '(' . $test->getName() . ')';
+
+ echo "<li class='fail'>\n";
+ echo "<span>" . get_class($message) . "</span>";
+
+ echo "<div class='msg'>" . $this->_htmlEntities($message->getMessage()) . "</div>\n";
+ echo "<div class='msg'>" . __d('cake_dev', 'Test case: %s', $testName) . "</div>\n";
+ echo "<div class='msg'>" . __d('cake_dev', 'Stack trace:') . '<br />' . $trace . "</div>\n";
+ echo "</li>\n";
+ }
+
+/**
+ * Prints the message for skipping tests.
+ *
+ * @param string $message Text of skip condition.
+ * @param PHPUnit_Framework_TestCase $test the test method skipped
+ * @return void
+ */
+ public function paintSkip($message, $test) {
+ echo "<li class='skipped'>\n";
+ echo "<span>Skipped</span> ";
+ echo $test->getName() . ': ' . $this->_htmlEntities($message->getMessage());
+ echo "</li>\n";
+ }
+
+/**
+ * Paints formatted text such as dumped variables.
+ *
+ * @param string $message Text to show.
+ * @return void
+ */
+ public function paintFormattedMessage($message) {
+ echo '<pre>' . $this->_htmlEntities($message) . '</pre>';
+ }
+
+/**
+ * Character set adjusted entity conversion.
+ *
+ * @param string $message Plain text or Unicode message.
+ * @return string Browser readable message.
+ */
+ protected function _htmlEntities($message) {
+ return htmlentities($message, ENT_COMPAT, $this->_characterSet);
+ }
+
+/**
+ * Gets a formatted stack trace.
+ *
+ * @param Exception $e Exception to get a stack trace for.
+ * @return string Generated stack trace.
+ */
+ protected function _getStackTrace(Exception $e) {
+ $trace = $e->getTrace();
+ $out = array();
+ foreach ($trace as $frame) {
+ if (isset($frame['file']) && isset($frame['line'])) {
+ $out[] = $frame['file'] . ' : ' . $frame['line'];
+ } elseif (isset($frame['class']) && isset($frame['function'])) {
+ $out[] = $frame['class'] . '::' . $frame['function'];
+ } else {
+ $out[] = '[internal]';
+ }
+ }
+ return implode('<br />', $out);
+ }
+
+/**
+ * A test suite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
+ if (!$this->_headerSent) {
+ echo $this->paintHeader();
+ }
+ echo '<h2>' . __d('cake_dev', 'Running %s', $suite->getName()) . '</h2>';
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeTextReporter.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeTextReporter.php
new file mode 100644
index 0000000..1c8c201
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/Reporter/CakeTextReporter.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * CakeTextReporter contains reporting features used for plain text based output
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('CakeBaseReporter', 'TestSuite/Reporter');
+App::uses('TextCoverageReport', 'TestSuite/Coverage');
+
+/**
+ * CakeTextReporter contains reporting features used for plain text based output
+ *
+ * @package Cake.TestSuite.Reporter
+ */
+class CakeTextReporter extends CakeBaseReporter {
+
+/**
+ * Sets the text/plain header if the test is not a CLI test.
+ *
+ * @return void
+ */
+ public function paintDocumentStart() {
+ if (!headers_sent()) {
+ header('Content-type: text/plain');
+ }
+ }
+
+/**
+ * Paints a pass
+ *
+ * @return void
+ */
+ public function paintPass() {
+ echo '.';
+ }
+
+/**
+ * Paints a failing test.
+ *
+ * @param $message PHPUnit_Framework_AssertionFailedError $message Failure object displayed in
+ * the context of the other tests.
+ * @return void
+ */
+ public function paintFail($message) {
+ $context = $message->getTrace();
+ $realContext = $context[3];
+ $context = $context[2];
+
+ printf(
+ "FAIL on line %s\n%s in\n%s %s()\n\n",
+ $context['line'], $message->toString(), $context['file'], $realContext['function']
+ );
+ }
+
+/**
+ * Paints the end of the test with a summary of
+ * the passes and failures.
+ *
+ * @param PHPUnit_Framework_TestResult $result Result object
+ * @return void
+ */
+ public function paintFooter($result) {
+ if ($result->failureCount() + $result->errorCount() == 0) {
+ echo "\nOK\n";
+ } else {
+ echo "FAILURES!!!\n";
+ }
+
+ echo "Test cases run: " . $result->count() .
+ "/" . ($result->count() - $result->skippedCount()) .
+ ', Passes: ' . $this->numAssertions .
+ ', Failures: ' . $result->failureCount() .
+ ', Exceptions: ' . $result->errorCount() . "\n";
+
+ echo 'Time: ' . $result->time() . " seconds\n";
+ echo 'Peak memory: ' . number_format(memory_get_peak_usage()) . " bytes\n";
+
+ if (isset($this->params['codeCoverage']) && $this->params['codeCoverage']) {
+ $coverage = $result->getCodeCoverage()->getSummary();
+ echo $this->paintCoverage($coverage);
+ }
+ }
+
+/**
+ * Paints the title only.
+ *
+ * @param string $test_name Name class of test.
+ * @return void
+ */
+ public function paintHeader() {
+ $this->paintDocumentStart();
+ flush();
+ }
+
+/**
+ * Paints a PHP exception.
+ *
+ * @param Exception $exception Exception to describe.
+ * @return void
+ */
+ public function paintException($exception) {
+ $message = 'Unexpected exception of type [' . get_class($exception) .
+ '] with message [' . $exception->getMessage() .
+ '] in [' . $exception->getFile() .
+ ' line ' . $exception->getLine() . ']';
+ echo $message . "\n\n";
+ }
+
+/**
+ * Prints the message for skipping tests.
+ *
+ * @param string $message Text of skip condition.
+ * @return void
+ */
+ public function paintSkip($message) {
+ printf("Skip: %s\n", $message->getMessage());
+ }
+
+/**
+ * Paints formatted text such as dumped variables.
+ *
+ * @param string $message Text to show.
+ * @return void
+ */
+ public function paintFormattedMessage($message) {
+ echo "$message\n";
+ flush();
+ }
+
+/**
+ * Generate a test case list in plain text.
+ * Creates as series of url's for tests that can be run.
+ * One case per line.
+ *
+ * @return void
+ */
+ public function testCaseList() {
+ $testCases = parent::testCaseList();
+ $app = $this->params['app'];
+ $plugin = $this->params['plugin'];
+
+ $buffer = "Core Test Cases:\n";
+ $urlExtra = '';
+ if ($app) {
+ $buffer = "App Test Cases:\n";
+ $urlExtra = '&app=true';
+ } elseif ($plugin) {
+ $buffer = Inflector::humanize($plugin) . " Test Cases:\n";
+ $urlExtra = '&plugin=' . $plugin;
+ }
+
+ if (1 > count($testCases)) {
+ $buffer .= "EMPTY";
+ echo $buffer;
+ }
+
+ foreach ($testCases as $testCaseFile => $testCase) {
+ $buffer .= $_SERVER['SERVER_NAME'] . $this->baseUrl() . "?case=" . $testCase . "&output=text\n";
+ }
+
+ $buffer .= "\n";
+ echo $buffer;
+ }
+
+/**
+ * Generates a Text summary of the coverage data.
+ *
+ * @param array $coverage Array of coverage data.
+ * @return string
+ */
+ public function paintCoverage($coverage) {
+ $reporter = new TextCoverageReport($coverage, $this);
+ echo $reporter->report();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/footer.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/footer.php
new file mode 100644
index 0000000..06af88e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/footer.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.templates
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?> </div>
+ </div>
+ <div id="footer">
+ <p>
+ <!--PLEASE USE ONE OF THE POWERED BY CAKEPHP LOGO-->
+ <a href="http://www.cakephp.org/" target="_blank">
+ <img src="<?php echo $baseDir; ?>img/cake.power.gif" alt="CakePHP(tm) :: Rapid Development Framework" /></a>
+ </p>
+ </div>
+ <?php
+ App::uses('View', 'View');
+ $null = null;
+ $View = new View($null, false);
+ echo $View->element('sql_dump');
+ ?>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/header.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/header.php
new file mode 100644
index 0000000..4d41719
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/header.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.templates
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>CakePHP Test Suite 2.2</title>
+ <style type="text/css">
+ body h2 {color: #777;}
+ h3 {font-size: 170%; padding-top: 1em}
+ a {font-size: 120%}
+ li {line-height: 140%}
+ .test-menu {float:left; margin-right: 24px;}
+ .test-results {float:left; width: 67%;}
+ ul.tests {margin: 0; font-size:12px;}
+ ul.tests li {
+ list-style: none;
+ margin: 14px 0;
+ padding-left: 20px;
+ }
+ ul.tests li span {
+ font-size:14px;
+ text-transform: uppercase;
+ font-weight: bold;
+ }
+ ul.tests li.pass span, ul.tests li.skipped span { display:inline;}
+ ul.tests li.fail span { color: red; }
+ ul.tests li.pass span { color: green; }
+ ul.tests li.skipped span { color: navy; }
+ ul.tests li.error span { color : #d15d00; }
+
+ ul.tests li.pass,
+ ul.tests li.error,
+ ul.tests li.skipped,
+ ul.tests li.fail {
+ background: #fff2f2 url(<?php echo $baseDir; ?>img/test-fail-icon.png) 5px 5px no-repeat;
+ border-top: 1px dotted red;
+ border-bottom: 1px dotted red;
+ padding:5px 10px 2px 25px;
+ }
+ ul.tests li.pass {
+ background-color: #f2fff2;
+ background-image: url(<?php echo $baseDir; ?>img/test-pass-icon.png);
+ border-color:green;
+ }
+ ul.tests li.skipped {
+ background-color: #edf1ff;
+ background-image: url(<?php echo $baseDir; ?>img/test-skip-icon.png);
+ border-color:navy;
+ }
+ ul.tests li.error {
+ background-color: #ffffe5;
+ background-image: url(<?php echo $baseDir; ?>img/test-error-icon.png);
+ border-color: #DF6300;
+ }
+ ul.tests li div { margin: 5px 0 8px 0; }
+ ul.tests li div.msg { font-weight: bold; }
+ table caption { color:#fff; }
+
+ div.code-coverage-results div.code-line {
+ padding-left:5px;
+ display:block;
+ margin-left:10px;
+ }
+ .coverage-toggle {
+ float:right;
+ margin-top:10px;
+ font-size:12px;
+ }
+ .coverage-container {
+ margin-top:1em;
+ }
+ div.code-coverage-results div.uncovered span.content { background:#ecc; }
+ div.code-coverage-results div.covered span.content { background:#cec; }
+ div.code-coverage-results div.ignored span.content { color:#aaa; }
+ div.code-coverage-results div:hover {
+ background:#e8e8e8;
+ cursor: pointer;
+ }
+ div.code-coverage-results div.covered:hover span.content { background:#b4edb4;}
+ div.code-coverage-results div.uncovered:hover span.content { background:#edb4b4;}
+ div.code-coverage-results span.line-num {
+ color:#666;
+ display:block;
+ float:left;
+ width:20px;
+ text-align:right;
+ margin-right:5px;
+ }
+ div.code-coverage-results span.line-num strong { color:#666; }
+ div.code-coverage-results div.start {
+ border:1px solid #aaa;
+ border-width:1px 1px 0px 1px;
+ margin-top:30px;
+ padding-top:5px;
+ }
+ div.code-coverage-results div.end {
+ border:1px solid #aaa;
+ border-width:0px 1px 1px 1px;
+ margin-bottom:30px;
+ padding-bottom:5px;
+ }
+ div.code-coverage-results div.realstart { margin-top:0px; }
+ div.code-coverage-results p.note {
+ color:#bbb;
+ padding:5px;
+ margin:5px 0 10px;
+ font-size:10px;
+ }
+ div.code-coverage-results span.result-bad { color: #a00; }
+ div.code-coverage-results span.result-ok { color: #fa0; }
+ div.code-coverage-results span.result-good { color: #0a0; }
+
+ div#version {
+ padding-top: 2px;
+ float: right;
+ padding-left: 20px;
+ }
+ </style>
+ <link rel="stylesheet" type="text/css" href="<?php echo $baseDir; ?>css/cake.generic.css" />
+ </head>
+ <body>
+ <div id="container">
+ <div id="header">
+ <div id="version">PHPUnit: <?php echo class_exists('PHPUnit_Runner_Version') ? PHPUnit_Runner_Version::id() : 'n/a'; ?></div>
+ <h1>CakePHP: the rapid development php framework</h1>
+ </div>
+ <div id="content">
+ <h2>CakePHP Test Suite 2.2</h2>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/menu.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/menu.php
new file mode 100644
index 0000000..df6ec41
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/menu.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Short description for file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.templates
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="test-menu">
+<ul>
+ <li>
+ <span style="font-size: 18px">App</span>
+ <ul>
+ <li><a href='<?php echo $cases; ?>'>Tests</a></li>
+ </ul>
+ </li>
+<?php if (!empty($plugins)): ?>
+ <li style="padding-top: 10px">
+ <span style="font-size: 18px">Plugins</span>
+ <?php foreach ($plugins as $plugin): ?>
+ <ul>
+ <li style="padding-top: 10px">
+ <span style="font-size: 18px"><?php echo $plugin; ?></span>
+ <ul>
+ <li><?php printf('<a href="%s&amp;plugin=%s">Tests</a>', $cases, $plugin); ?></li>
+ </ul>
+ </li>
+ </ul>
+ <?php endforeach; ?>
+ </li>
+<?php endif; ?>
+ <li style="padding-top: 10px">
+ <span style="font-size: 18px">Core</span>
+ <ul>
+ <li><a href='<?php echo $cases; ?>&amp;core=true'>Tests</a></li>
+ </ul>
+ </li>
+</ul>
+</div>
+<div class="test-results">
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/missing_connection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/missing_connection.php
new file mode 100644
index 0000000..fc9e3ca
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/missing_connection.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Missing Connection error page
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.templates
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php include dirname(__FILE__) . DS . 'header.php'; ?>
+<div id="content">
+ <h2>Missing Test Database Connection</h2>
+ <h3><?php echo $exception->getMessage(); ?></h3>
+ <pre><?php echo $exception->getTraceAsString(); ?></pre>
+</div>
+<?php
+include dirname(__FILE__) . DS . 'footer.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/phpunit.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/phpunit.php
new file mode 100644
index 0000000..ae111f7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/phpunit.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Missing PHPUnit
+ * error page.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.templates
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php include dirname(__FILE__) . DS . 'header.php'; ?>
+<div id="content">
+ <h2>PHPUnit is not installed!</h2>
+ <p>You must install PHPUnit to use the CakePHP(tm) Test Suite.</p>
+ <p>PHPUnit can be installed with pear, using the pear installer.</p>
+ <p>To install with the PEAR installer run the following commands:</p>
+ <ul>
+ <li><code>pear config-set auto_discover 1</code></li>
+ <li><code>pear install pear.phpunit.de/PHPUnit</code></li>
+ </ul>
+ <p>Once PHPUnit is installed make sure its located on PHP's <code>include_path</code> by checking your php.ini</p>
+ <p>For full instructions on how to <a href="http://www.phpunit.de/manual/current/en/installation.html" target="_blank">install PHPUnit, see the PHPUnit installation guide</a>.</p>
+ <p><a href="http://github.com/sebastianbergmann/phpunit" target="_blank">Download PHPUnit</a></p>
+</div>
+<?php
+include dirname(__FILE__) . DS . 'footer.php';
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/xdebug.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/xdebug.php
new file mode 100644
index 0000000..ecf24cb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/TestSuite/templates/xdebug.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Xdebug error page
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
+ * @package Cake.TestSuite.templates
+ * @since CakePHP(tm) v 1.2.0.4433
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<?php include dirname(__FILE__) . DS . 'header.php'; ?>
+<div id="content">
+ <h2>Xdebug is not installed</h2>
+ <p>You must install Xdebug to use the CakePHP(tm) Code Coverage Analyzation.</p>
+ <p><a href="http://www.xdebug.org/docs/install" target="_blank">Learn How To Install Xdebug</a></p>
+</div>
+<?php
+include dirname(__FILE__) . DS . 'footer.php';
+
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php
new file mode 100644
index 0000000..3b21cbc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php
@@ -0,0 +1,296 @@
+<?php
+/**
+ * CakeNumber Utility.
+ *
+ * Methods to make numbers more readable.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Number helper library.
+ *
+ * Methods to make numbers more readable.
+ *
+ * @package Cake.Utility
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html
+ */
+class CakeNumber {
+
+/**
+ * Currencies supported by the helper. You can add additional currency formats
+ * with CakeNumber::addFormat
+ *
+ * @var array
+ */
+ protected static $_currencies = array(
+ 'USD' => array(
+ 'wholeSymbol' => '$', 'wholePosition' => 'before', 'fractionSymbol' => 'c', 'fractionPosition' => 'after',
+ 'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()', 'escape' => true
+ ),
+ 'GBP' => array(
+ 'wholeSymbol' => '&#163;', 'wholePosition' => 'before', 'fractionSymbol' => 'p', 'fractionPosition' => 'after',
+ 'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()','escape' => false
+ ),
+ 'EUR' => array(
+ 'wholeSymbol' => '&#8364;', 'wholePosition' => 'before', 'fractionSymbol' => false, 'fractionPosition' => 'after',
+ 'zero' => 0, 'places' => 2, 'thousands' => '.', 'decimals' => ',', 'negative' => '()', 'escape' => false
+ )
+ );
+
+/**
+ * Default options for currency formats
+ *
+ * @var array
+ */
+ protected static $_currencyDefaults = array(
+ 'wholeSymbol' => '', 'wholePosition' => 'before', 'fractionSymbol' => '', 'fractionPosition' => 'after',
+ 'zero' => '0', 'places' => 2, 'thousands' => ',', 'decimals' => '.','negative' => '()', 'escape' => true,
+ );
+
+/**
+ * If native number_format() should be used. If >= PHP5.4
+ *
+ * @var boolean
+ */
+ protected static $_numberFormatSupport = null;
+
+/**
+ * Formats a number with a level of precision.
+ *
+ * @param float $number A floating point number.
+ * @param integer $precision The precision of the returned number.
+ * @return float Formatted float.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::precision
+ */
+ public static function precision($number, $precision = 3) {
+ return sprintf("%01.{$precision}F", $number);
+ }
+
+/**
+ * Returns a formatted-for-humans file size.
+ *
+ * @param integer $size Size in bytes
+ * @return string Human readable size
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
+ */
+ public static function toReadableSize($size) {
+ switch (true) {
+ case $size < 1024:
+ return __dn('cake', '%d Byte', '%d Bytes', $size, $size);
+ case round($size / 1024) < 1024:
+ return __d('cake', '%d KB', self::precision($size / 1024, 0));
+ case round($size / 1024 / 1024, 2) < 1024:
+ return __d('cake', '%.2f MB', self::precision($size / 1024 / 1024, 2));
+ case round($size / 1024 / 1024 / 1024, 2) < 1024:
+ return __d('cake', '%.2f GB', self::precision($size / 1024 / 1024 / 1024, 2));
+ default:
+ return __d('cake', '%.2f TB', self::precision($size / 1024 / 1024 / 1024 / 1024, 2));
+ }
+ }
+
+/**
+ * Formats a number into a percentage string.
+ *
+ * @param float $number A floating point number
+ * @param integer $precision The precision of the returned number
+ * @return string Percentage string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage
+ */
+ public static function toPercentage($number, $precision = 2) {
+ return self::precision($number, $precision) . '%';
+ }
+
+/**
+ * Formats a number into a currency format.
+ *
+ * @param float $number A floating point number
+ * @param integer $options if int then places, if string then before, if (,.-) then use it
+ * or array with places and before keys
+ * @return string formatted number
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::format
+ */
+ public static function format($number, $options = false) {
+ $places = 0;
+ if (is_int($options)) {
+ $places = $options;
+ }
+
+ $separators = array(',', '.', '-', ':');
+
+ $before = $after = null;
+ if (is_string($options) && !in_array($options, $separators)) {
+ $before = $options;
+ }
+ $thousands = ',';
+ if (!is_array($options) && in_array($options, $separators)) {
+ $thousands = $options;
+ }
+ $decimals = '.';
+ if (!is_array($options) && in_array($options, $separators)) {
+ $decimals = $options;
+ }
+
+ $escape = true;
+ if (is_array($options)) {
+ $options = array_merge(array('before' => '$', 'places' => 2, 'thousands' => ',', 'decimals' => '.'), $options);
+ extract($options);
+ }
+
+ $out = $before . self::_numberFormat($number, $places, $decimals, $thousands) . $after;
+
+ if ($escape) {
+ return h($out);
+ }
+ return $out;
+ }
+
+/**
+ * Alternative number_format() to accommodate multibyte decimals and thousands < PHP 5.4
+ *
+ * @param float $number
+ * @param integer $places
+ * @param string $decimals
+ * @param string $thousands
+ * @return string
+ */
+ protected static function _numberFormat($number, $places = 0, $decimals = '.', $thousands = ',') {
+ if (!isset(self::$_numberFormatSupport)) {
+ self::$_numberFormatSupport = version_compare(PHP_VERSION, '5.4.0', '>=');
+ }
+ if (self::$_numberFormatSupport) {
+ return number_format($number, $places, $decimals, $thousands);
+ }
+ $number = number_format($number, $places, '.', '');
+ $after = '';
+ $foundDecimal = strpos($number, '.');
+ if ($foundDecimal !== false) {
+ $after = substr($number, $foundDecimal);
+ $number = substr($number, 0, $foundDecimal);
+ }
+ while (($foundThousand = preg_replace('/(\d+)(\d\d\d)/', '\1 \2', $number)) != $number) {
+ $number = $foundThousand;
+ }
+ $number .= $after;
+ return strtr($number, array(' ' => $thousands, '.' => $decimals));
+ }
+
+/**
+ * Formats a number into a currency format.
+ *
+ * ### Options
+ *
+ * - `wholeSymbol` - The currency symbol to use for whole numbers,
+ * greater than 1, or less than -1.
+ * - `wholePosition` - The position the whole symbol should be placed
+ * valid options are 'before' & 'after'.
+ * - `fractionSymbol` - The currency symbol to use for fractional numbers.
+ * - `fractionPosition` - The position the fraction symbol should be placed
+ * valid options are 'before' & 'after'.
+ * - `before` - The currency symbol to place before whole numbers
+ * ie. '$'. `before` is an alias for `wholeSymbol`.
+ * - `after` - The currency symbol to place after decimal numbers
+ * ie. 'c'. Set to boolean false to use no decimal symbol.
+ * eg. 0.35 => $0.35. `after` is an alias for `fractionSymbol`
+ * - `zero` - The text to use for zero values, can be a
+ * string or a number. ie. 0, 'Free!'
+ * - `places` - Number of decimal places to use. ie. 2
+ * - `thousands` - Thousands separator ie. ','
+ * - `decimals` - Decimal separator symbol ie. '.'
+ * - `negative` - Symbol for negative numbers. If equal to '()',
+ * the number will be wrapped with ( and )
+ * - `escape` - Should the output be htmlentity escaped? Defaults to true
+ *
+ * @param float $number
+ * @param string $currency Shortcut to default options. Valid values are
+ * 'USD', 'EUR', 'GBP', otherwise set at least 'before' and 'after' options.
+ * @param array $options
+ * @return string Number formatted as a currency.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
+ */
+ public static function currency($number, $currency = 'USD', $options = array()) {
+ $default = self::$_currencyDefaults;
+
+ if (isset(self::$_currencies[$currency])) {
+ $default = self::$_currencies[$currency];
+ } elseif (is_string($currency)) {
+ $options['before'] = $currency;
+ }
+
+ $options = array_merge($default, $options);
+
+ if (isset($options['before']) && $options['before'] !== '') {
+ $options['wholeSymbol'] = $options['before'];
+ }
+ if (isset($options['after']) && !$options['after'] !== '') {
+ $options['fractionSymbol'] = $options['after'];
+ }
+
+ $result = $options['before'] = $options['after'] = null;
+
+ $symbolKey = 'whole';
+ if ($number == 0 ) {
+ if ($options['zero'] !== 0 ) {
+ return $options['zero'];
+ }
+ } elseif ($number < 1 && $number > -1 ) {
+ if ($options['fractionSymbol'] !== false) {
+ $multiply = intval('1' . str_pad('', $options['places'], '0'));
+ $number = $number * $multiply;
+ $options['places'] = null;
+ $symbolKey = 'fraction';
+ }
+ }
+
+ $position = $options[$symbolKey . 'Position'] != 'after' ? 'before' : 'after';
+ $options[$position] = $options[$symbolKey . 'Symbol'];
+
+ $abs = abs($number);
+ $result = self::format($abs, $options);
+
+ if ($number < 0 ) {
+ if ($options['negative'] == '()') {
+ $result = '(' . $result . ')';
+ } else {
+ $result = $options['negative'] . $result;
+ }
+ }
+ return $result;
+ }
+
+/**
+ * Add a currency format to the Number helper. Makes reusing
+ * currency formats easier.
+ *
+ * {{{ $number->addFormat('NOK', array('before' => 'Kr. ')); }}}
+ *
+ * You can now use `NOK` as a shortform when formatting currency amounts.
+ *
+ * {{{ $number->currency($value, 'NOK'); }}}
+ *
+ * Added formats are merged with the defaults defined in CakeNumber::$_currencyDefaults
+ * See CakeNumber::currency() for more information on the various options and their function.
+ *
+ * @param string $formatName The format name to be used in the future.
+ * @param array $options The array of options for this format.
+ * @return void
+ * @see NumberHelper::currency()
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::addFormat
+ */
+ public static function addFormat($formatName, $options) {
+ self::$_currencies[$formatName] = $options + self::$_currencyDefaults;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php
new file mode 100644
index 0000000..4788d53
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php
@@ -0,0 +1,1057 @@
+<?php
+/**
+ * CakeTime utility class file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Multibyte', 'I18n');
+
+/**
+ * Time Helper class for easy use of time data.
+ *
+ * Manipulation of time data.
+ *
+ * @package Cake.Utility
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html
+ */
+class CakeTime {
+
+/**
+ * The format to use when formatting a time using `CakeTime::nice()`
+ *
+ * The format should use the locale strings as defined in the PHP docs under
+ * `strftime` (http://php.net/manual/en/function.strftime.php)
+ *
+ * @var string
+ * @see CakeTime::format()
+ */
+ public static $niceFormat = '%a, %b %eS %Y, %H:%M';
+
+/**
+ * The format to use when formatting a time using `CakeTime::timeAgoInWords()`
+ * and the difference is more than `CakeTime::$wordEnd`
+ *
+ * @var string
+ * @see CakeTime::timeAgoInWords()
+ */
+ public static $wordFormat = 'j/n/y';
+
+/**
+ * The format to use when formatting a time using `CakeTime::niceShort()`
+ * and the difference is between 3 and 7 days
+ *
+ * @var string
+ * @see CakeTime::niceShort()
+ */
+ public static $niceShortFormat = '%d/%m, %H:%M';
+
+/**
+ * The format to use when formatting a time using `CakeTime::timeAgoInWords()`
+ * and the difference is less than `CakeTime::$wordEnd`
+ *
+ * @var array
+ * @see CakeTime::timeAgoInWords()
+ */
+ public static $wordAccuracy = array(
+ 'year' => "day",
+ 'month' => "day",
+ 'week' => "day",
+ 'day' => "hour",
+ 'hour' => "minute",
+ 'minute' => "minute",
+ 'second' => "second",
+ );
+
+/**
+ * The end of relative time telling
+ *
+ * @var string
+ * @see CakeTime::timeAgoInWords()
+ */
+ public static $wordEnd = '+1 month';
+
+/**
+ * Temporary variable containing timestamp value, used internally convertSpecifiers()
+ */
+ protected static $_time = null;
+
+/**
+ * Magic set method for backward compatibility.
+ *
+ * Used by TimeHelper to modify static variables in CakeTime
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'niceFormat':
+ self::${$name} = $value;
+ break;
+ default:
+ break;
+ }
+ }
+
+/**
+ * Magic set method for backward compatibility.
+ *
+ * Used by TimeHelper to get static variables in CakeTime
+ */
+ public function __get($name) {
+ switch ($name) {
+ case 'niceFormat':
+ return self::${$name};
+ break;
+ default:
+ return null;
+ break;
+ }
+ }
+
+/**
+ * Converts a string representing the format for the function strftime and returns a
+ * windows safe and i18n aware format.
+ *
+ * @param string $format Format with specifiers for strftime function.
+ * Accepts the special specifier %S which mimics the modifier S for date()
+ * @param string $time UNIX timestamp
+ * @return string windows safe and date() function compatible format for strftime
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function convertSpecifiers($format, $time = null) {
+ if (!$time) {
+ $time = time();
+ }
+ self::$_time = $time;
+ return preg_replace_callback('/\%(\w+)/', array('CakeTime', '_translateSpecifier'), $format);
+ }
+
+/**
+ * Auxiliary function to translate a matched specifier element from a regular expression into
+ * a windows safe and i18n aware specifier
+ *
+ * @param array $specifier match from regular expression
+ * @return string converted element
+ */
+ protected static function _translateSpecifier($specifier) {
+ switch ($specifier[1]) {
+ case 'a':
+ $abday = __dc('cake', 'abday', 5);
+ if (is_array($abday)) {
+ return $abday[date('w', self::$_time)];
+ }
+ break;
+ case 'A':
+ $day = __dc('cake', 'day', 5);
+ if (is_array($day)) {
+ return $day[date('w', self::$_time)];
+ }
+ break;
+ case 'c':
+ $format = __dc('cake', 'd_t_fmt', 5);
+ if ($format != 'd_t_fmt') {
+ return self::convertSpecifiers($format, self::$_time);
+ }
+ break;
+ case 'C':
+ return sprintf("%02d", date('Y', self::$_time) / 100);
+ case 'D':
+ return '%m/%d/%y';
+ case 'e':
+ if (DS === '/') {
+ return '%e';
+ }
+ $day = date('j', self::$_time);
+ if ($day < 10) {
+ $day = ' ' . $day;
+ }
+ return $day;
+ case 'eS' :
+ return date('jS', self::$_time);
+ case 'b':
+ case 'h':
+ $months = __dc('cake', 'abmon', 5);
+ if (is_array($months)) {
+ return $months[date('n', self::$_time) - 1];
+ }
+ return '%b';
+ case 'B':
+ $months = __dc('cake', 'mon', 5);
+ if (is_array($months)) {
+ return $months[date('n', self::$_time) - 1];
+ }
+ break;
+ case 'n':
+ return "\n";
+ case 'p':
+ case 'P':
+ $default = array('am' => 0, 'pm' => 1);
+ $meridiem = $default[date('a', self::$_time)];
+ $format = __dc('cake', 'am_pm', 5);
+ if (is_array($format)) {
+ $meridiem = $format[$meridiem];
+ return ($specifier[1] == 'P') ? strtolower($meridiem) : strtoupper($meridiem);
+ }
+ break;
+ case 'r':
+ $complete = __dc('cake', 't_fmt_ampm', 5);
+ if ($complete != 't_fmt_ampm') {
+ return str_replace('%p', self::_translateSpecifier(array('%p', 'p')), $complete);
+ }
+ break;
+ case 'R':
+ return date('H:i', self::$_time);
+ case 't':
+ return "\t";
+ case 'T':
+ return '%H:%M:%S';
+ case 'u':
+ return ($weekDay = date('w', self::$_time)) ? $weekDay : 7;
+ case 'x':
+ $format = __dc('cake', 'd_fmt', 5);
+ if ($format != 'd_fmt') {
+ return self::convertSpecifiers($format, self::$_time);
+ }
+ break;
+ case 'X':
+ $format = __dc('cake', 't_fmt', 5);
+ if ($format != 't_fmt') {
+ return self::convertSpecifiers($format, self::$_time);
+ }
+ break;
+ }
+ return $specifier[0];
+ }
+
+/**
+ * Converts given time (in server's time zone) to user's local time, given his/her timezone.
+ *
+ * @param string $serverTime UNIX timestamp
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return integer UNIX timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function convert($serverTime, $timezone) {
+ static $serverTimezone = null;
+ if (is_null($serverTimezone) || (date_default_timezone_get() !== $serverTimezone->getName())) {
+ $serverTimezone = new DateTimeZone(date_default_timezone_get());
+ }
+ $serverOffset = $serverTimezone->getOffset(new DateTime('@' . $serverTime));
+ $gmtTime = $serverTime - $serverOffset;
+ if (is_numeric($timezone)) {
+ $userOffset = $timezone * (60 * 60);
+ } else {
+ $timezone = self::timezone($timezone);
+ $userOffset = $timezone->getOffset(new DateTime('@' . $gmtTime));
+ }
+ $userTime = $gmtTime + $userOffset;
+ return (int)$userTime;
+ }
+
+/**
+ * Returns a timezone object from a string or the user's timezone object
+ *
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * If null it tries to get timezone from 'Config.timezone' config var
+ * @return DateTimeZone Timezone object
+ */
+ public static function timezone($timezone = null) {
+ static $tz = null;
+
+ if (is_object($timezone)) {
+ if ($tz === null || $tz->getName() !== $timezone->getName()) {
+ $tz = $timezone;
+ }
+ } else {
+ if ($timezone === null) {
+ $timezone = Configure::read('Config.timezone');
+ if ($timezone === null) {
+ $timezone = date_default_timezone_get();
+ }
+ }
+
+ if ($tz === null || $tz->getName() !== $timezone) {
+ $tz = new DateTimeZone($timezone);
+ }
+ }
+
+ return $tz;
+ }
+
+/**
+ * Returns server's offset from GMT in seconds.
+ *
+ * @return integer Offset
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function serverOffset() {
+ return date('Z', time());
+ }
+
+/**
+ * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Parsed timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function fromString($dateString, $timezone = null) {
+ if (empty($dateString)) {
+ return false;
+ }
+
+ if (is_integer($dateString) || is_numeric($dateString)) {
+ $date = intval($dateString);
+ } elseif (is_object($dateString) && $dateString instanceof DateTime) {
+ $clone = clone $dateString;
+ $clone->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ $date = (int)$clone->format('U') + $clone->getOffset();
+ } else {
+ $date = strtotime($dateString);
+ }
+
+ if ($date === -1 || empty($date)) {
+ return false;
+ }
+
+ if ($timezone === null) {
+ $timezone = Configure::read('Config.timezone');
+ }
+
+ if ($timezone !== null) {
+ return self::convert($date, $timezone);
+ }
+ return $date;
+ }
+
+/**
+ * Returns a nicely formatted date string for given Datetime string.
+ *
+ * See http://php.net/manual/en/function.strftime.php for information on formatting
+ * using locale strings.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function nice($dateString = null, $timezone = null, $format = null) {
+ if (!$dateString) {
+ $dateString = time();
+ }
+ $date = self::fromString($dateString, $timezone);
+
+ if (!$format) {
+ $format = self::$niceFormat;
+ }
+ $format = self::convertSpecifiers($format, $date);
+ return self::_strftime($format, $date);
+ }
+
+/**
+ * Returns a formatted descriptive date string for given datetime string.
+ *
+ * If the given date is today, the returned string could be "Today, 16:54".
+ * If the given date is tomorrow, the returned string could be "Tomorrow, 16:54".
+ * If the given date was yesterday, the returned string could be "Yesterday, 16:54".
+ * If the given date is within next or last week, the returned string could be "On Thursday, 16:54".
+ * If $dateString's year is the current year, the returned string does not
+ * include mention of the year.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Described, relative date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function niceShort($dateString = null, $timezone = null) {
+ if (!$dateString) {
+ $dateString = time();
+ }
+ $date = self::fromString($dateString, $timezone);
+
+ $y = self::isThisYear($date) ? '' : ' %Y';
+
+ $d = self::_strftime("%w", $date);
+ $day = array(
+ __d('cake', 'Sunday'),
+ __d('cake', 'Monday'),
+ __d('cake', 'Tuesday'),
+ __d('cake', 'Wednesday'),
+ __d('cake', 'Thursday'),
+ __d('cake', 'Friday'),
+ __d('cake', 'Saturday')
+ );
+
+ if (self::isToday($dateString, $timezone)) {
+ $ret = __d('cake', 'Today, %s', self::_strftime("%H:%M", $date));
+ } elseif (self::wasYesterday($dateString, $timezone)) {
+ $ret = __d('cake', 'Yesterday, %s', self::_strftime("%H:%M", $date));
+ } elseif (self::isTomorrow($dateString, $timezone)) {
+ $ret = __d('cake', 'Tomorrow, %s', self::_strftime("%H:%M", $date));
+ } elseif (self::wasWithinLast('7 days', $dateString, $timezone)) {
+ $ret = sprintf('%s %s', $day[$d], self::_strftime(self::$niceShortFormat, $date));
+ } elseif (self::isWithinNext('7 days', $dateString, $timezone)) {
+ $ret = __d('cake', 'On %s %s', $day[$d], self::_strftime(self::$niceShortFormat, $date));
+ } else {
+ $format = self::convertSpecifiers("%b %eS{$y}, %H:%M", $date);
+ $ret = self::_strftime($format, $date);
+ }
+ return $ret;
+ }
+
+/**
+ * Returns a partial SQL string to search for all records between two dates.
+ *
+ * @param integer|string|DateTime $begin UNIX timestamp, strtotime() valid string or DateTime object
+ * @param integer|string|DateTime $end UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $fieldName Name of database field to compare with
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Partial SQL string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function daysAsSql($begin, $end, $fieldName, $timezone = null) {
+ $begin = self::fromString($begin, $timezone);
+ $end = self::fromString($end, $timezone);
+ $begin = date('Y-m-d', $begin) . ' 00:00:00';
+ $end = date('Y-m-d', $end) . ' 23:59:59';
+
+ return "($fieldName >= '$begin') AND ($fieldName <= '$end')";
+ }
+
+/**
+ * Returns a partial SQL string to search for all records between two times
+ * occurring on the same day.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $fieldName Name of database field to compare with
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Partial SQL string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function dayAsSql($dateString, $fieldName, $timezone = null) {
+ return self::daysAsSql($dateString, $dateString, $fieldName);
+ }
+
+/**
+ * Returns true if given datetime string is today.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean True if datetime string is today
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public static function isToday($dateString, $timezone = null) {
+ $date = self::fromString($dateString, $timezone);
+ return date('Y-m-d', $date) == date('Y-m-d', time());
+ }
+
+/**
+ * Returns true if given datetime string is within this week.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current week
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public static function isThisWeek($dateString, $timezone = null) {
+ $date = self::fromString($dateString, $timezone);
+ return date('W o', $date) == date('W o', time());
+ }
+
+/**
+ * Returns true if given datetime string is within this month
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current month
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public static function isThisMonth($dateString, $timezone = null) {
+ $date = self::fromString($dateString);
+ return date('m Y', $date) == date('m Y', time());
+ }
+
+/**
+ * Returns true if given datetime string is within current year.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current year
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public static function isThisYear($dateString, $timezone = null) {
+ $date = self::fromString($dateString, $timezone);
+ return date('Y', $date) == date('Y', time());
+ }
+
+/**
+ * Returns true if given datetime string was yesterday.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean True if datetime string was yesterday
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ *
+ */
+ public static function wasYesterday($dateString, $timezone = null) {
+ $date = self::fromString($dateString, $timezone);
+ return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday'));
+ }
+
+/**
+ * Returns true if given datetime string is tomorrow.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean True if datetime string was yesterday
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public static function isTomorrow($dateString, $timezone = null) {
+ $date = self::fromString($dateString, $timezone);
+ return date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow'));
+ }
+
+/**
+ * Returns the quarter
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param boolean $range if true returns a range in Y-m-d format
+ * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function toQuarter($dateString, $range = false) {
+ $time = self::fromString($dateString);
+ $date = ceil(date('m', $time) / 3);
+
+ if ($range === true) {
+ $range = 'Y-m-d';
+ }
+
+ if ($range !== false) {
+ $year = date('Y', $time);
+
+ switch ($date) {
+ case 1:
+ $date = array($year . '-01-01', $year . '-03-31');
+ break;
+ case 2:
+ $date = array($year . '-04-01', $year . '-06-30');
+ break;
+ case 3:
+ $date = array($year . '-07-01', $year . '-09-30');
+ break;
+ case 4:
+ $date = array($year . '-10-01', $year . '-12-31');
+ break;
+ }
+ }
+ return $date;
+ }
+
+/**
+ * Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return integer Unix timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function toUnix($dateString, $timezone = null) {
+ return self::fromString($dateString, $timezone);
+ }
+
+/**
+ * Returns a formatted date in server's timezone.
+ *
+ * If a DateTime object is given or the dateString has a timezone
+ * segment, the timezone parameter will be ignored.
+ *
+ * If no timezone parameter is given and no DateTime object, the passed $dateString will be
+ * considered to be in the UTC timezone.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @param string $format date format string
+ * @return mixed Formatted date
+ */
+ public static function toServer($dateString, $timezone = null, $format = 'Y-m-d H:i:s') {
+ if ($timezone === null) {
+ $timezone = new DateTimeZone('UTC');
+ } elseif (is_string($timezone)) {
+ $timezone = new DateTimeZone($timezone);
+ } elseif (!($timezone instanceof DateTimeZone)) {
+ return false;
+ }
+
+ if ($dateString instanceof DateTime) {
+ $date = $dateString;
+ } elseif (is_integer($dateString) || is_numeric($dateString)) {
+ $dateString = (int)$dateString;
+
+ $date = new DateTime('@' . $dateString);
+ $date->setTimezone($timezone);
+ } else {
+ $date = new DateTime($dateString, $timezone);
+ }
+
+ $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
+ return $date->format($format);
+ }
+
+/**
+ * Returns a date formatted for Atom RSS feeds.
+ *
+ * @param string $dateString Datetime string or Unix timestamp
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function toAtom($dateString, $timezone = null) {
+ $date = self::fromString($dateString, $timezone);
+ return date('Y-m-d\TH:i:s\Z', $date);
+ }
+
+/**
+ * Formats date for RSS feeds
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function toRSS($dateString, $timezone = null) {
+ $date = self::fromString($dateString, $timezone);
+
+ if (!is_null($timezone)) {
+ if (is_numeric($timezone)) {
+ $userOffset = $timezone;
+ } else {
+ if (!is_object($timezone)) {
+ $timezone = new DateTimeZone($timezone);
+ }
+ $currentDate = new DateTime('@' . $date);
+ $currentDate->setTimezone($timezone);
+ $userOffset = $timezone->getOffset($currentDate) / 60 / 60;
+ }
+ if ($userOffset == 0) {
+ $timezone = '+0000';
+ } else {
+ $hours = (int)floor(abs($userOffset));
+ $minutes = (int)(fmod(abs($userOffset), $hours) * 60);
+ $timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT);
+ }
+ return date('D, d M Y H:i:s', $date) . ' ' . $timezone;
+ }
+ return date("r", $date);
+ }
+
+/**
+ * Returns either a relative date or a formatted date depending
+ * on the difference between the current time and given datetime.
+ * $datetime should be in a *strtotime* - parsable format, like MySQL's datetime datatype.
+ *
+ * ### Options:
+ *
+ * - `format` => a fall back format if the relative time is longer than the duration specified by end
+ * - `accuracy` => Specifies how accurate the date should be described (array)
+ * - year => The format if years > 0 (default "day")
+ * - month => The format if months > 0 (default "day")
+ * - week => The format if weeks > 0 (default "day")
+ * - day => The format if weeks > 0 (default "hour")
+ * - hour => The format if hours > 0 (default "minute")
+ * - minute => The format if minutes > 0 (default "minute")
+ * - second => The format if seconds > 0 (default "second")
+ * - `end` => The end of relative time telling
+ * - `userOffset` => Users offset from GMT (in hours) *Deprecated* use timezone intead.
+ * - `timezone` => The user timezone the timestamp should be formatted in.
+ *
+ * Relative dates look something like this:
+ *
+ * - 3 weeks, 4 days ago
+ * - 15 seconds ago
+ *
+ * Default date formatting is d/m/yy e.g: on 18/2/09
+ *
+ * The returned string includes 'ago' or 'on' and assumes you'll properly add a word
+ * like 'Posted ' before the function output.
+ *
+ * NOTE: If the difference is one week or more, the lowest level of accuracy is day
+ *
+ * @param integer|string|DateTime $dateTime Datetime UNIX timestamp, strtotime() valid string or DateTime object
+ * @param array $options Default format if timestamp is used in $dateString
+ * @return string Relative time string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function timeAgoInWords($dateTime, $options = array()) {
+ $timezone = null;
+ $format = self::$wordFormat;
+ $end = self::$wordEnd;
+ $accuracy = self::$wordAccuracy;
+
+ if (is_array($options)) {
+ if (isset($options['timezone'])) {
+ $timezone = $options['timezone'];
+ } elseif (isset($options['userOffset'])) {
+ $timezone = $options['userOffset'];
+ }
+
+ if (isset($options['accuracy'])) {
+ if (is_array($options['accuracy'])) {
+ $accuracy = array_merge($accuracy, $options['accuracy']);
+ } else {
+ foreach ($accuracy as $key => $level) {
+ $accuracy[$key] = $options['accuracy'];
+ }
+ }
+ }
+
+ if (isset($options['format'])) {
+ $format = $options['format'];
+ }
+ if (isset($options['end'])) {
+ $end = $options['end'];
+ }
+ unset($options['end'], $options['format']);
+ } else {
+ $format = $options;
+ }
+
+ $now = self::fromString(time(), $timezone);
+ $inSeconds = self::fromString($dateTime, $timezone);
+ $backwards = ($inSeconds > $now);
+
+ if ($backwards) {
+ $futureTime = $inSeconds;
+ $pastTime = $now;
+ } else {
+ $futureTime = $now;
+ $pastTime = $inSeconds;
+ }
+ $diff = $futureTime - $pastTime;
+
+ // If more than a week, then take into account the length of months
+ if ($diff >= 604800) {
+ list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime));
+
+ list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime));
+ $years = $months = $weeks = $days = $hours = $minutes = $seconds = 0;
+
+ $years = $future['Y'] - $past['Y'];
+ $months = $future['m'] + ((12 * $years) - $past['m']);
+
+ if ($months >= 12) {
+ $years = floor($months / 12);
+ $months = $months - ($years * 12);
+ }
+ if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] == 1) {
+ $years--;
+ }
+
+ if ($future['d'] >= $past['d']) {
+ $days = $future['d'] - $past['d'];
+ } else {
+ $daysInPastMonth = date('t', $pastTime);
+ $daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y']));
+
+ if (!$backwards) {
+ $days = ($daysInPastMonth - $past['d']) + $future['d'];
+ } else {
+ $days = ($daysInFutureMonth - $past['d']) + $future['d'];
+ }
+
+ if ($future['m'] != $past['m']) {
+ $months--;
+ }
+ }
+
+ if ($months == 0 && $years >= 1 && $diff < ($years * 31536000)) {
+ $months = 11;
+ $years--;
+ }
+
+ if ($months >= 12) {
+ $years = $years + 1;
+ $months = $months - 12;
+ }
+
+ if ($days >= 7) {
+ $weeks = floor($days / 7);
+ $days = $days - ($weeks * 7);
+ }
+ } else {
+ $years = $months = $weeks = 0;
+ $days = floor($diff / 86400);
+
+ $diff = $diff - ($days * 86400);
+
+ $hours = floor($diff / 3600);
+ $diff = $diff - ($hours * 3600);
+
+ $minutes = floor($diff / 60);
+ $diff = $diff - ($minutes * 60);
+ $seconds = $diff;
+ }
+ $relativeDate = '';
+ $diff = $futureTime - $pastTime;
+
+ if ($diff > abs($now - self::fromString($end))) {
+ $relativeDate = __d('cake', 'on %s', date($format, $inSeconds));
+ } else {
+ if ($years > 0) {
+ $f = $accuracy['year'];
+ } elseif (abs($months) > 0) {
+ $f = $accuracy['month'];
+ } elseif (abs($weeks) > 0) {
+ $f = $accuracy['week'];
+ } elseif (abs($days) > 0) {
+ $f = $accuracy['day'];
+ } elseif (abs($hours) > 0) {
+ $f = $accuracy['hour'];
+ } elseif (abs($minutes) > 0) {
+ $f = $accuracy['minute'];
+ } else {
+ $f = $accuracy['second'];
+ }
+
+ $f = str_replace(array('year', 'month', 'week', 'day', 'hour', 'minute', 'second'), array(1, 2, 3, 4, 5, 6, 7), $f);
+
+ $relativeDate .= $f >= 1 && $years > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years) : '';
+ $relativeDate .= $f >= 2 && $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : '';
+ $relativeDate .= $f >= 3 && $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
+ $relativeDate .= $f >= 4 && $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
+ $relativeDate .= $f >= 5 && $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : '';
+ $relativeDate .= $f >= 6 && $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : '';
+ $relativeDate .= $f >= 7 && $seconds > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds) : '';
+
+ if (!$backwards) {
+ $relativeDate = __d('cake', '%s ago', $relativeDate);
+ }
+ }
+
+ // If now
+ if ($diff == 0) {
+ $relativeDate = __d('cake', 'just now', 'just now');
+ }
+ return $relativeDate;
+ }
+
+/**
+ * Returns true if specified datetime was within the interval specified, else false.
+ *
+ * @param string|integer $timeInterval the numeric value with space then time type.
+ * Example of valid types: 6 hours, 2 days, 1 minute.
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public static function wasWithinLast($timeInterval, $dateString, $timezone = null) {
+ $tmp = str_replace(' ', '', $timeInterval);
+ if (is_numeric($tmp)) {
+ $timeInterval = $tmp . ' ' . __d('cake', 'days');
+ }
+
+ $date = self::fromString($dateString, $timezone);
+ $interval = self::fromString('-' . $timeInterval);
+
+ if ($date >= $interval && $date <= time()) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Returns true if specified datetime is within the interval specified, else false.
+ *
+ * @param string|integer $timeInterval the numeric value with space then time type.
+ * Example of valid types: 6 hours, 2 days, 1 minute.
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public static function isWithinNext($timeInterval, $dateString, $timezone = null) {
+ $tmp = str_replace(' ', '', $timeInterval);
+ if (is_numeric($tmp)) {
+ $timeInterval = $tmp . ' ' . __d('cake', 'days');
+ }
+
+ $date = self::fromString($dateString, $timezone);
+ $interval = self::fromString('+' . $timeInterval);
+
+ if ($date <= $interval && $date >= time()) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Returns gmt as a UNIX timestamp.
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @return integer UNIX timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function gmt($dateString = null) {
+ if ($dateString != null) {
+ $time = self::fromString($dateString);
+ } else {
+ $time = time();
+ }
+ $hour = intval(date("G", $time));
+ $minute = intval(date("i", $time));
+ $second = intval(date("s", $time));
+ $month = intval(date("n", $time));
+ $day = intval(date("j", $time));
+ $year = intval(date("Y", $time));
+ return gmmktime($hour, $minute, $second, $month, $day, $year);
+ }
+
+/**
+ * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
+ * This function also accepts a time string and a format string as first and second parameters.
+ * In that case this function behaves as a wrapper for TimeHelper::i18nFormat()
+ *
+ * ## Examples:
+ * {{{
+ * CakeTime::format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012
+ * CakeTime::format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale
+ * CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed
+ * CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone
+ * }}}
+ *
+ * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string)
+ * @param integer|string|DateTime $format date format string (or UNIX timestamp, strtotime() valid string or DateTime object)
+ * @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function format($date, $format = null, $default = false, $timezone = null) {
+ //Backwards compatible params order
+ $time = self::fromString($format, $timezone);
+ $_time = is_numeric($time) ? false : self::fromString($date, $timezone);
+
+ if (is_numeric($_time) && $time === false) {
+ return self::i18nFormat($_time, $format, $default, $timezone);
+ }
+ if ($time === false && $default !== false) {
+ return $default;
+ }
+ return date($date, $time);
+ }
+
+/**
+ * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
+ * It take in account the default date format for the current language if a LC_TIME file is used.
+ *
+ * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $format strftime format string.
+ * @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value
+ * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
+ * @return string Formatted and translated date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public static function i18nFormat($date, $format = null, $default = false, $timezone = null) {
+ $date = self::fromString($date, $timezone);
+ if ($date === false && $default !== false) {
+ return $default;
+ }
+ if (empty($format)) {
+ $format = '%x';
+ }
+ $format = self::convertSpecifiers($format, $date);
+ return self::_strftime($format, $date);
+ }
+
+/**
+ * Get list of timezone identifiers
+ *
+ * @param integer|string $filter A regex to filter identifer
+ * Or one of DateTimeZone class constants (PHP 5.3 and above)
+ * @param string $country A two-letter ISO 3166-1 compatible country code.
+ * This option is only used when $filter is set to DateTimeZone::PER_COUNTRY (available only in PHP 5.3 and above)
+ * @param boolean $group If true (default value) groups the identifiers list by primary region
+ * @return array List of timezone identifiers
+ * @since 2.2
+ */
+ public static function listTimezones($filter = null, $country = null, $group = true) {
+ $regex = null;
+ if (is_string($filter)) {
+ $regex = $filter;
+ $filter = null;
+ }
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+ if ($regex === null) {
+ $regex = '#^((Africa|America|Antartica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)/|UTC)#';
+ }
+ $identifiers = DateTimeZone::listIdentifiers();
+ } else {
+ if ($filter === null) {
+ $filter = DateTimeZone::ALL;
+ }
+ $identifiers = DateTimeZone::listIdentifiers($filter, $country);
+ }
+
+ if ($regex) {
+ foreach ($identifiers as $key => $tz) {
+ if (!preg_match($regex, $tz)) {
+ unset($identifiers[$key]);
+ }
+ }
+ }
+
+ if ($group) {
+ $return = array();
+ foreach ($identifiers as $key => $tz) {
+ $item = explode('/', $tz, 2);
+ if (isset($item[1])) {
+ $return[$item[0]][$tz] = $item[1];
+ } else {
+ $return[$item[0]] = array($tz => $item[0]);
+ }
+ }
+ return $return;
+ } else {
+ return array_combine($identifiers, $identifiers);
+ }
+ }
+
+/**
+ * Multibyte wrapper for strftime.
+ *
+ * Handles utf8_encoding the result of strftime when necessary.
+ *
+ * @param string $format Format string.
+ * @param integer $date Timestamp to format.
+ * @return string formatted string with correct encoding.
+ */
+ protected static function _strftime($format, $date) {
+ $format = strftime($format, $date);
+ $encoding = Configure::read('App.encoding');
+
+ if (!empty($encoding) && $encoding === 'UTF-8') {
+ if (function_exists('mb_check_encoding')) {
+ $valid = mb_check_encoding($format, $encoding);
+ } else {
+ $valid = !Multibyte::checkMultibyte($format);
+ }
+ if (!$valid) {
+ $format = utf8_encode($format);
+ }
+ }
+ return $format;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php
new file mode 100644
index 0000000..da7b125
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php
@@ -0,0 +1,368 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 0.9.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Included libraries.
+ */
+App::uses('Model', 'Model');
+App::uses('AppModel', 'Model');
+App::uses('ConnectionManager', 'Model');
+
+/**
+ * Class Collections.
+ *
+ * A repository for class objects, each registered with a key.
+ * If you try to add an object with the same key twice, nothing will come of it.
+ * If you need a second instance of an object, give it another key.
+ *
+ * @package Cake.Utility
+ */
+class ClassRegistry {
+
+/**
+ * Names of classes with their objects.
+ *
+ * @var array
+ */
+ protected $_objects = array();
+
+/**
+ * Names of class names mapped to the object in the registry.
+ *
+ * @var array
+ */
+ protected $_map = array();
+
+/**
+ * Default constructor parameter settings, indexed by type
+ *
+ * @var array
+ */
+ protected $_config = array();
+
+/**
+ * Return a singleton instance of the ClassRegistry.
+ *
+ * @return ClassRegistry instance
+ */
+ public static function &getInstance() {
+ static $instance = array();
+ if (!$instance) {
+ $instance[0] = new ClassRegistry();
+ }
+ return $instance[0];
+ }
+
+/**
+ * Loads a class, registers the object in the registry and returns instance of the object. ClassRegistry::init()
+ * is used as a factory for models, and handle correct injecting of settings, that assist in testing.
+ *
+ * Examples
+ * Simple Use: Get a Post model instance ```ClassRegistry::init('Post');```
+ *
+ * Expanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model');```
+ *
+ * Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);```
+ *
+ * When $class is a numeric keyed array, multiple class instances will be stored in the registry,
+ * no instance of the object will be returned
+ * {{{
+ * array(
+ * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry'),
+ * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry'),
+ * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry')
+ * );
+ * }}}
+ * @param string|array $class as a string or a single key => value array instance will be created,
+ * stored in the registry and returned.
+ * @param boolean $strict if set to true it will return false if the class was not found instead
+ * of trying to create an AppModel
+ * @return object instance of ClassName.
+ * @throws CakeException when you try to construct an interface or abstract class.
+ */
+ public static function init($class, $strict = false) {
+ $_this = ClassRegistry::getInstance();
+ $false = false;
+ $true = true;
+
+ if (is_array($class)) {
+ $objects = $class;
+ if (!isset($class[0])) {
+ $objects = array($class);
+ }
+ } else {
+ $objects = array(array('class' => $class));
+ }
+ $defaults = isset($_this->_config['Model']) ? $_this->_config['Model'] : array();
+ $count = count($objects);
+ $availableDs = array_keys(ConnectionManager::enumConnectionObjects());
+
+ foreach ($objects as $key => $settings) {
+ if (is_array($settings)) {
+ $pluginPath = null;
+ $settings = array_merge($defaults, $settings);
+ $class = $settings['class'];
+
+ list($plugin, $class) = pluginSplit($class);
+ if ($plugin) {
+ $pluginPath = $plugin . '.';
+ }
+
+ if (empty($settings['alias'])) {
+ $settings['alias'] = $class;
+ }
+ $alias = $settings['alias'];
+
+ if ($model = $_this->_duplicate($alias, $class)) {
+ $_this->map($alias, $class);
+ return $model;
+ }
+
+ App::uses($plugin . 'AppModel', $pluginPath . 'Model');
+ App::uses($class, $pluginPath . 'Model');
+
+ if (class_exists($class) || interface_exists($class)) {
+ $reflection = new ReflectionClass($class);
+ if ($reflection->isAbstract() || $reflection->isInterface()) {
+ throw new CakeException(__d('cake_dev', 'Cannot create instance of %s, as it is abstract or is an interface', $class));
+ }
+ $testing = isset($settings['testing']) ? $settings['testing'] : false;
+ if ($testing) {
+ $settings['ds'] = 'test';
+ $defaultProperties = $reflection->getDefaultProperties();
+ if (isset($defaultProperties['useDbConfig'])) {
+ $useDbConfig = $defaultProperties['useDbConfig'];
+ if (in_array('test_' . $useDbConfig, $availableDs)) {
+ $useDbConfig = 'test_' . $useDbConfig;
+ }
+ if (strpos($useDbConfig, 'test') === 0) {
+ $settings['ds'] = $useDbConfig;
+ }
+ }
+ }
+ if ($reflection->getConstructor()) {
+ $instance = $reflection->newInstance($settings);
+ } else {
+ $instance = $reflection->newInstance();
+ }
+ if ($strict) {
+ $instance = ($instance instanceof Model) ? $instance : null;
+ }
+ }
+ if (!isset($instance)) {
+ if ($strict) {
+ return false;
+ } elseif ($plugin && class_exists($plugin . 'AppModel')) {
+ $appModel = $plugin . 'AppModel';
+ } else {
+ $appModel = 'AppModel';
+ }
+ if (!empty($appModel)) {
+ $settings['name'] = $class;
+ $instance = new $appModel($settings);
+ }
+
+ if (!isset($instance)) {
+ trigger_error(__d('cake_dev', '(ClassRegistry::init() could not create instance of %1$s class %2$s ', $class, $type), E_USER_WARNING);
+ return $false;
+ }
+ }
+ $_this->map($alias, $class);
+ } elseif (is_numeric($settings)) {
+ trigger_error(__d('cake_dev', '(ClassRegistry::init() Attempted to create instance of a class with a numeric name'), E_USER_WARNING);
+ return $false;
+ }
+ }
+
+ if ($count > 1) {
+ return $true;
+ }
+ return $instance;
+ }
+
+/**
+ * Add $object to the registry, associating it with the name $key.
+ *
+ * @param string $key Key for the object in registry
+ * @param object $object Object to store
+ * @return boolean True if the object was written, false if $key already exists
+ */
+ public static function addObject($key, $object) {
+ $_this = ClassRegistry::getInstance();
+ $key = Inflector::underscore($key);
+ if (!isset($_this->_objects[$key])) {
+ $_this->_objects[$key] = $object;
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Remove object which corresponds to given key.
+ *
+ * @param string $key Key of object to remove from registry
+ * @return void
+ */
+ public static function removeObject($key) {
+ $_this = ClassRegistry::getInstance();
+ $key = Inflector::underscore($key);
+ if (isset($_this->_objects[$key])) {
+ unset($_this->_objects[$key]);
+ }
+ }
+
+/**
+ * Returns true if given key is present in the ClassRegistry.
+ *
+ * @param string $key Key to look for
+ * @return boolean true if key exists in registry, false otherwise
+ */
+ public static function isKeySet($key) {
+ $_this = ClassRegistry::getInstance();
+ $key = Inflector::underscore($key);
+ if (isset($_this->_objects[$key])) {
+ return true;
+ } elseif (isset($_this->_map[$key])) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Get all keys from the registry.
+ *
+ * @return array Set of keys stored in registry
+ */
+ public static function keys() {
+ $_this = ClassRegistry::getInstance();
+ return array_keys($_this->_objects);
+ }
+
+/**
+ * Return object which corresponds to given key.
+ *
+ * @param string $key Key of object to look for
+ * @return mixed Object stored in registry or boolean false if the object does not exist.
+ */
+ public static function &getObject($key) {
+ $_this = ClassRegistry::getInstance();
+ $key = Inflector::underscore($key);
+ $return = false;
+ if (isset($_this->_objects[$key])) {
+ $return = $_this->_objects[$key];
+ } else {
+ $key = $_this->_getMap($key);
+ if (isset($_this->_objects[$key])) {
+ $return = $_this->_objects[$key];
+ }
+ }
+ return $return;
+ }
+
+/**
+ * Sets the default constructor parameter for an object type
+ *
+ * @param string $type Type of object. If this parameter is omitted, defaults to "Model"
+ * @param array $param The parameter that will be passed to object constructors when objects
+ * of $type are created
+ * @return mixed Void if $param is being set. Otherwise, if only $type is passed, returns
+ * the previously-set value of $param, or null if not set.
+ */
+ public static function config($type, $param = array()) {
+ $_this = ClassRegistry::getInstance();
+
+ if (empty($param) && is_array($type)) {
+ $param = $type;
+ $type = 'Model';
+ } elseif (is_null($param)) {
+ unset($_this->_config[$type]);
+ } elseif (empty($param) && is_string($type)) {
+ return isset($_this->_config[$type]) ? $_this->_config[$type] : null;
+ }
+ if (isset($_this->_config[$type]['testing'])) {
+ $param['testing'] = true;
+ }
+ $_this->_config[$type] = $param;
+ }
+
+/**
+ * Checks to see if $alias is a duplicate $class Object
+ *
+ * @param string $alias
+ * @param string $class
+ * @return boolean
+ */
+ protected function &_duplicate($alias, $class) {
+ $duplicate = false;
+ if ($this->isKeySet($alias)) {
+ $model = $this->getObject($alias);
+ if (is_object($model) && (is_a($model, $class) || $model->alias === $class)) {
+ $duplicate = $model;
+ }
+ unset($model);
+ }
+ return $duplicate;
+ }
+
+/**
+ * Add a key name pair to the registry to map name to class in the registry.
+ *
+ * @param string $key Key to include in map
+ * @param string $name Key that is being mapped
+ * @return void
+ */
+ public static function map($key, $name) {
+ $_this = ClassRegistry::getInstance();
+ $key = Inflector::underscore($key);
+ $name = Inflector::underscore($name);
+ if (!isset($_this->_map[$key])) {
+ $_this->_map[$key] = $name;
+ }
+ }
+
+/**
+ * Get all keys from the map in the registry.
+ *
+ * @return array Keys of registry's map
+ */
+ public static function mapKeys() {
+ $_this = ClassRegistry::getInstance();
+ return array_keys($_this->_map);
+ }
+
+/**
+ * Return the name of a class in the registry.
+ *
+ * @param string $key Key to find in map
+ * @return string Mapped value
+ */
+ protected function _getMap($key) {
+ if (isset($this->_map[$key])) {
+ return $this->_map[$key];
+ }
+ }
+
+/**
+ * Flushes all objects from the ClassRegistry.
+ *
+ * @return void
+ */
+ public static function flush() {
+ $_this = ClassRegistry::getInstance();
+ $_this->_objects = array();
+ $_this->_map = array();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php
new file mode 100644
index 0000000..1d7410a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php
@@ -0,0 +1,817 @@
+<?php
+/**
+ * Framework debugging and PHP error-handling class
+ *
+ * Provides enhanced logging, stack traces, and rendering debug views
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 1.2.4560
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeLog', 'Log');
+App::uses('String', 'Utility');
+
+/**
+ * Provide custom logging and error handling.
+ *
+ * Debugger overrides PHP's default error handling to provide stack traces and enhanced logging
+ *
+ * @package Cake.Utility
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#debugger-class
+ */
+class Debugger {
+
+/**
+ * A list of errors generated by the application.
+ *
+ * @var array
+ */
+ public $errors = array();
+
+/**
+ * The current output format.
+ *
+ * @var string
+ */
+ protected $_outputFormat = 'js';
+
+/**
+ * Templates used when generating trace or error strings. Can be global or indexed by the format
+ * value used in $_outputFormat.
+ *
+ * @var string
+ */
+ protected $_templates = array(
+ 'log' => array(
+ 'trace' => '{:reference} - {:path}, line {:line}',
+ 'error' => "{:error} ({:code}): {:description} in [{:file}, line {:line}]"
+ ),
+ 'js' => array(
+ 'error' => '',
+ 'info' => '',
+ 'trace' => '<pre class="stack-trace">{:trace}</pre>',
+ 'code' => '',
+ 'context' => '',
+ 'links' => array(),
+ 'escapeContext' => true,
+ ),
+ 'html' => array(
+ 'trace' => '<pre class="cake-error trace"><b>Trace</b> <p>{:trace}</p></pre>',
+ 'context' => '<pre class="cake-error context"><b>Context</b> <p>{:context}</p></pre>',
+ 'escapeContext' => true,
+ ),
+ 'txt' => array(
+ 'error' => "{:error}: {:code} :: {:description} on line {:line} of {:path}\n{:info}",
+ 'code' => '',
+ 'info' => ''
+ ),
+ 'base' => array(
+ 'traceLine' => '{:reference} - {:path}, line {:line}',
+ 'trace' => "Trace:\n{:trace}\n",
+ 'context' => "Context:\n{:context}\n",
+ ),
+ 'log' => array(),
+ );
+
+/**
+ * Holds current output data when outputFormat is false.
+ *
+ * @var string
+ */
+ protected $_data = array();
+
+/**
+ * Constructor.
+ *
+ */
+ public function __construct() {
+ $docRef = ini_get('docref_root');
+
+ if (empty($docRef) && function_exists('ini_set')) {
+ ini_set('docref_root', 'http://php.net/');
+ }
+ if (!defined('E_RECOVERABLE_ERROR')) {
+ define('E_RECOVERABLE_ERROR', 4096);
+ }
+
+ $e = '<pre class="cake-error">';
+ $e .= '<a href="javascript:void(0);" onclick="document.getElementById(\'{:id}-trace\')';
+ $e .= '.style.display = (document.getElementById(\'{:id}-trace\').style.display == ';
+ $e .= '\'none\' ? \'\' : \'none\');"><b>{:error}</b> ({:code})</a>: {:description} ';
+ $e .= '[<b>{:path}</b>, line <b>{:line}</b>]';
+
+ $e .= '<div id="{:id}-trace" class="cake-stack-trace" style="display: none;">';
+ $e .= '{:links}{:info}</div>';
+ $e .= '</pre>';
+ $this->_templates['js']['error'] = $e;
+
+ $t = '<div id="{:id}-trace" class="cake-stack-trace" style="display: none;">';
+ $t .= '{:context}{:code}{:trace}</div>';
+ $this->_templates['js']['info'] = $t;
+
+ $links = array();
+ $link = '<a href="javascript:void(0);" onclick="document.getElementById(\'{:id}-code\')';
+ $link .= '.style.display = (document.getElementById(\'{:id}-code\').style.display == ';
+ $link .= '\'none\' ? \'\' : \'none\')">Code</a>';
+ $links['code'] = $link;
+
+ $link = '<a href="javascript:void(0);" onclick="document.getElementById(\'{:id}-context\')';
+ $link .= '.style.display = (document.getElementById(\'{:id}-context\').style.display == ';
+ $link .= '\'none\' ? \'\' : \'none\')">Context</a>';
+ $links['context'] = $link;
+
+ $this->_templates['js']['links'] = $links;
+
+ $this->_templates['js']['context'] = '<pre id="{:id}-context" class="cake-context" ';
+ $this->_templates['js']['context'] .= 'style="display: none;">{:context}</pre>';
+
+ $this->_templates['js']['code'] = '<pre id="{:id}-code" class="cake-code-dump" ';
+ $this->_templates['js']['code'] .= 'style="display: none;">{:code}</pre>';
+
+ $e = '<pre class="cake-error"><b>{:error}</b> ({:code}) : {:description} ';
+ $e .= '[<b>{:path}</b>, line <b>{:line}]</b></pre>';
+ $this->_templates['html']['error'] = $e;
+
+ $this->_templates['html']['context'] = '<pre class="cake-context"><b>Context</b> ';
+ $this->_templates['html']['context'] .= '<p>{:context}</p></pre>';
+ }
+
+/**
+ * Returns a reference to the Debugger singleton object instance.
+ *
+ * @param string $class
+ * @return object
+ */
+ public static function &getInstance($class = null) {
+ static $instance = array();
+ if (!empty($class)) {
+ if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) {
+ $instance[0] = new $class();
+ }
+ }
+ if (!$instance) {
+ $instance[0] = new Debugger();
+ }
+ return $instance[0];
+ }
+
+/**
+ * Recursively formats and outputs the contents of the supplied variable.
+ *
+ *
+ * @param mixed $var the variable to dump
+ * @return void
+ * @see Debugger::exportVar()
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::dump
+ */
+ public static function dump($var) {
+ pr(self::exportVar($var));
+ }
+
+/**
+ * Creates an entry in the log file. The log entry will contain a stack trace from where it was called.
+ * as well as export the variable using exportVar. By default the log is written to the debug log.
+ *
+ * @param mixed $var Variable or content to log
+ * @param integer $level type of log to use. Defaults to LOG_DEBUG
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::log
+ */
+ public static function log($var, $level = LOG_DEBUG) {
+ $source = self::trace(array('start' => 1)) . "\n";
+ CakeLog::write($level, "\n" . $source . self::exportVar($var));
+ }
+
+/**
+ * Overrides PHP's default error handling.
+ *
+ * @param integer $code Code of error
+ * @param string $description Error description
+ * @param string $file File on which error occurred
+ * @param integer $line Line that triggered the error
+ * @param array $context Context
+ * @return boolean true if error was handled
+ * @deprecated This function is superseded by Debugger::outputError()
+ */
+ public static function showError($code, $description, $file = null, $line = null, $context = null) {
+ $self = Debugger::getInstance();
+
+ if (empty($file)) {
+ $file = '[internal]';
+ }
+ if (empty($line)) {
+ $line = '??';
+ }
+ $path = self::trimPath($file);
+
+ $info = compact('code', 'description', 'file', 'line');
+ if (!in_array($info, $self->errors)) {
+ $self->errors[] = $info;
+ } else {
+ return;
+ }
+
+ switch ($code) {
+ case E_PARSE:
+ case E_ERROR:
+ case E_CORE_ERROR:
+ case E_COMPILE_ERROR:
+ case E_USER_ERROR:
+ $error = 'Fatal Error';
+ $level = LOG_ERR;
+ break;
+ case E_WARNING:
+ case E_USER_WARNING:
+ case E_COMPILE_WARNING:
+ case E_RECOVERABLE_ERROR:
+ $error = 'Warning';
+ $level = LOG_WARNING;
+ break;
+ case E_NOTICE:
+ case E_USER_NOTICE:
+ $error = 'Notice';
+ $level = LOG_NOTICE;
+ break;
+ case E_DEPRECATED:
+ case E_USER_DEPRECATED:
+ $error = 'Deprecated';
+ $level = LOG_NOTICE;
+ break;
+ default:
+ return;
+ break;
+ }
+
+ $data = compact(
+ 'level', 'error', 'code', 'description', 'file', 'path', 'line', 'context'
+ );
+ echo $self->outputError($data);
+
+ if ($error == 'Fatal Error') {
+ exit();
+ }
+ return true;
+ }
+
+/**
+ * Outputs a stack trace based on the supplied options.
+ *
+ * ### Options
+ *
+ * - `depth` - The number of stack frames to return. Defaults to 999
+ * - `format` - The format you want the return. Defaults to the currently selected format. If
+ * format is 'array' or 'points' the return will be an array.
+ * - `args` - Should arguments for functions be shown? If true, the arguments for each method call
+ * will be displayed.
+ * - `start` - The stack frame to start generating a trace from. Defaults to 0
+ *
+ * @param array $options Format for outputting stack trace
+ * @return mixed Formatted stack trace
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::trace
+ */
+ public static function trace($options = array()) {
+ $self = Debugger::getInstance();
+ $defaults = array(
+ 'depth' => 999,
+ 'format' => $self->_outputFormat,
+ 'args' => false,
+ 'start' => 0,
+ 'scope' => null,
+ 'exclude' => array('call_user_func_array', 'trigger_error')
+ );
+ $options = Hash::merge($defaults, $options);
+
+ $backtrace = debug_backtrace();
+ $count = count($backtrace);
+ $back = array();
+
+ $_trace = array(
+ 'line' => '??',
+ 'file' => '[internal]',
+ 'class' => null,
+ 'function' => '[main]'
+ );
+
+ for ($i = $options['start']; $i < $count && $i < $options['depth']; $i++) {
+ $trace = array_merge(array('file' => '[internal]', 'line' => '??'), $backtrace[$i]);
+ $signature = $reference = '[main]';
+
+ if (isset($backtrace[$i + 1])) {
+ $next = array_merge($_trace, $backtrace[$i + 1]);
+ $signature = $reference = $next['function'];
+
+ if (!empty($next['class'])) {
+ $signature = $next['class'] . '::' . $next['function'];
+ $reference = $signature . '(';
+ if ($options['args'] && isset($next['args'])) {
+ $args = array();
+ foreach ($next['args'] as $arg) {
+ $args[] = Debugger::exportVar($arg);
+ }
+ $reference .= join(', ', $args);
+ }
+ $reference .= ')';
+ }
+ }
+ if (in_array($signature, $options['exclude'])) {
+ continue;
+ }
+ if ($options['format'] == 'points' && $trace['file'] != '[internal]') {
+ $back[] = array('file' => $trace['file'], 'line' => $trace['line']);
+ } elseif ($options['format'] == 'array') {
+ $back[] = $trace;
+ } else {
+ if (isset($self->_templates[$options['format']]['traceLine'])) {
+ $tpl = $self->_templates[$options['format']]['traceLine'];
+ } else {
+ $tpl = $self->_templates['base']['traceLine'];
+ }
+ $trace['path'] = self::trimPath($trace['file']);
+ $trace['reference'] = $reference;
+ unset($trace['object'], $trace['args']);
+ $back[] = String::insert($tpl, $trace, array('before' => '{:', 'after' => '}'));
+ }
+ }
+
+ if ($options['format'] == 'array' || $options['format'] == 'points') {
+ return $back;
+ }
+ return implode("\n", $back);
+ }
+
+/**
+ * Shortens file paths by replacing the application base path with 'APP', and the CakePHP core
+ * path with 'CORE'.
+ *
+ * @param string $path Path to shorten
+ * @return string Normalized path
+ */
+ public static function trimPath($path) {
+ if (!defined('CAKE_CORE_INCLUDE_PATH') || !defined('APP')) {
+ return $path;
+ }
+
+ if (strpos($path, APP) === 0) {
+ return str_replace(APP, 'APP' . DS, $path);
+ } elseif (strpos($path, CAKE_CORE_INCLUDE_PATH) === 0) {
+ return str_replace(CAKE_CORE_INCLUDE_PATH, 'CORE', $path);
+ } elseif (strpos($path, ROOT) === 0) {
+ return str_replace(ROOT, 'ROOT', $path);
+ }
+
+ if (strpos($path, CAKE) === 0) {
+ return str_replace($corePath, 'CORE' . DS, $path);
+ }
+ return $path;
+ }
+
+/**
+ * Grabs an excerpt from a file and highlights a given line of code.
+ *
+ * Usage:
+ *
+ * `Debugger::excerpt('/path/to/file', 100, 4);`
+ *
+ * The above would return an array of 8 items. The 4th item would be the provided line,
+ * and would be wrapped in `<span class="code-highlight"></span>`. All of the lines
+ * are processed with highlight_string() as well, so they have basic PHP syntax highlighting
+ * applied.
+ *
+ * @param string $file Absolute path to a PHP file
+ * @param integer $line Line number to highlight
+ * @param integer $context Number of lines of context to extract above and below $line
+ * @return array Set of lines highlighted
+ * @see http://php.net/highlight_string
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::excerpt
+ */
+ public static function excerpt($file, $line, $context = 2) {
+ $lines = array();
+ if (!file_exists($file)) {
+ return array();
+ }
+ $data = @explode("\n", file_get_contents($file));
+
+ if (empty($data) || !isset($data[$line])) {
+ return;
+ }
+ for ($i = $line - ($context + 1); $i < $line + $context; $i++) {
+ if (!isset($data[$i])) {
+ continue;
+ }
+ $string = str_replace(array("\r\n", "\n"), "", self::_highlight($data[$i]));
+ if ($i == $line) {
+ $lines[] = '<span class="code-highlight">' . $string . '</span>';
+ } else {
+ $lines[] = $string;
+ }
+ }
+ return $lines;
+ }
+
+/**
+ * Wraps the highlight_string funciton in case the server API does not
+ * implement the function as it is the case of the HipHop interpreter
+ *
+ * @param string $str the string to convert
+ * @return string
+ */
+ protected static function _highlight($str) {
+ static $supportHighlight = null;
+ if (!$supportHighlight && function_exists('hphp_log')) {
+ $supportHighlight = false;
+ return htmlentities($str);
+ }
+ $supportHighlight = true;
+ return highlight_string($str, true);
+ }
+
+/**
+ * Converts a variable to a string for debug output.
+ *
+ * *Note:* The following keys will have their contents
+ * replaced with `*****`:
+ *
+ * - password
+ * - login
+ * - host
+ * - database
+ * - port
+ * - prefix
+ * - schema
+ *
+ * This is done to protect database credentials, which could be accidentally
+ * shown in an error message if CakePHP is deployed in development mode.
+ *
+ * @param string $var Variable to convert
+ * @param integer $depth The depth to output to. Defaults to 3.
+ * @return string Variable as a formatted string
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::exportVar
+ */
+ public static function exportVar($var, $depth = 3) {
+ return self::_export($var, $depth, 0);
+ }
+
+/**
+ * Protected export function used to keep track of indentation and recursion.
+ *
+ * @param mixed $var The variable to dump.
+ * @param integer $depth The remaining depth.
+ * @param integer $indent The current indentation level.
+ * @return string The dumped variable.
+ */
+ protected static function _export($var, $depth, $indent) {
+ switch (self::getType($var)) {
+ case 'boolean':
+ return ($var) ? 'true' : 'false';
+ break;
+ case 'integer':
+ return '(int) ' . $var;
+ case 'float':
+ return '(float) ' . $var;
+ break;
+ case 'string':
+ if (trim($var) == '') {
+ return "''";
+ }
+ return "'" . $var . "'";
+ break;
+ case 'array':
+ return self::_array($var, $depth - 1, $indent + 1);
+ break;
+ case 'resource':
+ return strtolower(gettype($var));
+ break;
+ case 'null':
+ return 'null';
+ default:
+ return self::_object($var, $depth - 1, $indent + 1);
+ break;
+ }
+ }
+
+/**
+ * Export an array type object. Filters out keys used in datasource configuration.
+ *
+ * The following keys are replaced with ***'s
+ *
+ * - password
+ * - login
+ * - host
+ * - database
+ * - port
+ * - prefix
+ * - schema
+ *
+ * @param array $var The array to export.
+ * @param integer $depth The current depth, used for recursion tracking.
+ * @param integer $indent The current indentation level.
+ * @return string Exported array.
+ */
+ protected static function _array(array $var, $depth, $indent) {
+ $secrets = array(
+ 'password' => '*****',
+ 'login' => '*****',
+ 'host' => '*****',
+ 'database' => '*****',
+ 'port' => '*****',
+ 'prefix' => '*****',
+ 'schema' => '*****'
+ );
+ $replace = array_intersect_key($secrets, $var);
+ $var = $replace + $var;
+
+ $out = "array(";
+ $n = $break = $end = null;
+ if (!empty($var)) {
+ $n = "\n";
+ $break = "\n" . str_repeat("\t", $indent);
+ $end = "\n" . str_repeat("\t", $indent - 1);
+ }
+ $vars = array();
+
+ if ($depth >= 0) {
+ foreach ($var as $key => $val) {
+ $vars[] = $break . self::exportVar($key) .
+ ' => ' .
+ self::_export($val, $depth, $indent);
+ }
+ } else {
+ $vars[] = $break . '[maximum depth reached]';
+ }
+ return $out . implode(',', $vars) . $end . ')';
+ }
+
+/**
+ * Handles object to string conversion.
+ *
+ * @param string $var Object to convert
+ * @param integer $depth The current depth, used for tracking recursion.
+ * @param integer $indent The current indentation level.
+ * @return string
+ * @see Debugger::exportVar()
+ */
+ protected static function _object($var, $depth, $indent) {
+ $out = '';
+ $props = array();
+
+ $className = get_class($var);
+ $out .= 'object(' . $className . ') {';
+
+ if ($depth > 0) {
+ $end = "\n" . str_repeat("\t", $indent - 1);
+ $break = "\n" . str_repeat("\t", $indent);
+ $objectVars = get_object_vars($var);
+ foreach ($objectVars as $key => $value) {
+ $value = self::_export($value, $depth - 1, $indent);
+ $props[] = "$key => " . $value;
+ }
+ $out .= $break . implode($break, $props) . $end;
+ }
+ $out .= '}';
+ return $out;
+ }
+
+/**
+ * Get/Set the output format for Debugger error rendering.
+ *
+ * @param string $format The format you want errors to be output as.
+ * Leave null to get the current format.
+ * @return mixed Returns null when setting. Returns the current format when getting.
+ * @throws CakeException when choosing a format that doesn't exist.
+ */
+ public static function outputAs($format = null) {
+ $self = Debugger::getInstance();
+ if ($format === null) {
+ return $self->_outputFormat;
+ }
+ if ($format !== false && !isset($self->_templates[$format])) {
+ throw new CakeException(__d('cake_dev', 'Invalid Debugger output format.'));
+ }
+ $self->_outputFormat = $format;
+ }
+
+/**
+ * Add an output format or update a format in Debugger.
+ *
+ * `Debugger::addFormat('custom', $data);`
+ *
+ * Where $data is an array of strings that use String::insert() variable
+ * replacement. The template vars should be in a `{:id}` style.
+ * An error formatter can have the following keys:
+ *
+ * - 'error' - Used for the container for the error message. Gets the following template
+ * variables: `id`, `error`, `code`, `description`, `path`, `line`, `links`, `info`
+ * - 'info' - A combination of `code`, `context` and `trace`. Will be set with
+ * the contents of the other template keys.
+ * - 'trace' - The container for a stack trace. Gets the following template
+ * variables: `trace`
+ * - 'context' - The container element for the context variables.
+ * Gets the following templates: `id`, `context`
+ * - 'links' - An array of HTML links that are used for creating links to other resources.
+ * Typically this is used to create javascript links to open other sections.
+ * Link keys, are: `code`, `context`, `help`. See the js output format for an
+ * example.
+ * - 'traceLine' - Used for creating lines in the stacktrace. Gets the following
+ * template variables: `reference`, `path`, `line`
+ *
+ * Alternatively if you want to use a custom callback to do all the formatting, you can use
+ * the callback key, and provide a callable:
+ *
+ * `Debugger::addFormat('custom', array('callback' => array($foo, 'outputError'));`
+ *
+ * The callback can expect two parameters. The first is an array of all
+ * the error data. The second contains the formatted strings generated using
+ * the other template strings. Keys like `info`, `links`, `code`, `context` and `trace`
+ * will be present depending on the other templates in the format type.
+ *
+ * @param string $format Format to use, including 'js' for JavaScript-enhanced HTML, 'html' for
+ * straight HTML output, or 'txt' for unformatted text.
+ * @param array $strings Template strings, or a callback to be used for the output format.
+ * @return The resulting format string set.
+ */
+ public static function addFormat($format, array $strings) {
+ $self = Debugger::getInstance();
+ if (isset($self->_templates[$format])) {
+ if (isset($strings['links'])) {
+ $self->_templates[$format]['links'] = array_merge(
+ $self->_templates[$format]['links'],
+ $strings['links']
+ );
+ unset($strings['links']);
+ }
+ $self->_templates[$format] = array_merge($self->_templates[$format], $strings);
+ } else {
+ $self->_templates[$format] = $strings;
+ }
+ return $self->_templates[$format];
+ }
+
+/**
+ * Switches output format, updates format strings.
+ * Can be used to switch the active output format:
+ *
+ * @param string $format Format to use, including 'js' for JavaScript-enhanced HTML, 'html' for
+ * straight HTML output, or 'txt' for unformatted text.
+ * @param array $strings Template strings to be used for the output format.
+ * @return string
+ * @deprecated Use Debugger::outputAs() and Debugger::addFormat(). Will be removed
+ * in 3.0
+ */
+ public function output($format = null, $strings = array()) {
+ $self = Debugger::getInstance();
+ $data = null;
+
+ if (is_null($format)) {
+ return Debugger::outputAs();
+ }
+
+ if (!empty($strings)) {
+ return Debugger::addFormat($format, $strings);
+ }
+
+ if ($format === true && !empty($self->_data)) {
+ $data = $self->_data;
+ $self->_data = array();
+ $format = false;
+ }
+ Debugger::outputAs($format);
+ return $data;
+ }
+
+/**
+ * Takes a processed array of data from an error and displays it in the chosen format.
+ *
+ * @param string $data
+ * @return void
+ */
+ public function outputError($data) {
+ $defaults = array(
+ 'level' => 0,
+ 'error' => 0,
+ 'code' => 0,
+ 'description' => '',
+ 'file' => '',
+ 'line' => 0,
+ 'context' => array(),
+ 'start' => 2,
+ );
+ $data += $defaults;
+
+ $files = $this->trace(array('start' => $data['start'], 'format' => 'points'));
+ $code = '';
+ if (isset($files[1]['file'])) {
+ $code = $this->excerpt($files[1]['file'], $files[1]['line'] - 1, 1);
+ }
+ $trace = $this->trace(array('start' => $data['start'], 'depth' => '20'));
+ $insertOpts = array('before' => '{:', 'after' => '}');
+ $context = array();
+ $links = array();
+ $info = '';
+
+ foreach ((array)$data['context'] as $var => $value) {
+ $context[] = "\${$var} = " . $this->exportVar($value, 1);
+ }
+
+ switch ($this->_outputFormat) {
+ case false:
+ $this->_data[] = compact('context', 'trace') + $data;
+ return;
+ case 'log':
+ $this->log(compact('context', 'trace') + $data);
+ return;
+ }
+
+ $data['trace'] = $trace;
+ $data['id'] = 'cakeErr' . uniqid();
+ $tpl = array_merge($this->_templates['base'], $this->_templates[$this->_outputFormat]);
+
+ if (isset($tpl['links'])) {
+ foreach ($tpl['links'] as $key => $val) {
+ $links[$key] = String::insert($val, $data, $insertOpts);
+ }
+ }
+
+ if (!empty($tpl['escapeContext'])) {
+ $context = h($context);
+ }
+
+ $infoData = compact('code', 'context', 'trace');
+ foreach ($infoData as $key => $value) {
+ if (empty($value) || !isset($tpl[$key])) {
+ continue;
+ }
+ if (is_array($value)) {
+ $value = join("\n", $value);
+ }
+ $info .= String::insert($tpl[$key], array($key => $value) + $data, $insertOpts);
+ }
+ $links = join(' ', $links);
+
+ if (isset($tpl['callback']) && is_callable($tpl['callback'])) {
+ return call_user_func($tpl['callback'], $data, compact('links', 'info'));
+ }
+ echo String::insert($tpl['error'], compact('links', 'info') + $data, $insertOpts);
+ }
+
+/**
+ * Get the type of the given variable. Will return the classname
+ * for objects.
+ *
+ * @param mixed $var The variable to get the type of
+ * @return string The type of variable.
+ */
+ public static function getType($var) {
+ if (is_object($var)) {
+ return get_class($var);
+ }
+ if (is_null($var)) {
+ return 'null';
+ }
+ if (is_string($var)) {
+ return 'string';
+ }
+ if (is_array($var)) {
+ return 'array';
+ }
+ if (is_int($var)) {
+ return 'integer';
+ }
+ if (is_bool($var)) {
+ return 'boolean';
+ }
+ if (is_float($var)) {
+ return 'float';
+ }
+ if (is_resource($var)) {
+ return 'resource';
+ }
+ return 'unknown';
+ }
+
+/**
+ * Verifies that the application's salt and cipher seed value has been changed from the default value.
+ *
+ * @return void
+ */
+ public static function checkSecurityKeys() {
+ if (Configure::read('Security.salt') == 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi') {
+ trigger_error(__d('cake_dev', 'Please change the value of \'Security.salt\' in app/Config/core.php to a salt value specific to your application'), E_USER_NOTICE);
+ }
+
+ if (Configure::read('Security.cipherSeed') === '76859309657453542496749683645') {
+ trigger_error(__d('cake_dev', 'Please change the value of \'Security.cipherSeed\' in app/Config/core.php to a numeric (digits only) seed value specific to your application'), E_USER_NOTICE);
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php
new file mode 100644
index 0000000..6fe9399
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php
@@ -0,0 +1,568 @@
+<?php
+/**
+ * Convenience class for reading, writing and appending to files.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Folder', 'Utility');
+
+/**
+ * Convenience class for reading, writing and appending to files.
+ *
+ * @package Cake.Utility
+ */
+class File {
+
+/**
+ * Folder object of the File
+ *
+ * @var Folder
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::$Folder
+ */
+ public $Folder = null;
+
+/**
+ * Filename
+ *
+ * @var string
+ * http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::$name
+ */
+ public $name = null;
+
+/**
+ * File info
+ *
+ * @var array
+ * http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::$info
+ */
+ public $info = array();
+
+/**
+ * Holds the file handler resource if the file is opened
+ *
+ * @var resource
+ * http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::$handle
+ */
+ public $handle = null;
+
+/**
+ * Enable locking for file reading and writing
+ *
+ * @var boolean
+ * http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::$lock
+ */
+ public $lock = null;
+
+/**
+ * Path property
+ *
+ * Current file's absolute path
+ *
+ * @var mixed null
+ * http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::$path
+ */
+ public $path = null;
+
+/**
+ * Constructor
+ *
+ * @param string $path Path to file
+ * @param boolean $create Create file if it does not exist (if true)
+ * @param integer $mode Mode to apply to the folder holding the file
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File
+ */
+ public function __construct($path, $create = false, $mode = 0755) {
+ $this->Folder = new Folder(dirname($path), $create, $mode);
+ if (!is_dir($path)) {
+ $this->name = basename($path);
+ }
+ $this->pwd();
+ $create && !$this->exists() && $this->safe($path) && $this->create();
+ }
+
+/**
+ * Closes the current file if it is opened
+ *
+ */
+ public function __destruct() {
+ $this->close();
+ }
+
+/**
+ * Creates the File.
+ *
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::create
+ */
+ public function create() {
+ $dir = $this->Folder->pwd();
+ if (is_dir($dir) && is_writable($dir) && !$this->exists()) {
+ if (touch($this->path)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Opens the current file with a given $mode
+ *
+ * @param string $mode A valid 'fopen' mode string (r|w|a ...)
+ * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't
+ * @return boolean True on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::open
+ */
+ public function open($mode = 'r', $force = false) {
+ if (!$force && is_resource($this->handle)) {
+ return true;
+ }
+ clearstatcache();
+ if ($this->exists() === false) {
+ if ($this->create() === false) {
+ return false;
+ }
+ }
+
+ $this->handle = fopen($this->path, $mode);
+ if (is_resource($this->handle)) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Return the contents of this File as a string.
+ *
+ * @param string $bytes where to start
+ * @param string $mode A `fread` compatible mode.
+ * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't
+ * @return mixed string on success, false on failure
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::read
+ */
+ public function read($bytes = false, $mode = 'rb', $force = false) {
+ if ($bytes === false && $this->lock === null) {
+ return file_get_contents($this->path);
+ }
+ if ($this->open($mode, $force) === false) {
+ return false;
+ }
+ if ($this->lock !== null && flock($this->handle, LOCK_SH) === false) {
+ return false;
+ }
+ if (is_int($bytes)) {
+ return fread($this->handle, $bytes);
+ }
+
+ $data = '';
+ while (!feof($this->handle)) {
+ $data .= fgets($this->handle, 4096);
+ }
+
+ if ($this->lock !== null) {
+ flock($this->handle, LOCK_UN);
+ }
+ if ($bytes === false) {
+ $this->close();
+ }
+ return trim($data);
+ }
+
+/**
+ * Sets or gets the offset for the currently opened file.
+ *
+ * @param integer|boolean $offset The $offset in bytes to seek. If set to false then the current offset is returned.
+ * @param integer $seek PHP Constant SEEK_SET | SEEK_CUR | SEEK_END determining what the $offset is relative to
+ * @return mixed True on success, false on failure (set mode), false on failure or integer offset on success (get mode)
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::offset
+ */
+ public function offset($offset = false, $seek = SEEK_SET) {
+ if ($offset === false) {
+ if (is_resource($this->handle)) {
+ return ftell($this->handle);
+ }
+ } elseif ($this->open() === true) {
+ return fseek($this->handle, $offset, $seek) === 0;
+ }
+ return false;
+ }
+
+/**
+ * Prepares a ascii string for writing. Converts line endings to the
+ * correct terminator for the current platform. If windows "\r\n" will be used
+ * all other platforms will use "\n"
+ *
+ * @param string $data Data to prepare for writing.
+ * @param boolean $forceWindows
+ * @return string The with converted line endings.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::prepare
+ */
+ public static function prepare($data, $forceWindows = false) {
+ $lineBreak = "\n";
+ if (DIRECTORY_SEPARATOR == '\\' || $forceWindows === true) {
+ $lineBreak = "\r\n";
+ }
+ return strtr($data, array("\r\n" => $lineBreak, "\n" => $lineBreak, "\r" => $lineBreak));
+ }
+
+/**
+ * Write given data to this File.
+ *
+ * @param string $data Data to write to this File.
+ * @param string $mode Mode of writing. {@link http://php.net/fwrite See fwrite()}.
+ * @param string $force force the file to open
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::write
+ */
+ public function write($data, $mode = 'w', $force = false) {
+ $success = false;
+ if ($this->open($mode, $force) === true) {
+ if ($this->lock !== null) {
+ if (flock($this->handle, LOCK_EX) === false) {
+ return false;
+ }
+ }
+
+ if (fwrite($this->handle, $data) !== false) {
+ $success = true;
+ }
+ if ($this->lock !== null) {
+ flock($this->handle, LOCK_UN);
+ }
+ }
+ return $success;
+ }
+
+/**
+ * Append given data string to this File.
+ *
+ * @param string $data Data to write
+ * @param string $force force the file to open
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::append
+ */
+ public function append($data, $force = false) {
+ return $this->write($data, 'a', $force);
+ }
+
+/**
+ * Closes the current file if it is opened.
+ *
+ * @return boolean True if closing was successful or file was already closed, otherwise false
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::close
+ */
+ public function close() {
+ if (!is_resource($this->handle)) {
+ return true;
+ }
+ return fclose($this->handle);
+ }
+
+/**
+ * Deletes the File.
+ *
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::delete
+ */
+ public function delete() {
+ clearstatcache();
+ if (is_resource($this->handle)) {
+ fclose($this->handle);
+ $this->handle = null;
+ }
+ if ($this->exists()) {
+ return unlink($this->path);
+ }
+ return false;
+ }
+
+/**
+ * Returns the File info as an array with the following keys:
+ *
+ * - dirname
+ * - basename
+ * - extension
+ * - filename
+ * - filesize
+ * - mime
+ *
+ * @return array File information.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::info
+ */
+ public function info() {
+ if ($this->info == null) {
+ $this->info = pathinfo($this->path);
+ }
+ if (!isset($this->info['filename'])) {
+ $this->info['filename'] = $this->name();
+ }
+ if (!isset($this->info['filesize'])) {
+ $this->info['filesize'] = $this->size();
+ }
+ if (!isset($this->info['mime'])) {
+ $this->info['mime'] = $this->mime();
+ }
+ return $this->info;
+ }
+
+/**
+ * Returns the File extension.
+ *
+ * @return string The File extension
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::ext
+ */
+ public function ext() {
+ if ($this->info == null) {
+ $this->info();
+ }
+ if (isset($this->info['extension'])) {
+ return $this->info['extension'];
+ }
+ return false;
+ }
+
+/**
+ * Returns the File name without extension.
+ *
+ * @return string The File name without extension.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::name
+ */
+ public function name() {
+ if ($this->info == null) {
+ $this->info();
+ }
+ if (isset($this->info['extension'])) {
+ return basename($this->name, '.' . $this->info['extension']);
+ } elseif ($this->name) {
+ return $this->name;
+ }
+ return false;
+ }
+
+/**
+ * makes filename safe for saving
+ *
+ * @param string $name The name of the file to make safe if different from $this->name
+ * @param string $ext The name of the extension to make safe if different from $this->ext
+ * @return string $ext the extension of the file
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::safe
+ */
+ public function safe($name = null, $ext = null) {
+ if (!$name) {
+ $name = $this->name;
+ }
+ if (!$ext) {
+ $ext = $this->ext();
+ }
+ return preg_replace("/(?:[^\w\.-]+)/", "_", basename($name, $ext));
+ }
+
+/**
+ * Get md5 Checksum of file with previous check of Filesize
+ *
+ * @param integer|boolean $maxsize in MB or true to force
+ * @return string md5 Checksum {@link http://php.net/md5_file See md5_file()}
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::md5
+ */
+ public function md5($maxsize = 5) {
+ if ($maxsize === true) {
+ return md5_file($this->path);
+ }
+
+ $size = $this->size();
+ if ($size && $size < ($maxsize * 1024) * 1024) {
+ return md5_file($this->path);
+ }
+
+ return false;
+ }
+
+/**
+ * Returns the full path of the File.
+ *
+ * @return string Full path to file
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::pwd
+ */
+ public function pwd() {
+ if (is_null($this->path)) {
+ $this->path = $this->Folder->slashTerm($this->Folder->pwd()) . $this->name;
+ }
+ return $this->path;
+ }
+
+/**
+ * Returns true if the File exists.
+ *
+ * @return boolean true if it exists, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::exists
+ */
+ public function exists() {
+ return (file_exists($this->path) && is_file($this->path));
+ }
+
+/**
+ * Returns the "chmod" (permissions) of the File.
+ *
+ * @return string Permissions for the file
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::perms
+ */
+ public function perms() {
+ if ($this->exists()) {
+ return substr(sprintf('%o', fileperms($this->path)), -4);
+ }
+ return false;
+ }
+
+/**
+ * Returns the Filesize
+ *
+ * @return integer size of the file in bytes, or false in case of an error
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::size
+ */
+ public function size() {
+ if ($this->exists()) {
+ return filesize($this->path);
+ }
+ return false;
+ }
+
+/**
+ * Returns true if the File is writable.
+ *
+ * @return boolean true if its writable, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::writable
+ */
+ public function writable() {
+ return is_writable($this->path);
+ }
+
+/**
+ * Returns true if the File is executable.
+ *
+ * @return boolean true if its executable, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::executable
+ */
+ public function executable() {
+ return is_executable($this->path);
+ }
+
+/**
+ * Returns true if the File is readable.
+ *
+ * @return boolean true if file is readable, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::readable
+ */
+ public function readable() {
+ return is_readable($this->path);
+ }
+
+/**
+ * Returns the File's owner.
+ *
+ * @return integer the Fileowner
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::owner
+ */
+ public function owner() {
+ if ($this->exists()) {
+ return fileowner($this->path);
+ }
+ return false;
+ }
+
+/**
+ * Returns the File's group.
+ *
+ * @return integer the Filegroup
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::group
+ */
+ public function group() {
+ if ($this->exists()) {
+ return filegroup($this->path);
+ }
+ return false;
+ }
+
+/**
+ * Returns last access time.
+ *
+ * @return integer timestamp Timestamp of last access time
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::lastAccess
+ */
+ public function lastAccess() {
+ if ($this->exists()) {
+ return fileatime($this->path);
+ }
+ return false;
+ }
+
+/**
+ * Returns last modified time.
+ *
+ * @return integer timestamp Timestamp of last modification
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::lastChange
+ */
+ public function lastChange() {
+ if ($this->exists()) {
+ return filemtime($this->path);
+ }
+ return false;
+ }
+
+/**
+ * Returns the current folder.
+ *
+ * @return Folder Current folder
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::Folder
+ */
+ public function &folder() {
+ return $this->Folder;
+ }
+
+/**
+ * Copy the File to $dest
+ *
+ * @param string $dest destination for the copy
+ * @param boolean $overwrite Overwrite $dest if exists
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::copy
+ */
+ public function copy($dest, $overwrite = true) {
+ if (!$this->exists() || is_file($dest) && !$overwrite) {
+ return false;
+ }
+ return copy($this->path, $dest);
+ }
+
+/**
+ * Get the mime type of the file. Uses the finfo extension if
+ * its available, otherwise falls back to mime_content_type
+ *
+ * @return false|string The mimetype of the file, or false if reading fails.
+ */
+ public function mime() {
+ if (!$this->exists()) {
+ return false;
+ }
+ if (function_exists('finfo_open')) {
+ $finfo = finfo_open(FILEINFO_MIME);
+ list($type, $charset) = explode(';', finfo_file($finfo, $this->pwd()));
+ return $type;
+ } elseif (function_exists('mime_content_type')) {
+ return mime_content_type($this->pwd());
+ }
+ return false;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php
new file mode 100644
index 0000000..08895bf
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php
@@ -0,0 +1,780 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Folder structure browser, lists folders and files.
+ * Provides an Object interface for Common directory related tasks.
+ *
+ * @package Cake.Utility
+ */
+class Folder {
+
+/**
+ * Path to Folder.
+ *
+ * @var string
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::$path
+ */
+ public $path = null;
+
+/**
+ * Sortedness. Whether or not list results
+ * should be sorted by name.
+ *
+ * @var boolean
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::$sort
+ */
+ public $sort = false;
+
+/**
+ * Mode to be used on create. Does nothing on windows platforms.
+ *
+ * @var integer
+ * http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::$mode
+ */
+ public $mode = 0755;
+
+/**
+ * Holds messages from last method.
+ *
+ * @var array
+ */
+ protected $_messages = array();
+
+/**
+ * Holds errors from last method.
+ *
+ * @var array
+ */
+ protected $_errors = array();
+
+/**
+ * Holds array of complete directory paths.
+ *
+ * @var array
+ */
+ protected $_directories;
+
+/**
+ * Holds array of complete file paths.
+ *
+ * @var array
+ */
+ protected $_files;
+
+/**
+ * Constructor.
+ *
+ * @param string $path Path to folder
+ * @param boolean $create Create folder if not found
+ * @param string|boolean $mode Mode (CHMOD) to apply to created folder, false to ignore
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder
+ */
+ public function __construct($path = false, $create = false, $mode = false) {
+ if (empty($path)) {
+ $path = TMP;
+ }
+ if ($mode) {
+ $this->mode = $mode;
+ }
+
+ if (!file_exists($path) && $create === true) {
+ $this->create($path, $this->mode);
+ }
+ if (!Folder::isAbsolute($path)) {
+ $path = realpath($path);
+ }
+ if (!empty($path)) {
+ $this->cd($path);
+ }
+ }
+
+/**
+ * Return current path.
+ *
+ * @return string Current path
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::pwd
+ */
+ public function pwd() {
+ return $this->path;
+ }
+
+/**
+ * Change directory to $path.
+ *
+ * @param string $path Path to the directory to change to
+ * @return string The new path. Returns false on failure
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::cd
+ */
+ public function cd($path) {
+ $path = $this->realpath($path);
+ if (is_dir($path)) {
+ return $this->path = $path;
+ }
+ return false;
+ }
+
+/**
+ * Returns an array of the contents of the current directory.
+ * The returned array holds two arrays: One of directories and one of files.
+ *
+ * @param boolean $sort Whether you want the results sorted, set this and the sort property
+ * to false to get unsorted results.
+ * @param array|boolean $exceptions Either an array or boolean true will not grab dot files
+ * @param boolean $fullPath True returns the full path
+ * @return mixed Contents of current directory as an array, an empty array on failure
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::read
+ */
+ public function read($sort = true, $exceptions = false, $fullPath = false) {
+ $dirs = $files = array();
+
+ if (!$this->pwd()) {
+ return array($dirs, $files);
+ }
+ if (is_array($exceptions)) {
+ $exceptions = array_flip($exceptions);
+ }
+ $skipHidden = isset($exceptions['.']) || $exceptions === true;
+
+ try {
+ $iterator = new DirectoryIterator($this->path);
+ } catch (Exception $e) {
+ return array($dirs, $files);
+ }
+
+ foreach ($iterator as $item) {
+ if ($item->isDot()) {
+ continue;
+ }
+ $name = $item->getFileName();
+ if ($skipHidden && $name[0] === '.' || isset($exceptions[$name])) {
+ continue;
+ }
+ if ($fullPath) {
+ $name = $item->getPathName();
+ }
+ if ($item->isDir()) {
+ $dirs[] = $name;
+ } else {
+ $files[] = $name;
+ }
+ }
+ if ($sort || $this->sort) {
+ sort($dirs);
+ sort($files);
+ }
+ return array($dirs, $files);
+ }
+
+/**
+ * Returns an array of all matching files in current directory.
+ *
+ * @param string $regexpPattern Preg_match pattern (Defaults to: .*)
+ * @param boolean $sort Whether results should be sorted.
+ * @return array Files that match given pattern
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::find
+ */
+ public function find($regexpPattern = '.*', $sort = false) {
+ list($dirs, $files) = $this->read($sort);
+ return array_values(preg_grep('/^' . $regexpPattern . '$/i', $files));
+ }
+
+/**
+ * Returns an array of all matching files in and below current directory.
+ *
+ * @param string $pattern Preg_match pattern (Defaults to: .*)
+ * @param boolean $sort Whether results should be sorted.
+ * @return array Files matching $pattern
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::findRecursive
+ */
+ public function findRecursive($pattern = '.*', $sort = false) {
+ if (!$this->pwd()) {
+ return array();
+ }
+ $startsOn = $this->path;
+ $out = $this->_findRecursive($pattern, $sort);
+ $this->cd($startsOn);
+ return $out;
+ }
+
+/**
+ * Private helper function for findRecursive.
+ *
+ * @param string $pattern Pattern to match against
+ * @param boolean $sort Whether results should be sorted.
+ * @return array Files matching pattern
+ */
+ protected function _findRecursive($pattern, $sort = false) {
+ list($dirs, $files) = $this->read($sort);
+ $found = array();
+
+ foreach ($files as $file) {
+ if (preg_match('/^' . $pattern . '$/i', $file)) {
+ $found[] = Folder::addPathElement($this->path, $file);
+ }
+ }
+ $start = $this->path;
+
+ foreach ($dirs as $dir) {
+ $this->cd(Folder::addPathElement($start, $dir));
+ $found = array_merge($found, $this->findRecursive($pattern, $sort));
+ }
+ return $found;
+ }
+
+/**
+ * Returns true if given $path is a Windows path.
+ *
+ * @param string $path Path to check
+ * @return boolean true if windows path, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isWindowsPath
+ */
+ public static function isWindowsPath($path) {
+ return (preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\');
+ }
+
+/**
+ * Returns true if given $path is an absolute path.
+ *
+ * @param string $path Path to check
+ * @return boolean true if path is absolute.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isAbsolute
+ */
+ public static function isAbsolute($path) {
+ return !empty($path) && ($path[0] === '/' || preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\');
+ }
+
+/**
+ * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
+ *
+ * @param string $path Path to check
+ * @return string Set of slashes ("\\" or "/")
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::normalizePath
+ */
+ public static function normalizePath($path) {
+ return Folder::correctSlashFor($path);
+ }
+
+/**
+ * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
+ *
+ * @param string $path Path to check
+ * @return string Set of slashes ("\\" or "/")
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::correctSlashFor
+ */
+ public static function correctSlashFor($path) {
+ return (Folder::isWindowsPath($path)) ? '\\' : '/';
+ }
+
+/**
+ * Returns $path with added terminating slash (corrected for Windows or other OS).
+ *
+ * @param string $path Path to check
+ * @return string Path with ending slash
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::slashTerm
+ */
+ public static function slashTerm($path) {
+ if (Folder::isSlashTerm($path)) {
+ return $path;
+ }
+ return $path . Folder::correctSlashFor($path);
+ }
+
+/**
+ * Returns $path with $element added, with correct slash in-between.
+ *
+ * @param string $path Path
+ * @param string $element Element to and at end of path
+ * @return string Combined path
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::addPathElement
+ */
+ public static function addPathElement($path, $element) {
+ return rtrim($path, DS) . DS . $element;
+ }
+
+/**
+ * Returns true if the File is in a given CakePath.
+ *
+ * @param string $path The path to check.
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::inCakePath
+ */
+ public function inCakePath($path = '') {
+ $dir = substr(Folder::slashTerm(ROOT), 0, -1);
+ $newdir = $dir . $path;
+
+ return $this->inPath($newdir);
+ }
+
+/**
+ * Returns true if the File is in given path.
+ *
+ * @param string $path The path to check that the current pwd() resides with in.
+ * @param boolean $reverse Reverse the search, check that pwd() resides within $path.
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::inPath
+ */
+ public function inPath($path = '', $reverse = false) {
+ $dir = Folder::slashTerm($path);
+ $current = Folder::slashTerm($this->pwd());
+
+ if (!$reverse) {
+ $return = preg_match('/^(.*)' . preg_quote($dir, '/') . '(.*)/', $current);
+ } else {
+ $return = preg_match('/^(.*)' . preg_quote($current, '/') . '(.*)/', $dir);
+ }
+ return (bool)$return;
+ }
+
+/**
+ * Change the mode on a directory structure recursively. This includes changing the mode on files as well.
+ *
+ * @param string $path The path to chmod
+ * @param integer $mode octal value 0755
+ * @param boolean $recursive chmod recursively, set to false to only change the current directory.
+ * @param array $exceptions array of files, directories to skip
+ * @return boolean Returns TRUE on success, FALSE on failure
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::chmod
+ */
+ public function chmod($path, $mode = false, $recursive = true, $exceptions = array()) {
+ if (!$mode) {
+ $mode = $this->mode;
+ }
+
+ if ($recursive === false && is_dir($path)) {
+ if (@chmod($path, intval($mode, 8))) {
+ $this->_messages[] = __d('cake_dev', '%s changed to %s', $path, $mode);
+ return true;
+ }
+
+ $this->_errors[] = __d('cake_dev', '%s NOT changed to %s', $path, $mode);
+ return false;
+ }
+
+ if (is_dir($path)) {
+ $paths = $this->tree($path);
+
+ foreach ($paths as $type) {
+ foreach ($type as $key => $fullpath) {
+ $check = explode(DS, $fullpath);
+ $count = count($check);
+
+ if (in_array($check[$count - 1], $exceptions)) {
+ continue;
+ }
+
+ if (@chmod($fullpath, intval($mode, 8))) {
+ $this->_messages[] = __d('cake_dev', '%s changed to %s', $fullpath, $mode);
+ } else {
+ $this->_errors[] = __d('cake_dev', '%s NOT changed to %s', $fullpath, $mode);
+ }
+ }
+ }
+
+ if (empty($this->_errors)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns an array of nested directories and files in each directory
+ *
+ * @param string $path the directory path to build the tree from
+ * @param array|boolean $exceptions Either an array of files/folder to exclude
+ * or boolean true to not grab dot files/folders
+ * @param string $type either 'file' or 'dir'. null returns both files and directories
+ * @return mixed array of nested directories and files in each directory
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::tree
+ */
+ public function tree($path = null, $exceptions = false, $type = null) {
+ if ($path == null) {
+ $path = $this->path;
+ }
+ $files = array();
+ $directories = array($path);
+
+ if (is_array($exceptions)) {
+ $exceptions = array_flip($exceptions);
+ }
+ $skipHidden = false;
+ if ($exceptions === true) {
+ $skipHidden = true;
+ } elseif (isset($exceptions['.'])) {
+ $skipHidden = true;
+ unset($exceptions['.']);
+ }
+
+ try {
+ $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME | RecursiveDirectoryIterator::CURRENT_AS_SELF);
+ $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
+ } catch (Exception $e) {
+ if ($type === null) {
+ return array(array(), array());
+ }
+ return array();
+ }
+
+ foreach ($iterator as $itemPath => $fsIterator) {
+ if ($skipHidden) {
+ $subPathName = $fsIterator->getSubPathname();
+ if ($subPathName{0} == '.' || strpos($subPathName, DS . '.') !== false) {
+ continue;
+ }
+ }
+ $item = $fsIterator->current();
+ if (!empty($exceptions) && isset($exceptions[$item->getFilename()])) {
+ continue;
+ }
+
+ if ($item->isFile()) {
+ $files[] = $itemPath;
+ } elseif ($item->isDir() && !$item->isDot()) {
+ $directories[] = $itemPath;
+ }
+ }
+ if ($type === null) {
+ return array($directories, $files);
+ }
+ if ($type === 'dir') {
+ return $directories;
+ }
+ return $files;
+ }
+
+/**
+ * Create a directory structure recursively. Can be used to create
+ * deep path structures like `/foo/bar/baz/shoe/horn`
+ *
+ * @param string $pathname The directory structure to create
+ * @param integer $mode octal value 0755
+ * @return boolean Returns TRUE on success, FALSE on failure
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::create
+ */
+ public function create($pathname, $mode = false) {
+ if (is_dir($pathname) || empty($pathname)) {
+ return true;
+ }
+
+ if (!$mode) {
+ $mode = $this->mode;
+ }
+
+ if (is_file($pathname)) {
+ $this->_errors[] = __d('cake_dev', '%s is a file', $pathname);
+ return false;
+ }
+ $pathname = rtrim($pathname, DS);
+ $nextPathname = substr($pathname, 0, strrpos($pathname, DS));
+
+ if ($this->create($nextPathname, $mode)) {
+ if (!file_exists($pathname)) {
+ $old = umask(0);
+ if (mkdir($pathname, $mode)) {
+ umask($old);
+ $this->_messages[] = __d('cake_dev', '%s created', $pathname);
+ return true;
+ } else {
+ umask($old);
+ $this->_errors[] = __d('cake_dev', '%s NOT created', $pathname);
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns the size in bytes of this Folder and its contents.
+ *
+ * @return integer size in bytes of current folder
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::dirsize
+ */
+ public function dirsize() {
+ $size = 0;
+ $directory = Folder::slashTerm($this->path);
+ $stack = array($directory);
+ $count = count($stack);
+ for ($i = 0, $j = $count; $i < $j; ++$i) {
+ if (is_file($stack[$i])) {
+ $size += filesize($stack[$i]);
+ } elseif (is_dir($stack[$i])) {
+ $dir = dir($stack[$i]);
+ if ($dir) {
+ while (false !== ($entry = $dir->read())) {
+ if ($entry === '.' || $entry === '..') {
+ continue;
+ }
+ $add = $stack[$i] . $entry;
+
+ if (is_dir($stack[$i] . $entry)) {
+ $add = Folder::slashTerm($add);
+ }
+ $stack[] = $add;
+ }
+ $dir->close();
+ }
+ }
+ $j = count($stack);
+ }
+ return $size;
+ }
+
+/**
+ * Recursively Remove directories if the system allows.
+ *
+ * @param string $path Path of directory to delete
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::delete
+ */
+ public function delete($path = null) {
+ if (!$path) {
+ $path = $this->pwd();
+ }
+ if (!$path) {
+ return null;
+ }
+ $path = Folder::slashTerm($path);
+ if (is_dir($path)) {
+ try {
+ $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::CURRENT_AS_SELF);
+ $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::CHILD_FIRST);
+ } catch (Exception $e) {
+ return false;
+ }
+
+ foreach ($iterator as $item) {
+ $filePath = $item->getPathname();
+ if ($item->isFile() || $item->isLink()) {
+ if (@unlink($filePath)) {
+ $this->_messages[] = __d('cake_dev', '%s removed', $filePath);
+ } else {
+ $this->_errors[] = __d('cake_dev', '%s NOT removed', $filePath);
+ }
+ } elseif ($item->isDir() && !$item->isDot()) {
+ if (@rmdir($filePath)) {
+ $this->_messages[] = __d('cake_dev', '%s removed', $filePath);
+ } else {
+ $this->_errors[] = __d('cake_dev', '%s NOT removed', $filePath);
+ return false;
+ }
+ }
+ }
+
+ $path = rtrim($path, DS);
+ if (@rmdir($path)) {
+ $this->_messages[] = __d('cake_dev', '%s removed', $path);
+ } else {
+ $this->_errors[] = __d('cake_dev', '%s NOT removed', $path);
+ return false;
+ }
+ }
+ return true;
+ }
+
+/**
+ * Recursive directory copy.
+ *
+ * ### Options
+ *
+ * - `to` The directory to copy to.
+ * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd().
+ * - `mode` The mode to copy the files/directories with.
+ * - `skip` Files/directories to skip.
+ *
+ * @param array|string $options Either an array of options (see above) or a string of the destination directory.
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::copy
+ */
+ public function copy($options = array()) {
+ if (!$this->pwd()) {
+ return false;
+ }
+ $to = null;
+ if (is_string($options)) {
+ $to = $options;
+ $options = array();
+ }
+ $options = array_merge(array('to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => array()), $options);
+
+ $fromDir = $options['from'];
+ $toDir = $options['to'];
+ $mode = $options['mode'];
+
+ if (!$this->cd($fromDir)) {
+ $this->_errors[] = __d('cake_dev', '%s not found', $fromDir);
+ return false;
+ }
+
+ if (!is_dir($toDir)) {
+ $this->create($toDir, $mode);
+ }
+
+ if (!is_writable($toDir)) {
+ $this->_errors[] = __d('cake_dev', '%s not writable', $toDir);
+ return false;
+ }
+
+ $exceptions = array_merge(array('.', '..', '.svn'), $options['skip']);
+ if ($handle = @opendir($fromDir)) {
+ while (false !== ($item = readdir($handle))) {
+ if (!in_array($item, $exceptions)) {
+ $from = Folder::addPathElement($fromDir, $item);
+ $to = Folder::addPathElement($toDir, $item);
+ if (is_file($from)) {
+ if (copy($from, $to)) {
+ chmod($to, intval($mode, 8));
+ touch($to, filemtime($from));
+ $this->_messages[] = __d('cake_dev', '%s copied to %s', $from, $to);
+ } else {
+ $this->_errors[] = __d('cake_dev', '%s NOT copied to %s', $from, $to);
+ }
+ }
+
+ if (is_dir($from) && !file_exists($to)) {
+ $old = umask(0);
+ if (mkdir($to, $mode)) {
+ umask($old);
+ $old = umask(0);
+ chmod($to, $mode);
+ umask($old);
+ $this->_messages[] = __d('cake_dev', '%s created', $to);
+ $options = array_merge($options, array('to' => $to, 'from' => $from));
+ $this->copy($options);
+ } else {
+ $this->_errors[] = __d('cake_dev', '%s not created', $to);
+ }
+ }
+ }
+ }
+ closedir($handle);
+ } else {
+ return false;
+ }
+
+ if (!empty($this->_errors)) {
+ return false;
+ }
+ return true;
+ }
+
+/**
+ * Recursive directory move.
+ *
+ * ### Options
+ *
+ * - `to` The directory to copy to.
+ * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd().
+ * - `chmod` The mode to copy the files/directories with.
+ * - `skip` Files/directories to skip.
+ *
+ * @param array $options (to, from, chmod, skip)
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::move
+ */
+ public function move($options) {
+ $to = null;
+ if (is_string($options)) {
+ $to = $options;
+ $options = (array)$options;
+ }
+ $options = array_merge(
+ array('to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => array()),
+ $options
+ );
+
+ if ($this->copy($options)) {
+ if ($this->delete($options['from'])) {
+ return (bool)$this->cd($options['to']);
+ }
+ }
+ return false;
+ }
+
+/**
+ * get messages from latest method
+ *
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::messages
+ */
+ public function messages() {
+ return $this->_messages;
+ }
+
+/**
+ * get error from latest method
+ *
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::errors
+ */
+ public function errors() {
+ return $this->_errors;
+ }
+
+/**
+ * Get the real path (taking ".." and such into account)
+ *
+ * @param string $path Path to resolve
+ * @return string The resolved path
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::realpath
+ */
+ public function realpath($path) {
+ $path = str_replace('/', DS, trim($path));
+ if (strpos($path, '..') === false) {
+ if (!Folder::isAbsolute($path)) {
+ $path = Folder::addPathElement($this->path, $path);
+ }
+ return $path;
+ }
+ $parts = explode(DS, $path);
+ $newparts = array();
+ $newpath = '';
+ if ($path[0] === DS) {
+ $newpath = DS;
+ }
+
+ while (($part = array_shift($parts)) !== null) {
+ if ($part === '.' || $part === '') {
+ continue;
+ }
+ if ($part === '..') {
+ if (!empty($newparts)) {
+ array_pop($newparts);
+ continue;
+ } else {
+ return false;
+ }
+ }
+ $newparts[] = $part;
+ }
+ $newpath .= implode(DS, $newparts);
+
+ return Folder::slashTerm($newpath);
+ }
+
+/**
+ * Returns true if given $path ends in a slash (i.e. is slash-terminated).
+ *
+ * @param string $path Path to check
+ * @return boolean true if path ends with slash, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isSlashTerm
+ */
+ public static function isSlashTerm($path) {
+ $lastChar = $path[strlen($path) - 1];
+ return $lastChar === '/' || $lastChar === '\\';
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php
new file mode 100644
index 0000000..9514ccc
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php
@@ -0,0 +1,974 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('String', 'Utility');
+
+/**
+ * Library of array functions for manipulating and extracting data
+ * from arrays or 'sets' of data.
+ *
+ * `Hash` provides an improved interface, more consistent and
+ * predictable set of features over `Set`. While it lacks the spotty
+ * support for pseudo Xpath, its more fully featured dot notation provides
+ * similar features in a more consistent implementation.
+ *
+ * @package Cake.Utility
+ */
+class Hash {
+
+/**
+ * Get a single value specified by $path out of $data.
+ * Does not support the full dot notation feature set,
+ * but is faster for simple read operations.
+ *
+ * @param array $data Array of data to operate on.
+ * @param string|array $path The path being searched for. Either a dot
+ * separated string, or an array of path segments.
+ * @return mixed The value fetched from the array, or null.
+ */
+ public static function get(array $data, $path) {
+ if (empty($data) || empty($path)) {
+ return null;
+ }
+ if (is_string($path)) {
+ $parts = explode('.', $path);
+ } else {
+ $parts = $path;
+ }
+ foreach ($parts as $key) {
+ if (is_array($data) && isset($data[$key])) {
+ $data =& $data[$key];
+ } else {
+ return null;
+ }
+
+ }
+ return $data;
+ }
+
+/**
+ * Gets the values from an array matching the $path expression.
+ * The path expression is a dot separated expression, that can contain a set
+ * of patterns and expressions:
+ *
+ * - `{n}` Matches any numeric key, or integer.
+ * - `{s}` Matches any string key.
+ * - `Foo` Matches any key with the exact same value.
+ *
+ * There are a number of attribute operators:
+ *
+ * - `=`, `!=` Equality.
+ * - `>`, `<`, `>=`, `<=` Value comparison.
+ * - `=/.../` Regular expression pattern match.
+ *
+ * Given a set of User array data, from a `$User->find('all')` call:
+ *
+ * - `1.User.name` Get the name of the user at index 1.
+ * - `{n}.User.name` Get the name of every user in the set of users.
+ * - `{n}.User[id]` Get the name of every user with an id key.
+ * - `{n}.User[id>=2]` Get the name of every user with an id key greater than or equal to 2.
+ * - `{n}.User[username=/^paul/]` Get User elements with username matching `^paul`.
+ *
+ * @param array $data The data to extract from.
+ * @param string $path The path to extract.
+ * @return array An array of the extracted values. Returns an empty array
+ * if there are no matches.
+ */
+ public static function extract(array $data, $path) {
+ if (empty($path)) {
+ return $data;
+ }
+
+ // Simple paths.
+ if (!preg_match('/[{\[]/', $path)) {
+ return (array)self::get($data, $path);
+ }
+
+ if (strpos('[', $path) === false) {
+ $tokens = explode('.', $path);
+ } else {
+ $tokens = String::tokenize($path, '.', '[', ']');
+ }
+
+ $_key = '__set_item__';
+
+ $context = array($_key => array($data));
+
+ foreach ($tokens as $token) {
+ $next = array();
+
+ $conditions = false;
+ $position = strpos($token, '[');
+ if ($position !== false) {
+ $conditions = substr($token, $position);
+ $token = substr($token, 0, $position);
+ }
+
+ foreach ($context[$_key] as $item) {
+ foreach ($item as $k => $v) {
+ if (self::_matchToken($k, $token)) {
+ $next[] = $v;
+ }
+ }
+ }
+
+ // Filter for attributes.
+ if ($conditions) {
+ $filter = array();
+ foreach ($next as $item) {
+ if (self::_matches($item, $conditions)) {
+ $filter[] = $item;
+ }
+ }
+ $next = $filter;
+ }
+ $context = array($_key => $next);
+
+ }
+ return $context[$_key];
+ }
+
+/**
+ * Check a key against a token.
+ *
+ * @param string $key The key in the array being searched.
+ * @param string $token The token being matched.
+ * @return boolean
+ */
+ protected static function _matchToken($key, $token) {
+ if ($token === '{n}') {
+ return is_numeric($key);
+ }
+ if ($token === '{s}') {
+ return is_string($key);
+ }
+ if (is_numeric($token)) {
+ return ($key == $token);
+ }
+ return ($key === $token);
+ }
+
+/**
+ * Checks whether or not $data matches the attribute patterns
+ *
+ * @param array $data Array of data to match.
+ * @param string $selector The patterns to match.
+ * @return boolean Fitness of expression.
+ */
+ protected static function _matches(array $data, $selector) {
+ preg_match_all(
+ '/(\[ (?<attr>[^=><!]+?) (\s* (?<op>[><!]?[=]|[><]) \s* (?<val>[^\]]+) )? \])/x',
+ $selector,
+ $conditions,
+ PREG_SET_ORDER
+ );
+
+ foreach ($conditions as $cond) {
+ $attr = $cond['attr'];
+ $op = isset($cond['op']) ? $cond['op'] : null;
+ $val = isset($cond['val']) ? $cond['val'] : null;
+
+ // Presence test.
+ if (empty($op) && empty($val) && !isset($data[$attr])) {
+ return false;
+ }
+
+ // Empty attribute = fail.
+ if (!(isset($data[$attr]) || array_key_exists($attr, $data))) {
+ return false;
+ }
+
+ $prop = isset($data[$attr]) ? $data[$attr] : null;
+
+ // Pattern matches and other operators.
+ if ($op === '=' && $val && $val[0] === '/') {
+ if (!preg_match($val, $prop)) {
+ return false;
+ }
+ } elseif (
+ ($op === '=' && $prop != $val) ||
+ ($op === '!=' && $prop == $val) ||
+ ($op === '>' && $prop <= $val) ||
+ ($op === '<' && $prop >= $val) ||
+ ($op === '>=' && $prop < $val) ||
+ ($op === '<=' && $prop > $val)
+ ) {
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+/**
+ * Insert $values into an array with the given $path. You can use
+ * `{n}` and `{s}` elements to insert $data multiple times.
+ *
+ * @param array $data The data to insert into.
+ * @param string $path The path to insert at.
+ * @param array $values The values to insert.
+ * @return array The data with $values inserted.
+ */
+ public static function insert(array $data, $path, $values = null) {
+ $tokens = explode('.', $path);
+ if (strpos($path, '{') === false) {
+ return self::_simpleOp('insert', $data, $tokens, $values);
+ }
+
+ $token = array_shift($tokens);
+ $nextPath = implode('.', $tokens);
+ foreach ($data as $k => $v) {
+ if (self::_matchToken($k, $token)) {
+ $data[$k] = self::insert($v, $nextPath, $values);
+ }
+ }
+ return $data;
+ }
+
+/**
+ * Perform a simple insert/remove operation.
+ *
+ * @param string $op The operation to do.
+ * @param array $data The data to operate on.
+ * @param array $path The path to work on.
+ * @param mixed $values The values to insert when doing inserts.
+ * @return array $data.
+ */
+ protected static function _simpleOp($op, $data, $path, $values = null) {
+ $_list =& $data;
+
+ $count = count($path);
+ $last = $count - 1;
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key === '0') {
+ $key = intval($key);
+ }
+ if ($op === 'insert') {
+ if ($i === $last) {
+ $_list[$key] = $values;
+ return $data;
+ }
+ if (!isset($_list[$key])) {
+ $_list[$key] = array();
+ }
+ $_list =& $_list[$key];
+ if (!is_array($_list)) {
+ $_list = array();
+ }
+ } elseif ($op === 'remove') {
+ if ($i === $last) {
+ unset($_list[$key]);
+ return $data;
+ }
+ if (!isset($_list[$key])) {
+ return $data;
+ }
+ $_list =& $_list[$key];
+ }
+ }
+ }
+
+/**
+ * Remove data matching $path from the $data array.
+ * You can use `{n}` and `{s}` to remove multiple elements
+ * from $data.
+ *
+ * @param array $data The data to operate on
+ * @param string $path A path expression to use to remove.
+ * @return array The modified array.
+ */
+ public static function remove(array $data, $path) {
+ $tokens = explode('.', $path);
+ if (strpos($path, '{') === false) {
+ return self::_simpleOp('remove', $data, $tokens);
+ }
+
+ $token = array_shift($tokens);
+ $nextPath = implode('.', $tokens);
+ foreach ($data as $k => $v) {
+ $match = self::_matchToken($k, $token);
+ if ($match && is_array($v)) {
+ $data[$k] = self::remove($v, $nextPath);
+ } elseif ($match) {
+ unset($data[$k]);
+ }
+ }
+ return $data;
+ }
+
+/**
+ * Creates an associative array using `$keyPath` as the path to build its keys, and optionally
+ * `$valuePath` as path to get the values. If `$valuePath` is not specified, all values will be initialized
+ * to null (useful for Hash::merge). You can optionally group the values by what is obtained when
+ * following the path specified in `$groupPath`.
+ *
+ * @param array $data Array from where to extract keys and values
+ * @param string $keyPath A dot-separated string.
+ * @param string $valuePath A dot-separated string.
+ * @param string $groupPath A dot-separated string.
+ * @return array Combined array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::combine
+ */
+ public static function combine(array $data, $keyPath, $valuePath = null, $groupPath = null) {
+ if (empty($data)) {
+ return array();
+ }
+
+ if (is_array($keyPath)) {
+ $format = array_shift($keyPath);
+ $keys = self::format($data, $keyPath, $format);
+ } else {
+ $keys = self::extract($data, $keyPath);
+ }
+ if (empty($keys)) {
+ return array();
+ }
+
+ if (!empty($valuePath) && is_array($valuePath)) {
+ $format = array_shift($valuePath);
+ $vals = self::format($data, $valuePath, $format);
+ } elseif (!empty($valuePath)) {
+ $vals = self::extract($data, $valuePath);
+ }
+
+ $count = count($keys);
+ for ($i = 0; $i < $count; $i++) {
+ $vals[$i] = isset($vals[$i]) ? $vals[$i] : null;
+ }
+
+ if ($groupPath !== null) {
+ $group = self::extract($data, $groupPath);
+ if (!empty($group)) {
+ $c = count($keys);
+ for ($i = 0; $i < $c; $i++) {
+ if (!isset($group[$i])) {
+ $group[$i] = 0;
+ }
+ if (!isset($out[$group[$i]])) {
+ $out[$group[$i]] = array();
+ }
+ $out[$group[$i]][$keys[$i]] = $vals[$i];
+ }
+ return $out;
+ }
+ }
+ if (empty($vals)) {
+ return array();
+ }
+ return array_combine($keys, $vals);
+ }
+
+/**
+ * Returns a formated series of values extracted from `$data`, using
+ * `$format` as the format and `$paths` as the values to extract.
+ *
+ * Usage:
+ *
+ * {{{
+ * $result = Hash::format($users, array('{n}.User.id', '{n}.User.name'), '%s : %s');
+ * }}}
+ *
+ * The `$format` string can use any format options that `vsprintf()` and `sprintf()` do.
+ *
+ * @param array $data Source array from which to extract the data
+ * @param string $paths An array containing one or more Hash::extract()-style key paths
+ * @param string $format Format string into which values will be inserted, see sprintf()
+ * @return array An array of strings extracted from `$path` and formatted with `$format`
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::format
+ * @see sprintf()
+ * @see Hash::extract()
+ */
+ public static function format(array $data, array $paths, $format) {
+ $extracted = array();
+ $count = count($paths);
+
+ if (!$count) {
+ return;
+ }
+
+ for ($i = 0; $i < $count; $i++) {
+ $extracted[] = self::extract($data, $paths[$i]);
+ }
+ $out = array();
+ $data = $extracted;
+ $count = count($data[0]);
+
+ $countTwo = count($data);
+ for ($j = 0; $j < $count; $j++) {
+ $args = array();
+ for ($i = 0; $i < $countTwo; $i++) {
+ if (array_key_exists($j, $data[$i])) {
+ $args[] = $data[$i][$j];
+ }
+ }
+ $out[] = vsprintf($format, $args);
+ }
+ return $out;
+ }
+
+/**
+ * Determines if one array contains the exact keys and values of another.
+ *
+ * @param array $data The data to search through.
+ * @param array $needle The values to file in $data
+ * @return boolean true if $data contains $needle, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::contains
+ */
+ public static function contains(array $data, array $needle) {
+ if (empty($data) || empty($needle)) {
+ return false;
+ }
+ $stack = array();
+
+ $i = 1;
+ while (!empty($needle)) {
+ $key = key($needle);
+ $val = $needle[$key];
+ unset($needle[$key]);
+
+ if (isset($data[$key]) && is_array($val)) {
+ $next = $data[$key];
+ unset($data[$key]);
+
+ if (!empty($val)) {
+ $stack[] = array($val, $next);
+ }
+ } elseif (!isset($data[$key]) || $data[$key] != $val) {
+ return false;
+ }
+
+ if (empty($needle) && !empty($stack)) {
+ list($needle, $data) = array_pop($stack);
+ }
+ }
+ return true;
+ }
+
+/**
+ * Test whether or not a given path exists in $data.
+ * This method uses the same path syntax as Hash::extract()
+ *
+ * Checking for paths that could target more than one element will
+ * make sure that at least one matching element exists.
+ *
+ * @param array $data The data to check.
+ * @param string $path The path to check for.
+ * @return boolean Existence of path.
+ * @see Hash::extract()
+ */
+ public static function check(array $data, $path) {
+ $results = self::extract($data, $path);
+ if (!is_array($results)) {
+ return false;
+ }
+ return count($results) > 0;
+ }
+
+/**
+ * Recursively filters a data set.
+ *
+ * @param array $data Either an array to filter, or value when in callback
+ * @param callable $callback A function to filter the data with. Defaults to
+ * `self::_filter()` Which strips out all non-zero empty values.
+ * @return array Filtered array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::filter
+ */
+ public static function filter(array $data, $callback = array('self', '_filter')) {
+ foreach ($data as $k => $v) {
+ if (is_array($v)) {
+ $data[$k] = self::filter($v, $callback);
+ }
+ }
+ return array_filter($data, $callback);
+ }
+
+/**
+ * Callback function for filtering.
+ *
+ * @param array $var Array to filter.
+ * @return boolean
+ */
+ protected static function _filter($var) {
+ if ($var === 0 || $var === '0' || !empty($var)) {
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Collapses a multi-dimensional array into a single dimension, using a delimited array path for
+ * each array element's key, i.e. array(array('Foo' => array('Bar' => 'Far'))) becomes
+ * array('0.Foo.Bar' => 'Far').)
+ *
+ * @param array $data Array to flatten
+ * @param string $separator String used to separate array key elements in a path, defaults to '.'
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::flatten
+ */
+ public static function flatten(array $data, $separator = '.') {
+ $result = array();
+ $stack = array();
+ $path = null;
+
+ reset($data);
+ while (!empty($data)) {
+ $key = key($data);
+ $element = $data[$key];
+ unset($data[$key]);
+
+ if (is_array($element)) {
+ if (!empty($data)) {
+ $stack[] = array($data, $path);
+ }
+ $data = $element;
+ $path .= $key . $separator;
+ } else {
+ $result[$path . $key] = $element;
+ }
+
+ if (empty($data) && !empty($stack)) {
+ list($data, $path) = array_pop($stack);
+ }
+ }
+ return $result;
+ }
+
+/**
+ * Expand/unflattens an string to an array
+ *
+ * For example, unflattens an array that was collapsed with `Hash::flatten()`
+ * into a multi-dimensional array. So, `array('0.Foo.Bar' => 'Far')` becomes
+ * `array(array('Foo' => array('Bar' => 'Far')))`.
+ *
+ * @param array $data Flattened array
+ * @param string $separator The delimiter used
+ * @return array
+ */
+ public static function expand($data, $separator = '.') {
+ $result = array();
+ foreach ($data as $flat => $value) {
+ $keys = explode($separator, $flat);
+ $keys = array_reverse($keys);
+ $child = array(
+ $keys[0] => $value
+ );
+ array_shift($keys);
+ foreach ($keys as $k) {
+ $child = array(
+ $k => $child
+ );
+ }
+ $result = self::merge($result, $child);
+ }
+ return $result;
+ }
+
+/**
+ * This function can be thought of as a hybrid between PHP's `array_merge` and `array_merge_recursive`.
+ *
+ * The difference between this method and the built-in ones, is that if an array key contains another array, then
+ * Hash::merge() will behave in a recursive fashion (unlike `array_merge`). But it will not act recursively for
+ * keys that contain scalar values (unlike `array_merge_recursive`).
+ *
+ * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.
+ *
+ * @param array $data Array to be merged
+ * @param mixed $merge Array to merge with. The argument and all trailing arguments will be array cast when merged
+ * @return array Merged array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::merge
+ */
+ public static function merge(array $data, $merge) {
+ $args = func_get_args();
+ $return = current($args);
+
+ while (($arg = next($args)) !== false) {
+ foreach ((array)$arg as $key => $val) {
+ if (!empty($return[$key]) && is_array($return[$key]) && is_array($val)) {
+ $return[$key] = self::merge($return[$key], $val);
+ } elseif (is_int($key)) {
+ $return[] = $val;
+ } else {
+ $return[$key] = $val;
+ }
+ }
+ }
+ return $return;
+ }
+
+/**
+ * Checks to see if all the values in the array are numeric
+ *
+ * @param array $array The array to check.
+ * @return boolean true if values are numeric, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::numeric
+ */
+ public static function numeric(array $data) {
+ if (empty($data)) {
+ return false;
+ }
+ $values = array_values($data);
+ $str = implode('', $values);
+ return (bool)ctype_digit($str);
+ }
+
+/**
+ * Counts the dimensions of an array.
+ * Only considers the dimension of the first element in the array.
+ *
+ * If you have an un-even or hetrogenous array, consider using Hash::maxDimensions()
+ * to get the dimensions of the array.
+ *
+ * @param array $array Array to count dimensions on
+ * @return integer The number of dimensions in $data
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::dimensions
+ */
+ public static function dimensions(array $data) {
+ if (empty($data)) {
+ return 0;
+ }
+ reset($data);
+ $depth = 1;
+ while ($elem = array_shift($data)) {
+ if (is_array($elem)) {
+ $depth += 1;
+ $data =& $elem;
+ } else {
+ break;
+ }
+ }
+ return $depth;
+ }
+
+/**
+ * Counts the dimensions of *all* array elements. Useful for finding the maximum
+ * number of dimensions in a mixed array.
+ *
+ * @param array $data Array to count dimensions on
+ * @return integer The maximum number of dimensions in $data
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::maxDimensions
+ */
+ public static function maxDimensions(array $data) {
+ $depth = array();
+ if (is_array($data) && reset($data) !== false) {
+ foreach ($data as $value) {
+ $depth[] = self::dimensions((array)$value) + 1;
+ }
+ }
+ return max($depth);
+ }
+
+/**
+ * Map a callback across all elements in a set.
+ * Can be provided a path to only modify slices of the set.
+ *
+ * @param array $data The data to map over, and extract data out of.
+ * @param string $path The path to extract for mapping over.
+ * @param callable $function The function to call on each extracted value.
+ * @return array An array of the modified values.
+ */
+ public static function map(array $data, $path, $function) {
+ $values = (array)self::extract($data, $path);
+ return array_map($function, $values);
+ }
+
+/**
+ * Reduce a set of extracted values using `$function`.
+ *
+ * @param array $data The data to reduce.
+ * @param string $path The path to extract from $data.
+ * @return mixed The reduced value.
+ */
+ public static function reduce(array $data, $path, $function) {
+ $values = (array)self::extract($data, $path);
+ return array_reduce($values, $function);
+ }
+
+/**
+ * Apply a callback to a set of extracted values using `$function`.
+ * The function will get the extracted values as the first argument.
+ *
+ * @param array $data The data to reduce.
+ * @param string $path The path to extract from $data.
+ * @return mixed The results of the applied method.
+ */
+ public static function apply(array $data, $path, $function) {
+ $values = (array)self::extract($data, $path);
+ return call_user_func($function, $values);
+ }
+
+/**
+ * Sorts an array by any value, determined by a Set-compatible path
+ *
+ * ### Sort directions
+ *
+ * - `asc` Sort ascending.
+ * - `desc` Sort descending.
+ *
+ * ## Sort types
+ *
+ * - `numeric` Sort by numeric value.
+ * - `regular` Sort by numeric value.
+ * - `string` Sort by numeric value.
+ * - `natural` Sort by natural order. Requires PHP 5.4 or greater.
+ *
+ * @param array $data An array of data to sort
+ * @param string $path A Set-compatible path to the array value
+ * @param string $dir See directions above.
+ * @param string $type See direction types above. Defaults to 'regular'.
+ * @return array Sorted array of data
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::sort
+ */
+ public static function sort(array $data, $path, $dir, $type = 'regular') {
+ $originalKeys = array_keys($data);
+ $numeric = is_numeric(implode('', $originalKeys));
+ if ($numeric) {
+ $data = array_values($data);
+ }
+ $sortValues = self::extract($data, $path);
+ $sortCount = count($sortValues);
+ $dataCount = count($data);
+
+ // Make sortValues match the data length, as some keys could be missing
+ // the sorted value path.
+ if ($sortCount < $dataCount) {
+ $sortValues = array_pad($sortValues, $dataCount, null);
+ }
+ $result = self::_squash($sortValues);
+ $keys = self::extract($result, '{n}.id');
+ $values = self::extract($result, '{n}.value');
+
+ $dir = strtolower($dir);
+ $type = strtolower($type);
+ if ($type == 'natural' && version_compare(PHP_VERSION, '5.4.0', '<')) {
+ $type == 'regular';
+ }
+ if ($dir === 'asc') {
+ $dir = SORT_ASC;
+ } else {
+ $dir = SORT_DESC;
+ }
+ if ($type === 'numeric') {
+ $type = SORT_NUMERIC;
+ } elseif ($type === 'string') {
+ $type = SORT_STRING;
+ } elseif ($type === 'natural') {
+ $type = SORT_NATURAL;
+ } else {
+ $type = SORT_REGULAR;
+ }
+ array_multisort($values, $dir, $type, $keys, $dir, $type);
+ $sorted = array();
+ $keys = array_unique($keys);
+
+ foreach ($keys as $k) {
+ if ($numeric) {
+ $sorted[] = $data[$k];
+ continue;
+ }
+ if (isset($originalKeys[$k])) {
+ $sorted[$originalKeys[$k]] = $data[$originalKeys[$k]];
+ } else {
+ $sorted[$k] = $data[$k];
+ }
+ }
+ return $sorted;
+ }
+
+/**
+ * Helper method for sort()
+ * Sqaushes an array to a single hash so it can be sorted.
+ *
+ * @param array $data The data to squash.
+ * @param string $key The key for the data.
+ * @return array
+ */
+ protected static function _squash($data, $key = null) {
+ $stack = array();
+ foreach ($data as $k => $r) {
+ $id = $k;
+ if (!is_null($key)) {
+ $id = $key;
+ }
+ if (is_array($r) && !empty($r)) {
+ $stack = array_merge($stack, self::_squash($r, $id));
+ } else {
+ $stack[] = array('id' => $id, 'value' => $r);
+ }
+ }
+ return $stack;
+ }
+
+/**
+ * Computes the difference between two complex arrays.
+ * This method differs from the built-in array_diff() in that it will preserve keys
+ * and work on multi-dimensional arrays.
+ *
+ * @param array $data First value
+ * @param array $compare Second value
+ * @return array Returns the key => value pairs that are not common in $data and $compare
+ * The expression for this function is ($data - $compare) + ($compare - ($data - $compare))
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::diff
+ */
+ public static function diff(array $data, $compare) {
+ if (empty($data)) {
+ return (array)$compare;
+ }
+ if (empty($compare)) {
+ return (array)$data;
+ }
+ $intersection = array_intersect_key($data, $compare);
+ while (($key = key($intersection)) !== null) {
+ if ($data[$key] == $compare[$key]) {
+ unset($data[$key]);
+ unset($compare[$key]);
+ }
+ next($intersection);
+ }
+ return $data + $compare;
+ }
+
+/**
+ * Merges the difference between $data and $push onto $data.
+ *
+ * @param array $data The data to append onto.
+ * @param array $compare The data to compare and append onto.
+ * @return array The merged array.
+ */
+ public static function mergeDiff(array $data, $compare) {
+ if (empty($data) && !empty($compare)) {
+ return $compare;
+ }
+ if (empty($compare)) {
+ return $data;
+ }
+ foreach ($compare as $key => $value) {
+ if (!array_key_exists($key, $data)) {
+ $data[$key] = $value;
+ } elseif (is_array($value)) {
+ $data[$key] = self::mergeDiff($data[$key], $compare[$key]);
+ }
+ }
+ return $data;
+ }
+
+/**
+ * Normalizes an array, and converts it to a standard format.
+ *
+ * @param array $data List to normalize
+ * @param boolean $assoc If true, $data will be converted to an associative array.
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::normalize
+ */
+ public static function normalize(array $data, $assoc = true) {
+ $keys = array_keys($data);
+ $count = count($keys);
+ $numeric = true;
+
+ if (!$assoc) {
+ for ($i = 0; $i < $count; $i++) {
+ if (!is_int($keys[$i])) {
+ $numeric = false;
+ break;
+ }
+ }
+ }
+ if (!$numeric || $assoc) {
+ $newList = array();
+ for ($i = 0; $i < $count; $i++) {
+ if (is_int($keys[$i])) {
+ $newList[$data[$keys[$i]]] = null;
+ } else {
+ $newList[$keys[$i]] = $data[$keys[$i]];
+ }
+ }
+ $data = $newList;
+ }
+ return $data;
+ }
+
+/**
+ * Takes in a flat array and returns a nested array
+ *
+ * ### Options:
+ *
+ * - `children` The key name to use in the resultset for children.
+ * - `idPath` The path to a key that identifies each entry. Should be
+ * compatible with Hash::extract(). Defaults to `{n}.$alias.id`
+ * - `parentPath` The path to a key that identifies the parent of each entry.
+ * Should be compatible with Hash::extract(). Defaults to `{n}.$alias.parent_id`
+ * - `root` The id of the desired top-most result.
+ *
+ * @param array $data The data to nest.
+ * @param array $options Options are:
+ * @return array of results, nested
+ * @see Hash::extract()
+ */
+ public static function nest(array $data, $options = array()) {
+ if (!$data) {
+ return $data;
+ }
+
+ $alias = key(current($data));
+ $options += array(
+ 'idPath' => "{n}.$alias.id",
+ 'parentPath' => "{n}.$alias.parent_id",
+ 'children' => 'children',
+ 'root' => null
+ );
+
+ $return = $idMap = array();
+ $ids = self::extract($data, $options['idPath']);
+
+ $idKeys = explode('.', $options['idPath']);
+ array_shift($idKeys);
+
+ $parentKeys = explode('.', $options['parentPath']);
+ array_shift($parentKeys);
+
+ foreach ($data as $result) {
+ $result[$options['children']] = array();
+
+ $id = self::get($result, $idKeys);
+ $parentId = self::get($result, $parentKeys);
+
+ if (isset($idMap[$id][$options['children']])) {
+ $idMap[$id] = array_merge($result, (array)$idMap[$id]);
+ } else {
+ $idMap[$id] = array_merge($result, array($options['children'] => array()));
+ }
+ if (!$parentId || !in_array($parentId, $ids)) {
+ $return[] =& $idMap[$id];
+ } else {
+ $idMap[$parentId][$options['children']][] =& $idMap[$id];
+ }
+ }
+
+ if ($options['root']) {
+ $root = $options['root'];
+ } else {
+ $root = self::get($return[0], $parentKeys);
+ }
+
+ foreach ($return as $i => $result) {
+ $id = self::get($result, $idKeys);
+ $parentId = self::get($result, $parentKeys);
+ if ($id !== $root && $parentId != $root) {
+ unset($return[$i]);
+ }
+ }
+ return array_values($return);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php
new file mode 100644
index 0000000..31829d6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php
@@ -0,0 +1,551 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Pluralize and singularize English words.
+ *
+ * Inflector pluralizes and singularizes English nouns.
+ * Used by Cake's naming conventions throughout the framework.
+ *
+ * @package Cake.Utility
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html
+ */
+class Inflector {
+
+/**
+ * Plural inflector rules
+ *
+ * @var array
+ */
+ protected static $_plural = array(
+ 'rules' => array(
+ '/(s)tatus$/i' => '\1\2tatuses',
+ '/(quiz)$/i' => '\1zes',
+ '/^(ox)$/i' => '\1\2en',
+ '/([m|l])ouse$/i' => '\1ice',
+ '/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
+ '/(x|ch|ss|sh)$/i' => '\1es',
+ '/([^aeiouy]|qu)y$/i' => '\1ies',
+ '/(hive)$/i' => '\1s',
+ '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
+ '/sis$/i' => 'ses',
+ '/([ti])um$/i' => '\1a',
+ '/(p)erson$/i' => '\1eople',
+ '/(m)an$/i' => '\1en',
+ '/(c)hild$/i' => '\1hildren',
+ '/(buffal|tomat)o$/i' => '\1\2oes',
+ '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
+ '/us$/i' => 'uses',
+ '/(alias)$/i' => '\1es',
+ '/(ax|cris|test)is$/i' => '\1es',
+ '/s$/' => 's',
+ '/^$/' => '',
+ '/$/' => 's',
+ ),
+ 'uninflected' => array(
+ '.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people'
+ ),
+ 'irregular' => array(
+ 'atlas' => 'atlases',
+ 'beef' => 'beefs',
+ 'brother' => 'brothers',
+ 'cafe' => 'cafes',
+ 'child' => 'children',
+ 'corpus' => 'corpuses',
+ 'cow' => 'cows',
+ 'ganglion' => 'ganglions',
+ 'genie' => 'genies',
+ 'genus' => 'genera',
+ 'graffito' => 'graffiti',
+ 'hoof' => 'hoofs',
+ 'loaf' => 'loaves',
+ 'man' => 'men',
+ 'money' => 'monies',
+ 'mongoose' => 'mongooses',
+ 'move' => 'moves',
+ 'mythos' => 'mythoi',
+ 'niche' => 'niches',
+ 'numen' => 'numina',
+ 'occiput' => 'occiputs',
+ 'octopus' => 'octopuses',
+ 'opus' => 'opuses',
+ 'ox' => 'oxen',
+ 'penis' => 'penises',
+ 'person' => 'people',
+ 'sex' => 'sexes',
+ 'soliloquy' => 'soliloquies',
+ 'testis' => 'testes',
+ 'trilby' => 'trilbys',
+ 'turf' => 'turfs'
+ )
+ );
+
+/**
+ * Singular inflector rules
+ *
+ * @var array
+ */
+ protected static $_singular = array(
+ 'rules' => array(
+ '/(s)tatuses$/i' => '\1\2tatus',
+ '/^(.*)(menu)s$/i' => '\1\2',
+ '/(quiz)zes$/i' => '\\1',
+ '/(matr)ices$/i' => '\1ix',
+ '/(vert|ind)ices$/i' => '\1ex',
+ '/^(ox)en/i' => '\1',
+ '/(alias)(es)*$/i' => '\1',
+ '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
+ '/([ftw]ax)es/i' => '\1',
+ '/(cris|ax|test)es$/i' => '\1is',
+ '/(shoe|slave)s$/i' => '\1',
+ '/(o)es$/i' => '\1',
+ '/ouses$/' => 'ouse',
+ '/([^a])uses$/' => '\1us',
+ '/([m|l])ice$/i' => '\1ouse',
+ '/(x|ch|ss|sh)es$/i' => '\1',
+ '/(m)ovies$/i' => '\1\2ovie',
+ '/(s)eries$/i' => '\1\2eries',
+ '/([^aeiouy]|qu)ies$/i' => '\1y',
+ '/([lr])ves$/i' => '\1f',
+ '/(tive)s$/i' => '\1',
+ '/(hive)s$/i' => '\1',
+ '/(drive)s$/i' => '\1',
+ '/([^fo])ves$/i' => '\1fe',
+ '/(^analy)ses$/i' => '\1sis',
+ '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
+ '/([ti])a$/i' => '\1um',
+ '/(p)eople$/i' => '\1\2erson',
+ '/(m)en$/i' => '\1an',
+ '/(c)hildren$/i' => '\1\2hild',
+ '/(n)ews$/i' => '\1\2ews',
+ '/eaus$/' => 'eau',
+ '/^(.*us)$/' => '\\1',
+ '/s$/i' => ''
+ ),
+ 'uninflected' => array(
+ '.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss'
+ ),
+ 'irregular' => array(
+ 'foes' => 'foe',
+ 'waves' => 'wave',
+ 'curves' => 'curve'
+ )
+ );
+
+/**
+ * Words that should not be inflected
+ *
+ * @var array
+ */
+ protected static $_uninflected = array(
+ 'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus',
+ 'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps',
+ 'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder',
+ 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
+ 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings',
+ 'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media',
+ 'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese',
+ 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese',
+ 'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
+ 'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'swine', 'testes',
+ 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting', 'wildebeest',
+ 'Yengeese'
+ );
+
+/**
+ * Default map of accented and special characters to ASCII characters
+ *
+ * @var array
+ */
+ protected static $_transliteration = array(
+ '/ä|æ|ǽ/' => 'ae',
+ '/ö|œ/' => 'oe',
+ '/ü/' => 'ue',
+ '/Ä/' => 'Ae',
+ '/Ü/' => 'Ue',
+ '/Ö/' => 'Oe',
+ '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
+ '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
+ '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
+ '/ç|ć|ĉ|ċ|č/' => 'c',
+ '/Ð|Ď|Đ/' => 'D',
+ '/ð|ď|đ/' => 'd',
+ '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
+ '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
+ '/Ĝ|Ğ|Ġ|Ģ/' => 'G',
+ '/ĝ|ğ|ġ|ģ/' => 'g',
+ '/Ĥ|Ħ/' => 'H',
+ '/ĥ|ħ/' => 'h',
+ '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
+ '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
+ '/Ĵ/' => 'J',
+ '/ĵ/' => 'j',
+ '/Ķ/' => 'K',
+ '/ķ/' => 'k',
+ '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
+ '/ĺ|ļ|ľ|ŀ|ł/' => 'l',
+ '/Ñ|Ń|Ņ|Ň/' => 'N',
+ '/ñ|ń|ņ|ň|ʼn/' => 'n',
+ '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
+ '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
+ '/Ŕ|Ŗ|Ř/' => 'R',
+ '/ŕ|ŗ|ř/' => 'r',
+ '/Ś|Ŝ|Ş|Š/' => 'S',
+ '/ś|ŝ|ş|š|ſ/' => 's',
+ '/Ţ|Ť|Ŧ/' => 'T',
+ '/ţ|ť|ŧ/' => 't',
+ '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
+ '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
+ '/Ý|Ÿ|Ŷ/' => 'Y',
+ '/ý|ÿ|ŷ/' => 'y',
+ '/Ŵ/' => 'W',
+ '/ŵ/' => 'w',
+ '/Ź|Ż|Ž/' => 'Z',
+ '/ź|ż|ž/' => 'z',
+ '/Æ|Ǽ/' => 'AE',
+ '/ß/' => 'ss',
+ '/IJ/' => 'IJ',
+ '/ij/' => 'ij',
+ '/Œ/' => 'OE',
+ '/ƒ/' => 'f'
+ );
+
+/**
+ * Method cache array.
+ *
+ * @var array
+ */
+ protected static $_cache = array();
+
+/**
+ * The initial state of Inflector so reset() works.
+ *
+ * @var array
+ */
+ protected static $_initialState = array();
+
+/**
+ * Cache inflected values, and return if already available
+ *
+ * @param string $type Inflection type
+ * @param string $key Original value
+ * @param string $value Inflected value
+ * @return string Inflected value, from cache
+ */
+ protected static function _cache($type, $key, $value = false) {
+ $key = '_' . $key;
+ $type = '_' . $type;
+ if ($value !== false) {
+ self::$_cache[$type][$key] = $value;
+ return $value;
+ }
+ if (!isset(self::$_cache[$type][$key])) {
+ return false;
+ }
+ return self::$_cache[$type][$key];
+ }
+
+/**
+ * Clears Inflectors inflected value caches. And resets the inflection
+ * rules to the initial values.
+ *
+ * @return void
+ */
+ public static function reset() {
+ if (empty(self::$_initialState)) {
+ self::$_initialState = get_class_vars('Inflector');
+ return;
+ }
+ foreach (self::$_initialState as $key => $val) {
+ if ($key != '_initialState') {
+ self::${$key} = $val;
+ }
+ }
+ }
+
+/**
+ * Adds custom inflection $rules, of either 'plural', 'singular' or 'transliteration' $type.
+ *
+ * ### Usage:
+ *
+ * {{{
+ * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
+ * Inflector::rules('plural', array(
+ * 'rules' => array('/^(inflect)ors$/i' => '\1ables'),
+ * 'uninflected' => array('dontinflectme'),
+ * 'irregular' => array('red' => 'redlings')
+ * ));
+ * Inflector::rules('transliteration', array('/å/' => 'aa'));
+ * }}}
+ *
+ * @param string $type The type of inflection, either 'plural', 'singular' or 'transliteration'
+ * @param array $rules Array of rules to be added.
+ * @param boolean $reset If true, will unset default inflections for all
+ * new rules that are being defined in $rules.
+ * @return void
+ */
+ public static function rules($type, $rules, $reset = false) {
+ $var = '_' . $type;
+
+ switch ($type) {
+ case 'transliteration':
+ if ($reset) {
+ self::$_transliteration = $rules;
+ } else {
+ self::$_transliteration = $rules + self::$_transliteration;
+ }
+ break;
+
+ default:
+ foreach ($rules as $rule => $pattern) {
+ if (is_array($pattern)) {
+ if ($reset) {
+ self::${$var}[$rule] = $pattern;
+ } else {
+ if ($rule === 'uninflected') {
+ self::${$var}[$rule] = array_merge($pattern, self::${$var}[$rule]);
+ } else {
+ self::${$var}[$rule] = $pattern + self::${$var}[$rule];
+ }
+ }
+ unset($rules[$rule], self::${$var}['cache' . ucfirst($rule)]);
+ if (isset(self::${$var}['merged'][$rule])) {
+ unset(self::${$var}['merged'][$rule]);
+ }
+ if ($type === 'plural') {
+ self::$_cache['pluralize'] = self::$_cache['tableize'] = array();
+ } elseif ($type === 'singular') {
+ self::$_cache['singularize'] = array();
+ }
+ }
+ }
+ self::${$var}['rules'] = $rules + self::${$var}['rules'];
+ break;
+ }
+ }
+
+/**
+ * Return $word in plural form.
+ *
+ * @param string $word Word in singular
+ * @return string Word in plural
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::pluralize
+ */
+ public static function pluralize($word) {
+ if (isset(self::$_cache['pluralize'][$word])) {
+ return self::$_cache['pluralize'][$word];
+ }
+
+ if (!isset(self::$_plural['merged']['irregular'])) {
+ self::$_plural['merged']['irregular'] = self::$_plural['irregular'];
+ }
+
+ if (!isset(self::$_plural['merged']['uninflected'])) {
+ self::$_plural['merged']['uninflected'] = array_merge(self::$_plural['uninflected'], self::$_uninflected);
+ }
+
+ if (!isset(self::$_plural['cacheUninflected']) || !isset(self::$_plural['cacheIrregular'])) {
+ self::$_plural['cacheUninflected'] = '(?:' . implode('|', self::$_plural['merged']['uninflected']) . ')';
+ self::$_plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_plural['merged']['irregular'])) . ')';
+ }
+
+ if (preg_match('/(.*)\\b(' . self::$_plural['cacheIrregular'] . ')$/i', $word, $regs)) {
+ self::$_cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_plural['merged']['irregular'][strtolower($regs[2])], 1);
+ return self::$_cache['pluralize'][$word];
+ }
+
+ if (preg_match('/^(' . self::$_plural['cacheUninflected'] . ')$/i', $word, $regs)) {
+ self::$_cache['pluralize'][$word] = $word;
+ return $word;
+ }
+
+ foreach (self::$_plural['rules'] as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ self::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
+ return self::$_cache['pluralize'][$word];
+ }
+ }
+ }
+
+/**
+ * Return $word in singular form.
+ *
+ * @param string $word Word in plural
+ * @return string Word in singular
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::singularize
+ */
+ public static function singularize($word) {
+ if (isset(self::$_cache['singularize'][$word])) {
+ return self::$_cache['singularize'][$word];
+ }
+
+ if (!isset(self::$_singular['merged']['uninflected'])) {
+ self::$_singular['merged']['uninflected'] = array_merge(
+ self::$_singular['uninflected'],
+ self::$_uninflected
+ );
+ }
+
+ if (!isset(self::$_singular['merged']['irregular'])) {
+ self::$_singular['merged']['irregular'] = array_merge(
+ self::$_singular['irregular'],
+ array_flip(self::$_plural['irregular'])
+ );
+ }
+
+ if (!isset(self::$_singular['cacheUninflected']) || !isset(self::$_singular['cacheIrregular'])) {
+ self::$_singular['cacheUninflected'] = '(?:' . join('|', self::$_singular['merged']['uninflected']) . ')';
+ self::$_singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$_singular['merged']['irregular'])) . ')';
+ }
+
+ if (preg_match('/(.*)\\b(' . self::$_singular['cacheIrregular'] . ')$/i', $word, $regs)) {
+ self::$_cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_singular['merged']['irregular'][strtolower($regs[2])], 1);
+ return self::$_cache['singularize'][$word];
+ }
+
+ if (preg_match('/^(' . self::$_singular['cacheUninflected'] . ')$/i', $word, $regs)) {
+ self::$_cache['singularize'][$word] = $word;
+ return $word;
+ }
+
+ foreach (self::$_singular['rules'] as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ self::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
+ return self::$_cache['singularize'][$word];
+ }
+ }
+ self::$_cache['singularize'][$word] = $word;
+ return $word;
+ }
+
+/**
+ * Returns the given lower_case_and_underscored_word as a CamelCased word.
+ *
+ * @param string $lowerCaseAndUnderscoredWord Word to camelize
+ * @return string Camelized word. LikeThis.
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::camelize
+ */
+ public static function camelize($lowerCaseAndUnderscoredWord) {
+ if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
+ $result = str_replace(' ', '', Inflector::humanize($lowerCaseAndUnderscoredWord));
+ self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
+ }
+ return $result;
+ }
+
+/**
+ * Returns the given camelCasedWord as an underscored_word.
+ *
+ * @param string $camelCasedWord Camel-cased word to be "underscorized"
+ * @return string Underscore-syntaxed version of the $camelCasedWord
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::underscore
+ */
+ public static function underscore($camelCasedWord) {
+ if (!($result = self::_cache(__FUNCTION__, $camelCasedWord))) {
+ $result = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
+ self::_cache(__FUNCTION__, $camelCasedWord, $result);
+ }
+ return $result;
+ }
+
+/**
+ * Returns the given underscored_word_group as a Human Readable Word Group.
+ * (Underscores are replaced by spaces and capitalized following words.)
+ *
+ * @param string $lowerCaseAndUnderscoredWord String to be made more readable
+ * @return string Human-readable string
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::humanize
+ */
+ public static function humanize($lowerCaseAndUnderscoredWord) {
+ if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
+ $result = ucwords(str_replace('_', ' ', $lowerCaseAndUnderscoredWord));
+ self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
+ }
+ return $result;
+ }
+
+/**
+ * Returns corresponding table name for given model $className. ("people" for the model class "Person").
+ *
+ * @param string $className Name of class to get database table name for
+ * @return string Name of the database table for given class
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::tableize
+ */
+ public static function tableize($className) {
+ if (!($result = self::_cache(__FUNCTION__, $className))) {
+ $result = Inflector::pluralize(Inflector::underscore($className));
+ self::_cache(__FUNCTION__, $className, $result);
+ }
+ return $result;
+ }
+
+/**
+ * Returns Cake model class name ("Person" for the database table "people".) for given database table.
+ *
+ * @param string $tableName Name of database table to get class name for
+ * @return string Class name
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::classify
+ */
+ public static function classify($tableName) {
+ if (!($result = self::_cache(__FUNCTION__, $tableName))) {
+ $result = Inflector::camelize(Inflector::singularize($tableName));
+ self::_cache(__FUNCTION__, $tableName, $result);
+ }
+ return $result;
+ }
+
+/**
+ * Returns camelBacked version of an underscored string.
+ *
+ * @param string $string
+ * @return string in variable form
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::variable
+ */
+ public static function variable($string) {
+ if (!($result = self::_cache(__FUNCTION__, $string))) {
+ $camelized = Inflector::camelize(Inflector::underscore($string));
+ $replace = strtolower(substr($camelized, 0, 1));
+ $result = preg_replace('/\\w/', $replace, $camelized, 1);
+ self::_cache(__FUNCTION__, $string, $result);
+ }
+ return $result;
+ }
+
+/**
+ * Returns a string with all spaces converted to underscores (by default), accented
+ * characters converted to non-accented characters, and non word characters removed.
+ *
+ * @param string $string the string you want to slug
+ * @param string $replacement will replace keys in map
+ * @return string
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::slug
+ */
+ public static function slug($string, $replacement = '_') {
+ $quotedReplacement = preg_quote($replacement, '/');
+
+ $merge = array(
+ '/[^\s\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
+ '/\\s+/' => $replacement,
+ sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
+ );
+
+ $map = self::$_transliteration + $merge;
+ return preg_replace(array_keys($map), array_values($map), $string);
+ }
+
+}
+
+// Store the initial state
+Inflector::reset();
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php
new file mode 100644
index 0000000..96ec3d5
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php
@@ -0,0 +1,326 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Deals with Collections of objects. Keeping registries of those objects,
+ * loading and constructing new objects and triggering callbacks. Each subclass needs
+ * to implement its own load() functionality.
+ *
+ * All core subclasses of ObjectCollection by convention loaded objects are stored
+ * in `$this->_loaded`. Enabled objects are stored in `$this->_enabled`. In addition
+ * the all support an `enabled` option that controls the enabled/disabled state of the object
+ * when loaded.
+ *
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 2.0
+ */
+abstract class ObjectCollection {
+
+/**
+ * List of the currently-enabled objects
+ *
+ * @var array
+ */
+ protected $_enabled = array();
+
+/**
+ * A hash of loaded objects, indexed by name
+ *
+ * @var array
+ */
+ protected $_loaded = array();
+
+/**
+ * Default object priority. A non zero integer.
+ *
+ * @var int
+ */
+ public $defaultPriority = 10;
+
+/**
+ * Loads a new object onto the collection. Can throw a variety of exceptions
+ *
+ * Implementations of this class support a `$options['enabled']` flag which enables/disables
+ * a loaded object.
+ *
+ * @param string $name Name of object to load.
+ * @param array $options Array of configuration options for the object to be constructed.
+ * @return object the constructed object
+ */
+ abstract public function load($name, $options = array());
+
+/**
+ * Trigger a callback method on every object in the collection.
+ * Used to trigger methods on objects in the collection. Will fire the methods in the
+ * order they were attached.
+ *
+ * ### Options
+ *
+ * - `breakOn` Set to the value or values you want the callback propagation to stop on.
+ * Can either be a scalar value, or an array of values to break on. Defaults to `false`.
+ *
+ * - `break` Set to true to enabled breaking. When a trigger is broken, the last returned value
+ * will be returned. If used in combination with `collectReturn` the collected results will be returned.
+ * Defaults to `false`.
+ *
+ * - `collectReturn` Set to true to collect the return of each object into an array.
+ * This array of return values will be returned from the trigger() call. Defaults to `false`.
+ *
+ * - `modParams` Allows each object the callback gets called on to modify the parameters to the next object.
+ * Setting modParams to an integer value will allow you to modify the parameter with that index.
+ * Any non-null value will modify the parameter index indicated.
+ * Defaults to false.
+ *
+ *
+ * @param string $callback|CakeEvent Method to fire on all the objects. Its assumed all the objects implement
+ * the method you are calling. If an instance of CakeEvent is provided, then then Event name will parsed to
+ * get the callback name. This is done by getting the last word after any dot in the event name
+ * (eg. `Model.afterSave` event will trigger the `afterSave` callback)
+ * @param array $params Array of parameters for the triggered callback.
+ * @param array $options Array of options.
+ * @return mixed Either the last result or all results if collectReturn is on.
+ * @throws CakeException when modParams is used with an index that does not exist.
+ */
+ public function trigger($callback, $params = array(), $options = array()) {
+ if (empty($this->_enabled)) {
+ return true;
+ }
+ if ($callback instanceof CakeEvent) {
+ $event = $callback;
+ if (is_array($event->data)) {
+ $params =& $event->data;
+ }
+ if (empty($event->omitSubject)) {
+ $subject = $event->subject();
+ }
+ //TODO: Temporary BC check, while we move all the triggers system into the CakeEventManager
+ foreach (array('break', 'breakOn', 'collectReturn', 'modParams') as $opt) {
+ if (isset($event->{$opt})) {
+ $options[$opt] = $event->{$opt};
+ }
+ }
+ $parts = explode('.', $event->name());
+ $callback = array_pop($parts);
+ }
+ $options = array_merge(
+ array(
+ 'break' => false,
+ 'breakOn' => false,
+ 'collectReturn' => false,
+ 'modParams' => false
+ ),
+ $options
+ );
+ $collected = array();
+ $list = array_keys($this->_enabled);
+ if ($options['modParams'] !== false && !isset($params[$options['modParams']])) {
+ throw new CakeException(__d('cake_dev', 'Cannot use modParams with indexes that do not exist.'));
+ }
+ foreach ($list as $name) {
+ $result = call_user_func_array(array($this->_loaded[$name], $callback), compact('subject') + $params);
+ if ($options['collectReturn'] === true) {
+ $collected[] = $result;
+ }
+ if (
+ $options['break'] && ($result === $options['breakOn'] ||
+ (is_array($options['breakOn']) && in_array($result, $options['breakOn'], true)))
+ ) {
+ return $result;
+ } elseif ($options['modParams'] !== false && !in_array($result, array(true, false, null), true)) {
+ $params[$options['modParams']] = $result;
+ }
+ }
+ if ($options['modParams'] !== false) {
+ return $params[$options['modParams']];
+ }
+ return $options['collectReturn'] ? $collected : $result;
+ }
+
+/**
+ * Provide public read access to the loaded objects
+ *
+ * @param string $name Name of property to read
+ * @return mixed
+ */
+ public function __get($name) {
+ if (isset($this->_loaded[$name])) {
+ return $this->_loaded[$name];
+ }
+ return null;
+ }
+
+/**
+ * Provide isset access to _loaded
+ *
+ * @param string $name Name of object being checked.
+ * @return boolean
+ */
+ public function __isset($name) {
+ return isset($this->_loaded[$name]);
+ }
+
+/**
+ * Enables callbacks on an object or array of objects
+ *
+ * @param string|array $name CamelCased name of the object(s) to enable (string or array)
+ * @param boolean Prioritize enabled list after enabling object(s)
+ * @return void
+ */
+ public function enable($name, $prioritize = true) {
+ $enabled = false;
+ foreach ((array)$name as $object) {
+ if (isset($this->_loaded[$object]) && !isset($this->_enabled[$object])) {
+ $priority = isset($this->_loaded[$object]->settings['priority']) ? $this->_loaded[$object]->settings['priority'] : $this->defaultPriority;
+ $this->_enabled[$object] = array($priority);
+ $enabled = true;
+ }
+ }
+ if ($prioritize && $enabled) {
+ $this->prioritize();
+ }
+ }
+
+/**
+ * Prioritize list of enabled object
+ *
+ * @return array Prioritized list of object
+ */
+ public function prioritize() {
+ $i = 1;
+ foreach ($this->_enabled as $name => $priority) {
+ $priority[1] = $i++;
+ $this->_enabled[$name] = $priority;
+ }
+ asort($this->_enabled);
+ return $this->_enabled;
+ }
+
+/**
+ * Set priority for an object or array of objects
+ *
+ * @param string|array $name CamelCased name of the object(s) to enable (string or array)
+ * If string the second param $priority is used else it should be an associative array
+ * with keys as object names and values as priorities to set.
+ * @param integer|null Integer priority to set or null for default
+ * @return void
+ */
+ public function setPriority($name, $priority = null) {
+ if (is_string($name)) {
+ $name = array($name => $priority);
+ }
+ foreach ($name as $obj => $prio) {
+ if (isset($this->_loaded[$obj])) {
+ if (is_null($prio)) {
+ $prio = $this->defaultPriority;
+ }
+ $this->_loaded[$obj]->settings['priority'] = $prio;
+ if (isset($this->_enabled[$obj])) {
+ $this->_enabled[$obj] = array($prio);
+ }
+ }
+ }
+ $this->prioritize();
+ }
+
+/**
+ * Disables callbacks on a object or array of objects. Public object methods are still
+ * callable as normal.
+ *
+ * @param string|array $name CamelCased name of the objects(s) to disable (string or array)
+ * @return void
+ */
+ public function disable($name) {
+ foreach ((array)$name as $object) {
+ unset($this->_enabled[$object]);
+ }
+ }
+
+/**
+ * Gets the list of currently-enabled objects, or, the current status of a single objects
+ *
+ * @param string $name Optional. The name of the object to check the status of. If omitted,
+ * returns an array of currently-enabled object
+ * @return mixed If $name is specified, returns the boolean status of the corresponding object.
+ * Otherwise, returns an array of all enabled objects.
+ */
+ public function enabled($name = null) {
+ if (!empty($name)) {
+ return isset($this->_enabled[$name]);
+ }
+ return array_keys($this->_enabled);
+ }
+
+/**
+ * Gets the list of attached objects, or, whether the given object is attached
+ *
+ * @param string $name Optional. The name of the behavior to check the status of. If omitted,
+ * returns an array of currently-attached behaviors
+ * @return mixed If $name is specified, returns the boolean status of the corresponding behavior.
+ * Otherwise, returns an array of all attached behaviors.
+ */
+ public function attached($name = null) {
+ if (!empty($name)) {
+ return isset($this->_loaded[$name]);
+ }
+ return array_keys($this->_loaded);
+ }
+
+/**
+ * Name of the object to remove from the collection
+ *
+ * @param string $name Name of the object to delete.
+ * @return void
+ */
+ public function unload($name) {
+ list($plugin, $name) = pluginSplit($name);
+ unset($this->_loaded[$name]);
+ unset($this->_enabled[$name]);
+ }
+
+/**
+ * Adds or overwrites an instantiated object to the collection
+ *
+ * @param string $name Name of the object
+ * @param Object $object The object to use
+ * @return array Loaded objects
+ */
+ public function set($name = null, $object = null) {
+ if (!empty($name) && !empty($object)) {
+ list($plugin, $name) = pluginSplit($name);
+ $this->_loaded[$name] = $object;
+ }
+ return $this->_loaded;
+ }
+
+/**
+ * Normalizes an object array, creates an array that makes lazy loading
+ * easier
+ *
+ * @param array $objects Array of child objects to normalize.
+ * @return array Array of normalized objects.
+ */
+ public static function normalizeObjectArray($objects) {
+ $normal = array();
+ foreach ($objects as $i => $objectName) {
+ $options = array();
+ if (!is_int($i)) {
+ $options = (array)$objectName;
+ $objectName = $i;
+ }
+ list($plugin, $name) = pluginSplit($objectName);
+ $normal[$name] = array('class' => $objectName, 'settings' => $options);
+ }
+ return $normal;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php
new file mode 100644
index 0000000..dfb55f3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php
@@ -0,0 +1,264 @@
+<?php
+/**
+ * Washes strings from unwanted noise.
+ *
+ * Helpful methods to make unsafe strings usable.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::import('Model', 'ConnectionManager');
+
+/**
+ * Data Sanitization.
+ *
+ * Removal of alphanumeric characters, SQL-safe slash-added strings, HTML-friendly strings,
+ * and all of the above on arrays.
+ *
+ * @package Cake.Utility
+ */
+class Sanitize {
+
+/**
+ * Removes any non-alphanumeric characters.
+ *
+ * @param string $string String to sanitize
+ * @param array $allowed An array of additional characters that are not to be removed.
+ * @return string Sanitized string
+ */
+ public static function paranoid($string, $allowed = array()) {
+ $allow = null;
+ if (!empty($allowed)) {
+ foreach ($allowed as $value) {
+ $allow .= "\\$value";
+ }
+ }
+
+ if (is_array($string)) {
+ $cleaned = array();
+ foreach ($string as $key => $clean) {
+ $cleaned[$key] = preg_replace("/[^{$allow}a-zA-Z0-9]/", '', $clean);
+ }
+ } else {
+ $cleaned = preg_replace("/[^{$allow}a-zA-Z0-9]/", '', $string);
+ }
+ return $cleaned;
+ }
+
+/**
+ * Makes a string SQL-safe.
+ *
+ * @param string $string String to sanitize
+ * @param string $connection Database connection being used
+ * @return string SQL safe string
+ */
+ public static function escape($string, $connection = 'default') {
+ $db = ConnectionManager::getDataSource($connection);
+ if (is_numeric($string) || $string === null || is_bool($string)) {
+ return $string;
+ }
+ $string = $db->value($string, 'string');
+ if ($string[0] === 'N') {
+ $string = substr($string, 2);
+ } else {
+ $string = substr($string, 1);
+ }
+
+ $string = substr($string, 0, -1);
+ return $string;
+ }
+
+/**
+ * Returns given string safe for display as HTML. Renders entities.
+ *
+ * strip_tags() does not validating HTML syntax or structure, so it might strip whole passages
+ * with broken HTML.
+ *
+ * ### Options:
+ *
+ * - remove (boolean) if true strips all HTML tags before encoding
+ * - charset (string) the charset used to encode the string
+ * - quotes (int) see http://php.net/manual/en/function.htmlentities.php
+ * - double (boolean) doube encode html entities
+ *
+ * @param string $string String from where to strip tags
+ * @param array $options Array of options to use.
+ * @return string Sanitized string
+ */
+ public static function html($string, $options = array()) {
+ static $defaultCharset = false;
+ if ($defaultCharset === false) {
+ $defaultCharset = Configure::read('App.encoding');
+ if ($defaultCharset === null) {
+ $defaultCharset = 'UTF-8';
+ }
+ }
+ $default = array(
+ 'remove' => false,
+ 'charset' => $defaultCharset,
+ 'quotes' => ENT_QUOTES,
+ 'double' => true
+ );
+
+ $options = array_merge($default, $options);
+
+ if ($options['remove']) {
+ $string = strip_tags($string);
+ }
+
+ return htmlentities($string, $options['quotes'], $options['charset'], $options['double']);
+ }
+
+/**
+ * Strips extra whitespace from output
+ *
+ * @param string $str String to sanitize
+ * @return string whitespace sanitized string
+ */
+ public static function stripWhitespace($str) {
+ $r = preg_replace('/[\n\r\t]+/', '', $str);
+ return preg_replace('/\s{2,}/u', ' ', $r);
+ }
+
+/**
+ * Strips image tags from output
+ *
+ * @param string $str String to sanitize
+ * @return string Sting with images stripped.
+ */
+ public static function stripImages($str) {
+ $str = preg_replace('/(<a[^>]*>)(<img[^>]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5<br />', $str);
+ $str = preg_replace('/(<img[^>]+alt=")([^"]*)("[^>]*>)/i', '$2<br />', $str);
+ $str = preg_replace('/<img[^>]*>/i', '', $str);
+ return $str;
+ }
+
+/**
+ * Strips scripts and stylesheets from output
+ *
+ * @param string $str String to sanitize
+ * @return string String with <script>, <style>, <link>, <img> elements removed.
+ */
+ public static function stripScripts($str) {
+ return preg_replace('/(<link[^>]+rel="[^"]*stylesheet"[^>]*>|<img[^>]*>|style="[^"]*")|<script[^>]*>.*?<\/script>|<style[^>]*>.*?<\/style>|<!--.*?-->/is', '', $str);
+ }
+
+/**
+ * Strips extra whitespace, images, scripts and stylesheets from output
+ *
+ * @param string $str String to sanitize
+ * @return string sanitized string
+ */
+ public static function stripAll($str) {
+ $str = Sanitize::stripWhitespace($str);
+ $str = Sanitize::stripImages($str);
+ $str = Sanitize::stripScripts($str);
+ return $str;
+ }
+
+/**
+ * Strips the specified tags from output. First parameter is string from
+ * where to remove tags. All subsequent parameters are tags.
+ *
+ * Ex.`$clean = Sanitize::stripTags($dirty, 'b', 'p', 'div');`
+ *
+ * Will remove all `<b>`, `<p>`, and `<div>` tags from the $dirty string.
+ *
+ * @param string $str,... String to sanitize
+ * @return string sanitized String
+ */
+ public static function stripTags($str) {
+ $params = func_get_args();
+
+ for ($i = 1, $count = count($params); $i < $count; $i++) {
+ $str = preg_replace('/<' . $params[$i] . '\b[^>]*>/i', '', $str);
+ $str = preg_replace('/<\/' . $params[$i] . '[^>]*>/i', '', $str);
+ }
+ return $str;
+ }
+
+/**
+ * Sanitizes given array or value for safe input. Use the options to specify
+ * the connection to use, and what filters should be applied (with a boolean
+ * value). Valid filters:
+ *
+ * - odd_spaces - removes any non space whitespace characters
+ * - encode - Encode any html entities. Encode must be true for the `remove_html` to work.
+ * - dollar - Escape `$` with `\$`
+ * - carriage - Remove `\r`
+ * - unicode -
+ * - escape - Should the string be SQL escaped.
+ * - backslash -
+ * - remove_html - Strip HTML with strip_tags. `encode` must be true for this option to work.
+ *
+ * @param string|array $data Data to sanitize
+ * @param string|array $options If string, DB connection being used, otherwise set of options
+ * @return mixed Sanitized data
+ */
+ public static function clean($data, $options = array()) {
+ if (empty($data)) {
+ return $data;
+ }
+
+ if (is_string($options)) {
+ $options = array('connection' => $options);
+ } elseif (!is_array($options)) {
+ $options = array();
+ }
+
+ $options = array_merge(array(
+ 'connection' => 'default',
+ 'odd_spaces' => true,
+ 'remove_html' => false,
+ 'encode' => true,
+ 'dollar' => true,
+ 'carriage' => true,
+ 'unicode' => true,
+ 'escape' => true,
+ 'backslash' => true
+ ), $options);
+
+ if (is_array($data)) {
+ foreach ($data as $key => $val) {
+ $data[$key] = Sanitize::clean($val, $options);
+ }
+ return $data;
+ } else {
+ if ($options['odd_spaces']) {
+ $data = str_replace(chr(0xCA), '', $data);
+ }
+ if ($options['encode']) {
+ $data = Sanitize::html($data, array('remove' => $options['remove_html']));
+ }
+ if ($options['dollar']) {
+ $data = str_replace("\\\$", "$", $data);
+ }
+ if ($options['carriage']) {
+ $data = str_replace("\r", "", $data);
+ }
+ if ($options['unicode']) {
+ $data = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $data);
+ }
+ if ($options['escape']) {
+ $data = Sanitize::escape($data, $options['connection']);
+ }
+ if ($options['backslash']) {
+ $data = preg_replace("/\\\(?!&amp;#|\?#)/", "\\", $data);
+ }
+ return $data;
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Security.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Security.php
new file mode 100644
index 0000000..6438338
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Security.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Core Security
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v .0.10.0.1233
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('String', 'Utility');
+
+/**
+ * Security Library contains utility methods related to security
+ *
+ * @package Cake.Utility
+ */
+class Security {
+
+/**
+ * Default hash method
+ *
+ * @var string
+ */
+ public static $hashType = null;
+
+/**
+ * Get allowed minutes of inactivity based on security level.
+ *
+ * @return integer Allowed inactivity in minutes
+ */
+ public static function inactiveMins() {
+ switch (Configure::read('Security.level')) {
+ case 'high':
+ return 10;
+ break;
+ case 'medium':
+ return 100;
+ break;
+ case 'low':
+ default:
+ return 300;
+ break;
+ }
+ }
+
+/**
+ * Generate authorization hash.
+ *
+ * @return string Hash
+ */
+ public static function generateAuthKey() {
+ return Security::hash(String::uuid());
+ }
+
+/**
+ * Validate authorization hash.
+ *
+ * @param string $authKey Authorization hash
+ * @return boolean Success
+ * @todo Complete implementation
+ */
+ public static function validateAuthKey($authKey) {
+ return true;
+ }
+
+/**
+ * Create a hash from string using given method.
+ * Fallback on next available method.
+ *
+ * @param string $string String to hash
+ * @param string $type Method to use (sha1/sha256/md5)
+ * @param boolean $salt If true, automatically appends the application's salt
+ * value to $string (Security.salt)
+ * @return string Hash
+ */
+ public static function hash($string, $type = null, $salt = false) {
+ if ($salt) {
+ if (is_string($salt)) {
+ $string = $salt . $string;
+ } else {
+ $string = Configure::read('Security.salt') . $string;
+ }
+ }
+
+ if (empty($type)) {
+ $type = self::$hashType;
+ }
+ $type = strtolower($type);
+
+ if ($type == 'sha1' || $type == null) {
+ if (function_exists('sha1')) {
+ $return = sha1($string);
+ return $return;
+ }
+ $type = 'sha256';
+ }
+
+ if ($type == 'sha256' && function_exists('mhash')) {
+ return bin2hex(mhash(MHASH_SHA256, $string));
+ }
+
+ if (function_exists('hash')) {
+ return hash($type, $string);
+ }
+ return md5($string);
+ }
+
+/**
+ * Sets the default hash method for the Security object. This affects all objects using
+ * Security::hash().
+ *
+ * @param string $hash Method to use (sha1/sha256/md5)
+ * @return void
+ * @see Security::hash()
+ */
+ public static function setHash($hash) {
+ self::$hashType = $hash;
+ }
+
+/**
+ * Encrypts/Decrypts a text using the given key.
+ *
+ * @param string $text Encrypted string to decrypt, normal string to encrypt
+ * @param string $key Key to use
+ * @return string Encrypted/Decrypted string
+ */
+ public static function cipher($text, $key) {
+ if (empty($key)) {
+ trigger_error(__d('cake_dev', 'You cannot use an empty key for Security::cipher()'), E_USER_WARNING);
+ return '';
+ }
+
+ srand(Configure::read('Security.cipherSeed'));
+ $out = '';
+ $keyLength = strlen($key);
+ for ($i = 0, $textLength = strlen($text); $i < $textLength; $i++) {
+ $j = ord(substr($key, $i % $keyLength, 1));
+ while ($j--) {
+ rand(0, 255);
+ }
+ $mask = rand(0, 255);
+ $out .= chr(ord(substr($text, $i, 1)) ^ $mask);
+ }
+ srand();
+ return $out;
+ }
+
+/**
+ * Encrypts/Decrypts a text using the given key using rijndael method.
+ *
+ * @param string $text Encrypted string to decrypt, normal string to encrypt
+ * @param string $key Key to use
+ * @param string $operation Operation to perform, encrypt or decrypt
+ * @return string Encrypted/Descrypted string
+ */
+ public static function rijndael($text, $key, $operation) {
+ if (empty($key)) {
+ trigger_error(__d('cake_dev', 'You cannot use an empty key for Security::rijndael()'), E_USER_WARNING);
+ return '';
+ }
+ if (empty($operation) || !in_array($operation, array('encrypt', 'decrypt'))) {
+ trigger_error(__d('cake_dev', 'You must specify the operation for Security::rijndael(), either encrypt or decrypt'), E_USER_WARNING);
+ return '';
+ }
+ if (strlen($key) < 32) {
+ trigger_error(__d('cake_dev', 'You must use a key larger than 32 bytes for Security::rijndael()'), E_USER_WARNING);
+ return '';
+ }
+ $algorithm = 'rijndael-256';
+ $mode = 'cbc';
+ $cryptKey = substr($key, 0, 32);
+ $iv = substr($key, strlen($key) - 32, 32);
+ $out = '';
+ if ($operation === 'encrypt') {
+ $out .= mcrypt_encrypt($algorithm, $cryptKey, $text, $mode, $iv);
+ } elseif ($operation === 'decrypt') {
+ $out .= rtrim(mcrypt_decrypt($algorithm, $cryptKey, $text, $mode, $iv), "\0");
+ }
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Set.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Set.php
new file mode 100644
index 0000000..3bfa008
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Set.php
@@ -0,0 +1,1108 @@
+<?php
+/**
+ * Library of array functions for Cake.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('String', 'Utility');
+App::uses('Hash', 'Utility');
+
+/**
+ * Class used for manipulation of arrays.
+ *
+ * @package Cake.Utility
+ */
+class Set {
+
+/**
+ * This function can be thought of as a hybrid between PHP's array_merge and array_merge_recursive. The difference
+ * to the two is that if an array key contains another array then the function behaves recursive (unlike array_merge)
+ * but does not do if for keys containing strings (unlike array_merge_recursive).
+ *
+ * Since this method emulates `array_merge`, it will re-order numeric keys. When combined with out of
+ * order numeric keys containing arrays, results can be lossy.
+ *
+ * Note: This function will work with an unlimited amount of arguments and typecasts non-array
+ * parameters into arrays.
+ *
+ * @param array $data Array to be merged
+ * @param array $merge Array to merge with
+ * @return array Merged array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::merge
+ */
+ public static function merge($data, $merge = null) {
+ $args = func_get_args();
+ if (empty($args[1])) {
+ return (array)$args[0];
+ }
+ if (!is_array($args[0])) {
+ $args[0] = (array)$args[0];
+ }
+ return call_user_func_array('Hash::merge', $args);
+ }
+
+/**
+ * Filters empty elements out of a route array, excluding '0'.
+ *
+ * @param array $var Either an array to filter, or value when in callback
+ * @return mixed Either filtered array, or true/false when in callback
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::filter
+ */
+ public static function filter(array $var) {
+ return Hash::filter($var);
+ }
+
+/**
+ * Pushes the differences in $array2 onto the end of $array
+ *
+ * @param array $array Original array
+ * @param array $array2 Differences to push
+ * @return array Combined array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::pushDiff
+ */
+ public static function pushDiff($array, $array2) {
+ if (empty($array) && !empty($array2)) {
+ return $array2;
+ }
+ if (!empty($array) && !empty($array2)) {
+ foreach ($array2 as $key => $value) {
+ if (!array_key_exists($key, $array)) {
+ $array[$key] = $value;
+ } else {
+ if (is_array($value)) {
+ $array[$key] = Set::pushDiff($array[$key], $array2[$key]);
+ }
+ }
+ }
+ }
+ return $array;
+ }
+
+/**
+ * Maps the contents of the Set object to an object hierarchy.
+ * Maintains numeric keys as arrays of objects
+ *
+ * @param string $class A class name of the type of object to map to
+ * @param string $tmp A temporary class name used as $class if $class is an array
+ * @return object Hierarchical object
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::map
+ */
+ public static function map($class = 'stdClass', $tmp = 'stdClass') {
+ if (is_array($class)) {
+ $val = $class;
+ $class = $tmp;
+ }
+
+ if (empty($val)) {
+ return null;
+ }
+ return Set::_map($val, $class);
+ }
+
+/**
+ * Maps the given value as an object. If $value is an object,
+ * it returns $value. Otherwise it maps $value as an object of
+ * type $class, and if primary assign _name_ $key on first array.
+ * If $value is not empty, it will be used to set properties of
+ * returned object (recursively). If $key is numeric will maintain array
+ * structure
+ *
+ * @param array $array Array to map
+ * @param string $class Class name
+ * @param boolean $primary whether to assign first array key as the _name_
+ * @return mixed Mapped object
+ */
+ protected static function _map(&$array, $class, $primary = false) {
+ if ($class === true) {
+ $out = new stdClass;
+ } else {
+ $out = new $class;
+ }
+ if (is_array($array)) {
+ $keys = array_keys($array);
+ foreach ($array as $key => $value) {
+ if ($keys[0] === $key && $class !== true) {
+ $primary = true;
+ }
+ if (is_numeric($key)) {
+ if (is_object($out)) {
+ $out = get_object_vars($out);
+ }
+ $out[$key] = Set::_map($value, $class);
+ if (is_object($out[$key])) {
+ if ($primary !== true && is_array($value) && Set::countDim($value, true) === 2) {
+ if (!isset($out[$key]->_name_)) {
+ $out[$key]->_name_ = $primary;
+ }
+ }
+ }
+ } elseif (is_array($value)) {
+ if ($primary === true) {
+ // @codingStandardsIgnoreStart Legacy junk
+ if (!isset($out->_name_)) {
+ $out->_name_ = $key;
+ }
+ // @codingStandardsIgnoreEnd
+ $primary = false;
+ foreach ($value as $key2 => $value2) {
+ $out->{$key2} = Set::_map($value2, true);
+ }
+ } else {
+ if (!is_numeric($key)) {
+ $out->{$key} = Set::_map($value, true, $key);
+ if (is_object($out->{$key}) && !is_numeric($key)) {
+ if (!isset($out->{$key}->_name_)) {
+ $out->{$key}->_name_ = $key;
+ }
+ }
+ } else {
+ $out->{$key} = Set::_map($value, true);
+ }
+ }
+ } else {
+ $out->{$key} = $value;
+ }
+ }
+ } else {
+ $out = $array;
+ }
+ return $out;
+ }
+
+/**
+ * Checks to see if all the values in the array are numeric
+ *
+ * @param array $array The array to check. If null, the value of the current Set object
+ * @return boolean true if values are numeric, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::numeric
+ */
+ public static function numeric($array = null) {
+ return Hash::numeric($array);
+ }
+
+/**
+ * Return a value from an array list if the key exists.
+ *
+ * If a comma separated $list is passed arrays are numeric with the key of the first being 0
+ * $list = 'no, yes' would translate to $list = array(0 => 'no', 1 => 'yes');
+ *
+ * If an array is used, keys can be strings example: array('no' => 0, 'yes' => 1);
+ *
+ * $list defaults to 0 = no 1 = yes if param is not passed
+ *
+ * @param array $select Key in $list to return
+ * @param array|string $list can be an array or a comma-separated list.
+ * @return string the value of the array key or null if no match
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::enum
+ */
+ public static function enum($select, $list = null) {
+ if (empty($list)) {
+ $list = array('no', 'yes');
+ }
+
+ $return = null;
+ $list = Set::normalize($list, false);
+
+ if (array_key_exists($select, $list)) {
+ $return = $list[$select];
+ }
+ return $return;
+ }
+
+/**
+ * Returns a series of values extracted from an array, formatted in a format string.
+ *
+ * @param array $data Source array from which to extract the data
+ * @param string $format Format string into which values will be inserted, see sprintf()
+ * @param array $keys An array containing one or more Set::extract()-style key paths
+ * @return array An array of strings extracted from $keys and formatted with $format
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::format
+ */
+ public static function format($data, $format, $keys) {
+ $extracted = array();
+ $count = count($keys);
+
+ if (!$count) {
+ return;
+ }
+
+ for ($i = 0; $i < $count; $i++) {
+ $extracted[] = Set::extract($data, $keys[$i]);
+ }
+ $out = array();
+ $data = $extracted;
+ $count = count($data[0]);
+
+ if (preg_match_all('/\{([0-9]+)\}/msi', $format, $keys2) && isset($keys2[1])) {
+ $keys = $keys2[1];
+ $format = preg_split('/\{([0-9]+)\}/msi', $format);
+ $count2 = count($format);
+
+ for ($j = 0; $j < $count; $j++) {
+ $formatted = '';
+ for ($i = 0; $i <= $count2; $i++) {
+ if (isset($format[$i])) {
+ $formatted .= $format[$i];
+ }
+ if (isset($keys[$i]) && isset($data[$keys[$i]][$j])) {
+ $formatted .= $data[$keys[$i]][$j];
+ }
+ }
+ $out[] = $formatted;
+ }
+ } else {
+ $count2 = count($data);
+ for ($j = 0; $j < $count; $j++) {
+ $args = array();
+ for ($i = 0; $i < $count2; $i++) {
+ if (array_key_exists($j, $data[$i])) {
+ $args[] = $data[$i][$j];
+ }
+ }
+ $out[] = vsprintf($format, $args);
+ }
+ }
+ return $out;
+ }
+
+/**
+ * Implements partial support for XPath 2.0. If $path does not contain a '/' the call
+ * is delegated to Set::classicExtract(). Also the $path and $data arguments are
+ * reversible.
+ *
+ * #### Currently implemented selectors:
+ *
+ * - /User/id (similar to the classic {n}.User.id)
+ * - /User[2]/name (selects the name of the second User)
+ * - /User[id>2] (selects all Users with an id > 2)
+ * - /User[id>2][<5] (selects all Users with an id > 2 but < 5)
+ * - /Post/Comment[author_name=john]/../name (Selects the name of all Posts that have at least one Comment written by john)
+ * - /Posts[name] (Selects all Posts that have a 'name' key)
+ * - /Comment/.[1] (Selects the contents of the first comment)
+ * - /Comment/.[:last] (Selects the last comment)
+ * - /Comment/.[:first] (Selects the first comment)
+ * - /Comment[text=/cakephp/i] (Selects the all comments that have a text matching the regex /cakephp/i)
+ * - /Comment/@* (Selects the all key names of all comments)
+ *
+ * #### Other limitations:
+ *
+ * - Only absolute paths starting with a single '/' are supported right now
+ *
+ * **Warning**: Even so it has plenty of unit tests the XPath support has not gone through a lot of
+ * real-world testing. Please report Bugs as you find them. Suggestions for additional features to
+ * implement are also very welcome!
+ *
+ * @param string $path An absolute XPath 2.0 path
+ * @param array $data An array of data to extract from
+ * @param array $options Currently only supports 'flatten' which can be disabled for higher XPath-ness
+ * @return array An array of matched items
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::extract
+ */
+ public static function extract($path, $data = null, $options = array()) {
+ if (is_string($data)) {
+ $tmp = $data;
+ $data = $path;
+ $path = $tmp;
+ }
+ if (strpos($path, '/') === false) {
+ return Set::classicExtract($data, $path);
+ }
+ if (empty($data)) {
+ return array();
+ }
+ if ($path === '/') {
+ return $data;
+ }
+ $contexts = $data;
+ $options = array_merge(array('flatten' => true), $options);
+ if (!isset($contexts[0])) {
+ $current = current($data);
+ if ((is_array($current) && count($data) < 1) || !is_array($current) || !Set::numeric(array_keys($data))) {
+ $contexts = array($data);
+ }
+ }
+ $tokens = array_slice(preg_split('/(?<!=|\\\\)\/(?![a-z-\s]*\])/', $path), 1);
+
+ do {
+ $token = array_shift($tokens);
+ $conditions = false;
+ if (preg_match_all('/\[([^=]+=\/[^\/]+\/|[^\]]+)\]/', $token, $m)) {
+ $conditions = $m[1];
+ $token = substr($token, 0, strpos($token, '['));
+ }
+ $matches = array();
+ foreach ($contexts as $key => $context) {
+ if (!isset($context['trace'])) {
+ $context = array('trace' => array(null), 'item' => $context, 'key' => $key);
+ }
+ if ($token === '..') {
+ if (count($context['trace']) == 1) {
+ $context['trace'][] = $context['key'];
+ }
+ $parent = implode('/', $context['trace']) . '/.';
+ $context['item'] = Set::extract($parent, $data);
+ $context['key'] = array_pop($context['trace']);
+ if (isset($context['trace'][1]) && $context['trace'][1] > 0) {
+ $context['item'] = $context['item'][0];
+ } elseif (!empty($context['item'][$key])) {
+ $context['item'] = $context['item'][$key];
+ } else {
+ $context['item'] = array_shift($context['item']);
+ }
+ $matches[] = $context;
+ continue;
+ }
+ if ($token === '@*' && is_array($context['item'])) {
+ $matches[] = array(
+ 'trace' => array_merge($context['trace'], (array)$key),
+ 'key' => $key,
+ 'item' => array_keys($context['item']),
+ );
+ } elseif (is_array($context['item'])
+ && array_key_exists($token, $context['item'])
+ && !(strval($key) === strval($token) && count($tokens) == 1 && $tokens[0] === '.')) {
+ $items = $context['item'][$token];
+ if (!is_array($items)) {
+ $items = array($items);
+ } elseif (!isset($items[0])) {
+ $current = current($items);
+ $currentKey = key($items);
+ if (!is_array($current) || (is_array($current) && count($items) <= 1 && !is_numeric($currentKey))) {
+ $items = array($items);
+ }
+ }
+
+ foreach ($items as $key => $item) {
+ $ctext = array($context['key']);
+ if (!is_numeric($key)) {
+ $ctext[] = $token;
+ $tok = array_shift($tokens);
+ if (isset($items[$tok])) {
+ $ctext[] = $tok;
+ $item = $items[$tok];
+ $matches[] = array(
+ 'trace' => array_merge($context['trace'], $ctext),
+ 'key' => $tok,
+ 'item' => $item,
+ );
+ break;
+ } elseif ($tok !== null) {
+ array_unshift($tokens, $tok);
+ }
+ } else {
+ $key = $token;
+ }
+
+ $matches[] = array(
+ 'trace' => array_merge($context['trace'], $ctext),
+ 'key' => $key,
+ 'item' => $item,
+ );
+ }
+ } elseif ($key === $token || (ctype_digit($token) && $key == $token) || $token === '.') {
+ $context['trace'][] = $key;
+ $matches[] = array(
+ 'trace' => $context['trace'],
+ 'key' => $key,
+ 'item' => $context['item'],
+ );
+ }
+ }
+ if ($conditions) {
+ foreach ($conditions as $condition) {
+ $filtered = array();
+ $length = count($matches);
+ foreach ($matches as $i => $match) {
+ if (Set::matches(array($condition), $match['item'], $i + 1, $length)) {
+ $filtered[$i] = $match;
+ }
+ }
+ $matches = $filtered;
+ }
+ }
+ $contexts = $matches;
+
+ if (empty($tokens)) {
+ break;
+ }
+ } while (1);
+
+ $r = array();
+
+ foreach ($matches as $match) {
+ if ((!$options['flatten'] || is_array($match['item'])) && !is_int($match['key'])) {
+ $r[] = array($match['key'] => $match['item']);
+ } else {
+ $r[] = $match['item'];
+ }
+ }
+ return $r;
+ }
+
+/**
+ * This function can be used to see if a single item or a given xpath match certain conditions.
+ *
+ * @param string|array $conditions An array of condition strings or an XPath expression
+ * @param array $data An array of data to execute the match on
+ * @param integer $i Optional: The 'nth'-number of the item being matched.
+ * @param integer $length
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::matches
+ */
+ public static function matches($conditions, $data = array(), $i = null, $length = null) {
+ if (empty($conditions)) {
+ return true;
+ }
+ if (is_string($conditions)) {
+ return !!Set::extract($conditions, $data);
+ }
+ foreach ($conditions as $condition) {
+ if ($condition === ':last') {
+ if ($i != $length) {
+ return false;
+ }
+ continue;
+ } elseif ($condition === ':first') {
+ if ($i != 1) {
+ return false;
+ }
+ continue;
+ }
+ if (!preg_match('/(.+?)([><!]?[=]|[><])(.*)/', $condition, $match)) {
+ if (ctype_digit($condition)) {
+ if ($i != $condition) {
+ return false;
+ }
+ } elseif (preg_match_all('/(?:^[0-9]+|(?<=,)[0-9]+)/', $condition, $matches)) {
+ return in_array($i, $matches[0]);
+ } elseif (!array_key_exists($condition, $data)) {
+ return false;
+ }
+ continue;
+ }
+ list(, $key, $op, $expected) = $match;
+ if (!(isset($data[$key]) || array_key_exists($key, $data))) {
+ return false;
+ }
+
+ $val = $data[$key];
+
+ if ($op === '=' && $expected && $expected{0} === '/') {
+ return preg_match($expected, $val);
+ }
+ if ($op === '=' && $val != $expected) {
+ return false;
+ }
+ if ($op === '!=' && $val == $expected) {
+ return false;
+ }
+ if ($op === '>' && $val <= $expected) {
+ return false;
+ }
+ if ($op === '<' && $val >= $expected) {
+ return false;
+ }
+ if ($op === '<=' && $val > $expected) {
+ return false;
+ }
+ if ($op === '>=' && $val < $expected) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+/**
+ * Gets a value from an array or object that is contained in a given path using an array path syntax, i.e.:
+ * "{n}.Person.{[a-z]+}" - Where "{n}" represents a numeric key, "Person" represents a string literal,
+ * and "{[a-z]+}" (i.e. any string literal enclosed in brackets besides {n} and {s}) is interpreted as
+ * a regular expression.
+ *
+ * @param array $data Array from where to extract
+ * @param string|array $path As an array, or as a dot-separated string.
+ * @return array Extracted data
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::classicExtract
+ */
+ public static function classicExtract($data, $path = null) {
+ if (empty($path)) {
+ return $data;
+ }
+ if (is_object($data)) {
+ if (!($data instanceof ArrayAccess || $data instanceof Traversable)) {
+ $data = get_object_vars($data);
+ }
+ }
+ if (empty($data)) {
+ return null;
+ }
+ if (is_string($path) && strpos($path, '{') !== false) {
+ $path = String::tokenize($path, '.', '{', '}');
+ } elseif (is_string($path)) {
+ $path = explode('.', $path);
+ }
+ $tmp = array();
+
+ if (empty($path)) {
+ return null;
+ }
+
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key === '0') {
+ if (isset($data[$key])) {
+ $data = $data[$key];
+ } else {
+ return null;
+ }
+ } elseif ($key === '{n}') {
+ foreach ($data as $j => $val) {
+ if (is_int($j)) {
+ $tmpPath = array_slice($path, $i + 1);
+ if (empty($tmpPath)) {
+ $tmp[] = $val;
+ } else {
+ $tmp[] = Set::classicExtract($val, $tmpPath);
+ }
+ }
+ }
+ return $tmp;
+ } elseif ($key === '{s}') {
+ foreach ($data as $j => $val) {
+ if (is_string($j)) {
+ $tmpPath = array_slice($path, $i + 1);
+ if (empty($tmpPath)) {
+ $tmp[] = $val;
+ } else {
+ $tmp[] = Set::classicExtract($val, $tmpPath);
+ }
+ }
+ }
+ return $tmp;
+ } elseif (false !== strpos($key, '{') && false !== strpos($key, '}')) {
+ $pattern = substr($key, 1, -1);
+
+ foreach ($data as $j => $val) {
+ if (preg_match('/^' . $pattern . '/s', $j) !== 0) {
+ $tmpPath = array_slice($path, $i + 1);
+ if (empty($tmpPath)) {
+ $tmp[$j] = $val;
+ } else {
+ $tmp[$j] = Set::classicExtract($val, $tmpPath);
+ }
+ }
+ }
+ return $tmp;
+ } else {
+ if (isset($data[$key])) {
+ $data = $data[$key];
+ } else {
+ return null;
+ }
+ }
+ }
+ return $data;
+ }
+
+/**
+ * Inserts $data into an array as defined by $path.
+ *
+ * @param array $list Where to insert into
+ * @param string $path A dot-separated string.
+ * @param array $data Data to insert
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::insert
+ */
+ public static function insert($list, $path, $data = null) {
+ return Hash::insert($list, $path, $data);
+ }
+
+/**
+ * Removes an element from a Set or array as defined by $path.
+ *
+ * @param array $list From where to remove
+ * @param string $path A dot-separated string.
+ * @return array Array with $path removed from its value
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::remove
+ */
+ public static function remove($list, $path = null) {
+ return Hash::remove($list, $path);
+ }
+
+/**
+ * Checks if a particular path is set in an array
+ *
+ * @param string|array $data Data to check on
+ * @param string|array $path A dot-separated string.
+ * @return boolean true if path is found, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::check
+ */
+ public static function check($data, $path = null) {
+ if (empty($path)) {
+ return $data;
+ }
+ if (!is_array($path)) {
+ $path = explode('.', $path);
+ }
+
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key === '0') {
+ $key = intval($key);
+ }
+ if ($i === count($path) - 1) {
+ return (is_array($data) && array_key_exists($key, $data));
+ }
+
+ if (!is_array($data) || !array_key_exists($key, $data)) {
+ return false;
+ }
+ $data =& $data[$key];
+ }
+ return true;
+ }
+
+/**
+ * Computes the difference between a Set and an array, two Sets, or two arrays
+ *
+ * @param mixed $val1 First value
+ * @param mixed $val2 Second value
+ * @return array Returns the key => value pairs that are not common in $val1 and $val2
+ * The expression for this function is($val1 - $val2) + ($val2 - ($val1 - $val2))
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::diff
+ */
+ public static function diff($val1, $val2 = null) {
+ if (empty($val1)) {
+ return (array)$val2;
+ }
+ if (empty($val2)) {
+ return (array)$val1;
+ }
+ $intersection = array_intersect_key($val1, $val2);
+ while (($key = key($intersection)) !== null) {
+ if ($val1[$key] == $val2[$key]) {
+ unset($val1[$key]);
+ unset($val2[$key]);
+ }
+ next($intersection);
+ }
+
+ return $val1 + $val2;
+ }
+
+/**
+ * Determines if one Set or array contains the exact keys and values of another.
+ *
+ * @param array $val1 First value
+ * @param array $val2 Second value
+ * @return boolean true if $val1 contains $val2, false otherwise
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::contains
+ */
+ public static function contains($val1, $val2 = null) {
+ if (empty($val1) || empty($val2)) {
+ return false;
+ }
+
+ foreach ($val2 as $key => $val) {
+ if (is_numeric($key)) {
+ Set::contains($val, $val1);
+ } else {
+ if (!isset($val1[$key]) || $val1[$key] != $val) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Counts the dimensions of an array. If $all is set to false (which is the default) it will
+ * only consider the dimension of the first element in the array.
+ *
+ * @param array $array Array to count dimensions on
+ * @param boolean $all Set to true to count the dimension considering all elements in array
+ * @param integer $count Start the dimension count at this number
+ * @return integer The number of dimensions in $array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::countDim
+ */
+ public static function countDim($array = null, $all = false, $count = 0) {
+ if ($all) {
+ $depth = array($count);
+ if (is_array($array) && reset($array) !== false) {
+ foreach ($array as $value) {
+ $depth[] = Set::countDim($value, true, $count + 1);
+ }
+ }
+ $return = max($depth);
+ } else {
+ if (is_array(reset($array))) {
+ $return = Set::countDim(reset($array)) + 1;
+ } else {
+ $return = 1;
+ }
+ }
+ return $return;
+ }
+
+/**
+ * Normalizes a string or array list.
+ *
+ * @param mixed $list List to normalize
+ * @param boolean $assoc If true, $list will be converted to an associative array
+ * @param string $sep If $list is a string, it will be split into an array with $sep
+ * @param boolean $trim If true, separated strings will be trimmed
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::normalize
+ */
+ public static function normalize($list, $assoc = true, $sep = ',', $trim = true) {
+ if (is_string($list)) {
+ $list = explode($sep, $list);
+ if ($trim) {
+ foreach ($list as $key => $value) {
+ $list[$key] = trim($value);
+ }
+ }
+ if ($assoc) {
+ return Hash::normalize($list);
+ }
+ } elseif (is_array($list)) {
+ $list = Hash::normalize($list, $assoc);
+ }
+ return $list;
+ }
+
+/**
+ * Creates an associative array using a $path1 as the path to build its keys, and optionally
+ * $path2 as path to get the values. If $path2 is not specified, all values will be initialized
+ * to null (useful for Set::merge). You can optionally group the values by what is obtained when
+ * following the path specified in $groupPath.
+ *
+ * @param array|object $data Array or object from where to extract keys and values
+ * @param string|array $path1 As an array, or as a dot-separated string.
+ * @param string|array $path2 As an array, or as a dot-separated string.
+ * @param string $groupPath As an array, or as a dot-separated string.
+ * @return array Combined array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::combine
+ */
+ public static function combine($data, $path1 = null, $path2 = null, $groupPath = null) {
+ if (empty($data)) {
+ return array();
+ }
+
+ if (is_object($data)) {
+ if (!($data instanceof ArrayAccess || $data instanceof Traversable)) {
+ $data = get_object_vars($data);
+ }
+ }
+
+ if (is_array($path1)) {
+ $format = array_shift($path1);
+ $keys = Set::format($data, $format, $path1);
+ } else {
+ $keys = Set::extract($data, $path1);
+ }
+ if (empty($keys)) {
+ return array();
+ }
+
+ if (!empty($path2) && is_array($path2)) {
+ $format = array_shift($path2);
+ $vals = Set::format($data, $format, $path2);
+ } elseif (!empty($path2)) {
+ $vals = Set::extract($data, $path2);
+ } else {
+ $count = count($keys);
+ for ($i = 0; $i < $count; $i++) {
+ $vals[$i] = null;
+ }
+ }
+
+ if ($groupPath != null) {
+ $group = Set::extract($data, $groupPath);
+ if (!empty($group)) {
+ $c = count($keys);
+ for ($i = 0; $i < $c; $i++) {
+ if (!isset($group[$i])) {
+ $group[$i] = 0;
+ }
+ if (!isset($out[$group[$i]])) {
+ $out[$group[$i]] = array();
+ }
+ $out[$group[$i]][$keys[$i]] = $vals[$i];
+ }
+ return $out;
+ }
+ }
+ if (empty($vals)) {
+ return array();
+ }
+ return array_combine($keys, $vals);
+ }
+
+/**
+ * Converts an object into an array.
+ * @param object $object Object to reverse
+ * @return array Array representation of given object
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::reverse
+ */
+ public static function reverse($object) {
+ $out = array();
+ if ($object instanceof SimpleXMLElement) {
+ return Xml::toArray($object);
+ } elseif (is_object($object)) {
+ $keys = get_object_vars($object);
+ if (isset($keys['_name_'])) {
+ $identity = $keys['_name_'];
+ unset($keys['_name_']);
+ }
+ $new = array();
+ foreach ($keys as $key => $value) {
+ if (is_array($value)) {
+ $new[$key] = (array)Set::reverse($value);
+ } else {
+ // @codingStandardsIgnoreStart Legacy junk
+ if (isset($value->_name_)) {
+ $new = array_merge($new, Set::reverse($value));
+ } else {
+ $new[$key] = Set::reverse($value);
+ }
+ // @codingStandardsIgnoreEnd
+ }
+ }
+ if (isset($identity)) {
+ $out[$identity] = $new;
+ } else {
+ $out = $new;
+ }
+ } elseif (is_array($object)) {
+ foreach ($object as $key => $value) {
+ $out[$key] = Set::reverse($value);
+ }
+ } else {
+ $out = $object;
+ }
+ return $out;
+ }
+
+/**
+ * Collapses a multi-dimensional array into a single dimension, using a delimited array path for
+ * each array element's key, i.e. array(array('Foo' => array('Bar' => 'Far'))) becomes
+ * array('0.Foo.Bar' => 'Far').
+ *
+ * @param array $data Array to flatten
+ * @param string $separator String used to separate array key elements in a path, defaults to '.'
+ * @return array
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::flatten
+ */
+ public static function flatten($data, $separator = '.') {
+ return Hash::flatten($data, $separator);
+ }
+
+/**
+ * Expand/unflattens an string to an array
+ *
+ * For example, unflattens an array that was collapsed with `Set::flatten()`
+ * into a multi-dimensional array. So, `array('0.Foo.Bar' => 'Far')` becomes
+ * `array(array('Foo' => array('Bar' => 'Far')))`.
+ *
+ * @param array $data Flattened array
+ * @param string $separator The delimiter used
+ * @return array
+ */
+ public static function expand($data, $separator = '.') {
+ return Hash::expand($data, $separator);
+ }
+
+/**
+ * Flattens an array for sorting
+ *
+ * @param array $results
+ * @param string $key
+ * @return array
+ */
+ protected static function _flatten($results, $key = null) {
+ $stack = array();
+ foreach ($results as $k => $r) {
+ $id = $k;
+ if (!is_null($key)) {
+ $id = $key;
+ }
+ if (is_array($r) && !empty($r)) {
+ $stack = array_merge($stack, Set::_flatten($r, $id));
+ } else {
+ $stack[] = array('id' => $id, 'value' => $r);
+ }
+ }
+ return $stack;
+ }
+
+/**
+ * Sorts an array by any value, determined by a Set-compatible path
+ *
+ * @param array $data An array of data to sort
+ * @param string $path A Set-compatible path to the array value
+ * @param string $dir Direction of sorting - either ascending (ASC), or descending (DESC)
+ * @return array Sorted array of data
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::sort
+ */
+ public static function sort($data, $path, $dir) {
+ $originalKeys = array_keys($data);
+ $numeric = false;
+ if (is_numeric(implode('', $originalKeys))) {
+ $data = array_values($data);
+ $numeric = true;
+ }
+ $result = Set::_flatten(Set::extract($data, $path));
+ list($keys, $values) = array(Set::extract($result, '{n}.id'), Set::extract($result, '{n}.value'));
+
+ $dir = strtolower($dir);
+ if ($dir === 'asc') {
+ $dir = SORT_ASC;
+ } elseif ($dir === 'desc') {
+ $dir = SORT_DESC;
+ }
+ array_multisort($values, $dir, $keys, $dir);
+ $sorted = array();
+ $keys = array_unique($keys);
+
+ foreach ($keys as $k) {
+ if ($numeric) {
+ $sorted[] = $data[$k];
+ } else {
+ if (isset($originalKeys[$k])) {
+ $sorted[$originalKeys[$k]] = $data[$originalKeys[$k]];
+ } else {
+ $sorted[$k] = $data[$k];
+ }
+ }
+ }
+ return $sorted;
+ }
+
+/**
+ * Allows the application of a callback method to elements of an
+ * array extracted by a Set::extract() compatible path.
+ *
+ * @param mixed $path Set-compatible path to the array value
+ * @param array $data An array of data to extract from & then process with the $callback.
+ * @param mixed $callback Callback method to be applied to extracted data.
+ * See http://ca2.php.net/manual/en/language.pseudo-types.php#language.types.callback for examples
+ * of callback formats.
+ * @param array $options Options are:
+ * - type : can be pass, map, or reduce. Map will handoff the given callback
+ * to array_map, reduce will handoff to array_reduce, and pass will
+ * use call_user_func_array().
+ * @return mixed Result of the callback when applied to extracted data
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::apply
+ */
+ public static function apply($path, $data, $callback, $options = array()) {
+ $defaults = array('type' => 'pass');
+ $options = array_merge($defaults, $options);
+ $extracted = Set::extract($path, $data);
+
+ if ($options['type'] === 'map') {
+ return array_map($callback, $extracted);
+ } elseif ($options['type'] === 'reduce') {
+ return array_reduce($extracted, $callback);
+ } elseif ($options['type'] === 'pass') {
+ return call_user_func_array($callback, array($extracted));
+ }
+ return null;
+ }
+
+/**
+ * Takes in a flat array and returns a nested array
+ *
+ * @param mixed $data
+ * @param array $options Options are:
+ * children - the key name to use in the resultset for children
+ * idPath - the path to a key that identifies each entry
+ * parentPath - the path to a key that identifies the parent of each entry
+ * root - the id of the desired top-most result
+ * @return array of results, nested
+ * @link
+ */
+ public static function nest($data, $options = array()) {
+ if (!$data) {
+ return $data;
+ }
+
+ $alias = key(current($data));
+ $options += array(
+ 'idPath' => "/$alias/id",
+ 'parentPath' => "/$alias/parent_id",
+ 'children' => 'children',
+ 'root' => null
+ );
+
+ $return = $idMap = array();
+ $ids = Set::extract($data, $options['idPath']);
+ $idKeys = explode('/', trim($options['idPath'], '/'));
+ $parentKeys = explode('/', trim($options['parentPath'], '/'));
+
+ foreach ($data as $result) {
+ $result[$options['children']] = array();
+
+ $id = Set::get($result, $idKeys);
+ $parentId = Set::get($result, $parentKeys);
+
+ if (isset($idMap[$id][$options['children']])) {
+ $idMap[$id] = array_merge($result, (array)$idMap[$id]);
+ } else {
+ $idMap[$id] = array_merge($result, array($options['children'] => array()));
+ }
+ if (!$parentId || !in_array($parentId, $ids)) {
+ $return[] =& $idMap[$id];
+ } else {
+ $idMap[$parentId][$options['children']][] =& $idMap[$id];
+ }
+ }
+
+ if ($options['root']) {
+ $root = $options['root'];
+ } else {
+ $root = Set::get($return[0], $parentKeys);
+ }
+
+ foreach ($return as $i => $result) {
+ $id = Set::get($result, $idKeys);
+ $parentId = Set::get($result, $parentKeys);
+ if ($id !== $root && $parentId != $root) {
+ unset($return[$i]);
+ }
+ }
+
+ return array_values($return);
+ }
+
+/**
+ * Return the value at the specified position
+ *
+ * @param array $input an array
+ * @param string|array $path string or array of array keys
+ * @return the value at the specified position or null if it doesn't exist
+ */
+ public static function get($input, $path = null) {
+ if (is_string($path)) {
+ if (strpos($path, '/') !== false) {
+ $keys = explode('/', trim($path, '/'));
+ } else {
+ $keys = explode('.', trim($path, '.'));
+ }
+ } else {
+ $keys = $path;
+ }
+ return Hash::get($input, $keys);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/String.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/String.php
new file mode 100644
index 0000000..01f9acb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/String.php
@@ -0,0 +1,605 @@
+<?php
+/**
+ * String handling methods.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 1.2.0.5551
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * String handling methods.
+ *
+ *
+ * @package Cake.Utility
+ */
+class String {
+
+/**
+ * Generate a random UUID
+ *
+ * @see http://www.ietf.org/rfc/rfc4122.txt
+ * @return RFC 4122 UUID
+ */
+ public static function uuid() {
+ $node = env('SERVER_ADDR');
+
+ if (strpos($node, ':') !== false) {
+ if (substr_count($node, '::')) {
+ $node = str_replace(
+ '::', str_repeat(':0000', 8 - substr_count($node, ':')) . ':', $node
+ );
+ }
+ $node = explode(':', $node);
+ $ipSix = '';
+
+ foreach ($node as $id) {
+ $ipSix .= str_pad(base_convert($id, 16, 2), 16, 0, STR_PAD_LEFT);
+ }
+ $node = base_convert($ipSix, 2, 10);
+
+ if (strlen($node) < 38) {
+ $node = null;
+ } else {
+ $node = crc32($node);
+ }
+ } elseif (empty($node)) {
+ $host = env('HOSTNAME');
+
+ if (empty($host)) {
+ $host = env('HOST');
+ }
+
+ if (!empty($host)) {
+ $ip = gethostbyname($host);
+
+ if ($ip === $host) {
+ $node = crc32($host);
+ } else {
+ $node = ip2long($ip);
+ }
+ }
+ } elseif ($node !== '127.0.0.1') {
+ $node = ip2long($node);
+ } else {
+ $node = null;
+ }
+
+ if (empty($node)) {
+ $node = crc32(Configure::read('Security.salt'));
+ }
+
+ if (function_exists('hphp_get_thread_id')) {
+ $pid = hphp_get_thread_id();
+ } elseif (function_exists('zend_thread_id')) {
+ $pid = zend_thread_id();
+ } else {
+ $pid = getmypid();
+ }
+
+ if (!$pid || $pid > 65535) {
+ $pid = mt_rand(0, 0xfff) | 0x4000;
+ }
+
+ list($timeMid, $timeLow) = explode(' ', microtime());
+ $uuid = sprintf(
+ "%08x-%04x-%04x-%02x%02x-%04x%08x", (int)$timeLow, (int)substr($timeMid, 2) & 0xffff,
+ mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3f) | 0x80, mt_rand(0, 0xff), $pid, $node
+ );
+
+ return $uuid;
+ }
+
+/**
+ * Tokenizes a string using $separator, ignoring any instance of $separator that appears between
+ * $leftBound and $rightBound
+ *
+ * @param string $data The data to tokenize
+ * @param string $separator The token to split the data on.
+ * @param string $leftBound The left boundary to ignore separators in.
+ * @param string $rightBound The right boundary to ignore separators in.
+ * @return array Array of tokens in $data.
+ */
+ public static function tokenize($data, $separator = ',', $leftBound = '(', $rightBound = ')') {
+ if (empty($data) || is_array($data)) {
+ return $data;
+ }
+
+ $depth = 0;
+ $offset = 0;
+ $buffer = '';
+ $results = array();
+ $length = strlen($data);
+ $open = false;
+
+ while ($offset <= $length) {
+ $tmpOffset = -1;
+ $offsets = array(
+ strpos($data, $separator, $offset),
+ strpos($data, $leftBound, $offset),
+ strpos($data, $rightBound, $offset)
+ );
+ for ($i = 0; $i < 3; $i++) {
+ if ($offsets[$i] !== false && ($offsets[$i] < $tmpOffset || $tmpOffset == -1)) {
+ $tmpOffset = $offsets[$i];
+ }
+ }
+ if ($tmpOffset !== -1) {
+ $buffer .= substr($data, $offset, ($tmpOffset - $offset));
+ if ($data{$tmpOffset} == $separator && $depth == 0) {
+ $results[] = $buffer;
+ $buffer = '';
+ } else {
+ $buffer .= $data{$tmpOffset};
+ }
+ if ($leftBound != $rightBound) {
+ if ($data{$tmpOffset} == $leftBound) {
+ $depth++;
+ }
+ if ($data{$tmpOffset} == $rightBound) {
+ $depth--;
+ }
+ } else {
+ if ($data{$tmpOffset} == $leftBound) {
+ if (!$open) {
+ $depth++;
+ $open = true;
+ } else {
+ $depth--;
+ $open = false;
+ }
+ }
+ }
+ $offset = ++$tmpOffset;
+ } else {
+ $results[] = $buffer . substr($data, $offset);
+ $offset = $length + 1;
+ }
+ }
+ if (empty($results) && !empty($buffer)) {
+ $results[] = $buffer;
+ }
+
+ if (!empty($results)) {
+ $data = array_map('trim', $results);
+ } else {
+ $data = array();
+ }
+ return $data;
+ }
+
+/**
+ * Replaces variable placeholders inside a $str with any given $data. Each key in the $data array
+ * corresponds to a variable placeholder name in $str.
+ * Example: `String::insert(':name is :age years old.', array('name' => 'Bob', '65'));`
+ * Returns: Bob is 65 years old.
+ *
+ * Available $options are:
+ *
+ * - before: The character or string in front of the name of the variable placeholder (Defaults to `:`)
+ * - after: The character or string after the name of the variable placeholder (Defaults to null)
+ * - escape: The character or string used to escape the before character / string (Defaults to `\`)
+ * - format: A regex to use for matching variable placeholders. Default is: `/(?<!\\)\:%s/`
+ * (Overwrites before, after, breaks escape / clean)
+ * - clean: A boolean or array with instructions for String::cleanInsert
+ *
+ * @param string $str A string containing variable placeholders
+ * @param string $data A key => val array where each key stands for a placeholder variable name
+ * to be replaced with val
+ * @param string $options An array of options, see description above
+ * @return string
+ */
+ public static function insert($str, $data, $options = array()) {
+ $defaults = array(
+ 'before' => ':', 'after' => null, 'escape' => '\\', 'format' => null, 'clean' => false
+ );
+ $options += $defaults;
+ $format = $options['format'];
+ $data = (array)$data;
+ if (empty($data)) {
+ return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
+ }
+
+ if (!isset($format)) {
+ $format = sprintf(
+ '/(?<!%s)%s%%s%s/',
+ preg_quote($options['escape'], '/'),
+ str_replace('%', '%%', preg_quote($options['before'], '/')),
+ str_replace('%', '%%', preg_quote($options['after'], '/'))
+ );
+ }
+
+ if (strpos($str, '?') !== false && is_numeric(key($data))) {
+ $offset = 0;
+ while (($pos = strpos($str, '?', $offset)) !== false) {
+ $val = array_shift($data);
+ $offset = $pos + strlen($val);
+ $str = substr_replace($str, $val, $pos, 1);
+ }
+ return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
+ } else {
+ asort($data);
+
+ $hashKeys = array();
+ foreach ($data as $key => $value) {
+ $hashKeys[] = crc32($key);
+ }
+
+ $tempData = array_combine(array_keys($data), array_values($hashKeys));
+ krsort($tempData);
+ foreach ($tempData as $key => $hashVal) {
+ $key = sprintf($format, preg_quote($key, '/'));
+ $str = preg_replace($key, $hashVal, $str);
+ }
+ $dataReplacements = array_combine($hashKeys, array_values($data));
+ foreach ($dataReplacements as $tmpHash => $tmpValue) {
+ $tmpValue = (is_array($tmpValue)) ? '' : $tmpValue;
+ $str = str_replace($tmpHash, $tmpValue, $str);
+ }
+ }
+
+ if (!isset($options['format']) && isset($options['before'])) {
+ $str = str_replace($options['escape'] . $options['before'], $options['before'], $str);
+ }
+ return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
+ }
+
+/**
+ * Cleans up a String::insert() formatted string with given $options depending on the 'clean' key in
+ * $options. The default method used is text but html is also available. The goal of this function
+ * is to replace all whitespace and unneeded markup around placeholders that did not get replaced
+ * by String::insert().
+ *
+ * @param string $str
+ * @param string $options
+ * @return string
+ * @see String::insert()
+ */
+ public static function cleanInsert($str, $options) {
+ $clean = $options['clean'];
+ if (!$clean) {
+ return $str;
+ }
+ if ($clean === true) {
+ $clean = array('method' => 'text');
+ }
+ if (!is_array($clean)) {
+ $clean = array('method' => $options['clean']);
+ }
+ switch ($clean['method']) {
+ case 'html':
+ $clean = array_merge(array(
+ 'word' => '[\w,.]+',
+ 'andText' => true,
+ 'replacement' => '',
+ ), $clean);
+ $kleenex = sprintf(
+ '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i',
+ preg_quote($options['before'], '/'),
+ $clean['word'],
+ preg_quote($options['after'], '/')
+ );
+ $str = preg_replace($kleenex, $clean['replacement'], $str);
+ if ($clean['andText']) {
+ $options['clean'] = array('method' => 'text');
+ $str = String::cleanInsert($str, $options);
+ }
+ break;
+ case 'text':
+ $clean = array_merge(array(
+ 'word' => '[\w,.]+',
+ 'gap' => '[\s]*(?:(?:and|or)[\s]*)?',
+ 'replacement' => '',
+ ), $clean);
+
+ $kleenex = sprintf(
+ '/(%s%s%s%s|%s%s%s%s)/',
+ preg_quote($options['before'], '/'),
+ $clean['word'],
+ preg_quote($options['after'], '/'),
+ $clean['gap'],
+ $clean['gap'],
+ preg_quote($options['before'], '/'),
+ $clean['word'],
+ preg_quote($options['after'], '/')
+ );
+ $str = preg_replace($kleenex, $clean['replacement'], $str);
+ break;
+ }
+ return $str;
+ }
+
+/**
+ * Wraps text to a specific width, can optionally wrap at word breaks.
+ *
+ * ### Options
+ *
+ * - `width` The width to wrap to. Defaults to 72
+ * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true.
+ * - `indent` String to indent with. Defaults to null.
+ * - `indentAt` 0 based index to start indenting at. Defaults to 0.
+ *
+ * @param string $text Text the text to format.
+ * @param array|integer $options Array of options to use, or an integer to wrap the text to.
+ * @return string Formatted text.
+ */
+ public static function wrap($text, $options = array()) {
+ if (is_numeric($options)) {
+ $options = array('width' => $options);
+ }
+ $options += array('width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0);
+ if ($options['wordWrap']) {
+ $wrapped = wordwrap($text, $options['width'], "\n");
+ } else {
+ $wrapped = trim(chunk_split($text, $options['width'] - 1, "\n"));
+ }
+ if (!empty($options['indent'])) {
+ $chunks = explode("\n", $wrapped);
+ for ($i = $options['indentAt'], $len = count($chunks); $i < $len; $i++) {
+ $chunks[$i] = $options['indent'] . $chunks[$i];
+ }
+ $wrapped = implode("\n", $chunks);
+ }
+ return $wrapped;
+ }
+
+/**
+ * Highlights a given phrase in a text. You can specify any expression in highlighter that
+ * may include the \1 expression to include the $phrase found.
+ *
+ * ### Options:
+ *
+ * - `format` The piece of html with that the phrase will be highlighted
+ * - `html` If true, will ignore any HTML tags, ensuring that only the correct text is highlighted
+ * - `regex` a custom regex rule that is ued to match words, default is '|$tag|iu'
+ *
+ * @param string $text Text to search the phrase in
+ * @param string $phrase The phrase that will be searched
+ * @param array $options An array of html attributes and options.
+ * @return string The highlighted text
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
+ */
+ public static function highlight($text, $phrase, $options = array()) {
+ if (empty($phrase)) {
+ return $text;
+ }
+
+ $default = array(
+ 'format' => '<span class="highlight">\1</span>',
+ 'html' => false,
+ 'regex' => "|%s|iu"
+ );
+ $options = array_merge($default, $options);
+ extract($options);
+
+ if (is_array($phrase)) {
+ $replace = array();
+ $with = array();
+
+ foreach ($phrase as $key => $segment) {
+ $segment = '(' . preg_quote($segment, '|') . ')';
+ if ($html) {
+ $segment = "(?![^<]+>)$segment(?![^<]+>)";
+ }
+
+ $with[] = (is_array($format)) ? $format[$key] : $format;
+ $replace[] = sprintf($options['regex'], $segment);
+ }
+
+ return preg_replace($replace, $with, $text);
+ } else {
+ $phrase = '(' . preg_quote($phrase, '|') . ')';
+ if ($html) {
+ $phrase = "(?![^<]+>)$phrase(?![^<]+>)";
+ }
+
+ return preg_replace(sprintf($options['regex'], $phrase), $format, $text);
+ }
+ }
+
+/**
+ * Strips given text of all links (<a href=....)
+ *
+ * @param string $text Text
+ * @return string The text without links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
+ */
+ public static function stripLinks($text) {
+ return preg_replace('|<a\s+[^>]+>|im', '', preg_replace('|<\/a>|im', '', $text));
+ }
+
+/**
+ * Truncates text.
+ *
+ * Cuts a string to the length of $length and replaces the last characters
+ * with the ending if the text is longer than length.
+ *
+ * ### Options:
+ *
+ * - `ending` Will be used as Ending and appended to the trimmed string
+ * - `exact` If false, $text will not be cut mid-word
+ * - `html` If true, HTML tags would be handled correctly
+ *
+ * @param string $text String to truncate.
+ * @param integer $length Length of returned string, including ellipsis.
+ * @param array $options An array of html attributes and options.
+ * @return string Trimmed string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::truncate
+ */
+ public static function truncate($text, $length = 100, $options = array()) {
+ $default = array(
+ 'ending' => '...', 'exact' => true, 'html' => false
+ );
+ $options = array_merge($default, $options);
+ extract($options);
+
+ if (!function_exists('mb_strlen')) {
+ class_exists('Multibyte');
+ }
+
+ if ($html) {
+ if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
+ return $text;
+ }
+ $totalLength = mb_strlen(strip_tags($ending));
+ $openTags = array();
+ $truncate = '';
+
+ preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
+ foreach ($tags as $tag) {
+ if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
+ if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {
+ array_unshift($openTags, $tag[2]);
+ } elseif (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
+ $pos = array_search($closeTag[1], $openTags);
+ if ($pos !== false) {
+ array_splice($openTags, $pos, 1);
+ }
+ }
+ }
+ $truncate .= $tag[1];
+
+ $contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
+ if ($contentLength + $totalLength > $length) {
+ $left = $length - $totalLength;
+ $entitiesLength = 0;
+ if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
+ foreach ($entities[0] as $entity) {
+ if ($entity[1] + 1 - $entitiesLength <= $left) {
+ $left--;
+ $entitiesLength += mb_strlen($entity[0]);
+ } else {
+ break;
+ }
+ }
+ }
+
+ $truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
+ break;
+ } else {
+ $truncate .= $tag[3];
+ $totalLength += $contentLength;
+ }
+ if ($totalLength >= $length) {
+ break;
+ }
+ }
+ } else {
+ if (mb_strlen($text) <= $length) {
+ return $text;
+ } else {
+ $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
+ }
+ }
+ if (!$exact) {
+ $spacepos = mb_strrpos($truncate, ' ');
+ if ($html) {
+ $truncateCheck = mb_substr($truncate, 0, $spacepos);
+ $lastOpenTag = mb_strrpos($truncateCheck, '<');
+ $lastCloseTag = mb_strrpos($truncateCheck, '>');
+ if ($lastOpenTag > $lastCloseTag) {
+ preg_match_all('/<[\w]+[^>]*>/s', $truncate, $lastTagMatches);
+ $lastTag = array_pop($lastTagMatches[0]);
+ $spacepos = mb_strrpos($truncate, $lastTag) + mb_strlen($lastTag);
+ }
+ $bits = mb_substr($truncate, $spacepos);
+ preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
+ if (!empty($droppedTags)) {
+ if (!empty($openTags)) {
+ foreach ($droppedTags as $closingTag) {
+ if (!in_array($closingTag[1], $openTags)) {
+ array_unshift($openTags, $closingTag[1]);
+ }
+ }
+ } else {
+ foreach ($droppedTags as $closingTag) {
+ array_push($openTags, $closingTag[1]);
+ }
+ }
+ }
+ }
+ $truncate = mb_substr($truncate, 0, $spacepos);
+ }
+ $truncate .= $ending;
+
+ if ($html) {
+ foreach ($openTags as $tag) {
+ $truncate .= '</' . $tag . '>';
+ }
+ }
+
+ return $truncate;
+ }
+
+/**
+ * Extracts an excerpt from the text surrounding the phrase with a number of characters on each side
+ * determined by radius.
+ *
+ * @param string $text String to search the phrase in
+ * @param string $phrase Phrase that will be searched for
+ * @param integer $radius The amount of characters that will be returned on each side of the founded phrase
+ * @param string $ending Ending that will be appended
+ * @return string Modified string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::excerpt
+ */
+ public static function excerpt($text, $phrase, $radius = 100, $ending = '...') {
+ if (empty($text) || empty($phrase)) {
+ return self::truncate($text, $radius * 2, array('ending' => $ending));
+ }
+
+ $append = $prepend = $ending;
+
+ $phraseLen = mb_strlen($phrase);
+ $textLen = mb_strlen($text);
+
+ $pos = mb_strpos(mb_strtolower($text), mb_strtolower($phrase));
+ if ($pos === false) {
+ return mb_substr($text, 0, $radius) . $ending;
+ }
+
+ $startPos = $pos - $radius;
+ if ($startPos <= 0) {
+ $startPos = 0;
+ $prepend = '';
+ }
+
+ $endPos = $pos + $phraseLen + $radius;
+ if ($endPos >= $textLen) {
+ $endPos = $textLen;
+ $append = '';
+ }
+
+ $excerpt = mb_substr($text, $startPos, $endPos - $startPos);
+ $excerpt = $prepend . $excerpt . $append;
+
+ return $excerpt;
+ }
+
+/**
+ * Creates a comma separated list where the last two items are joined with 'and', forming natural English
+ *
+ * @param array $list The list to be joined
+ * @param string $and The word used to join the last and second last items together with. Defaults to 'and'
+ * @param string $separator The separator used to join all the other items together. Defaults to ', '
+ * @return string The glued together string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
+ */
+ public static function toList($list, $and = 'and', $separator = ', ') {
+ if (count($list) > 1) {
+ return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list);
+ } else {
+ return array_pop($list);
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Validation.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Validation.php
new file mode 100644
index 0000000..d709732
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Validation.php
@@ -0,0 +1,937 @@
+<?php
+/**
+ * Validation Class. Used for validation of model data
+ *
+ * PHP Version 5.x
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP(tm) v 1.2.0.3830
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Multibyte', 'I18n');
+App::uses('File', 'Utility');
+// Load multibyte if the extension is missing.
+if (!function_exists('mb_strlen')) {
+ class_exists('Multibyte');
+}
+
+/**
+ * Offers different validation methods.
+ *
+ * @package Cake.Utility
+ * @since CakePHP v 1.2.0.3830
+ */
+class Validation {
+
+/**
+ * Some complex patterns needed in multiple places
+ *
+ * @var array
+ */
+ protected static $_pattern = array(
+ 'hostname' => '(?:[a-z0-9][-a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel)'
+ );
+
+/**
+ * Holds an array of errors messages set in this class.
+ * These are used for debugging purposes
+ *
+ * @var array
+ */
+ public static $errors = array();
+
+/**
+ * Checks that a string contains something other than whitespace
+ *
+ * Returns true if string contains something other than whitespace
+ *
+ * $check can be passed as an array:
+ * array('check' => 'valueToCheck');
+ *
+ * @param string|array $check Value to check
+ * @return boolean Success
+ */
+ public static function notEmpty($check) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+
+ if (empty($check) && $check != '0') {
+ return false;
+ }
+ return self::_check($check, '/[^\s]+/m');
+ }
+
+/**
+ * Checks that a string contains only integer or letters
+ *
+ * Returns true if string contains only integer or letters
+ *
+ * $check can be passed as an array:
+ * array('check' => 'valueToCheck');
+ *
+ * @param string|array $check Value to check
+ * @return boolean Success
+ */
+ public static function alphaNumeric($check) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+
+ if (empty($check) && $check != '0') {
+ return false;
+ }
+ return self::_check($check, '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/mu');
+ }
+
+/**
+ * Checks that a string length is within s specified range.
+ * Spaces are included in the character count.
+ * Returns true is string matches value min, max, or between min and max,
+ *
+ * @param string $check Value to check for length
+ * @param integer $min Minimum value in range (inclusive)
+ * @param integer $max Maximum value in range (inclusive)
+ * @return boolean Success
+ */
+ public static function between($check, $min, $max) {
+ $length = mb_strlen($check);
+ return ($length >= $min && $length <= $max);
+ }
+
+/**
+ * Returns true if field is left blank -OR- only whitespace characters are present in it's value
+ * Whitespace characters include Space, Tab, Carriage Return, Newline
+ *
+ * $check can be passed as an array:
+ * array('check' => 'valueToCheck');
+ *
+ * @param string|array $check Value to check
+ * @return boolean Success
+ */
+ public static function blank($check) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+ return !self::_check($check, '/[^\\s]/');
+ }
+
+/**
+ * Validation of credit card numbers.
+ * Returns true if $check is in the proper credit card format.
+ *
+ * @param string|array $check credit card number to validate
+ * @param string|array $type 'all' may be passed as a sting, defaults to fast which checks format of most major credit cards
+ * if an array is used only the values of the array are checked.
+ * Example: array('amex', 'bankcard', 'maestro')
+ * @param boolean $deep set to true this will check the Luhn algorithm of the credit card.
+ * @param string $regex A custom regex can also be passed, this will be used instead of the defined regex values
+ * @return boolean Success
+ * @see Validation::luhn()
+ */
+ public static function cc($check, $type = 'fast', $deep = false, $regex = null) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+
+ $check = str_replace(array('-', ' '), '', $check);
+ if (mb_strlen($check) < 13) {
+ return false;
+ }
+
+ if (!is_null($regex)) {
+ if (self::_check($check, $regex)) {
+ return self::luhn($check, $deep);
+ }
+ }
+ $cards = array(
+ 'all' => array(
+ 'amex' => '/^3[4|7]\\d{13}$/',
+ 'bankcard' => '/^56(10\\d\\d|022[1-5])\\d{10}$/',
+ 'diners' => '/^(?:3(0[0-5]|[68]\\d)\\d{11})|(?:5[1-5]\\d{14})$/',
+ 'disc' => '/^(?:6011|650\\d)\\d{12}$/',
+ 'electron' => '/^(?:417500|4917\\d{2}|4913\\d{2})\\d{10}$/',
+ 'enroute' => '/^2(?:014|149)\\d{11}$/',
+ 'jcb' => '/^(3\\d{4}|2100|1800)\\d{11}$/',
+ 'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/',
+ 'mc' => '/^5[1-5]\\d{14}$/',
+ 'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/',
+ 'switch' => '/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\\d{10}(\\d{2,3})?)|(?:564182\\d{10}(\\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\\d{10}(\\d{2,3})?)$/',
+ 'visa' => '/^4\\d{12}(\\d{3})?$/',
+ 'voyager' => '/^8699[0-9]{11}$/'
+ ),
+ 'fast' => '/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/'
+ );
+
+ if (is_array($type)) {
+ foreach ($type as $value) {
+ $regex = $cards['all'][strtolower($value)];
+
+ if (self::_check($check, $regex)) {
+ return self::luhn($check, $deep);
+ }
+ }
+ } elseif ($type == 'all') {
+ foreach ($cards['all'] as $value) {
+ $regex = $value;
+
+ if (self::_check($check, $regex)) {
+ return self::luhn($check, $deep);
+ }
+ }
+ } else {
+ $regex = $cards['fast'];
+
+ if (self::_check($check, $regex)) {
+ return self::luhn($check, $deep);
+ }
+ }
+ return false;
+ }
+
+/**
+ * Used to compare 2 numeric values.
+ *
+ * @param string|array $check1 if string is passed for a string must also be passed for $check2
+ * used as an array it must be passed as array('check1' => value, 'operator' => 'value', 'check2' -> value)
+ * @param string $operator Can be either a word or operand
+ * is greater >, is less <, greater or equal >=
+ * less or equal <=, is less <, equal to ==, not equal !=
+ * @param integer $check2 only needed if $check1 is a string
+ * @return boolean Success
+ */
+ public static function comparison($check1, $operator = null, $check2 = null) {
+ if (is_array($check1)) {
+ extract($check1, EXTR_OVERWRITE);
+ }
+ $operator = str_replace(array(' ', "\t", "\n", "\r", "\0", "\x0B"), '', strtolower($operator));
+
+ switch ($operator) {
+ case 'isgreater':
+ case '>':
+ if ($check1 > $check2) {
+ return true;
+ }
+ break;
+ case 'isless':
+ case '<':
+ if ($check1 < $check2) {
+ return true;
+ }
+ break;
+ case 'greaterorequal':
+ case '>=':
+ if ($check1 >= $check2) {
+ return true;
+ }
+ break;
+ case 'lessorequal':
+ case '<=':
+ if ($check1 <= $check2) {
+ return true;
+ }
+ break;
+ case 'equalto':
+ case '==':
+ if ($check1 == $check2) {
+ return true;
+ }
+ break;
+ case 'notequal':
+ case '!=':
+ if ($check1 != $check2) {
+ return true;
+ }
+ break;
+ default:
+ self::$errors[] = __d('cake_dev', 'You must define the $operator parameter for Validation::comparison()');
+ break;
+ }
+ return false;
+ }
+
+/**
+ * Used when a custom regular expression is needed.
+ *
+ * @param string|array $check When used as a string, $regex must also be a valid regular expression.
+ * As and array: array('check' => value, 'regex' => 'valid regular expression')
+ * @param string $regex If $check is passed as a string, $regex must also be set to valid regular expression
+ * @return boolean Success
+ */
+ public static function custom($check, $regex = null) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+ if ($regex === null) {
+ self::$errors[] = __d('cake_dev', 'You must define a regular expression for Validation::custom()');
+ return false;
+ }
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Date validation, determines if the string passed is a valid date.
+ * keys that expect full month, day and year will validate leap years
+ *
+ * @param string $check a valid date string
+ * @param string|array $format Use a string or an array of the keys below. Arrays should be passed as array('dmy', 'mdy', etc)
+ * Keys: dmy 27-12-2006 or 27-12-06 separators can be a space, period, dash, forward slash
+ * mdy 12-27-2006 or 12-27-06 separators can be a space, period, dash, forward slash
+ * ymd 2006-12-27 or 06-12-27 separators can be a space, period, dash, forward slash
+ * dMy 27 December 2006 or 27 Dec 2006
+ * Mdy December 27, 2006 or Dec 27, 2006 comma is optional
+ * My December 2006 or Dec 2006
+ * my 12/2006 separators can be a space, period, dash, forward slash
+ * @param string $regex If a custom regular expression is used this is the only validation that will occur.
+ * @return boolean Success
+ */
+ public static function date($check, $format = 'ymd', $regex = null) {
+ if (!is_null($regex)) {
+ return self::_check($check, $regex);
+ }
+
+ $regex['dmy'] = '%^(?:(?:31(\\/|-|\\.|\\x20)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.|\\x20)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.|\\x20)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.|\\x20)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
+ $regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])(\\/|-|\\.|\\x20)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.|\\x20)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.|\\x20)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
+ $regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\\/|-|\\.|\\x20)(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})(\\/|-|\\.|\\x20)(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%';
+ $regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/';
+ $regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep)(tember)?|(Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/';
+ $regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)[ /]((1[6-9]|[2-9]\\d)\\d{2})$%';
+ $regex['my'] = '%^(((0[123456789]|10|11|12)([- /.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$%';
+
+ $format = (is_array($format)) ? array_values($format) : array($format);
+ foreach ($format as $key) {
+ if (self::_check($check, $regex[$key]) === true) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Validates a datetime value
+ * All values matching the "date" core validation rule, and the "time" one will be valid
+ *
+ * @param array $check Value to check
+ * @param string|array $dateFormat Format of the date part
+ * Use a string or an array of the keys below. Arrays should be passed as array('dmy', 'mdy', etc)
+ * ## Keys:
+ *
+ * - dmy 27-12-2006 or 27-12-06 separators can be a space, period, dash, forward slash
+ * - mdy 12-27-2006 or 12-27-06 separators can be a space, period, dash, forward slash
+ * - ymd 2006-12-27 or 06-12-27 separators can be a space, period, dash, forward slash
+ * - dMy 27 December 2006 or 27 Dec 2006
+ * - Mdy December 27, 2006 or Dec 27, 2006 comma is optional
+ * - My December 2006 or Dec 2006
+ * - my 12/2006 separators can be a space, period, dash, forward slash
+ * @param string $regex Regex for the date part. If a custom regular expression is used this is the only validation that will occur.
+ * @return boolean True if the value is valid, false otherwise
+ * @see Validation::date
+ * @see Validation::time
+ */
+ public static function datetime($check, $dateFormat = 'ymd', $regex = null) {
+ $valid = false;
+ $parts = explode(' ', $check);
+ if (!empty($parts) && count($parts) > 1) {
+ $time = array_pop($parts);
+ $date = implode(' ', $parts);
+ $valid = self::date($date, $dateFormat, $regex) && self::time($time);
+ }
+ return $valid;
+ }
+
+/**
+ * Time validation, determines if the string passed is a valid time.
+ * Validates time as 24hr (HH:MM) or am/pm ([H]H:MM[a|p]m)
+ * Does not allow/validate seconds.
+ *
+ * @param string $check a valid time string
+ * @return boolean Success
+ */
+ public static function time($check) {
+ return self::_check($check, '%^((0?[1-9]|1[012])(:[0-5]\d){0,2} ?([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%');
+ }
+
+/**
+ * Boolean validation, determines if value passed is a boolean integer or true/false.
+ *
+ * @param string $check a valid boolean
+ * @return boolean Success
+ */
+ public static function boolean($check) {
+ $booleanList = array(0, 1, '0', '1', true, false);
+ return in_array($check, $booleanList, true);
+ }
+
+/**
+ * Checks that a value is a valid decimal. If $places is null, the $check is allowed to be a scientific float
+ * If no decimal point is found a false will be returned. Both the sign and exponent are optional.
+ *
+ * @param integer $check The value the test for decimal
+ * @param integer $places if set $check value must have exactly $places after the decimal point
+ * @param string $regex If a custom regular expression is used this is the only validation that will occur.
+ * @return boolean Success
+ */
+ public static function decimal($check, $places = null, $regex = null) {
+ if (is_null($regex)) {
+ if (is_null($places)) {
+ $regex = '/^[-+]?[0-9]*(\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?)?$/';
+ } else {
+ $regex = '/^[-+]?[0-9]*(\\.{1}[0-9]{' . $places . '})?$/';
+ }
+ }
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Validates for an email address.
+ *
+ * Only uses getmxrr() checking for deep validation if PHP 5.3.0+ is used, or
+ * any PHP version on a non-windows distribution
+ *
+ * @param string $check Value to check
+ * @param boolean $deep Perform a deeper validation (if true), by also checking availability of host
+ * @param string $regex Regex to use (if none it will use built in regex)
+ * @return boolean Success
+ */
+ public static function email($check, $deep = false, $regex = null) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+
+ if (is_null($regex)) {
+ $regex = '/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@' . self::$_pattern['hostname'] . '$/i';
+ }
+ $return = self::_check($check, $regex);
+ if ($deep === false || $deep === null) {
+ return $return;
+ }
+
+ if ($return === true && preg_match('/@(' . self::$_pattern['hostname'] . ')$/i', $check, $regs)) {
+ if (function_exists('getmxrr') && getmxrr($regs[1], $mxhosts)) {
+ return true;
+ }
+ if (function_exists('checkdnsrr') && checkdnsrr($regs[1], 'MX')) {
+ return true;
+ }
+ return is_array(gethostbynamel($regs[1]));
+ }
+ return false;
+ }
+
+/**
+ * Check that value is exactly $comparedTo.
+ *
+ * @param mixed $check Value to check
+ * @param mixed $comparedTo Value to compare
+ * @return boolean Success
+ */
+ public static function equalTo($check, $comparedTo) {
+ return ($check === $comparedTo);
+ }
+
+/**
+ * Check that value has a valid file extension.
+ *
+ * @param string|array $check Value to check
+ * @param array $extensions file extensions to allow. By default extensions are 'gif', 'jpeg', 'png', 'jpg'
+ * @return boolean Success
+ */
+ public static function extension($check, $extensions = array('gif', 'jpeg', 'png', 'jpg')) {
+ if (is_array($check)) {
+ return self::extension(array_shift($check), $extensions);
+ }
+ $extension = strtolower(pathinfo($check, PATHINFO_EXTENSION));
+ foreach ($extensions as $value) {
+ if ($extension === strtolower($value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Validation of an IP address.
+ *
+ * @param string $check The string to test.
+ * @param string $type The IP Protocol version to validate against
+ * @return boolean Success
+ */
+ public static function ip($check, $type = 'both') {
+ $type = strtolower($type);
+ $flags = 0;
+ if ($type === 'ipv4') {
+ $flags = FILTER_FLAG_IPV4;
+ }
+ if ($type === 'ipv6') {
+ $flags = FILTER_FLAG_IPV6;
+ }
+ return (boolean)filter_var($check, FILTER_VALIDATE_IP, array('flags' => $flags));
+ }
+
+/**
+ * Checks whether the length of a string is greater or equal to a minimal length.
+ *
+ * @param string $check The string to test
+ * @param integer $min The minimal string length
+ * @return boolean Success
+ */
+ public static function minLength($check, $min) {
+ return mb_strlen($check) >= $min;
+ }
+
+/**
+ * Checks whether the length of a string is smaller or equal to a maximal length..
+ *
+ * @param string $check The string to test
+ * @param integer $max The maximal string length
+ * @return boolean Success
+ */
+ public static function maxLength($check, $max) {
+ return mb_strlen($check) <= $max;
+ }
+
+/**
+ * Checks that a value is a monetary amount.
+ *
+ * @param string $check Value to check
+ * @param string $symbolPosition Where symbol is located (left/right)
+ * @return boolean Success
+ */
+ public static function money($check, $symbolPosition = 'left') {
+ $money = '(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?';
+ if ($symbolPosition == 'right') {
+ $regex = '/^' . $money . '(?<!\x{00a2})\p{Sc}?$/u';
+ } else {
+ $regex = '/^(?!\x{00a2})\p{Sc}?' . $money . '$/u';
+ }
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Validate a multiple select.
+ *
+ * Valid Options
+ *
+ * - in => provide a list of choices that selections must be made from
+ * - max => maximum number of non-zero choices that can be made
+ * - min => minimum number of non-zero choices that can be made
+ *
+ * @param array $check Value to check
+ * @param array $options Options for the check.
+ * @param boolean $strict Defaults to true, set to false to disable strict type check
+ * @return boolean Success
+ */
+ public static function multiple($check, $options = array(), $strict = true) {
+ $defaults = array('in' => null, 'max' => null, 'min' => null);
+ $options = array_merge($defaults, $options);
+ $check = array_filter((array)$check);
+ if (empty($check)) {
+ return false;
+ }
+ if ($options['max'] && count($check) > $options['max']) {
+ return false;
+ }
+ if ($options['min'] && count($check) < $options['min']) {
+ return false;
+ }
+ if ($options['in'] && is_array($options['in'])) {
+ foreach ($check as $val) {
+ if (!in_array($val, $options['in'], $strict)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+/**
+ * Checks if a value is numeric.
+ *
+ * @param string $check Value to check
+ * @return boolean Success
+ */
+ public static function numeric($check) {
+ return is_numeric($check);
+ }
+
+/**
+ * Checks if a value is a natural number.
+ *
+ * @param string $check Value to check
+ * @param boolean $allowZero Set true to allow zero, defaults to false
+ * @return boolean Success
+ * @see http://en.wikipedia.org/wiki/Natural_number
+ */
+ public static function naturalNumber($check, $allowZero = false) {
+ $regex = $allowZero ? '/^(?:0|[1-9][0-9]*)$/' : '/^[1-9][0-9]*$/';
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Check that a value is a valid phone number.
+ *
+ * @param string|array $check Value to check (string or array)
+ * @param string $regex Regular expression to use
+ * @param string $country Country code (defaults to 'all')
+ * @return boolean Success
+ */
+ public static function phone($check, $regex = null, $country = 'all') {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+
+ if (is_null($regex)) {
+ switch ($country) {
+ case 'us':
+ case 'all':
+ case 'can':
+ // includes all NANPA members.
+ // see http://en.wikipedia.org/wiki/North_American_Numbering_Plan#List_of_NANPA_countries_and_territories
+ $regex = '/^(?:\+?1)?[-. ]?\\(?[2-9][0-8][0-9]\\)?[-. ]?[2-9][0-9]{2}[-. ]?[0-9]{4}$/';
+ break;
+ }
+ }
+ if (empty($regex)) {
+ return self::_pass('phone', $check, $country);
+ }
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Checks that a given value is a valid postal code.
+ *
+ * @param string|array $check Value to check
+ * @param string $regex Regular expression to use
+ * @param string $country Country to use for formatting
+ * @return boolean Success
+ */
+ public static function postal($check, $regex = null, $country = 'us') {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+
+ if (is_null($regex)) {
+ switch ($country) {
+ case 'uk':
+ $regex = '/\\A\\b[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2}\\b\\z/i';
+ break;
+ case 'ca':
+ $regex = '/\\A\\b[ABCEGHJKLMNPRSTVXY][0-9][A-Z] [0-9][A-Z][0-9]\\b\\z/i';
+ break;
+ case 'it':
+ case 'de':
+ $regex = '/^[0-9]{5}$/i';
+ break;
+ case 'be':
+ $regex = '/^[1-9]{1}[0-9]{3}$/i';
+ break;
+ case 'us':
+ $regex = '/\\A\\b[0-9]{5}(?:-[0-9]{4})?\\b\\z/i';
+ break;
+ }
+ }
+ if (empty($regex)) {
+ return self::_pass('postal', $check, $country);
+ }
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Validate that a number is in specified range.
+ * if $lower and $upper are not set, will return true if
+ * $check is a legal finite on this platform
+ *
+ * @param string $check Value to check
+ * @param integer $lower Lower limit
+ * @param integer $upper Upper limit
+ * @return boolean Success
+ */
+ public static function range($check, $lower = null, $upper = null) {
+ if (!is_numeric($check)) {
+ return false;
+ }
+ if (isset($lower) && isset($upper)) {
+ return ($check > $lower && $check < $upper);
+ }
+ return is_finite($check);
+ }
+
+/**
+ * Checks that a value is a valid Social Security Number.
+ *
+ * @param string|array $check Value to check
+ * @param string $regex Regular expression to use
+ * @param string $country Country
+ * @return boolean Success
+ */
+ public static function ssn($check, $regex = null, $country = null) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+
+ if (is_null($regex)) {
+ switch ($country) {
+ case 'dk':
+ $regex = '/\\A\\b[0-9]{6}-[0-9]{4}\\b\\z/i';
+ break;
+ case 'nl':
+ $regex = '/\\A\\b[0-9]{9}\\b\\z/i';
+ break;
+ case 'us':
+ $regex = '/\\A\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b\\z/i';
+ break;
+ }
+ }
+ if (empty($regex)) {
+ return self::_pass('ssn', $check, $country);
+ }
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Checks that a value is a valid URL according to http://www.w3.org/Addressing/URL/url-spec.txt
+ *
+ * The regex checks for the following component parts:
+ *
+ * - a valid, optional, scheme
+ * - a valid ip address OR
+ * a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt
+ * with an optional port number
+ * - an optional valid path
+ * - an optional query string (get parameters)
+ * - an optional fragment (anchor tag)
+ *
+ * @param string $check Value to check
+ * @param boolean $strict Require URL to be prefixed by a valid scheme (one of http(s)/ftp(s)/file/news/gopher)
+ * @return boolean Success
+ */
+ public static function url($check, $strict = false) {
+ self::_populateIp();
+ $validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~[]') . '\/0-9a-z\p{L}\p{N}]|(%[0-9a-f]{2}))';
+ $regex = '/^(?:(?:https?|ftps?|sftp|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') .
+ '(?:' . self::$_pattern['IPv4'] . '|\[' . self::$_pattern['IPv6'] . '\]|' . self::$_pattern['hostname'] . ')(?::[1-9][0-9]{0,4})?' .
+ '(?:\/?|\/' . $validChars . '*)?' .
+ '(?:\?' . $validChars . '*)?' .
+ '(?:#' . $validChars . '*)?$/iu';
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Checks if a value is in a given list.
+ *
+ * @param string $check Value to check
+ * @param array $list List to check against
+ * @param boolean $strict Defaults to true, set to false to disable strict type check
+ * @return boolean Success
+ */
+ public static function inList($check, $list, $strict = true) {
+ return in_array($check, $list, $strict);
+ }
+
+/**
+ * Runs an user-defined validation.
+ *
+ * @param string|array $check value that will be validated in user-defined methods.
+ * @param object $object class that holds validation method
+ * @param string $method class method name for validation to run
+ * @param array $args arguments to send to method
+ * @return mixed user-defined class class method returns
+ */
+ public static function userDefined($check, $object, $method, $args = null) {
+ return call_user_func_array(array($object, $method), array($check, $args));
+ }
+
+/**
+ * Checks that a value is a valid uuid - http://tools.ietf.org/html/rfc4122
+ *
+ * @param string $check Value to check
+ * @return boolean Success
+ */
+ public static function uuid($check) {
+ $regex = '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i';
+ return self::_check($check, $regex);
+ }
+
+/**
+ * Attempts to pass unhandled Validation locales to a class starting with $classPrefix
+ * and ending with Validation. For example $classPrefix = 'nl', the class would be
+ * `NlValidation`.
+ *
+ * @param string $method The method to call on the other class.
+ * @param mixed $check The value to check or an array of parameters for the method to be called.
+ * @param string $classPrefix The prefix for the class to do the validation.
+ * @return mixed Return of Passed method, false on failure
+ */
+ protected static function _pass($method, $check, $classPrefix) {
+ $className = ucwords($classPrefix) . 'Validation';
+ if (!class_exists($className)) {
+ trigger_error(__d('cake_dev', 'Could not find %s class, unable to complete validation.', $className), E_USER_WARNING);
+ return false;
+ }
+ if (!method_exists($className, $method)) {
+ trigger_error(__d('cake_dev', 'Method %s does not exist on %s unable to complete validation.', $method, $className), E_USER_WARNING);
+ return false;
+ }
+ $check = (array)$check;
+ return call_user_func_array(array($className, $method), $check);
+ }
+
+/**
+ * Runs a regular expression match.
+ *
+ * @param string $check Value to check against the $regex expression
+ * @param string $regex Regular expression
+ * @return boolean Success of match
+ */
+ protected static function _check($check, $regex) {
+ if (preg_match($regex, $check)) {
+ self::$errors[] = false;
+ return true;
+ } else {
+ self::$errors[] = true;
+ return false;
+ }
+ }
+
+/**
+ * Get the values to use when value sent to validation method is
+ * an array.
+ *
+ * @param array $params Parameters sent to validation method
+ * @return void
+ */
+ protected static function _defaults($params) {
+ self::_reset();
+ $defaults = array(
+ 'check' => null,
+ 'regex' => null,
+ 'country' => null,
+ 'deep' => false,
+ 'type' => null
+ );
+ $params = array_merge($defaults, $params);
+ if ($params['country'] !== null) {
+ $params['country'] = mb_strtolower($params['country']);
+ }
+ return $params;
+ }
+
+/**
+ * Luhn algorithm
+ *
+ * @param string|array $check
+ * @param boolean $deep
+ * @return boolean Success
+ * @see http://en.wikipedia.org/wiki/Luhn_algorithm
+ */
+ public static function luhn($check, $deep = false) {
+ if (is_array($check)) {
+ extract(self::_defaults($check));
+ }
+ if ($deep !== true) {
+ return true;
+ }
+ if ($check == 0) {
+ return false;
+ }
+ $sum = 0;
+ $length = strlen($check);
+
+ for ($position = 1 - ($length % 2); $position < $length; $position += 2) {
+ $sum += $check[$position];
+ }
+
+ for ($position = ($length % 2); $position < $length; $position += 2) {
+ $number = $check[$position] * 2;
+ $sum += ($number < 10) ? $number : $number - 9;
+ }
+
+ return ($sum % 10 == 0);
+ }
+
+/**
+ * Checks the mime type of a file
+ *
+ * @param string|array $check
+ * @param array $mimeTypes to check for
+ * @return boolean Success
+ * @throws CakeException when mime type can not be determined.
+ */
+ public static function mimeType($check, $mimeTypes = array()) {
+ if (is_array($check) && isset($check['tmp_name'])) {
+ $check = $check['tmp_name'];
+ }
+
+ $File = new File($check);
+ $mime = $File->mime();
+
+ if ($mime === false) {
+ throw new CakeException(__d('cake_dev', 'Can not determine the mimetype.'));
+ }
+ return in_array($mime, $mimeTypes);
+ }
+
+/**
+ * Checking for upload errors
+ *
+ * @param string|array $check
+ * @retrun boolean
+ * @see http://www.php.net/manual/en/features.file-upload.errors.php
+ */
+ public static function uploadError($check) {
+ if (is_array($check) && isset($check['error'])) {
+ $check = $check['error'];
+ }
+
+ return $check === UPLOAD_ERR_OK;
+ }
+
+/**
+ * Lazily populate the IP address patterns used for validations
+ *
+ * @return void
+ */
+ protected static function _populateIp() {
+ if (!isset(self::$_pattern['IPv6'])) {
+ $pattern = '((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}';
+ $pattern .= '(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})';
+ $pattern .= '|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})';
+ $pattern .= '(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)';
+ $pattern .= '{4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))';
+ $pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}';
+ $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|';
+ $pattern .= '((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}';
+ $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))';
+ $pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4})';
+ $pattern .= '{0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)';
+ $pattern .= '|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]';
+ $pattern .= '\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4})';
+ $pattern .= '{1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?';
+
+ self::$_pattern['IPv6'] = $pattern;
+ }
+ if (!isset(self::$_pattern['IPv4'])) {
+ $pattern = '(?:(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])';
+ self::$_pattern['IPv4'] = $pattern;
+ }
+ }
+
+/**
+ * Reset internal variables for another validation run.
+ *
+ * @return void
+ */
+ protected static function _reset() {
+ self::$errors = array();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Xml.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Xml.php
new file mode 100644
index 0000000..f8662b2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Xml.php
@@ -0,0 +1,370 @@
+<?php
+/**
+ * XML handling for Cake.
+ *
+ * The methods in these classes enable the datasources that use XML to work.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.Utility
+ * @since CakePHP v .0.10.3.1400
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * XML handling for Cake.
+ *
+ * The methods in these classes enable the datasources that use XML to work.
+ *
+ * @package Cake.Utility
+ */
+class Xml {
+
+/**
+ * Initialize SimpleXMLElement or DOMDocument from a given XML string, file path, URL or array.
+ *
+ * ### Usage:
+ *
+ * Building XML from a string:
+ *
+ * `$xml = Xml::build('<example>text</example>');`
+ *
+ * Building XML from string (output DOMDocument):
+ *
+ * `$xml = Xml::build('<example>text</example>', array('return' => 'domdocument'));`
+ *
+ * Building XML from a file path:
+ *
+ * `$xml = Xml::build('/path/to/an/xml/file.xml');`
+ *
+ * Building from a remote URL:
+ *
+ * `$xml = Xml::build('http://example.com/example.xml');`
+ *
+ * Building from an array:
+ *
+ * {{{
+ * $value = array(
+ * 'tags' => array(
+ * 'tag' => array(
+ * array(
+ * 'id' => '1',
+ * 'name' => 'defect'
+ * ),
+ * array(
+ * 'id' => '2',
+ * 'name' => 'enhancement'
+ * )
+ * )
+ * )
+ * );
+ * $xml = Xml::build($value);
+ * }}}
+ *
+ * When building XML from an array ensure that there is only one top level element.
+ *
+ * ### Options
+ *
+ * - `return` Can be 'simplexml' to return object of SimpleXMLElement or 'domdocument' to return DOMDocument.
+ * - `loadEntities` Defaults to false. Set to true to enable loading of `<!ENTITY` definitions. This
+ * is disabled by default for security reasons.
+ * - If using array as input, you can pass `options` from Xml::fromArray.
+ *
+ * @param string|array $input XML string, a path to a file, an URL or an array
+ * @param array $options The options to use
+ * @return SimpleXMLElement|DOMDocument SimpleXMLElement or DOMDocument
+ * @throws XmlException
+ */
+ public static function build($input, $options = array()) {
+ if (!is_array($options)) {
+ $options = array('return' => (string)$options);
+ }
+ $defaults = array(
+ 'return' => 'simplexml',
+ 'loadEntities' => false,
+ );
+ $options = array_merge($defaults, $options);
+
+ if (is_array($input) || is_object($input)) {
+ return self::fromArray((array)$input, $options);
+ } elseif (strpos($input, '<') !== false) {
+ return self::_loadXml($input, $options);
+ } elseif (file_exists($input) || strpos($input, 'http://') === 0 || strpos($input, 'https://') === 0) {
+ $input = file_get_contents($input);
+ return self::_loadXml($input, $options);
+ } elseif (!is_string($input)) {
+ throw new XmlException(__d('cake_dev', 'Invalid input.'));
+ }
+ throw new XmlException(__d('cake_dev', 'XML cannot be read.'));
+ }
+
+/**
+ * Parse the input data and create either a SimpleXmlElement object or a DOMDocument.
+ *
+ * @param string $input The input to load.
+ * @param array $options The options to use. See Xml::build()
+ * @return SimpleXmlElement|DOMDocument.
+ */
+ protected static function _loadXml($input, $options) {
+ $hasDisable = function_exists('libxml_disable_entity_loader');
+ $internalErrors = libxml_use_internal_errors(true);
+ if ($hasDisable && !$options['loadEntities']) {
+ libxml_disable_entity_loader(true);
+ }
+ if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
+ $xml = new SimpleXMLElement($input, LIBXML_NOCDATA);
+ } else {
+ $xml = new DOMDocument();
+ $xml->loadXML($input);
+ }
+ if ($hasDisable && !$options['loadEntities']) {
+ libxml_disable_entity_loader(false);
+ }
+ libxml_use_internal_errors($internalErrors);
+ return $xml;
+ }
+
+/**
+ * Transform an array into a SimpleXMLElement
+ *
+ * ### Options
+ *
+ * - `format` If create childs ('tags') or attributes ('attribute').
+ * - `version` Version of XML document. Default is 1.0.
+ * - `encoding` Encoding of XML document. If null remove from XML header. Default is the some of application.
+ * - `return` If return object of SimpleXMLElement ('simplexml') or DOMDocument ('domdocument'). Default is SimpleXMLElement.
+ *
+ * Using the following data:
+ *
+ * {{{
+ * $value = array(
+ * 'root' => array(
+ * 'tag' => array(
+ * 'id' => 1,
+ * 'value' => 'defect',
+ * '@' => 'description'
+ * )
+ * )
+ * );
+ * }}}
+ *
+ * Calling `Xml::fromArray($value, 'tags');` Will generate:
+ *
+ * `<root><tag><id>1</id><value>defect</value>description</tag></root>`
+ *
+ * And calling `Xml::fromArray($value, 'attribute');` Will generate:
+ *
+ * `<root><tag id="1" value="defect">description</tag></root>`
+ *
+ * @param array $input Array with data
+ * @param array $options The options to use
+ * @return SimpleXMLElement|DOMDocument SimpleXMLElement or DOMDocument
+ * @throws XmlException
+ */
+ public static function fromArray($input, $options = array()) {
+ if (!is_array($input) || count($input) !== 1) {
+ throw new XmlException(__d('cake_dev', 'Invalid input.'));
+ }
+ $key = key($input);
+ if (is_integer($key)) {
+ throw new XmlException(__d('cake_dev', 'The key of input must be alphanumeric'));
+ }
+
+ if (!is_array($options)) {
+ $options = array('format' => (string)$options);
+ }
+ $defaults = array(
+ 'format' => 'tags',
+ 'version' => '1.0',
+ 'encoding' => Configure::read('App.encoding'),
+ 'return' => 'simplexml'
+ );
+ $options = array_merge($defaults, $options);
+
+ $dom = new DOMDocument($options['version'], $options['encoding']);
+ self::_fromArray($dom, $dom, $input, $options['format']);
+
+ $options['return'] = strtolower($options['return']);
+ if ($options['return'] === 'simplexml' || $options['return'] === 'simplexmlelement') {
+ return new SimpleXMLElement($dom->saveXML());
+ }
+ return $dom;
+ }
+
+/**
+ * Recursive method to create childs from array
+ *
+ * @param DOMDocument $dom Handler to DOMDocument
+ * @param DOMElement $node Handler to DOMElement (child)
+ * @param array $data Array of data to append to the $node.
+ * @param string $format Either 'attribute' or 'tags'. This determines where nested keys go.
+ * @return void
+ * @throws XmlException
+ */
+ protected static function _fromArray($dom, $node, &$data, $format) {
+ if (empty($data) || !is_array($data)) {
+ return;
+ }
+ foreach ($data as $key => $value) {
+ if (is_string($key)) {
+ if (!is_array($value)) {
+ if (is_bool($value)) {
+ $value = (int)$value;
+ } elseif ($value === null) {
+ $value = '';
+ }
+ $isNamespace = strpos($key, 'xmlns:');
+ if ($isNamespace !== false) {
+ $node->setAttributeNS('http://www.w3.org/2000/xmlns/', $key, $value);
+ continue;
+ }
+ if ($key[0] !== '@' && $format === 'tags') {
+ $child = null;
+ if (!is_numeric($value)) {
+ // Escape special characters
+ // http://www.w3.org/TR/REC-xml/#syntax
+ // https://bugs.php.net/bug.php?id=36795
+ $child = $dom->createElement($key, '');
+ $child->appendChild(new DOMText($value));
+ } else {
+ $child = $dom->createElement($key, $value);
+ }
+ $node->appendChild($child);
+ } else {
+ if ($key[0] === '@') {
+ $key = substr($key, 1);
+ }
+ $attribute = $dom->createAttribute($key);
+ $attribute->appendChild($dom->createTextNode($value));
+ $node->appendChild($attribute);
+ }
+ } else {
+ if ($key[0] === '@') {
+ throw new XmlException(__d('cake_dev', 'Invalid array'));
+ }
+ if (is_numeric(implode('', array_keys($value)))) { // List
+ foreach ($value as $item) {
+ $itemData = compact('dom', 'node', 'key', 'format');
+ $itemData['value'] = $item;
+ self::_createChild($itemData);
+ }
+ } else { // Struct
+ self::_createChild(compact('dom', 'node', 'key', 'value', 'format'));
+ }
+ }
+ } else {
+ throw new XmlException(__d('cake_dev', 'Invalid array'));
+ }
+ }
+ }
+
+/**
+ * Helper to _fromArray(). It will create childs of arrays
+ *
+ * @param array $data Array with informations to create childs
+ * @return void
+ */
+ protected static function _createChild($data) {
+ extract($data);
+ $childNS = $childValue = null;
+ if (is_array($value)) {
+ if (isset($value['@'])) {
+ $childValue = (string)$value['@'];
+ unset($value['@']);
+ }
+ if (isset($value['xmlns:'])) {
+ $childNS = $value['xmlns:'];
+ unset($value['xmlns:']);
+ }
+ } elseif (!empty($value) || $value === 0) {
+ $childValue = (string)$value;
+ }
+
+ if ($childValue) {
+ $child = $dom->createElement($key, $childValue);
+ } else {
+ $child = $dom->createElement($key);
+ }
+ if ($childNS) {
+ $child->setAttribute('xmlns', $childNS);
+ }
+
+ self::_fromArray($dom, $child, $value, $format);
+ $node->appendChild($child);
+ }
+
+/**
+ * Returns this XML structure as a array.
+ *
+ * @param SimpleXMLElement|DOMDocument|DOMNode $obj SimpleXMLElement, DOMDocument or DOMNode instance
+ * @return array Array representation of the XML structure.
+ * @throws XmlException
+ */
+ public static function toArray($obj) {
+ if ($obj instanceof DOMNode) {
+ $obj = simplexml_import_dom($obj);
+ }
+ if (!($obj instanceof SimpleXMLElement)) {
+ throw new XmlException(__d('cake_dev', 'The input is not instance of SimpleXMLElement, DOMDocument or DOMNode.'));
+ }
+ $result = array();
+ $namespaces = array_merge(array('' => ''), $obj->getNamespaces(true));
+ self::_toArray($obj, $result, '', array_keys($namespaces));
+ return $result;
+ }
+
+/**
+ * Recursive method to toArray
+ *
+ * @param SimpleXMLElement $xml SimpleXMLElement object
+ * @param array $parentData Parent array with data
+ * @param string $ns Namespace of current child
+ * @param array $namespaces List of namespaces in XML
+ * @return void
+ */
+ protected static function _toArray($xml, &$parentData, $ns, $namespaces) {
+ $data = array();
+
+ foreach ($namespaces as $namespace) {
+ foreach ($xml->attributes($namespace, true) as $key => $value) {
+ if (!empty($namespace)) {
+ $key = $namespace . ':' . $key;
+ }
+ $data['@' . $key] = (string)$value;
+ }
+
+ foreach ($xml->children($namespace, true) as $child) {
+ self::_toArray($child, $data, $namespace, $namespaces);
+ }
+ }
+
+ $asString = trim((string)$xml);
+ if (empty($data)) {
+ $data = $asString;
+ } elseif (!empty($asString)) {
+ $data['@'] = $asString;
+ }
+
+ if (!empty($ns)) {
+ $ns .= ':';
+ }
+ $name = $ns . $xml->getName();
+ if (isset($parentData[$name])) {
+ if (!is_array($parentData[$name]) || !isset($parentData[$name][0])) {
+ $parentData[$name] = array($parentData[$name]);
+ }
+ $parentData[$name][] = $data;
+ } else {
+ $parentData[$name] = $data;
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/VERSION.txt b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/VERSION.txt
new file mode 100644
index 0000000..3ec56db
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/VERSION.txt
@@ -0,0 +1,20 @@
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// +--------------------------------------------------------------------------------------------+ //
+// CakePHP Version
+//
+// Holds a static string representing the current version of CakePHP
+//
+// CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+// Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+//
+// Licensed under The MIT License
+// Redistributions of files must retain the above copyright notice.
+//
+// @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+// @link http://cakephp.org
+// @package cake.libs
+// @since CakePHP(tm) v 0.2.9
+// @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+// +--------------------------------------------------------------------------------------------+ //
+////////////////////////////////////////////////////////////////////////////////////////////////////
+2.2.1
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp
new file mode 100644
index 0000000..b744c16
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/exception_stack_trace.ctp
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Prints a stack trace for an exception
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Elements
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('Debugger', 'Utility');
+?>
+<h3>Stack Trace</h3>
+<ul class="cake-stack-trace">
+<?php foreach ($error->getTrace() as $i => $stack): ?>
+ <li><?php
+ $excerpt = $arguments = '';
+ $params = array();
+
+ if (isset($stack['file']) && isset($stack['line'])):
+ printf(
+ '<a href="#" onclick="traceToggle(event, \'file-excerpt-%s\')">%s line %s</a>',
+ $i,
+ Debugger::trimPath($stack['file']),
+ $stack['line']
+ );
+ $excerpt = sprintf('<div id="file-excerpt-%s" class="cake-code-dump" style="display:none;"><pre>', $i);
+ $excerpt .= implode("\n", Debugger::excerpt($stack['file'], $stack['line'] - 1, 2));
+ $excerpt .= '</pre></div> ';
+ else:
+ echo '<a href="#">[internal function]</a>';
+ endif;
+ echo ' &rarr; ';
+ if ($stack['function']):
+ $args = array();
+ if (!empty($stack['args'])):
+ foreach ((array)$stack['args'] as $arg):
+ $args[] = Debugger::getType($arg);
+ $params[] = Debugger::exportVar($arg, 2);
+ endforeach;
+ endif;
+
+ $called = isset($stack['class']) ? $stack['class'] . $stack['type'] . $stack['function'] : $stack['function'];
+
+ printf(
+ '<a href="#" onclick="traceToggle(event, \'trace-args-%s\')">%s(%s)</a> ',
+ $i,
+ $called,
+ implode(', ', $args)
+ );
+ $arguments = sprintf('<div id="trace-args-%s" class="cake-code-dump" style="display: none;"><pre>', $i);
+ $arguments .= implode("\n", $params);
+ $arguments .= '</pre></div>';
+ endif;
+ echo $excerpt;
+ echo $arguments;
+ ?></li>
+<?php endforeach; ?>
+</ul>
+<script type="text/javascript">
+function traceToggle(event, id) {
+ var el = document.getElementById(id);
+ el.style.display = (el.style.display == 'block') ? 'none' : 'block';
+ event.preventDefault();
+ return false;
+}
+</script>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp
new file mode 100644
index 0000000..c8e634d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Elements/sql_dump.ctp
@@ -0,0 +1,74 @@
+<?php
+/**
+ * SQL Dump element. Dumps out SQL log information
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Elements
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+if (!class_exists('ConnectionManager') || Configure::read('debug') < 2) {
+ return false;
+}
+$noLogs = !isset($logs);
+if ($noLogs):
+ $sources = ConnectionManager::sourceList();
+
+ $logs = array();
+ foreach ($sources as $source):
+ $db = ConnectionManager::getDataSource($source);
+ if (!method_exists($db, 'getLog')):
+ continue;
+ endif;
+ $logs[$source] = $db->getLog();
+ endforeach;
+endif;
+
+if ($noLogs || isset($_forced_from_dbo_)):
+ foreach ($logs as $source => $logInfo):
+ $text = $logInfo['count'] > 1 ? 'queries' : 'query';
+ printf(
+ '<table class="cake-sql-log" id="cakeSqlLog_%s" summary="Cake SQL Log" cellspacing="0">',
+ preg_replace('/[^A-Za-z0-9_]/', '_', uniqid(time(), true))
+ );
+ printf('<caption>(%s) %s %s took %s ms</caption>', $source, $logInfo['count'], $text, $logInfo['time']);
+ ?>
+ <thead>
+ <tr><th>Nr</th><th>Query</th><th>Error</th><th>Affected</th><th>Num. rows</th><th>Took (ms)</th></tr>
+ </thead>
+ <tbody>
+ <?php
+ foreach ($logInfo['log'] as $k => $i) :
+ $i += array('error' => '');
+ if (!empty($i['params']) && is_array($i['params'])) {
+ $bindParam = $bindType = null;
+ if (preg_match('/.+ :.+/', $i['query'])) {
+ $bindType = true;
+ }
+ foreach ($i['params'] as $bindKey => $bindVal) {
+ if ($bindType === true) {
+ $bindParam .= h($bindKey) ." => " . h($bindVal) . ", ";
+ } else {
+ $bindParam .= h($bindVal) . ", ";
+ }
+ }
+ $i['query'] .= " , params[ " . rtrim($bindParam, ', ') . " ]";
+ }
+ echo "<tr><td>" . ($k + 1) . "</td><td>" . h($i['query']) . "</td><td>{$i['error']}</td><td style = \"text-align: right\">{$i['affected']}</td><td style = \"text-align: right\">{$i['numRows']}</td><td style = \"text-align: right\">{$i['took']}</td></tr>\n";
+ endforeach;
+ ?>
+ </tbody></table>
+ <?php
+ endforeach;
+else:
+ echo '<p>Encountered unexpected $logs cannot generate SQL log</p>';
+endif;
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp
new file mode 100644
index 0000000..d7c6e76
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/fatal_error.ctp
@@ -0,0 +1,35 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 2.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Fatal Error'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo h($error->getMessage()); ?>
+ <br>
+
+ <strong><?php echo __d('cake_dev', 'File'); ?>: </strong>
+ <?php echo h($error->getFile()); ?>
+ <br>
+
+ <strong><?php echo __d('cake_dev', 'Line'); ?>: </strong>
+ <?php echo h($error->getLine()); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'fatal_error.ctp'); ?>
+</p>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp
new file mode 100644
index 0000000..614933e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_action.ctp
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Method in %s', $controller); ?></h2> <p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The action %1$s is not defined in controller %2$s', '<em>' . $action . '</em>', '<em>' . $controller . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create %1$s%2$s in file: %3$s.', '<em>' . $controller . '::</em>', '<em>' . $action . '()</em>', APP_DIR . DS . 'Controller' . DS . $controller . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $controller; ?> extends AppController {
+
+<strong>
+ public function <?php echo $action; ?>() {
+
+ }
+</strong>
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_action.ctp'); ?>
+</p>
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp
new file mode 100644
index 0000000..3bb8722
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_behavior.ctp
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Behavior'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'Model' . DS . 'Behavior' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class; ?> extends ModelBehavior {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_behavior.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp
new file mode 100644
index 0000000..d0e6d23
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_component.ctp
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Component'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR : CakePlugin::path($plugin)) . DS . 'Controller' . DS . 'Component' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class; ?> extends Component {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_component.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp
new file mode 100644
index 0000000..b29fb9f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_connection.ctp
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Database Connection'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s requires a database connection', $class); ?>
+</p>
+<?php if (!$enabled) : ?>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s driver is NOT enabled', $class); ?>
+</p>
+<?php endif; ?>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s.', APP_DIR . DS . 'View' . DS . 'Errors' . DS . basename(__FILE__)); ?>
+</p>
+
+<?php
+echo $this->element('exception_stack_trace');
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp
new file mode 100644
index 0000000..b4acb8e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_controller.ctp
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Controller'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'Controller' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class . ' extends ' . $plugin; ?>AppController {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_controller.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp
new file mode 100644
index 0000000..a8c892e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_database.ctp
@@ -0,0 +1,33 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Database Connection'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Scaffold requires a database connection'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Confirm you have created the file: %s', APP_DIR . DS . 'Config' . DS . 'database.php'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_database.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp
new file mode 100644
index 0000000..d3df930
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource.ctp
@@ -0,0 +1,30 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Datasource'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Datasource class %s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_datasource.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp
new file mode 100644
index 0000000..3bc6ff7
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_datasource_config.ctp
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Datasource Configuration'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The datasource configuration %1$s was not found in database.php.', '<em>' . $config . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_datasource_config.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp
new file mode 100644
index 0000000..62d7585
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_helper.ctp
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+$pluginDot = empty($plugin) ? null : $plugin . '.';
+?>
+<h2><?php echo __d('cake_dev', 'Missing Helper'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Create the class %s below in file: %s', '<em>' . $class . '</em>', (empty($plugin) ? APP_DIR . DS : CakePlugin::path($plugin)) . 'View' . DS . 'Helper' . DS . $class . '.php'); ?>
+</p>
+<pre>
+&lt;?php
+class <?php echo $class; ?> extends AppHelper {
+
+}
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_helper.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp
new file mode 100644
index 0000000..f623b61
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_layout.ctp
@@ -0,0 +1,33 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Layout'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The layout file %s can not be found or does not exist.', '<em>' . $file . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Confirm you have created the file: %s', '<em>' . $file . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_layout.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp
new file mode 100644
index 0000000..9d3f7ce
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_plugin.ctp
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Plugin'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The application is trying to load a file from the %s plugin', '<em>' . $plugin . '</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Make sure your plugin %s is in the ' . APP_DIR . DS . 'Plugin directory and was loaded', $plugin); ?>
+</p>
+<pre>
+&lt;?php
+CakePlugin::load('<?php echo $plugin?>');
+
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Loading all plugins'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you wish to load all plugins at once, use the following line in your ' . APP_DIR . DS . 'Config' . DS . 'bootstrap.php file'); ?>
+</p>
+<pre>
+CakePlugin::loadAll();
+</pre>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_plugin.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp
new file mode 100644
index 0000000..6e65871
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_table.ctp
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing Database Table'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Table %1$s for model %2$s was not found in datasource %3$s.', '<em>' . $table . '</em>', '<em>' . $class . '</em>', '<em>' . $ds . '</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_table.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp
new file mode 100644
index 0000000..c3b5920
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/missing_view.ctp
@@ -0,0 +1,33 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Missing View'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'The view for %1$s%2$s was not found.', '<em>' . Inflector::camelize($this->request->controller) . 'Controller::</em>', '<em>' . $this->request->action . '()</em>'); ?>
+</p>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Confirm you have created the file: %s', $file); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'missing_view.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp
new file mode 100644
index 0000000..9aecee6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/pdo_error.ctp
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Database Error'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo h($error->getMessage()); ?>
+</p>
+<?php if (!empty($error->queryString)) : ?>
+ <p class="notice">
+ <strong><?php echo __d('cake_dev', 'SQL Query'); ?>: </strong>
+ <?php echo $error->queryString; ?>
+ </p>
+<?php endif; ?>
+<?php if (!empty($error->params)) : ?>
+ <strong><?php echo __d('cake_dev', 'SQL Query Params'); ?>: </strong>
+ <?php echo Debugger::dump($error->params); ?>
+<?php endif; ?>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'pdo_error.ctp'); ?>
+</p>
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp
new file mode 100644
index 0000000..74264a2
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/private_action.ctp
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Private Method in %s', $controller); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', '%s%s cannot be accessed directly.', '<em>' . $controller . '::</em>', '<em>' . $action . '()</em>'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'private_action.ctp'); ?>
+</p>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp
new file mode 100644
index 0000000..492c561
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Errors/scaffold_error.ctp
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<h2><?php echo __d('cake_dev', 'Scaffold Error'); ?></h2>
+<p class="error">
+ <strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
+ <?php echo __d('cake_dev', 'Method _scaffoldError in was not found in the controller'); ?>
+</p>
+<p class="notice">
+ <strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>
+ <?php echo __d('cake_dev', 'If you want to customize this error message, create %s', APP_DIR . DS . 'View' . DS . 'Errors' . DS . 'scaffold_error.ctp'); ?>
+</p>
+<pre>
+&lt;?php
+function _scaffoldError() {<br />
+
+}
+
+</pre>
+
+<?php echo $this->element('exception_stack_trace'); ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php
new file mode 100644
index 0000000..f6b17ac
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper.php
@@ -0,0 +1,914 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Router', 'Routing');
+
+/**
+ * Abstract base class for all other Helpers in CakePHP.
+ * Provides common methods and features.
+ *
+ * @package Cake.View
+ */
+class Helper extends Object {
+
+/**
+ * List of helpers used by this helper
+ *
+ * @var array
+ */
+ public $helpers = array();
+
+/**
+ * A helper lookup table used to lazy load helper objects.
+ *
+ * @var array
+ */
+ protected $_helperMap = array();
+
+/**
+ * The current theme name if any.
+ *
+ * @var string
+ */
+ public $theme = null;
+
+/**
+ * Request object
+ *
+ * @var CakeRequest
+ */
+ public $request = null;
+
+/**
+ * Plugin path
+ *
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Holds the fields array('field_name' => array('type' => 'string', 'length' => 100),
+ * primaryKey and validates array('field_name')
+ *
+ * @var array
+ */
+ public $fieldset = array();
+
+/**
+ * Holds tag templates.
+ *
+ * @var array
+ */
+ public $tags = array();
+
+/**
+ * Holds the content to be cleaned.
+ *
+ * @var mixed
+ */
+ protected $_tainted = null;
+
+/**
+ * Holds the cleaned content.
+ *
+ * @var mixed
+ */
+ protected $_cleaned = null;
+
+/**
+ * The View instance this helper is attached to
+ *
+ * @var View
+ */
+ protected $_View;
+
+/**
+ * A list of strings that should be treated as suffixes, or
+ * sub inputs for a parent input. This is used for date/time
+ * inputs primarily.
+ *
+ * @var array
+ */
+ protected $_fieldSuffixes = array(
+ 'year', 'month', 'day', 'hour', 'min', 'second', 'meridian'
+ );
+
+/**
+ * The name of the current model entities are in scope of.
+ *
+ * @see Helper::setEntity()
+ * @var string
+ */
+ protected $_modelScope;
+
+/**
+ * The name of the current model association entities are in scope of.
+ *
+ * @see Helper::setEntity()
+ * @var string
+ */
+ protected $_association;
+
+/**
+ * The dot separated list of elements the current field entity is for.
+ *
+ * @see Helper::setEntity()
+ * @var string
+ */
+ protected $_entityPath;
+
+/**
+ * Minimized attributes
+ *
+ * @var array
+ */
+ protected $_minimizedAttributes = array(
+ 'compact', 'checked', 'declare', 'readonly', 'disabled', 'selected',
+ 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize',
+ 'autoplay', 'controls', 'loop', 'muted'
+ );
+
+/**
+ * Format to attribute
+ *
+ * @var string
+ */
+ protected $_attributeFormat = '%s="%s"';
+
+/**
+ * Format to attribute
+ *
+ * @var string
+ */
+ protected $_minimizedAttributeFormat = '%s="%s"';
+
+/**
+ * Default Constructor
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $this->_View = $View;
+ $this->request = $View->request;
+ if (!empty($this->helpers)) {
+ $this->_helperMap = ObjectCollection::normalizeObjectArray($this->helpers);
+ }
+ }
+
+/**
+ * Provide non fatal errors on missing method calls.
+ *
+ * @param string $method Method to invoke
+ * @param array $params Array of params for the method.
+ * @return void
+ */
+ public function __call($method, $params) {
+ trigger_error(__d('cake_dev', 'Method %1$s::%2$s does not exist', get_class($this), $method), E_USER_WARNING);
+ }
+
+/**
+ * Lazy loads helpers. Provides access to deprecated request properties as well.
+ *
+ * @param string $name Name of the property being accessed.
+ * @return mixed Helper or property found at $name
+ */
+ public function __get($name) {
+ if (isset($this->_helperMap[$name]) && !isset($this->{$name})) {
+ $settings = array_merge((array)$this->_helperMap[$name]['settings'], array('enabled' => false));
+ $this->{$name} = $this->_View->loadHelper($this->_helperMap[$name]['class'], $settings);
+ }
+ if (isset($this->{$name})) {
+ return $this->{$name};
+ }
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name};
+ case 'action':
+ return isset($this->request->params['action']) ? $this->request->params['action'] : '';
+ case 'params':
+ return $this->request;
+ }
+ }
+
+/**
+ * Provides backwards compatibility access for setting values to the request object.
+ *
+ * @param string $name Name of the property being accessed.
+ * @param mixed $value
+ * @return mixed Return the $value
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name} = $value;
+ case 'action':
+ return $this->request->params['action'] = $value;
+ }
+ return $this->{$name} = $value;
+ }
+
+/**
+ * Finds URL for specified action.
+ *
+ * Returns a URL pointing at the provided parameters.
+ *
+ * @param string|array $url Either a relative string url like `/products/view/23` or
+ * an array of url parameters. Using an array for urls will allow you to leverage
+ * the reverse routing features of CakePHP.
+ * @param boolean $full If true, the full base URL will be prepended to the result
+ * @return string Full translated URL with base path.
+ * @link http://book.cakephp.org/2.0/en/views/helpers.html
+ */
+ public function url($url = null, $full = false) {
+ return h(Router::url($url, $full));
+ }
+
+/**
+ * Checks if a file exists when theme is used, if no file is found default location is returned
+ *
+ * @param string $file The file to create a webroot path to.
+ * @return string Web accessible path to file.
+ */
+ public function webroot($file) {
+ $asset = explode('?', $file);
+ $asset[1] = isset($asset[1]) ? '?' . $asset[1] : null;
+ $webPath = "{$this->request->webroot}" . $asset[0];
+ $file = $asset[0];
+
+ if (!empty($this->theme)) {
+ $file = trim($file, '/');
+ $theme = $this->theme . '/';
+
+ if (DS === '\\') {
+ $file = str_replace('/', '\\', $file);
+ }
+
+ if (file_exists(Configure::read('App.www_root') . 'theme' . DS . $this->theme . DS . $file)) {
+ $webPath = "{$this->request->webroot}theme/" . $theme . $asset[0];
+ } else {
+ $themePath = App::themePath($this->theme);
+ $path = $themePath . 'webroot' . DS . $file;
+ if (file_exists($path)) {
+ $webPath = "{$this->request->webroot}theme/" . $theme . $asset[0];
+ }
+ }
+ }
+ if (strpos($webPath, '//') !== false) {
+ return str_replace('//', '/', $webPath . $asset[1]);
+ }
+ return $webPath . $asset[1];
+ }
+
+/**
+ * Generate url for given asset file. Depending on options passed provides full url with domain name.
+ * Also calls Helper::assetTimestamp() to add timestamp to local files
+ *
+ * @param string|array Path string or url array
+ * @param array $options Options array. Possible keys:
+ * `fullBase` Return full url with domain name
+ * `pathPrefix` Path prefix for relative urls
+ * `ext` Asset extension to append
+ * `plugin` False value will prevent parsing path as a plugin
+ * @return string Generated url
+ */
+ public function assetUrl($path, $options = array()) {
+ if (is_array($path)) {
+ $path = $this->url($path, !empty($options['fullBase']));
+ } elseif (strpos($path, '://') === false) {
+ if (!array_key_exists('plugin', $options) || $options['plugin'] !== false) {
+ list($plugin, $path) = $this->_View->pluginSplit($path, false);
+ }
+ if (!empty($options['pathPrefix']) && $path[0] !== '/') {
+ $path = $options['pathPrefix'] . $path;
+ }
+ if (
+ !empty($options['ext']) &&
+ strpos($path, '?') === false &&
+ substr($path, -strlen($options['ext'])) !== $options['ext']
+ ) {
+ $path .= $options['ext'];
+ }
+ if (isset($plugin)) {
+ $path = Inflector::underscore($plugin) . '/' . $path;
+ }
+ $path = h($this->assetTimestamp($this->webroot($path)));
+
+ if (!empty($options['fullBase'])) {
+ $base = $this->url('/', true);
+ $len = strlen($this->request->webroot);
+ if ($len) {
+ $base = substr($base, 0, -$len);
+ }
+ $path = $base . $path;
+ }
+ }
+
+ return $path;
+ }
+
+/**
+ * Adds a timestamp to a file based resource based on the value of `Asset.timestamp` in
+ * Configure. If Asset.timestamp is true and debug > 0, or Asset.timestamp == 'force'
+ * a timestamp will be added.
+ *
+ * @param string $path The file path to timestamp, the path must be inside WWW_ROOT
+ * @return string Path with a timestamp added, or not.
+ */
+ public function assetTimestamp($path) {
+ $stamp = Configure::read('Asset.timestamp');
+ $timestampEnabled = $stamp === 'force' || ($stamp === true && Configure::read('debug') > 0);
+ if ($timestampEnabled && strpos($path, '?') === false) {
+ $filepath = preg_replace('/^' . preg_quote($this->request->webroot, '/') . '/', '', $path);
+ $webrootPath = WWW_ROOT . str_replace('/', DS, $filepath);
+ if (file_exists($webrootPath)) {
+ return $path . '?' . @filemtime($webrootPath);
+ }
+ $segments = explode('/', ltrim($filepath, '/'));
+ if ($segments[0] === 'theme') {
+ $theme = $segments[1];
+ unset($segments[0], $segments[1]);
+ $themePath = App::themePath($theme) . 'webroot' . DS . implode(DS, $segments);
+ return $path . '?' . @filemtime($themePath);
+ } else {
+ $plugin = Inflector::camelize($segments[0]);
+ if (CakePlugin::loaded($plugin)) {
+ unset($segments[0]);
+ $pluginPath = CakePlugin::path($plugin) . 'webroot' . DS . implode(DS, $segments);
+ return $path . '?' . @filemtime($pluginPath);
+ }
+ }
+ }
+ return $path;
+ }
+
+/**
+ * Used to remove harmful tags from content. Removes a number of well known XSS attacks
+ * from content. However, is not guaranteed to remove all possibilities. Escaping
+ * content is the best way to prevent all possible attacks.
+ *
+ * @param string|array $output Either an array of strings to clean or a single string to clean.
+ * @return string|array cleaned content for output
+ */
+ public function clean($output) {
+ $this->_reset();
+ if (empty($output)) {
+ return null;
+ }
+ if (is_array($output)) {
+ foreach ($output as $key => $value) {
+ $return[$key] = $this->clean($value);
+ }
+ return $return;
+ }
+ $this->_tainted = $output;
+ $this->_clean();
+ return $this->_cleaned;
+ }
+
+/**
+ * Returns a space-delimited string with items of the $options array. If a
+ * key of $options array happens to be one of:
+ *
+ * - 'compact'
+ * - 'checked'
+ * - 'declare'
+ * - 'readonly'
+ * - 'disabled'
+ * - 'selected'
+ * - 'defer'
+ * - 'ismap'
+ * - 'nohref'
+ * - 'noshade'
+ * - 'nowrap'
+ * - 'multiple'
+ * - 'noresize'
+ *
+ * And its value is one of:
+ *
+ * - '1' (string)
+ * - 1 (integer)
+ * - true (boolean)
+ * - 'true' (string)
+ *
+ * Then the value will be reset to be identical with key's name.
+ * If the value is not one of these 3, the parameter is not output.
+ *
+ * 'escape' is a special option in that it controls the conversion of
+ * attributes to their html-entity encoded equivalents. Set to false to disable html-encoding.
+ *
+ * If value for any option key is set to `null` or `false`, that option will be excluded from output.
+ *
+ * @param array $options Array of options.
+ * @param array $exclude Array of options to be excluded, the options here will not be part of the return.
+ * @param string $insertBefore String to be inserted before options.
+ * @param string $insertAfter String to be inserted after options.
+ * @return string Composed attributes.
+ * @deprecated This method will be moved to HtmlHelper in 3.0
+ */
+ protected function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
+ if (!is_string($options)) {
+ $options = (array)$options + array('escape' => true);
+
+ if (!is_array($exclude)) {
+ $exclude = array();
+ }
+
+ $exclude = array('escape' => true) + array_flip($exclude);
+ $escape = $options['escape'];
+ $attributes = array();
+
+ foreach ($options as $key => $value) {
+ if (!isset($exclude[$key]) && $value !== false && $value !== null) {
+ $attributes[] = $this->_formatAttribute($key, $value, $escape);
+ }
+ }
+ $out = implode(' ', $attributes);
+ } else {
+ $out = $options;
+ }
+ return $out ? $insertBefore . $out . $insertAfter : '';
+ }
+
+/**
+ * Formats an individual attribute, and returns the string value of the composed attribute.
+ * Works with minimized attributes that have the same value as their name such as 'disabled' and 'checked'
+ *
+ * @param string $key The name of the attribute to create
+ * @param string $value The value of the attribute to create.
+ * @param boolean $escape Define if the value must be escaped
+ * @return string The composed attribute.
+ * @deprecated This method will be moved to HtmlHelper in 3.0
+ */
+ protected function _formatAttribute($key, $value, $escape = true) {
+ $attribute = '';
+ if (is_array($value)) {
+ $value = implode(' ' , $value);
+ }
+
+ if (is_numeric($key)) {
+ $attribute = sprintf($this->_minimizedAttributeFormat, $value, $value);
+ } elseif (in_array($key, $this->_minimizedAttributes)) {
+ if ($value === 1 || $value === true || $value === 'true' || $value === '1' || $value == $key) {
+ $attribute = sprintf($this->_minimizedAttributeFormat, $key, $key);
+ }
+ } else {
+ $attribute = sprintf($this->_attributeFormat, $key, ($escape ? h($value) : $value));
+ }
+ return $attribute;
+ }
+
+/**
+ * Sets this helper's model and field properties to the dot-separated value-pair in $entity.
+ *
+ * @param string $entity A field name, like "ModelName.fieldName" or "ModelName.ID.fieldName"
+ * @param boolean $setScope Sets the view scope to the model specified in $tagValue
+ * @return void
+ */
+ public function setEntity($entity, $setScope = false) {
+ if ($entity === null) {
+ $this->_modelScope = false;
+ }
+ if ($setScope === true) {
+ $this->_modelScope = $entity;
+ }
+ $parts = array_values(Hash::filter(explode('.', $entity)));
+ if (empty($parts)) {
+ return;
+ }
+ $count = count($parts);
+ $lastPart = isset($parts[$count - 1]) ? $parts[$count - 1] : null;
+
+ // Either 'body' or 'date.month' type inputs.
+ if (
+ ($count === 1 && $this->_modelScope && $setScope == false) ||
+ (
+ $count === 2 &&
+ in_array($lastPart, $this->_fieldSuffixes) &&
+ $this->_modelScope &&
+ $parts[0] !== $this->_modelScope
+ )
+ ) {
+ $entity = $this->_modelScope . '.' . $entity;
+ }
+
+ // 0.name, 0.created.month style inputs. Excludes inputs with the modelScope in them.
+ if (
+ $count >= 2 &&
+ is_numeric($parts[0]) &&
+ !is_numeric($parts[1]) &&
+ $this->_modelScope &&
+ strpos($entity, $this->_modelScope) === false
+ ) {
+ $entity = $this->_modelScope . '.' . $entity;
+ }
+
+ $this->_association = null;
+
+ $isHabtm = (
+ isset($this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type']) &&
+ $this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type'] === 'multiple' &&
+ $count == 1
+ );
+
+ // habtm models are special
+ if ($count == 1 && $isHabtm) {
+ $this->_association = $parts[0];
+ $entity = $parts[0] . '.' . $parts[0];
+ } else {
+ // check for associated model.
+ $reversed = array_reverse($parts);
+ foreach ($reversed as $i => $part) {
+ if ($i > 0 && preg_match('/^[A-Z]/', $part)) {
+ $this->_association = $part;
+ break;
+ }
+ }
+ }
+ $this->_entityPath = $entity;
+ }
+
+/**
+ * Returns the entity reference of the current context as an array of identity parts
+ *
+ * @return array An array containing the identity elements of an entity
+ */
+ public function entity() {
+ return explode('.', $this->_entityPath);
+ }
+
+/**
+ * Gets the currently-used model of the rendering context.
+ *
+ * @return string
+ */
+ public function model() {
+ if ($this->_association) {
+ return $this->_association;
+ }
+ return $this->_modelScope;
+ }
+
+/**
+ * Gets the currently-used model field of the rendering context.
+ * Strips off field suffixes such as year, month, day, hour, min, meridian
+ * when the current entity is longer than 2 elements.
+ *
+ * @return string
+ */
+ public function field() {
+ $entity = $this->entity();
+ $count = count($entity);
+ $last = $entity[$count - 1];
+ if ($count > 2 && in_array($last, $this->_fieldSuffixes)) {
+ $last = isset($entity[$count - 2]) ? $entity[$count - 2] : null;
+ }
+ return $last;
+ }
+
+/**
+ * Generates a DOM ID for the selected element, if one is not set.
+ * Uses the current View::entity() settings to generate a CamelCased id attribute.
+ *
+ * @param array|string $options Either an array of html attributes to add $id into, or a string
+ * with a view entity path to get a domId for.
+ * @param string $id The name of the 'id' attribute.
+ * @return mixed If $options was an array, an array will be returned with $id set. If a string
+ * was supplied, a string will be returned.
+ * @todo Refactor this method to not have as many input/output options.
+ */
+ public function domId($options = null, $id = 'id') {
+ if (is_array($options) && array_key_exists($id, $options) && $options[$id] === null) {
+ unset($options[$id]);
+ return $options;
+ } elseif (!is_array($options) && $options !== null) {
+ $this->setEntity($options);
+ return $this->domId();
+ }
+
+ $entity = $this->entity();
+ $model = array_shift($entity);
+ $dom = $model . join('', array_map(array('Inflector', 'camelize'), $entity));
+
+ if (is_array($options) && !array_key_exists($id, $options)) {
+ $options[$id] = $dom;
+ } elseif ($options === null) {
+ return $dom;
+ }
+ return $options;
+ }
+
+/**
+ * Gets the input field name for the current tag. Creates input name attributes
+ * using CakePHP's data[Model][field] formatting.
+ *
+ * @param array|string $options If an array, should be an array of attributes that $key needs to be added to.
+ * If a string or null, will be used as the View entity.
+ * @param string $field
+ * @param string $key The name of the attribute to be set, defaults to 'name'
+ * @return mixed If an array was given for $options, an array with $key set will be returned.
+ * If a string was supplied a string will be returned.
+ * @todo Refactor this method to not have as many input/output options.
+ */
+ protected function _name($options = array(), $field = null, $key = 'name') {
+ if ($options === null) {
+ $options = array();
+ } elseif (is_string($options)) {
+ $field = $options;
+ $options = 0;
+ }
+
+ if (!empty($field)) {
+ $this->setEntity($field);
+ }
+
+ if (is_array($options) && array_key_exists($key, $options)) {
+ return $options;
+ }
+
+ switch ($field) {
+ case '_method':
+ $name = $field;
+ break;
+ default:
+ $name = 'data[' . implode('][', $this->entity()) . ']';
+ break;
+ }
+
+ if (is_array($options)) {
+ $options[$key] = $name;
+ return $options;
+ } else {
+ return $name;
+ }
+ }
+
+/**
+ * Gets the data for the current tag
+ *
+ * @param array|string $options If an array, should be an array of attributes that $key needs to be added to.
+ * If a string or null, will be used as the View entity.
+ * @param string $field
+ * @param string $key The name of the attribute to be set, defaults to 'value'
+ * @return mixed If an array was given for $options, an array with $key set will be returned.
+ * If a string was supplied a string will be returned.
+ * @todo Refactor this method to not have as many input/output options.
+ */
+ public function value($options = array(), $field = null, $key = 'value') {
+ if ($options === null) {
+ $options = array();
+ } elseif (is_string($options)) {
+ $field = $options;
+ $options = 0;
+ }
+
+ if (is_array($options) && isset($options[$key])) {
+ return $options;
+ }
+
+ if (!empty($field)) {
+ $this->setEntity($field);
+ }
+ $result = null;
+ $data = $this->request->data;
+
+ $entity = $this->entity();
+ if (!empty($data) && !empty($entity)) {
+ $result = Hash::get($data, implode('.', $entity));
+ }
+
+ $habtmKey = $this->field();
+ if (empty($result) && isset($data[$habtmKey][$habtmKey]) && is_array($data[$habtmKey])) {
+ $result = $data[$habtmKey][$habtmKey];
+ } elseif (empty($result) && isset($data[$habtmKey]) && is_array($data[$habtmKey])) {
+ if (ClassRegistry::isKeySet($habtmKey)) {
+ $model = ClassRegistry::getObject($habtmKey);
+ $result = $this->_selectedArray($data[$habtmKey], $model->primaryKey);
+ }
+ }
+
+ if (is_array($options)) {
+ if ($result === null && isset($options['default'])) {
+ $result = $options['default'];
+ }
+ unset($options['default']);
+ }
+
+ if (is_array($options)) {
+ $options[$key] = $result;
+ return $options;
+ } else {
+ return $result;
+ }
+ }
+
+/**
+ * Sets the defaults for an input tag. Will set the
+ * name, value, and id attributes for an array of html attributes. Will also
+ * add a 'form-error' class if the field contains validation errors.
+ *
+ * @param string $field The field name to initialize.
+ * @param array $options Array of options to use while initializing an input field.
+ * @return array Array options for the form input.
+ */
+ protected function _initInputField($field, $options = array()) {
+ if ($field !== null) {
+ $this->setEntity($field);
+ }
+ $options = (array)$options;
+ $options = $this->_name($options);
+ $options = $this->value($options);
+ $options = $this->domId($options);
+ return $options;
+ }
+
+/**
+ * Adds the given class to the element options
+ *
+ * @param array $options Array options/attributes to add a class to
+ * @param string $class The classname being added.
+ * @param string $key the key to use for class.
+ * @return array Array of options with $key set.
+ */
+ public function addClass($options = array(), $class = null, $key = 'class') {
+ if (isset($options[$key]) && trim($options[$key]) != '') {
+ $options[$key] .= ' ' . $class;
+ } else {
+ $options[$key] = $class;
+ }
+ return $options;
+ }
+
+/**
+ * Returns a string generated by a helper method
+ *
+ * This method can be overridden in subclasses to do generalized output post-processing
+ *
+ * @param string $str String to be output.
+ * @return string
+ * @deprecated This method will be removed in future versions.
+ */
+ public function output($str) {
+ return $str;
+ }
+
+/**
+ * Before render callback. beforeRender is called before the view file is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The view file that is going to be rendered
+ * @return void
+ */
+ public function beforeRender($viewFile) {
+ }
+
+/**
+ * After render callback. afterRender is called after the view file is rendered
+ * but before the layout has been rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The view file that was rendered.
+ * @return void
+ */
+ public function afterRender($viewFile) {
+ }
+
+/**
+ * Before layout callback. beforeLayout is called before the layout is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $layoutFile The layout about to be rendered.
+ * @return void
+ */
+ public function beforeLayout($layoutFile) {
+ }
+
+/**
+ * After layout callback. afterLayout is called after the layout has rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $layoutFile The layout file that was rendered.
+ * @return void
+ */
+ public function afterLayout($layoutFile) {
+ }
+
+/**
+ * Before render file callback.
+ * Called before any view fragment is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The file about to be rendered.
+ * @return void
+ */
+ public function beforeRenderFile($viewfile) {
+ }
+
+/**
+ * After render file callback.
+ * Called after any view fragment is rendered.
+ *
+ * Overridden in subclasses.
+ *
+ * @param string $viewFile The file just be rendered.
+ * @param string $content The content that was rendered.
+ * @return void
+ */
+ public function afterRenderFile($viewfile, $content) {
+ }
+
+/**
+ * Transforms a recordset from a hasAndBelongsToMany association to a list of selected
+ * options for a multiple select element
+ *
+ * @param string|array $data
+ * @param string $key
+ * @return array
+ */
+ protected function _selectedArray($data, $key = 'id') {
+ if (!is_array($data)) {
+ $model = $data;
+ if (!empty($this->request->data[$model][$model])) {
+ return $this->request->data[$model][$model];
+ }
+ if (!empty($this->request->data[$model])) {
+ $data = $this->request->data[$model];
+ }
+ }
+ $array = array();
+ if (!empty($data)) {
+ foreach ($data as $row) {
+ if (isset($row[$key])) {
+ $array[$row[$key]] = $row[$key];
+ }
+ }
+ }
+ return empty($array) ? null : $array;
+ }
+
+/**
+ * Resets the vars used by Helper::clean() to null
+ *
+ * @return void
+ */
+ protected function _reset() {
+ $this->_tainted = null;
+ $this->_cleaned = null;
+ }
+
+/**
+ * Removes harmful content from output
+ *
+ * @return void
+ */
+ protected function _clean() {
+ if (get_magic_quotes_gpc()) {
+ $this->_cleaned = stripslashes($this->_tainted);
+ } else {
+ $this->_cleaned = $this->_tainted;
+ }
+
+ $this->_cleaned = str_replace(array("&amp;", "&lt;", "&gt;"), array("&amp;amp;", "&amp;lt;", "&amp;gt;"), $this->_cleaned);
+ $this->_cleaned = preg_replace('#(&\#*\w+)[\x00-\x20]+;#u', "$1;", $this->_cleaned);
+ $this->_cleaned = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', "$1$2;", $this->_cleaned);
+ $this->_cleaned = html_entity_decode($this->_cleaned, ENT_COMPAT, "UTF-8");
+ $this->_cleaned = preg_replace('#(<[^>]+[\x00-\x20\"\'\/])(on|xmlns)[^>]*>#iUu', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*)[\\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2nojavascript...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=([\'\"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2novbscript...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=*([\'\"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#iUu', '$1=$2nomozbinding...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=([\'\"]*)[\x00-\x20]*data[\x00-\x20]*:#Uu', '$1=$2nodata...', $this->_cleaned);
+ $this->_cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*expression[\x00-\x20]*\([^>]*>#iU', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*behaviour[\x00-\x20]*\([^>]*>#iU', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*>#iUu', "$1>", $this->_cleaned);
+ $this->_cleaned = preg_replace('#</*\w+:\w[^>]*>#i', "", $this->_cleaned);
+ do {
+ $oldstring = $this->_cleaned;
+ $this->_cleaned = preg_replace('#</*(applet|meta|xml|blink|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|title|base)[^>]*>#i', "", $this->_cleaned);
+ } while ($oldstring != $this->_cleaned);
+ $this->_cleaned = str_replace(array("&amp;", "&lt;", "&gt;"), array("&amp;amp;", "&amp;lt;", "&amp;gt;"), $this->_cleaned);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php
new file mode 100644
index 0000000..a480886
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/CacheHelper.php
@@ -0,0 +1,321 @@
+<?php
+/**
+ * CacheHelper helps create full page view caching.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.0.0.2277
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * CacheHelper helps create full page view caching.
+ *
+ * When using CacheHelper you don't call any of its methods, they are all automatically
+ * called by View, and use the $cacheAction settings set in the controller.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html
+ */
+class CacheHelper extends AppHelper {
+
+/**
+ * Array of strings replaced in cached views.
+ * The strings are found between `<!--nocache--><!--/nocache-->` in views
+ *
+ * @var array
+ */
+ protected $_replace = array();
+
+/**
+ * Array of string that are replace with there var replace above.
+ * The strings are any content inside `<!--nocache--><!--/nocache-->` and includes the tags in views
+ *
+ * @var array
+ */
+ protected $_match = array();
+
+/**
+ * Counter used for counting nocache section tags.
+ *
+ * @var integer
+ */
+ protected $_counter = 0;
+
+/**
+ * Is CacheHelper enabled? should files + output be parsed.
+ *
+ * @return boolean
+ */
+ protected function _enabled() {
+ return (($this->_View->cacheAction != false)) && (Configure::read('Cache.check') === true);
+ }
+
+/**
+ * Parses the view file and stores content for cache file building.
+ *
+ * @param string $viewFile
+ * @return void
+ */
+ public function afterRenderFile($viewFile, $output) {
+ if ($this->_enabled()) {
+ return $this->_parseContent($viewFile, $output);
+ }
+ }
+
+/**
+ * Parses the layout file and stores content for cache file building.
+ *
+ * @param string $layoutFile
+ * @return void
+ */
+ public function afterLayout($layoutFile) {
+ if ($this->_enabled()) {
+ $this->_View->output = $this->cache($layoutFile, $this->_View->output);
+ }
+ $this->_View->output = preg_replace('/<!--\/?nocache-->/', '', $this->_View->output);
+ }
+
+/**
+ * Parse a file + output. Matches nocache tags between the current output and the current file
+ * stores a reference of the file, so the generated can be swapped back with the file contents when
+ * writing the cache file.
+ *
+ * @param string $file The filename to process.
+ * @param string $out The output for the file.
+ * @return string Updated content.
+ */
+ protected function _parseContent($file, $out) {
+ $out = preg_replace_callback('/<!--nocache-->/', array($this, '_replaceSection'), $out);
+ $this->_parseFile($file, $out);
+ return $out;
+ }
+
+/**
+ * Main method used to cache a view
+ *
+ * @param string $file File to cache
+ * @param string $out output to cache
+ * @return string view ouput
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html
+ */
+ public function cache($file, $out) {
+ $cacheTime = 0;
+ $useCallbacks = false;
+ $cacheAction = $this->_View->cacheAction;
+
+ if (is_array($cacheAction)) {
+ $keys = array_keys($cacheAction);
+ $index = null;
+
+ foreach ($keys as $action) {
+ if ($action == $this->request->params['action']) {
+ $index = $action;
+ break;
+ }
+ }
+
+ if (!isset($index) && $this->request->params['action'] == 'index') {
+ $index = 'index';
+ }
+
+ $options = $cacheAction;
+ if (isset($cacheAction[$index])) {
+ if (is_array($cacheAction[$index])) {
+ $options = array_merge(array('duration' => 0, 'callbacks' => false), $cacheAction[$index]);
+ } else {
+ $cacheTime = $cacheAction[$index];
+ }
+ }
+ if (isset($options['duration'])) {
+ $cacheTime = $options['duration'];
+ }
+ if (isset($options['callbacks'])) {
+ $useCallbacks = $options['callbacks'];
+ }
+ } else {
+ $cacheTime = $cacheAction;
+ }
+
+ if ($cacheTime != '' && $cacheTime > 0) {
+ $cached = $this->_parseOutput($out);
+ $this->_writeFile($cached, $cacheTime, $useCallbacks);
+ $out = $this->_stripTags($out);
+ }
+ return $out;
+ }
+
+/**
+ * Parse file searching for no cache tags
+ *
+ * @param string $file The filename that needs to be parsed.
+ * @param string $cache The cached content
+ * @return void
+ */
+ protected function _parseFile($file, $cache) {
+ if (is_file($file)) {
+ $file = file_get_contents($file);
+ } elseif ($file = fileExistsInPath($file)) {
+ $file = file_get_contents($file);
+ }
+ preg_match_all('/(<!--nocache:\d{3}-->(?<=<!--nocache:\d{3}-->)[\\s\\S]*?(?=<!--\/nocache-->)<!--\/nocache-->)/i', $cache, $outputResult, PREG_PATTERN_ORDER);
+ preg_match_all('/(?<=<!--nocache-->)([\\s\\S]*?)(?=<!--\/nocache-->)/i', $file, $fileResult, PREG_PATTERN_ORDER);
+ $fileResult = $fileResult[0];
+ $outputResult = $outputResult[0];
+
+ if (!empty($this->_replace)) {
+ foreach ($outputResult as $i => $element) {
+ $index = array_search($element, $this->_match);
+ if ($index !== false) {
+ unset($outputResult[$i]);
+ }
+ }
+ $outputResult = array_values($outputResult);
+ }
+
+ if (!empty($fileResult)) {
+ $i = 0;
+ foreach ($fileResult as $cacheBlock) {
+ if (isset($outputResult[$i])) {
+ $this->_replace[] = $cacheBlock;
+ $this->_match[] = $outputResult[$i];
+ }
+ $i++;
+ }
+ }
+ }
+
+/**
+ * Munges the output from a view with cache tags, and numbers the sections.
+ * This helps solve issues with empty/duplicate content.
+ *
+ * @return string The content with cake:nocache tags replaced.
+ */
+ protected function _replaceSection() {
+ $this->_counter += 1;
+ return sprintf('<!--nocache:%03d-->', $this->_counter);
+ }
+
+/**
+ * Strip cake:nocache tags from a string. Since View::render()
+ * only removes un-numbered nocache tags, remove all the numbered ones.
+ * This is the complement to _replaceSection.
+ *
+ * @param string $content String to remove tags from.
+ * @return string String with tags removed.
+ */
+ protected function _stripTags($content) {
+ return preg_replace('#<!--/?nocache(\:\d{3})?-->#', '', $content);
+ }
+
+/**
+ * Parse the output and replace cache tags
+ *
+ * @param string $cache Output to replace content in.
+ * @return string with all replacements made to <!--nocache--><!--nocache-->
+ */
+ protected function _parseOutput($cache) {
+ $count = 0;
+ if (!empty($this->_match)) {
+ foreach ($this->_match as $found) {
+ $original = $cache;
+ $length = strlen($found);
+ $position = 0;
+
+ for ($i = 1; $i <= 1; $i++) {
+ $position = strpos($cache, $found, $position);
+
+ if ($position !== false) {
+ $cache = substr($original, 0, $position);
+ $cache .= $this->_replace[$count];
+ $cache .= substr($original, $position + $length);
+ } else {
+ break;
+ }
+ }
+ $count++;
+ }
+ return $cache;
+ }
+ return $cache;
+ }
+
+/**
+ * Write a cached version of the file
+ *
+ * @param string $content view content to write to a cache file.
+ * @param string $timestamp Duration to set for cache file.
+ * @param boolean $useCallbacks
+ * @return boolean success of caching view.
+ */
+ protected function _writeFile($content, $timestamp, $useCallbacks = false) {
+ $now = time();
+
+ if (is_numeric($timestamp)) {
+ $cacheTime = $now + $timestamp;
+ } else {
+ $cacheTime = strtotime($timestamp, $now);
+ }
+ $path = $this->request->here();
+ if ($path == '/') {
+ $path = 'home';
+ }
+ $cache = strtolower(Inflector::slug($path));
+
+ if (empty($cache)) {
+ return;
+ }
+ $cache = $cache . '.php';
+ $file = '<!--cachetime:' . $cacheTime . '--><?php';
+
+ if (empty($this->_View->plugin)) {
+ $file .= "
+ App::uses('{$this->_View->name}Controller', 'Controller');
+ ";
+ } else {
+ $file .= "
+ App::uses('{$this->_View->plugin}AppController', '{$this->_View->plugin}.Controller');
+ App::uses('{$this->_View->name}Controller', '{$this->_View->plugin}.Controller');
+ ";
+ }
+
+ $file .= '
+ $request = unserialize(base64_decode(\'' . base64_encode(serialize($this->request)) . '\'));
+ $response = new CakeResponse(array("charset" => Configure::read("App.encoding")));
+ $controller = new ' . $this->_View->name . 'Controller($request, $response);
+ $controller->plugin = $this->plugin = \'' . $this->_View->plugin . '\';
+ $controller->helpers = $this->helpers = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->helpers)) . '\'));
+ $controller->layout = $this->layout = \'' . $this->_View->layout . '\';
+ $controller->theme = $this->theme = \'' . $this->_View->theme . '\';
+ $controller->viewVars = unserialize(base64_decode(\'' . base64_encode(serialize($this->_View->viewVars)) . '\'));
+ Router::setRequestInfo($controller->request);
+ $this->request = $request;';
+
+ if ($useCallbacks == true) {
+ $file .= '
+ $controller->constructClasses();
+ $controller->startupProcess();';
+ }
+
+ $file .= '
+ $this->viewVars = $controller->viewVars;
+ $this->loadHelpers();
+ extract($this->viewVars, EXTR_SKIP);
+ ?>';
+ $content = preg_replace("/(<\\?xml)/", "<?php echo '$1'; ?>", $content);
+ $file .= $content;
+ return cache('views' . DS . $cache, $file, $timestamp);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php
new file mode 100644
index 0000000..e63614a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/FormHelper.php
@@ -0,0 +1,2604 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+App::uses('ClassRegistry', 'Utility');
+App::uses('AppHelper', 'View/Helper');
+App::uses('Hash', 'Utility');
+
+/**
+ * Form helper library.
+ *
+ * Automatic generation of HTML FORMs from given data.
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html
+ */
+class FormHelper extends AppHelper {
+
+/**
+ * Other helpers used by FormHelper
+ *
+ * @var array
+ */
+ public $helpers = array('Html');
+
+/**
+ * Options used by DateTime fields
+ *
+ * @var array
+ */
+ protected $_options = array(
+ 'day' => array(), 'minute' => array(), 'hour' => array(),
+ 'month' => array(), 'year' => array(), 'meridian' => array()
+ );
+
+/**
+ * List of fields created, used with secure forms.
+ *
+ * @var array
+ */
+ public $fields = array();
+
+/**
+ * Constant used internally to skip the securing process,
+ * and neither add the field to the hash or to the unlocked fields.
+ *
+ * @var string
+ */
+ const SECURE_SKIP = 'skip';
+
+/**
+ * Defines the type of form being created. Set by FormHelper::create().
+ *
+ * @var string
+ */
+ public $requestType = null;
+
+/**
+ * The default model being used for the current form.
+ *
+ * @var string
+ */
+ public $defaultModel = null;
+
+/**
+ * Persistent default options used by input(). Set by FormHelper::create().
+ *
+ * @var array
+ */
+ protected $_inputDefaults = array();
+
+/**
+ * An array of field names that have been excluded from
+ * the Token hash used by SecurityComponent's validatePost method
+ *
+ * @see FormHelper::_secure()
+ * @see SecurityComponent::validatePost()
+ * @var array
+ */
+ protected $_unlockedFields = array();
+
+/**
+ * Holds the model references already loaded by this helper
+ * product of trying to inspect them out of field names
+ *
+ * @var array
+ */
+ protected $_models = array();
+
+/**
+ * Holds all the validation errors for models loaded and inspected
+ * it can also be set manually to be able to display custom error messages
+ * in the any of the input fields generated by this helper
+ *
+ * @var array
+ */
+ public $validationErrors = array();
+
+/**
+ * Copies the validationErrors variable from the View object into this instance
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ parent::__construct($View, $settings);
+ $this->validationErrors =& $View->validationErrors;
+ }
+
+/**
+ * Guess the location for a model based on its name and tries to create a new instance
+ * or get an already created instance of the model
+ *
+ * @param string $model
+ * @return Model model instance
+ */
+ protected function _getModel($model) {
+ $object = null;
+ if (!$model || $model === 'Model') {
+ return $object;
+ }
+
+ if (array_key_exists($model, $this->_models)) {
+ return $this->_models[$model];
+ }
+
+ if (ClassRegistry::isKeySet($model)) {
+ $object = ClassRegistry::getObject($model);
+ } elseif (isset($this->request->params['models'][$model])) {
+ $plugin = $this->request->params['models'][$model]['plugin'];
+ $plugin .= ($plugin) ? '.' : null;
+ $object = ClassRegistry::init(array(
+ 'class' => $plugin . $this->request->params['models'][$model]['className'],
+ 'alias' => $model
+ ));
+ } elseif (ClassRegistry::isKeySet($this->defaultModel)) {
+ $defaultObject = ClassRegistry::getObject($this->defaultModel);
+ if (in_array($model, array_keys($defaultObject->getAssociated()), true) && isset($defaultObject->{$model})) {
+ $object = $defaultObject->{$model};
+ }
+ } else {
+ $object = ClassRegistry::init($model, true);
+ }
+
+ $this->_models[$model] = $object;
+ if (!$object) {
+ return null;
+ }
+
+ $this->fieldset[$model] = array('fields' => null, 'key' => $object->primaryKey, 'validates' => null);
+ return $object;
+ }
+
+/**
+ * Inspects the model properties to extract information from them.
+ * Currently it can extract information from the the fields, the primary key and required fields
+ *
+ * The $key parameter accepts the following list of values:
+ *
+ * - key: Returns the name of the primary key for the model
+ * - fields: Returns the model schema
+ * - validates: returns the list of fields that are required
+ * - errors: returns the list of validation errors
+ *
+ * If the $field parameter is passed if will return the information for that sole field.
+ *
+ * `$this->_introspectModel('Post', 'fields', 'title');` will return the schema information for title column
+ *
+ * @param string $model name of the model to extract information from
+ * @param string $key name of the special information key to obtain (key, fields, validates, errors)
+ * @param string $field name of the model field to get information from
+ * @return mixed information extracted for the special key and field in a model
+ */
+ protected function _introspectModel($model, $key, $field = null) {
+ $object = $this->_getModel($model);
+ if (!$object) {
+ return;
+ }
+
+ if ($key === 'key') {
+ return $this->fieldset[$model]['key'] = $object->primaryKey;
+ }
+
+ if ($key === 'fields') {
+ if (!isset($this->fieldset[$model]['fields'])) {
+ $fields = $this->fieldset[$model]['fields'] = $object->schema();
+ foreach ($object->hasAndBelongsToMany as $alias => $assocData) {
+ $this->fieldset[$object->alias]['fields'][$alias] = array('type' => 'multiple');
+ }
+ }
+ if (empty($field)) {
+ return $this->fieldset[$model]['fields'];
+ } elseif (isset($this->fieldset[$model]['fields'][$field])) {
+ return $this->fieldset[$model]['fields'][$field];
+ } else {
+ return isset($object->hasAndBelongsToMany[$field]) ? array('type' => 'multiple') : null;
+ }
+ }
+
+ if ($key === 'errors' && !isset($this->validationErrors[$model])) {
+ $this->validationErrors[$model] =& $object->validationErrors;
+ return $this->validationErrors[$model];
+ } elseif ($key === 'errors' && isset($this->validationErrors[$model])) {
+ return $this->validationErrors[$model];
+ }
+
+ if ($key === 'validates' && !isset($this->fieldset[$model]['validates'])) {
+ $validates = array();
+ if (!empty($object->validate)) {
+ foreach ($object->validator() as $validateField => $validateProperties) {
+ if ($this->_isRequiredField($validateProperties)) {
+ $validates[$validateField] = true;
+ }
+ }
+ }
+ $this->fieldset[$model]['validates'] = $validates;
+ }
+
+ if ($key === 'validates') {
+ if (empty($field)) {
+ return $this->fieldset[$model]['validates'];
+ } else {
+ return isset($this->fieldset[$model]['validates'][$field]) ?
+ $this->fieldset[$model]['validates'] : null;
+ }
+ }
+ }
+
+/**
+ * Returns if a field is required to be filled based on validation properties from the validating object.
+ *
+ * @param CakeValidationSet $validationRules
+ * @return boolean true if field is required to be filled, false otherwise
+ */
+ protected function _isRequiredField($validationRules) {
+ foreach ($validationRules as $rule) {
+ $rule->isUpdate($this->requestType === 'put');
+ if (!$rule->isEmptyAllowed()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Returns false if given form field described by the current entity has no errors.
+ * Otherwise it returns the validation message
+ *
+ * @return mixed Either false when there or no errors, or an array of error
+ * strings. An error string could be ''.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::tagIsInvalid
+ */
+ public function tagIsInvalid() {
+ $entity = $this->entity();
+ $model = array_shift($entity);
+ $errors = array();
+ if (!empty($entity) && isset($this->validationErrors[$model])) {
+ $errors = $this->validationErrors[$model];
+ }
+ if (!empty($entity) && empty($errors)) {
+ $errors = $this->_introspectModel($model, 'errors');
+ }
+ if (empty($errors)) {
+ return false;
+ }
+ $errors = Hash::get($errors, join('.', $entity));
+ return $errors === null ? false : $errors;
+ }
+
+/**
+ * Returns an HTML FORM element.
+ *
+ * ### Options:
+ *
+ * - `type` Form method defaults to POST
+ * - `action` The controller action the form submits to, (optional).
+ * - `url` The url the form submits to. Can be a string or a url array. If you use 'url'
+ * you should leave 'action' undefined.
+ * - `default` Allows for the creation of Ajax forms. Set this to false to prevent the default event handler.
+ * Will create an onsubmit attribute if it doesn't not exist. If it does, default action suppression
+ * will be appended.
+ * - `onsubmit` Used in conjunction with 'default' to create ajax forms.
+ * - `inputDefaults` set the default $options for FormHelper::input(). Any options that would
+ * be set when using FormHelper::input() can be set here. Options set with `inputDefaults`
+ * can be overridden when calling input()
+ * - `encoding` Set the accept-charset encoding for the form. Defaults to `Configure::read('App.encoding')`
+ *
+ * @param string $model The model object which the form is being defined for. Should
+ * include the plugin name for plugin forms. e.g. `ContactManager.Contact`.
+ * @param array $options An array of html attributes and options.
+ * @return string An formatted opening FORM tag.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-create
+ */
+ public function create($model = null, $options = array()) {
+ $created = $id = false;
+ $append = '';
+
+ if (is_array($model) && empty($options)) {
+ $options = $model;
+ $model = null;
+ }
+
+ if (empty($model) && $model !== false && !empty($this->request->params['models'])) {
+ $model = key($this->request->params['models']);
+ } elseif (empty($model) && empty($this->request->params['models'])) {
+ $model = false;
+ }
+ $this->defaultModel = $model;
+
+ $key = null;
+ if ($model !== false) {
+ $object = $this->_getModel($model);
+ $key = $this->_introspectModel($model, 'key');
+ $this->setEntity($model, true);
+ }
+
+ if ($model !== false && $key) {
+ $recordExists = (
+ isset($this->request->data[$model]) &&
+ !empty($this->request->data[$model][$key]) &&
+ !is_array($this->request->data[$model][$key])
+ );
+
+ if ($recordExists) {
+ $created = true;
+ $id = $this->request->data[$model][$key];
+ }
+ }
+
+ $options = array_merge(array(
+ 'type' => ($created && empty($options['action'])) ? 'put' : 'post',
+ 'action' => null,
+ 'url' => null,
+ 'default' => true,
+ 'encoding' => strtolower(Configure::read('App.encoding')),
+ 'inputDefaults' => array()),
+ $options);
+ $this->inputDefaults($options['inputDefaults']);
+ unset($options['inputDefaults']);
+
+ if (!isset($options['id'])) {
+ $domId = isset($options['action']) ? $options['action'] : $this->request['action'];
+ $options['id'] = $this->domId($domId . 'Form');
+ }
+
+ if ($options['action'] === null && $options['url'] === null) {
+ $options['action'] = $this->request->here(false);
+ } elseif (empty($options['url']) || is_array($options['url'])) {
+ if (empty($options['url']['controller'])) {
+ if (!empty($model)) {
+ $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model));
+ } elseif (!empty($this->request->params['controller'])) {
+ $options['url']['controller'] = Inflector::underscore($this->request->params['controller']);
+ }
+ }
+ if (empty($options['action'])) {
+ $options['action'] = $this->request->params['action'];
+ }
+
+ $plugin = null;
+ if ($this->plugin) {
+ $plugin = Inflector::underscore($this->plugin);
+ }
+ $actionDefaults = array(
+ 'plugin' => $plugin,
+ 'controller' => $this->_View->viewPath,
+ 'action' => $options['action'],
+ );
+ $options['action'] = array_merge($actionDefaults, (array)$options['url']);
+ if (empty($options['action'][0]) && !empty($id)) {
+ $options['action'][0] = $id;
+ }
+ } elseif (is_string($options['url'])) {
+ $options['action'] = $options['url'];
+ }
+ unset($options['url']);
+
+ switch (strtolower($options['type'])) {
+ case 'get':
+ $htmlAttributes['method'] = 'get';
+ break;
+ case 'file':
+ $htmlAttributes['enctype'] = 'multipart/form-data';
+ $options['type'] = ($created) ? 'put' : 'post';
+ case 'post':
+ case 'put':
+ case 'delete':
+ $append .= $this->hidden('_method', array(
+ 'name' => '_method', 'value' => strtoupper($options['type']), 'id' => null,
+ 'secure' => self::SECURE_SKIP
+ ));
+ default:
+ $htmlAttributes['method'] = 'post';
+ break;
+ }
+ $this->requestType = strtolower($options['type']);
+
+ $action = $this->url($options['action']);
+ unset($options['type'], $options['action']);
+
+ if ($options['default'] == false) {
+ if (!isset($options['onsubmit'])) {
+ $options['onsubmit'] = '';
+ }
+ $htmlAttributes['onsubmit'] = $options['onsubmit'] . 'event.returnValue = false; return false;';
+ }
+ unset($options['default']);
+
+ if (!empty($options['encoding'])) {
+ $htmlAttributes['accept-charset'] = $options['encoding'];
+ unset($options['encoding']);
+ }
+
+ $htmlAttributes = array_merge($options, $htmlAttributes);
+
+ $this->fields = array();
+ $append .= $this->_csrfField();
+
+ if (!empty($append)) {
+ $append = $this->Html->useTag('block', ' style="display:none;"', $append);
+ }
+
+ if ($model !== false) {
+ $this->setEntity($model, true);
+ $this->_introspectModel($model, 'fields');
+ }
+ return $this->Html->useTag('form', $action, $htmlAttributes) . $append;
+ }
+
+/**
+ * Return a CSRF input if the _Token is present.
+ * Used to secure forms in conjunction with SecurityComponent
+ *
+ * @return string
+ */
+ protected function _csrfField() {
+ if (empty($this->request->params['_Token'])) {
+ return '';
+ }
+ if (!empty($this->request['_Token']['unlockedFields'])) {
+ foreach ((array)$this->request['_Token']['unlockedFields'] as $unlocked) {
+ $this->_unlockedFields[] = $unlocked;
+ }
+ }
+ return $this->hidden('_Token.key', array(
+ 'value' => $this->request->params['_Token']['key'], 'id' => 'Token' . mt_rand(),
+ 'secure' => self::SECURE_SKIP
+ ));
+ }
+
+/**
+ * Closes an HTML form, cleans up values set by FormHelper::create(), and writes hidden
+ * input fields where appropriate.
+ *
+ * If $options is set a form submit button will be created. Options can be either a string or an array.
+ *
+ * {{{
+ * array usage:
+ *
+ * array('label' => 'save'); value="save"
+ * array('label' => 'save', 'name' => 'Whatever'); value="save" name="Whatever"
+ * array('name' => 'Whatever'); value="Submit" name="Whatever"
+ * array('label' => 'save', 'name' => 'Whatever', 'div' => 'good') <div class="good"> value="save" name="Whatever"
+ * array('label' => 'save', 'name' => 'Whatever', 'div' => array('class' => 'good')); <div class="good"> value="save" name="Whatever"
+ * }}}
+ *
+ * @param string|array $options as a string will use $options as the value of button,
+ * @return string a closing FORM tag optional submit button.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#closing-the-form
+ */
+ public function end($options = null) {
+ $out = null;
+ $submit = null;
+
+ if ($options !== null) {
+ $submitOptions = array();
+ if (is_string($options)) {
+ $submit = $options;
+ } else {
+ if (isset($options['label'])) {
+ $submit = $options['label'];
+ unset($options['label']);
+ }
+ $submitOptions = $options;
+ }
+ $out .= $this->submit($submit, $submitOptions);
+ }
+ if (isset($this->request['_Token']) && !empty($this->request['_Token'])) {
+ $out .= $this->secure($this->fields);
+ $this->fields = array();
+ }
+ $this->setEntity(null);
+ $out .= $this->Html->useTag('formend');
+
+ $this->_View->modelScope = false;
+ return $out;
+ }
+
+/**
+ * Generates a hidden field with a security hash based on the fields used in the form.
+ *
+ * @param array $fields The list of fields to use when generating the hash
+ * @return string A hidden input field with a security hash
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::secure
+ */
+ public function secure($fields = array()) {
+ if (!isset($this->request['_Token']) || empty($this->request['_Token'])) {
+ return;
+ }
+ $locked = array();
+ $unlockedFields = $this->_unlockedFields;
+
+ foreach ($fields as $key => $value) {
+ if (!is_int($key)) {
+ $locked[$key] = $value;
+ unset($fields[$key]);
+ }
+ }
+
+ sort($unlockedFields, SORT_STRING);
+ sort($fields, SORT_STRING);
+ ksort($locked, SORT_STRING);
+ $fields += $locked;
+
+ $locked = implode(array_keys($locked), '|');
+ $unlocked = implode($unlockedFields, '|');
+ $fields = Security::hash(serialize($fields) . $unlocked . Configure::read('Security.salt'));
+
+ $out = $this->hidden('_Token.fields', array(
+ 'value' => urlencode($fields . ':' . $locked),
+ 'id' => 'TokenFields' . mt_rand()
+ ));
+ $out .= $this->hidden('_Token.unlocked', array(
+ 'value' => urlencode($unlocked),
+ 'id' => 'TokenUnlocked' . mt_rand()
+ ));
+ return $this->Html->useTag('block', ' style="display:none;"', $out);
+ }
+
+/**
+ * Add to or get the list of fields that are currently unlocked.
+ * Unlocked fields are not included in the field hash used by SecurityComponent
+ * unlocking a field once its been added to the list of secured fields will remove
+ * it from the list of fields.
+ *
+ * @param string $name The dot separated name for the field.
+ * @return mixed Either null, or the list of fields.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::unlockField
+ */
+ public function unlockField($name = null) {
+ if ($name === null) {
+ return $this->_unlockedFields;
+ }
+ if (!in_array($name, $this->_unlockedFields)) {
+ $this->_unlockedFields[] = $name;
+ }
+ $index = array_search($name, $this->fields);
+ if ($index !== false) {
+ unset($this->fields[$index]);
+ }
+ unset($this->fields[$name]);
+ }
+
+/**
+ * Determine which fields of a form should be used for hash.
+ * Populates $this->fields
+ *
+ * @param boolean $lock Whether this field should be part of the validation
+ * or excluded as part of the unlockedFields.
+ * @param string|array $field Reference to field to be secured. Should be dot separated to indicate nesting.
+ * @param mixed $value Field value, if value should not be tampered with.
+ * @return void
+ */
+ protected function _secure($lock, $field = null, $value = null) {
+ if (!$field) {
+ $field = $this->entity();
+ } elseif (is_string($field)) {
+ $field = Hash::filter(explode('.', $field));
+ }
+
+ foreach ($this->_unlockedFields as $unlockField) {
+ $unlockParts = explode('.', $unlockField);
+ if (array_values(array_intersect($field, $unlockParts)) === $unlockParts) {
+ return;
+ }
+ }
+
+ $field = implode('.', $field);
+ $field = preg_replace('/(\.\d+)+$/', '', $field);
+
+ if ($lock) {
+ if (!in_array($field, $this->fields)) {
+ if ($value !== null) {
+ return $this->fields[$field] = $value;
+ }
+ $this->fields[] = $field;
+ }
+ } else {
+ $this->unlockField($field);
+ }
+ }
+
+/**
+ * Returns true if there is an error for the given field, otherwise false
+ *
+ * @param string $field This should be "Modelname.fieldname"
+ * @return boolean If there are errors this method returns true, else false.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::isFieldError
+ */
+ public function isFieldError($field) {
+ $this->setEntity($field);
+ return (bool)$this->tagIsInvalid();
+ }
+
+/**
+ * Returns a formatted error message for given FORM field, NULL if no errors.
+ *
+ * ### Options:
+ *
+ * - `escape` bool Whether or not to html escape the contents of the error.
+ * - `wrap` mixed Whether or not the error message should be wrapped in a div. If a
+ * string, will be used as the HTML tag to use.
+ * - `class` string The classname for the error message
+ *
+ * @param string $field A field name, like "Modelname.fieldname"
+ * @param string|array $text Error message as string or array of messages.
+ * If array contains `attributes` key it will be used as options for error container
+ * @param array $options Rendering options for <div /> wrapper tag
+ * @return string If there are errors this method returns an error message, otherwise null.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::error
+ */
+ public function error($field, $text = null, $options = array()) {
+ $defaults = array('wrap' => true, 'class' => 'error-message', 'escape' => true);
+ $options = array_merge($defaults, $options);
+ $this->setEntity($field);
+
+ $error = $this->tagIsInvalid();
+ if ($error === false) {
+ return null;
+ }
+ if (is_array($text)) {
+ if (isset($text['attributes']) && is_array($text['attributes'])) {
+ $options = array_merge($options, $text['attributes']);
+ unset($text['attributes']);
+ }
+ $tmp = array();
+ foreach ($error as &$e) {
+ if (isset($text[$e])) {
+ $tmp[] = $text[$e];
+ } else {
+ $tmp[] = $e;
+ }
+ }
+ $text = $tmp;
+ }
+
+ if ($text !== null) {
+ $error = $text;
+ }
+ if (is_array($error)) {
+ foreach ($error as &$e) {
+ if (is_numeric($e)) {
+ $e = __d('cake', 'Error in field %s', Inflector::humanize($this->field()));
+ }
+ }
+ }
+ if ($options['escape']) {
+ $error = h($error);
+ unset($options['escape']);
+ }
+ if (is_array($error)) {
+ if (count($error) > 1) {
+ $listParams = array();
+ if (isset($options['listOptions'])) {
+ if (is_string($options['listOptions'])) {
+ $listParams[] = $options['listOptions'];
+ } else {
+ if (isset($options['listOptions']['itemOptions'])) {
+ $listParams[] = $options['listOptions']['itemOptions'];
+ unset($options['listOptions']['itemOptions']);
+ } else {
+ $listParams[] = array();
+ }
+ if (isset($options['listOptions']['tag'])) {
+ $listParams[] = $options['listOptions']['tag'];
+ unset($options['listOptions']['tag']);
+ }
+ array_unshift($listParams, $options['listOptions']);
+ }
+ unset($options['listOptions']);
+ }
+ array_unshift($listParams, $error);
+ $error = call_user_func_array(array($this->Html, 'nestedList'), $listParams);
+ } else {
+ $error = array_pop($error);
+ }
+ }
+ if ($options['wrap']) {
+ $tag = is_string($options['wrap']) ? $options['wrap'] : 'div';
+ unset($options['wrap']);
+ return $this->Html->tag($tag, $error, $options);
+ } else {
+ return $error;
+ }
+ }
+
+/**
+ * Returns a formatted LABEL element for HTML FORMs. Will automatically generate
+ * a for attribute if one is not provided.
+ *
+ * ### Options
+ *
+ * - `for` - Set the for attribute, if its not defined the for attribute
+ * will be generated from the $fieldName parameter using
+ * FormHelper::domId().
+ *
+ * Examples:
+ *
+ * The text and for attribute are generated off of the fieldname
+ *
+ * {{{
+ * echo $this->Form->label('Post.published');
+ * <label for="PostPublished">Published</label>
+ * }}}
+ *
+ * Custom text:
+ *
+ * {{{
+ * echo $this->Form->label('Post.published', 'Publish');
+ * <label for="PostPublished">Publish</label>
+ * }}}
+ *
+ * Custom class name:
+ *
+ * {{{
+ * echo $this->Form->label('Post.published', 'Publish', 'required');
+ * <label for="PostPublished" class="required">Publish</label>
+ * }}}
+ *
+ * Custom attributes:
+ *
+ * {{{
+ * echo $this->Form->label('Post.published', 'Publish', array(
+ * 'for' => 'post-publish'
+ * ));
+ * <label for="post-publish">Publish</label>
+ * }}}
+ *
+ * @param string $fieldName This should be "Modelname.fieldname"
+ * @param string $text Text that will appear in the label field. If
+ * $text is left undefined the text will be inflected from the
+ * fieldName.
+ * @param array|string $options An array of HTML attributes, or a string, to be used as a class name.
+ * @return string The formatted LABEL element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::label
+ */
+ public function label($fieldName = null, $text = null, $options = array()) {
+ if (empty($fieldName)) {
+ $fieldName = implode('.', $this->entity());
+ }
+
+ if ($text === null) {
+ if (strpos($fieldName, '.') !== false) {
+ $fieldElements = explode('.', $fieldName);
+ $text = array_pop($fieldElements);
+ } else {
+ $text = $fieldName;
+ }
+ if (substr($text, -3) == '_id') {
+ $text = substr($text, 0, -3);
+ }
+ $text = __(Inflector::humanize(Inflector::underscore($text)));
+ }
+
+ if (is_string($options)) {
+ $options = array('class' => $options);
+ }
+
+ if (isset($options['for'])) {
+ $labelFor = $options['for'];
+ unset($options['for']);
+ } else {
+ $labelFor = $this->domId($fieldName);
+ }
+
+ return $this->Html->useTag('label', $labelFor, $options, $text);
+ }
+
+/**
+ * Generate a set of inputs for `$fields`. If $fields is null the current model
+ * will be used.
+ *
+ * In addition to controller fields output, `$fields` can be used to control legend
+ * and fieldset rendering with the `fieldset` and `legend` keys.
+ * `$form->inputs(array('legend' => 'My legend'));` Would generate an input set with
+ * a custom legend. You can customize individual inputs through `$fields` as well.
+ *
+ * {{{
+ * $form->inputs(array(
+ * 'name' => array('label' => 'custom label')
+ * ));
+ * }}}
+ *
+ * In addition to fields control, inputs() allows you to use a few additional options.
+ *
+ * - `fieldset` Set to false to disable the fieldset. If a string is supplied it will be used as
+ * the classname for the fieldset element.
+ * - `legend` Set to false to disable the legend for the generated input set. Or supply a string
+ * to customize the legend text.
+ *
+ * @param array $fields An array of fields to generate inputs for, or null.
+ * @param array $blacklist a simple array of fields to not create inputs for.
+ * @return string Completed form inputs.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::inputs
+ */
+ public function inputs($fields = null, $blacklist = null) {
+ $fieldset = $legend = true;
+ $model = $this->model();
+ if (is_array($fields)) {
+ if (array_key_exists('legend', $fields)) {
+ $legend = $fields['legend'];
+ unset($fields['legend']);
+ }
+
+ if (isset($fields['fieldset'])) {
+ $fieldset = $fields['fieldset'];
+ unset($fields['fieldset']);
+ }
+ } elseif ($fields !== null) {
+ $fieldset = $legend = $fields;
+ if (!is_bool($fieldset)) {
+ $fieldset = true;
+ }
+ $fields = array();
+ }
+
+ if (empty($fields)) {
+ $fields = array_keys($this->_introspectModel($model, 'fields'));
+ }
+
+ if ($legend === true) {
+ $actionName = __d('cake', 'New %s');
+ $isEdit = (
+ strpos($this->request->params['action'], 'update') !== false ||
+ strpos($this->request->params['action'], 'edit') !== false
+ );
+ if ($isEdit) {
+ $actionName = __d('cake', 'Edit %s');
+ }
+ $modelName = Inflector::humanize(Inflector::underscore($model));
+ $legend = sprintf($actionName, __($modelName));
+ }
+
+ $out = null;
+ foreach ($fields as $name => $options) {
+ if (is_numeric($name) && !is_array($options)) {
+ $name = $options;
+ $options = array();
+ }
+ $entity = explode('.', $name);
+ $blacklisted = (
+ is_array($blacklist) &&
+ (in_array($name, $blacklist) || in_array(end($entity), $blacklist))
+ );
+ if ($blacklisted) {
+ continue;
+ }
+ $out .= $this->input($name, $options);
+ }
+
+ if (is_string($fieldset)) {
+ $fieldsetClass = sprintf(' class="%s"', $fieldset);
+ } else {
+ $fieldsetClass = '';
+ }
+
+ if ($fieldset && $legend) {
+ return $this->Html->useTag('fieldset', $fieldsetClass, $this->Html->useTag('legend', $legend) . $out);
+ } elseif ($fieldset) {
+ return $this->Html->useTag('fieldset', $fieldsetClass, $out);
+ } else {
+ return $out;
+ }
+ }
+
+/**
+ * Generates a form input element complete with label and wrapper div
+ *
+ * ### Options
+ *
+ * See each field type method for more information. Any options that are part of
+ * $attributes or $options for the different **type** methods can be included in `$options` for input().i
+ * Additionally, any unknown keys that are not in the list below, or part of the selected type's options
+ * will be treated as a regular html attribute for the generated input.
+ *
+ * - `type` - Force the type of widget you want. e.g. `type => 'select'`
+ * - `label` - Either a string label, or an array of options for the label. See FormHelper::label()
+ * - `div` - Either `false` to disable the div, or an array of options for the div.
+ * See HtmlHelper::div() for more options.
+ * - `options` - for widgets that take options e.g. radio, select
+ * - `error` - control the error message that is produced
+ * - `empty` - String or boolean to enable empty select box options.
+ * - `before` - Content to place before the label + input.
+ * - `after` - Content to place after the label + input.
+ * - `between` - Content to place between the label + input.
+ * - `format` - format template for element order. Any element that is not in the array, will not be in the output.
+ * - Default input format order: array('before', 'label', 'between', 'input', 'after', 'error')
+ * - Default checkbox format order: array('before', 'input', 'between', 'label', 'after', 'error')
+ * - Hidden input will not be formatted
+ * - Radio buttons cannot have the order of input and label elements controlled with these settings.
+ *
+ * @param string $fieldName This should be "Modelname.fieldname"
+ * @param array $options Each type of input takes different options.
+ * @return string Completed form widget.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#creating-form-elements
+ */
+ public function input($fieldName, $options = array()) {
+ $this->setEntity($fieldName);
+
+ $options = array_merge(
+ array('before' => null, 'between' => null, 'after' => null, 'format' => null),
+ $this->_inputDefaults,
+ $options
+ );
+
+ $modelKey = $this->model();
+ $fieldKey = $this->field();
+
+ if (!isset($options['type'])) {
+ $magicType = true;
+ $options['type'] = 'text';
+ if (isset($options['options'])) {
+ $options['type'] = 'select';
+ } elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) {
+ $options['type'] = 'password';
+ } elseif (isset($options['checked'])) {
+ $options['type'] = 'checkbox';
+ } elseif ($fieldDef = $this->_introspectModel($modelKey, 'fields', $fieldKey)) {
+ $type = $fieldDef['type'];
+ $primaryKey = $this->fieldset[$modelKey]['key'];
+ }
+
+ if (isset($type)) {
+ $map = array(
+ 'string' => 'text', 'datetime' => 'datetime',
+ 'boolean' => 'checkbox', 'timestamp' => 'datetime',
+ 'text' => 'textarea', 'time' => 'time',
+ 'date' => 'date', 'float' => 'number',
+ 'integer' => 'number'
+ );
+
+ if (isset($this->map[$type])) {
+ $options['type'] = $this->map[$type];
+ } elseif (isset($map[$type])) {
+ $options['type'] = $map[$type];
+ }
+ if ($fieldKey == $primaryKey) {
+ $options['type'] = 'hidden';
+ }
+ if (
+ $options['type'] === 'number' &&
+ $type === 'float' &&
+ !isset($options['step'])
+ ) {
+ $options['step'] = 'any';
+ }
+ }
+ if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') {
+ $options['type'] = 'select';
+ }
+
+ if ($modelKey === $fieldKey) {
+ $options['type'] = 'select';
+ if (!isset($options['multiple'])) {
+ $options['multiple'] = 'multiple';
+ }
+ }
+ }
+ $types = array('checkbox', 'radio', 'select');
+
+ if (
+ (!isset($options['options']) && in_array($options['type'], $types)) ||
+ (isset($magicType) && $options['type'] == 'text')
+ ) {
+ $varName = Inflector::variable(
+ Inflector::pluralize(preg_replace('/_id$/', '', $fieldKey))
+ );
+ $varOptions = $this->_View->getVar($varName);
+ if (is_array($varOptions)) {
+ if ($options['type'] !== 'radio') {
+ $options['type'] = 'select';
+ }
+ $options['options'] = $varOptions;
+ }
+ }
+
+ $autoLength = (!array_key_exists('maxlength', $options) && isset($fieldDef['length']));
+ if ($autoLength && $options['type'] == 'text') {
+ $options['maxlength'] = $fieldDef['length'];
+ }
+ if ($autoLength && $fieldDef['type'] == 'float') {
+ $options['maxlength'] = array_sum(explode(',', $fieldDef['length'])) + 1;
+ }
+
+ $divOptions = array();
+ $div = $this->_extractOption('div', $options, true);
+ unset($options['div']);
+
+ if (!empty($div)) {
+ $divOptions['class'] = 'input';
+ $divOptions = $this->addClass($divOptions, $options['type']);
+ if (is_string($div)) {
+ $divOptions['class'] = $div;
+ } elseif (is_array($div)) {
+ $divOptions = array_merge($divOptions, $div);
+ }
+ if ($this->_introspectModel($modelKey, 'validates', $fieldKey)) {
+ $divOptions = $this->addClass($divOptions, 'required');
+ }
+ if (!isset($divOptions['tag'])) {
+ $divOptions['tag'] = 'div';
+ }
+ }
+
+ $label = null;
+ if (isset($options['label']) && $options['type'] !== 'radio') {
+ $label = $options['label'];
+ unset($options['label']);
+ }
+
+ if ($options['type'] === 'radio') {
+ $label = false;
+ if (isset($options['options'])) {
+ $radioOptions = (array)$options['options'];
+ unset($options['options']);
+ }
+ }
+
+ if ($label !== false) {
+ $label = $this->_inputLabel($fieldName, $label, $options);
+ }
+
+ $error = $this->_extractOption('error', $options, null);
+ unset($options['error']);
+
+ $selected = $this->_extractOption('selected', $options, null);
+ unset($options['selected']);
+
+ if (isset($options['rows']) || isset($options['cols'])) {
+ $options['type'] = 'textarea';
+ }
+
+ if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time' || $options['type'] === 'select') {
+ $options += array('empty' => false);
+ }
+ if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time') {
+ $dateFormat = $this->_extractOption('dateFormat', $options, 'MDY');
+ $timeFormat = $this->_extractOption('timeFormat', $options, 12);
+ unset($options['dateFormat'], $options['timeFormat']);
+ }
+
+ $type = $options['type'];
+ $out = array_merge(
+ array('before' => null, 'label' => null, 'between' => null, 'input' => null, 'after' => null, 'error' => null),
+ array('before' => $options['before'], 'label' => $label, 'between' => $options['between'], 'after' => $options['after'])
+ );
+ $format = null;
+ if (is_array($options['format']) && in_array('input', $options['format'])) {
+ $format = $options['format'];
+ }
+ unset($options['type'], $options['before'], $options['between'], $options['after'], $options['format']);
+
+ switch ($type) {
+ case 'hidden':
+ $input = $this->hidden($fieldName, $options);
+ $format = array('input');
+ unset($divOptions);
+ break;
+ case 'checkbox':
+ $input = $this->checkbox($fieldName, $options);
+ $format = $format ? $format : array('before', 'input', 'between', 'label', 'after', 'error');
+ break;
+ case 'radio':
+ if (isset($out['between'])) {
+ $options['between'] = $out['between'];
+ $out['between'] = null;
+ }
+ $input = $this->radio($fieldName, $radioOptions, $options);
+ break;
+ case 'file':
+ $input = $this->file($fieldName, $options);
+ break;
+ case 'select':
+ $options += array('options' => array(), 'value' => $selected);
+ $list = $options['options'];
+ unset($options['options']);
+ $input = $this->select($fieldName, $list, $options);
+ break;
+ case 'time':
+ $options['value'] = $selected;
+ $input = $this->dateTime($fieldName, null, $timeFormat, $options);
+ break;
+ case 'date':
+ $options['value'] = $selected;
+ $input = $this->dateTime($fieldName, $dateFormat, null, $options);
+ break;
+ case 'datetime':
+ $options['value'] = $selected;
+ $input = $this->dateTime($fieldName, $dateFormat, $timeFormat, $options);
+ break;
+ case 'textarea':
+ $input = $this->textarea($fieldName, $options + array('cols' => '30', 'rows' => '6'));
+ break;
+ case 'url':
+ $input = $this->text($fieldName, array('type' => 'url') + $options);
+ break;
+ default:
+ $input = $this->{$type}($fieldName, $options);
+ }
+
+ if ($type != 'hidden' && $error !== false) {
+ $errMsg = $this->error($fieldName, $error);
+ if ($errMsg) {
+ $divOptions = $this->addClass($divOptions, 'error');
+ $out['error'] = $errMsg;
+ }
+ }
+
+ $out['input'] = $input;
+ $format = $format ? $format : array('before', 'label', 'between', 'input', 'after', 'error');
+ $output = '';
+ foreach ($format as $element) {
+ $output .= $out[$element];
+ unset($out[$element]);
+ }
+
+ if (!empty($divOptions['tag'])) {
+ $tag = $divOptions['tag'];
+ unset($divOptions['tag']);
+ $output = $this->Html->tag($tag, $output, $divOptions);
+ }
+ return $output;
+ }
+
+/**
+ * Extracts a single option from an options array.
+ *
+ * @param string $name The name of the option to pull out.
+ * @param array $options The array of options you want to extract.
+ * @param mixed $default The default option value
+ * @return mixed the contents of the option or default
+ */
+ protected function _extractOption($name, $options, $default = null) {
+ if (array_key_exists($name, $options)) {
+ return $options[$name];
+ }
+ return $default;
+ }
+
+/**
+ * Generate a label for an input() call.
+ *
+ * $options can contain a hash of id overrides. These overrides will be
+ * used instead of the generated values if present.
+ *
+ * @param string $fieldName
+ * @param string $label
+ * @param array $options Options for the label element.
+ * @return string Generated label element
+ * @deprecated 'NONE' option is deprecated and will be removed in 3.0
+ */
+ protected function _inputLabel($fieldName, $label, $options) {
+ $labelAttributes = $this->domId(array(), 'for');
+ $idKey = null;
+ if ($options['type'] === 'date' || $options['type'] === 'datetime') {
+ $firstInput = 'M';
+ if (
+ array_key_exists('dateFormat', $options) &&
+ ($options['dateFormat'] === null || $options['dateFormat'] === 'NONE')
+ ) {
+ $firstInput = 'H';
+ } elseif (!empty($options['dateFormat'])) {
+ $firstInput = substr($options['dateFormat'], 0, 1);
+ }
+ switch ($firstInput) {
+ case 'D':
+ $idKey = 'day';
+ $labelAttributes['for'] .= 'Day';
+ break;
+ case 'Y':
+ $idKey = 'year';
+ $labelAttributes['for'] .= 'Year';
+ break;
+ case 'M':
+ $idKey = 'month';
+ $labelAttributes['for'] .= 'Month';
+ break;
+ case 'H':
+ $idKey = 'hour';
+ $labelAttributes['for'] .= 'Hour';
+ }
+ }
+ if ($options['type'] === 'time') {
+ $labelAttributes['for'] .= 'Hour';
+ $idKey = 'hour';
+ }
+ if (isset($idKey) && isset($options['id']) && isset($options['id'][$idKey])) {
+ $labelAttributes['for'] = $options['id'][$idKey];
+ }
+
+ if (is_array($label)) {
+ $labelText = null;
+ if (isset($label['text'])) {
+ $labelText = $label['text'];
+ unset($label['text']);
+ }
+ $labelAttributes = array_merge($labelAttributes, $label);
+ } else {
+ $labelText = $label;
+ }
+
+ if (isset($options['id']) && is_string($options['id'])) {
+ $labelAttributes = array_merge($labelAttributes, array('for' => $options['id']));
+ }
+ return $this->label($fieldName, $labelText, $labelAttributes);
+ }
+
+/**
+ * Creates a checkbox input widget.
+ *
+ * ### Options:
+ *
+ * - `value` - the value of the checkbox
+ * - `checked` - boolean indicate that this checkbox is checked.
+ * - `hiddenField` - boolean to indicate if you want the results of checkbox() to include
+ * a hidden input with a value of ''.
+ * - `disabled` - create a disabled input.
+ * - `default` - Set the default value for the checkbox. This allows you to start checkboxes
+ * as checked, without having to check the POST data. A matching POST data value, will overwrite
+ * the default value.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname.fieldname"
+ * @param array $options Array of HTML attributes.
+ * @return string An HTML text input element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-select-checkbox-and-radio-inputs
+ */
+ public function checkbox($fieldName, $options = array()) {
+ $valueOptions = array();
+ if (isset($options['default'])) {
+ $valueOptions['default'] = $options['default'];
+ unset($options['default']);
+ }
+
+ $options = $this->_initInputField($fieldName, $options) + array('hiddenField' => true);
+ $value = current($this->value($valueOptions));
+ $output = "";
+
+ if (empty($options['value'])) {
+ $options['value'] = 1;
+ }
+ if (
+ (!isset($options['checked']) && !empty($value) && $value == $options['value']) ||
+ !empty($options['checked'])
+ ) {
+ $options['checked'] = 'checked';
+ }
+ if ($options['hiddenField']) {
+ $hiddenOptions = array(
+ 'id' => $options['id'] . '_',
+ 'name' => $options['name'],
+ 'value' => ($options['hiddenField'] !== true ? $options['hiddenField'] : '0'),
+ 'secure' => false
+ );
+ if (isset($options['disabled']) && $options['disabled'] == true) {
+ $hiddenOptions['disabled'] = 'disabled';
+ }
+ $output = $this->hidden($fieldName, $hiddenOptions);
+ }
+ unset($options['hiddenField']);
+
+ return $output . $this->Html->useTag('checkbox', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates a set of radio widgets. Will create a legend and fieldset
+ * by default. Use $options to control this
+ *
+ * ### Attributes:
+ *
+ * - `separator` - define the string in between the radio buttons
+ * - `between` - the string between legend and input set
+ * - `legend` - control whether or not the widget set has a fieldset & legend
+ * - `value` - indicate a value that is should be checked
+ * - `label` - boolean to indicate whether or not labels for widgets show be displayed
+ * - `hiddenField` - boolean to indicate if you want the results of radio() to include
+ * a hidden input with a value of ''. This is useful for creating radio sets that non-continuous
+ * - `disabled` - Set to `true` or `disabled` to disable all the radio buttons.
+ * - `empty` - Set to `true` to create a input with the value '' as the first option. When `true`
+ * the radio label will be 'empty'. Set this option to a string to control the label value.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname.fieldname"
+ * @param array $options Radio button options array.
+ * @param array $attributes Array of HTML attributes, and special attributes above.
+ * @return string Completed radio widget set.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-select-checkbox-and-radio-inputs
+ */
+ public function radio($fieldName, $options = array(), $attributes = array()) {
+ $attributes = $this->_initInputField($fieldName, $attributes);
+
+ $showEmpty = $this->_extractOption('empty', $attributes);
+ if ($showEmpty) {
+ $showEmpty = ($showEmpty === true) ? __('empty') : $showEmpty;
+ $options = array('' => $showEmpty) + $options;
+ }
+ unset($attributes['empty']);
+
+ $legend = false;
+ if (isset($attributes['legend'])) {
+ $legend = $attributes['legend'];
+ unset($attributes['legend']);
+ } elseif (count($options) > 1) {
+ $legend = __(Inflector::humanize($this->field()));
+ }
+
+ $label = true;
+ if (isset($attributes['label'])) {
+ $label = $attributes['label'];
+ unset($attributes['label']);
+ }
+
+ $separator = null;
+ if (isset($attributes['separator'])) {
+ $separator = $attributes['separator'];
+ unset($attributes['separator']);
+ }
+
+ $between = null;
+ if (isset($attributes['between'])) {
+ $between = $attributes['between'];
+ unset($attributes['between']);
+ }
+
+ $value = null;
+ if (isset($attributes['value'])) {
+ $value = $attributes['value'];
+ } else {
+ $value = $this->value($fieldName);
+ }
+
+ $disabled = array();
+ if (isset($attributes['disabled'])) {
+ $disabled = $attributes['disabled'];
+ }
+
+ $out = array();
+
+ $hiddenField = isset($attributes['hiddenField']) ? $attributes['hiddenField'] : true;
+ unset($attributes['hiddenField']);
+
+ foreach ($options as $optValue => $optTitle) {
+ $optionsHere = array('value' => $optValue);
+
+ if (isset($value) && $optValue == $value) {
+ $optionsHere['checked'] = 'checked';
+ }
+ if ($disabled && (!is_array($disabled) || in_array($optValue, $disabled))) {
+ $optionsHere['disabled'] = true;
+ }
+ $tagName = Inflector::camelize(
+ $attributes['id'] . '_' . Inflector::slug($optValue)
+ );
+
+ if ($label) {
+ $optTitle = $this->Html->useTag('label', $tagName, '', $optTitle);
+ }
+ $allOptions = array_merge($attributes, $optionsHere);
+ $out[] = $this->Html->useTag('radio', $attributes['name'], $tagName,
+ array_diff_key($allOptions, array('name' => '', 'type' => '', 'id' => '')),
+ $optTitle
+ );
+ }
+ $hidden = null;
+
+ if ($hiddenField) {
+ if (!isset($value) || $value === '') {
+ $hidden = $this->hidden($fieldName, array(
+ 'id' => $attributes['id'] . '_', 'value' => '', 'name' => $attributes['name']
+ ));
+ }
+ }
+ $out = $hidden . implode($separator, $out);
+
+ if ($legend) {
+ $out = $this->Html->useTag('fieldset', '', $this->Html->useTag('legend', $legend) . $between . $out);
+ }
+ return $out;
+ }
+
+/**
+ * Missing method handler - implements various simple input types. Is used to create inputs
+ * of various types. e.g. `$this->Form->text();` will create `<input type="text" />` while
+ * `$this->Form->range();` will create `<input type="range" />`
+ *
+ * ### Usage
+ *
+ * `$this->Form->search('User.query', array('value' => 'test'));`
+ *
+ * Will make an input like:
+ *
+ * `<input type="search" id="UserQuery" name="data[User][query]" value="test" />`
+ *
+ * The first argument to an input type should always be the fieldname, in `Model.field` format.
+ * The second argument should always be an array of attributes for the input.
+ *
+ * @param string $method Method name / input type to make.
+ * @param array $params Parameters for the method call
+ * @return string Formatted input method.
+ * @throws CakeException When there are no params for the method call.
+ */
+ public function __call($method, $params) {
+ $options = array();
+ if (empty($params)) {
+ throw new CakeException(__d('cake_dev', 'Missing field name for FormHelper::%s', $method));
+ }
+ if (isset($params[1])) {
+ $options = $params[1];
+ }
+ if (!isset($options['type'])) {
+ $options['type'] = $method;
+ }
+ $options = $this->_initInputField($params[0], $options);
+ return $this->Html->useTag('input', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates a textarea widget.
+ *
+ * ### Options:
+ *
+ * - `escape` - Whether or not the contents of the textarea should be escaped. Defaults to true.
+ *
+ * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
+ * @param array $options Array of HTML attributes, and special options above.
+ * @return string A generated HTML text input element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::textarea
+ */
+ public function textarea($fieldName, $options = array()) {
+ $options = $this->_initInputField($fieldName, $options);
+ $value = null;
+
+ if (array_key_exists('value', $options)) {
+ $value = $options['value'];
+ if (!array_key_exists('escape', $options) || $options['escape'] !== false) {
+ $value = h($value);
+ }
+ unset($options['value']);
+ }
+ return $this->Html->useTag('textarea', $options['name'], array_diff_key($options, array('type' => '', 'name' => '')), $value);
+ }
+
+/**
+ * Creates a hidden input field.
+ *
+ * @param string $fieldName Name of a field, in the form of "Modelname.fieldname"
+ * @param array $options Array of HTML attributes.
+ * @return string A generated hidden input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::hidden
+ */
+ public function hidden($fieldName, $options = array()) {
+ $secure = true;
+
+ if (isset($options['secure'])) {
+ $secure = $options['secure'];
+ unset($options['secure']);
+ }
+ $options = $this->_initInputField($fieldName, array_merge(
+ $options, array('secure' => self::SECURE_SKIP)
+ ));
+
+ if ($secure && $secure !== self::SECURE_SKIP) {
+ $this->_secure(true, null, '' . $options['value']);
+ }
+
+ return $this->Html->useTag('hidden', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates file input widget.
+ *
+ * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
+ * @param array $options Array of HTML attributes.
+ * @return string A generated file input.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::file
+ */
+ public function file($fieldName, $options = array()) {
+ $options += array('secure' => true);
+ $secure = $options['secure'];
+ $options['secure'] = self::SECURE_SKIP;
+
+ $options = $this->_initInputField($fieldName, $options);
+ $field = $this->entity();
+
+ foreach (array('name', 'type', 'tmp_name', 'error', 'size') as $suffix) {
+ $this->_secure($secure, array_merge($field, array($suffix)));
+ }
+
+ return $this->Html->useTag('file', $options['name'], array_diff_key($options, array('name' => '')));
+ }
+
+/**
+ * Creates a `<button>` tag. The type attribute defaults to `type="submit"`
+ * You can change it to a different value by using `$options['type']`.
+ *
+ * ### Options:
+ *
+ * - `escape` - HTML entity encode the $title of the button. Defaults to false.
+ *
+ * @param string $title The button's caption. Not automatically HTML encoded
+ * @param array $options Array of options and HTML attributes.
+ * @return string A HTML button tag.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::button
+ */
+ public function button($title, $options = array()) {
+ $options += array('type' => 'submit', 'escape' => false, 'secure' => false);
+ if ($options['escape']) {
+ $title = h($title);
+ }
+ if (isset($options['name'])) {
+ $name = str_replace(array('[', ']'), array('.', ''), $options['name']);
+ $this->_secure($options['secure'], $name);
+ }
+ return $this->Html->useTag('button', $options, $title);
+ }
+
+/**
+ * Create a `<button>` tag with a surrounding `<form>` that submits via POST.
+ *
+ * This method creates a `<form>` element. So do not use this method in an already opened form.
+ * Instead use FormHelper::submit() or FormHelper::button() to create buttons inside opened forms.
+ *
+ * ### Options:
+ *
+ * - `data` - Array with key/value to pass in input hidden
+ * - Other options is the same of button method.
+ *
+ * @param string $title The button's caption. Not automatically HTML encoded
+ * @param string|array $url URL as string or array
+ * @param array $options Array of options and HTML attributes.
+ * @return string A HTML button tag.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::postButton
+ */
+ public function postButton($title, $url, $options = array()) {
+ $out = $this->create(false, array('id' => false, 'url' => $url));
+ if (isset($options['data']) && is_array($options['data'])) {
+ foreach ($options['data'] as $key => $value) {
+ $out .= $this->hidden($key, array('value' => $value, 'id' => false));
+ }
+ unset($options['data']);
+ }
+ $out .= $this->button($title, $options);
+ $out .= $this->end();
+ return $out;
+ }
+
+/**
+ * Creates an HTML link, but access the url using method POST.
+ * Requires javascript to be enabled in browser.
+ *
+ * This method creates a `<form>` element. So do not use this method inside an existing form.
+ * Instead you should add a submit button using FormHelper::submit()
+ *
+ * ### Options:
+ *
+ * - `data` - Array with key/value to pass in input hidden
+ * - `confirm` - Can be used instead of $confirmMessage.
+ * - Other options is the same of HtmlHelper::link() method.
+ * - The option `onclick` will be replaced.
+ *
+ * @param string $title The content to be wrapped by <a> tags.
+ * @param string|array $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
+ * @param array $options Array of HTML attributes.
+ * @param string $confirmMessage JavaScript confirmation message.
+ * @return string An `<a />` element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::postLink
+ */
+ public function postLink($title, $url = null, $options = array(), $confirmMessage = false) {
+ if (!empty($options['confirm'])) {
+ $confirmMessage = $options['confirm'];
+ unset($options['confirm']);
+ }
+
+ $formName = uniqid('post_');
+ $formUrl = $this->url($url);
+ $out = $this->Html->useTag('form', $formUrl, array('name' => $formName, 'id' => $formName, 'style' => 'display:none;', 'method' => 'post'));
+ $out .= $this->Html->useTag('hidden', '_method', ' value="POST"');
+ $out .= $this->_csrfField();
+
+ $fields = array();
+ if (isset($options['data']) && is_array($options['data'])) {
+ foreach ($options['data'] as $key => $value) {
+ $fields[$key] = $value;
+ $out .= $this->hidden($key, array('value' => $value, 'id' => false));
+ }
+ unset($options['data']);
+ }
+ $out .= $this->secure($fields);
+ $out .= $this->Html->useTag('formend');
+
+ $url = '#';
+ $onClick = 'document.' . $formName . '.submit();';
+ if ($confirmMessage) {
+ $confirmMessage = str_replace(array("'", '"'), array("\'", '\"'), $confirmMessage);
+ $options['onclick'] = "if (confirm('{$confirmMessage}')) { {$onClick} }";
+ } else {
+ $options['onclick'] = $onClick;
+ }
+ $options['onclick'] .= ' event.returnValue = false; return false;';
+
+ $out .= $this->Html->link($title, $url, $options);
+ return $out;
+ }
+
+/**
+ * Creates a submit button element. This method will generate `<input />` elements that
+ * can be used to submit, and reset forms by using $options. image submits can be created by supplying an
+ * image path for $caption.
+ *
+ * ### Options
+ *
+ * - `div` - Include a wrapping div? Defaults to true. Accepts sub options similar to
+ * FormHelper::input().
+ * - `before` - Content to include before the input.
+ * - `after` - Content to include after the input.
+ * - `type` - Set to 'reset' for reset inputs. Defaults to 'submit'
+ * - Other attributes will be assigned to the input element.
+ *
+ * ### Options
+ *
+ * - `div` - Include a wrapping div? Defaults to true. Accepts sub options similar to
+ * FormHelper::input().
+ * - Other attributes will be assigned to the input element.
+ *
+ * @param string $caption The label appearing on the button OR if string contains :// or the
+ * extension .jpg, .jpe, .jpeg, .gif, .png use an image if the extension
+ * exists, AND the first character is /, image is relative to webroot,
+ * OR if the first character is not /, image is relative to webroot/img.
+ * @param array $options Array of options. See above.
+ * @return string A HTML submit button
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::submit
+ */
+ public function submit($caption = null, $options = array()) {
+ if (!is_string($caption) && empty($caption)) {
+ $caption = __d('cake', 'Submit');
+ }
+ $out = null;
+ $div = true;
+
+ if (isset($options['div'])) {
+ $div = $options['div'];
+ unset($options['div']);
+ }
+ $options += array('type' => 'submit', 'before' => null, 'after' => null, 'secure' => false);
+ $divOptions = array('tag' => 'div');
+
+ if ($div === true) {
+ $divOptions['class'] = 'submit';
+ } elseif ($div === false) {
+ unset($divOptions);
+ } elseif (is_string($div)) {
+ $divOptions['class'] = $div;
+ } elseif (is_array($div)) {
+ $divOptions = array_merge(array('class' => 'submit', 'tag' => 'div'), $div);
+ }
+
+ if (isset($options['name'])) {
+ $name = str_replace(array('[', ']'), array('.', ''), $options['name']);
+ $this->_secure($options['secure'], $name);
+ }
+ unset($options['secure']);
+
+ $before = $options['before'];
+ $after = $options['after'];
+ unset($options['before'], $options['after']);
+
+ $isUrl = strpos($caption, '://') !== false;
+ $isImage = preg_match('/\.(jpg|jpe|jpeg|gif|png|ico)$/', $caption);
+
+ if ($isUrl || $isImage) {
+ $unlockFields = array('x', 'y');
+ if (isset($options['name'])) {
+ $unlockFields = array(
+ $options['name'] . '_x', $options['name'] . '_y'
+ );
+ }
+ foreach ($unlockFields as $ignore) {
+ $this->unlockField($ignore);
+ }
+ }
+
+ if ($isUrl) {
+ unset($options['type']);
+ $tag = $this->Html->useTag('submitimage', $caption, $options);
+ } elseif ($isImage) {
+ unset($options['type']);
+ if ($caption{0} !== '/') {
+ $url = $this->webroot(IMAGES_URL . $caption);
+ } else {
+ $url = $this->webroot(trim($caption, '/'));
+ }
+ $url = $this->assetTimestamp($url);
+ $tag = $this->Html->useTag('submitimage', $url, $options);
+ } else {
+ $options['value'] = $caption;
+ $tag = $this->Html->useTag('submit', $options);
+ }
+ $out = $before . $tag . $after;
+
+ if (isset($divOptions)) {
+ $tag = $divOptions['tag'];
+ unset($divOptions['tag']);
+ $out = $this->Html->tag($tag, $out, $divOptions);
+ }
+ return $out;
+ }
+
+/**
+ * Returns a formatted SELECT element.
+ *
+ * ### Attributes:
+ *
+ * - `showParents` - If included in the array and set to true, an additional option element
+ * will be added for the parent of each option group. You can set an option with the same name
+ * and it's key will be used for the value of the option.
+ * - `multiple` - show a multiple select box. If set to 'checkbox' multiple checkboxes will be
+ * created instead.
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `escape` - If true contents of options will be HTML entity encoded. Defaults to true.
+ * - `value` The selected value of the input.
+ * - `class` - When using multiple = checkbox the classname to apply to the divs. Defaults to 'checkbox'.
+ *
+ * ### Using options
+ *
+ * A simple array will create normal options:
+ *
+ * {{{
+ * $options = array(1 => 'one', 2 => 'two);
+ * $this->Form->select('Model.field', $options));
+ * }}}
+ *
+ * While a nested options array will create optgroups with options inside them.
+ * {{{
+ * $options = array(
+ * 1 => 'bill',
+ * 'fred' => array(
+ * 2 => 'fred',
+ * 3 => 'fred jr.'
+ * )
+ * );
+ * $this->Form->select('Model.field', $options);
+ * }}}
+ *
+ * In the above `2 => 'fred'` will not generate an option element. You should enable the `showParents`
+ * attribute to show the fred option.
+ *
+ * If you have multiple options that need to have the same value attribute, you can
+ * use an array of arrays to express this:
+ *
+ * {{{
+ * $options = array(
+ * array('name' => 'United states', 'value' => 'USA'),
+ * array('name' => 'USA', 'value' => 'USA'),
+ * );
+ * }}}
+ *
+ * @param string $fieldName Name attribute of the SELECT
+ * @param array $options Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the
+ * SELECT element
+ * @param array $attributes The HTML attributes of the select element.
+ * @return string Formatted SELECT element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-select-checkbox-and-radio-inputs
+ */
+ public function select($fieldName, $options = array(), $attributes = array()) {
+ $select = array();
+ $style = null;
+ $tag = null;
+ $attributes += array(
+ 'class' => null,
+ 'escape' => true,
+ 'secure' => true,
+ 'empty' => '',
+ 'showParents' => false,
+ 'hiddenField' => true
+ );
+
+ $escapeOptions = $this->_extractOption('escape', $attributes);
+ $secure = $this->_extractOption('secure', $attributes);
+ $showEmpty = $this->_extractOption('empty', $attributes);
+ $showParents = $this->_extractOption('showParents', $attributes);
+ $hiddenField = $this->_extractOption('hiddenField', $attributes);
+ unset($attributes['escape'], $attributes['secure'], $attributes['empty'], $attributes['showParents'], $attributes['hiddenField']);
+ $id = $this->_extractOption('id', $attributes);
+
+ $attributes = $this->_initInputField($fieldName, array_merge(
+ (array)$attributes, array('secure' => self::SECURE_SKIP)
+ ));
+
+ if (is_string($options) && isset($this->_options[$options])) {
+ $options = $this->_generateOptions($options);
+ } elseif (!is_array($options)) {
+ $options = array();
+ }
+ if (isset($attributes['type'])) {
+ unset($attributes['type']);
+ }
+
+ if (!empty($attributes['multiple'])) {
+ $style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null;
+ $template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart';
+ $tag = $template;
+ if ($hiddenField) {
+ $hiddenAttributes = array(
+ 'value' => '',
+ 'id' => $attributes['id'] . ($style ? '' : '_'),
+ 'secure' => false,
+ 'name' => $attributes['name']
+ );
+ $select[] = $this->hidden(null, $hiddenAttributes);
+ }
+ } else {
+ $tag = 'selectstart';
+ }
+
+ if (!empty($tag) || isset($template)) {
+ if ((!isset($secure) || $secure == true) && empty($attributes['disabled'])) {
+ $this->_secure(true);
+ }
+ $select[] = $this->Html->useTag($tag, $attributes['name'], array_diff_key($attributes, array('name' => '', 'value' => '')));
+ }
+ $emptyMulti = (
+ $showEmpty !== null && $showEmpty !== false && !(
+ empty($showEmpty) && (isset($attributes) &&
+ array_key_exists('multiple', $attributes))
+ )
+ );
+
+ if ($emptyMulti) {
+ $showEmpty = ($showEmpty === true) ? '' : $showEmpty;
+ $options = array('' => $showEmpty) + $options;
+ }
+
+ if (!$id) {
+ $attributes['id'] = Inflector::camelize($attributes['id']);
+ }
+
+ $select = array_merge($select, $this->_selectOptions(
+ array_reverse($options, true),
+ array(),
+ $showParents,
+ array(
+ 'escape' => $escapeOptions,
+ 'style' => $style,
+ 'name' => $attributes['name'],
+ 'value' => $attributes['value'],
+ 'class' => $attributes['class'],
+ 'id' => $attributes['id']
+ )
+ ));
+
+ $template = ($style == 'checkbox') ? 'checkboxmultipleend' : 'selectend';
+ $select[] = $this->Html->useTag($template);
+ return implode("\n", $select);
+ }
+
+/**
+ * Returns a SELECT element for days.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param array $attributes HTML attributes for the select element
+ * @return string A generated day select box.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::day
+ */
+ public function day($fieldName = null, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('day', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ $attributes['value'] = date('d', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ return $this->select($fieldName . ".day", $this->_generateOptions('day'), $attributes);
+ }
+
+/**
+ * Returns a SELECT element for years
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `orderYear` - Ordering of year values in select options.
+ * Possible values 'asc', 'desc'. Default 'desc'
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param integer $minYear First year in sequence
+ * @param integer $maxYear Last year in sequence
+ * @param array $attributes Attribute array for the select elements.
+ * @return string Completed year select input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::year
+ */
+ public function year($fieldName, $minYear = null, $maxYear = null, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ if ((empty($attributes['value']) || $attributes['value'] === true) && $value = $this->value($fieldName)) {
+ if (is_array($value)) {
+ extract($value);
+ $attributes['value'] = $year;
+ } else {
+ if (empty($value)) {
+ if (!$attributes['empty'] && !$maxYear) {
+ $attributes['value'] = 'now';
+
+ } elseif (!$attributes['empty'] && $maxYear && !$attributes['value']) {
+ $attributes['value'] = $maxYear;
+ }
+ } else {
+ $attributes['value'] = $value;
+ }
+ }
+ }
+
+ if (strlen($attributes['value']) > 4 || $attributes['value'] === 'now') {
+ $attributes['value'] = date('Y', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ $yearOptions = array('min' => $minYear, 'max' => $maxYear, 'order' => 'desc');
+ if (isset($attributes['orderYear'])) {
+ $yearOptions['order'] = $attributes['orderYear'];
+ unset($attributes['orderYear']);
+ }
+ return $this->select(
+ $fieldName . '.year', $this->_generateOptions('year', $yearOptions),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a SELECT element for months.
+ *
+ * ### Attributes:
+ *
+ * - `monthNames` - If false, 2 digit numbers will be used instead of text.
+ * If a array, the given array will be used.
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param array $attributes Attributes for the select element
+ * @return string A generated month select dropdown.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::month
+ */
+ public function month($fieldName, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('month', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ $attributes['value'] = date('m', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ $defaults = array('monthNames' => true);
+ $attributes = array_merge($defaults, (array)$attributes);
+ $monthNames = $attributes['monthNames'];
+ unset($attributes['monthNames']);
+
+ return $this->select(
+ $fieldName . ".month",
+ $this->_generateOptions('month', array('monthNames' => $monthNames)),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a SELECT element for hours.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param boolean $format24Hours True for 24 hours format
+ * @param array $attributes List of HTML attributes
+ * @return string Completed hour select input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::hour
+ */
+ public function hour($fieldName, $format24Hours = false, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('hour', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ if ($format24Hours) {
+ $attributes['value'] = date('H', strtotime($attributes['value']));
+ } else {
+ $attributes['value'] = date('g', strtotime($attributes['value']));
+ }
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ return $this->select(
+ $fieldName . ".hour",
+ $this->_generateOptions($format24Hours ? 'hour24' : 'hour'),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a SELECT element for minutes.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param string $attributes Array of Attributes
+ * @return string Completed minute select input.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::minute
+ */
+ public function minute($fieldName, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $attributes = $this->_dateTimeSelected('min', $fieldName, $attributes);
+
+ if (strlen($attributes['value']) > 2) {
+ $attributes['value'] = date('i', strtotime($attributes['value']));
+ } elseif ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ $minuteOptions = array();
+
+ if (isset($attributes['interval'])) {
+ $minuteOptions['interval'] = $attributes['interval'];
+ unset($attributes['interval']);
+ }
+ return $this->select(
+ $fieldName . ".min", $this->_generateOptions('minute', $minuteOptions),
+ $attributes
+ );
+ }
+
+/**
+ * Selects values for dateTime selects.
+ *
+ * @param string $select Name of element field. ex. 'day'
+ * @param string $fieldName Name of fieldName being generated ex. Model.created
+ * @param array $attributes Array of attributes, must contain 'empty' key.
+ * @return array Attributes array with currently selected value.
+ */
+ protected function _dateTimeSelected($select, $fieldName, $attributes) {
+ if ((empty($attributes['value']) || $attributes['value'] === true) && $value = $this->value($fieldName)) {
+ if (is_array($value) && isset($value[$select])) {
+ $attributes['value'] = $value[$select];
+ } else {
+ if (empty($value)) {
+ if (!$attributes['empty']) {
+ $attributes['value'] = 'now';
+ }
+ } else {
+ $attributes['value'] = $value;
+ }
+ }
+ }
+ return $attributes;
+ }
+
+/**
+ * Returns a SELECT element for AM or PM.
+ *
+ * ### Attributes:
+ *
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` The selected value of the input.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param string $attributes Array of Attributes
+ * @return string Completed meridian select input
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::meridian
+ */
+ public function meridian($fieldName, $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ if ((empty($attributes['value']) || $attributes['value'] === true) && $value = $this->value($fieldName)) {
+ if (is_array($value)) {
+ extract($value);
+ $attributes['value'] = $meridian;
+ } else {
+ if (empty($value)) {
+ if (!$attributes['empty']) {
+ $attributes['value'] = date('a');
+ }
+ } else {
+ $attributes['value'] = date('a', strtotime($value));
+ }
+ }
+ }
+
+ if ($attributes['value'] === false) {
+ $attributes['value'] = null;
+ }
+ return $this->select(
+ $fieldName . ".meridian", $this->_generateOptions('meridian'),
+ $attributes
+ );
+ }
+
+/**
+ * Returns a set of SELECT elements for a full datetime setup: day, month and year, and then time.
+ *
+ * ### Attributes:
+ *
+ * - `monthNames` If false, 2 digit numbers will be used instead of text.
+ * If a array, the given array will be used.
+ * - `minYear` The lowest year to use in the year select
+ * - `maxYear` The maximum year to use in the year select
+ * - `interval` The interval for the minutes select. Defaults to 1
+ * - `separator` The contents of the string between select elements. Defaults to '-'
+ * - `empty` - If true, the empty select option is shown. If a string,
+ * that string is displayed as the empty element.
+ * - `value` | `default` The default value to be used by the input. A value in `$this->data`
+ * matching the field name will override this value. If no default is provided `time()` will be used.
+ *
+ * @param string $fieldName Prefix name for the SELECT element
+ * @param string $dateFormat DMY, MDY, YMD, or null to not generate date inputs.
+ * @param string $timeFormat 12, 24, or null to not generate time inputs.
+ * @param string $attributes array of Attributes
+ * @return string Generated set of select boxes for the date and time formats chosen.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::dateTime
+ */
+ public function dateTime($fieldName, $dateFormat = 'DMY', $timeFormat = '12', $attributes = array()) {
+ $attributes += array('empty' => true, 'value' => null);
+ $year = $month = $day = $hour = $min = $meridian = null;
+
+ if (empty($attributes['value'])) {
+ $attributes = $this->value($attributes, $fieldName);
+ }
+
+ if ($attributes['value'] === null && $attributes['empty'] != true) {
+ $attributes['value'] = time();
+ }
+
+ if (!empty($attributes['value'])) {
+ if (is_array($attributes['value'])) {
+ extract($attributes['value']);
+ } else {
+ if (is_numeric($attributes['value'])) {
+ $attributes['value'] = strftime('%Y-%m-%d %H:%M:%S', $attributes['value']);
+ }
+ $meridian = 'am';
+ $pos = strpos($attributes['value'], '-');
+ if ($pos !== false) {
+ $date = explode('-', $attributes['value']);
+ $days = explode(' ', $date[2]);
+ $day = $days[0];
+ $month = $date[1];
+ $year = $date[0];
+ } else {
+ $days[1] = $attributes['value'];
+ }
+
+ if (!empty($timeFormat)) {
+ $time = explode(':', $days[1]);
+
+ if (($time[0] > 12) && $timeFormat == '12') {
+ $time[0] = $time[0] - 12;
+ $meridian = 'pm';
+ } elseif ($time[0] == '12' && $timeFormat == '12') {
+ $meridian = 'pm';
+ } elseif ($time[0] == '00' && $timeFormat == '12') {
+ $time[0] = 12;
+ } elseif ($time[0] >= 12) {
+ $meridian = 'pm';
+ }
+ if ($time[0] == 0 && $timeFormat == '12') {
+ $time[0] = 12;
+ }
+ $hour = $min = null;
+ if (isset($time[1])) {
+ $hour = $time[0];
+ $min = $time[1];
+ }
+ }
+ }
+ }
+
+ $elements = array('Day', 'Month', 'Year', 'Hour', 'Minute', 'Meridian');
+ $defaults = array(
+ 'minYear' => null, 'maxYear' => null, 'separator' => '-',
+ 'interval' => 1, 'monthNames' => true
+ );
+ $attributes = array_merge($defaults, (array)$attributes);
+ if (isset($attributes['minuteInterval'])) {
+ $attributes['interval'] = $attributes['minuteInterval'];
+ unset($attributes['minuteInterval']);
+ }
+ $minYear = $attributes['minYear'];
+ $maxYear = $attributes['maxYear'];
+ $separator = $attributes['separator'];
+ $interval = $attributes['interval'];
+ $monthNames = $attributes['monthNames'];
+ $attributes = array_diff_key($attributes, $defaults);
+
+ if (isset($attributes['id'])) {
+ if (is_string($attributes['id'])) {
+ // build out an array version
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $attributes;
+ ${$selectAttrName}['id'] = $attributes['id'] . $element;
+ }
+ } elseif (is_array($attributes['id'])) {
+ // check for missing ones and build selectAttr for each element
+ $attributes['id'] += array(
+ 'month' => '', 'year' => '', 'day' => '',
+ 'hour' => '', 'minute' => '', 'meridian' => ''
+ );
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $attributes;
+ ${$selectAttrName}['id'] = $attributes['id'][strtolower($element)];
+ }
+ }
+ } else {
+ // build the selectAttrName with empty id's to pass
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $attributes;
+ }
+ }
+
+ $selects = array();
+ foreach (preg_split('//', $dateFormat, -1, PREG_SPLIT_NO_EMPTY) as $char) {
+ switch ($char) {
+ case 'Y':
+ $selectYearAttr['value'] = $year;
+ $selects[] = $this->year(
+ $fieldName, $minYear, $maxYear, $selectYearAttr
+ );
+ break;
+ case 'M':
+ $selectMonthAttr['value'] = $month;
+ $selectMonthAttr['monthNames'] = $monthNames;
+ $selects[] = $this->month($fieldName, $selectMonthAttr);
+ break;
+ case 'D':
+ $selectDayAttr['value'] = $day;
+ $selects[] = $this->day($fieldName, $selectDayAttr);
+ break;
+ }
+ }
+ $opt = implode($separator, $selects);
+
+ if (!empty($interval) && $interval > 1 && !empty($min)) {
+ $min = round($min * (1 / $interval)) * $interval;
+ }
+ $selectMinuteAttr['interval'] = $interval;
+ switch ($timeFormat) {
+ case '24':
+ $selectHourAttr['value'] = $hour;
+ $selectMinuteAttr['value'] = $min;
+ $opt .= $this->hour($fieldName, true, $selectHourAttr) . ':' .
+ $this->minute($fieldName, $selectMinuteAttr);
+ break;
+ case '12':
+ $selectHourAttr['value'] = $hour;
+ $selectMinuteAttr['value'] = $min;
+ $selectMeridianAttr['value'] = $meridian;
+ $opt .= $this->hour($fieldName, false, $selectHourAttr) . ':' .
+ $this->minute($fieldName, $selectMinuteAttr) . ' ' .
+ $this->meridian($fieldName, $selectMeridianAttr);
+ break;
+ default:
+ $opt .= '';
+ break;
+ }
+ return $opt;
+ }
+
+/**
+ * Gets the input field name for the current tag
+ *
+ * @param array $options
+ * @param string $field
+ * @param string $key
+ * @return array
+ */
+ protected function _name($options = array(), $field = null, $key = 'name') {
+ if ($this->requestType == 'get') {
+ if ($options === null) {
+ $options = array();
+ } elseif (is_string($options)) {
+ $field = $options;
+ $options = 0;
+ }
+
+ if (!empty($field)) {
+ $this->setEntity($field);
+ }
+
+ if (is_array($options) && isset($options[$key])) {
+ return $options;
+ }
+
+ $entity = $this->entity();
+ $model = $this->model();
+ $name = $model === $entity[0] && isset($entity[1]) ? $entity[1] : $entity[0];
+ $last = $entity[count($entity) - 1];
+ if (in_array($last, $this->_fieldSuffixes)) {
+ $name .= '[' . $last . ']';
+ }
+
+ if (is_array($options)) {
+ $options[$key] = $name;
+ return $options;
+ } else {
+ return $name;
+ }
+ }
+ return parent::_name($options, $field, $key);
+ }
+
+/**
+ * Returns an array of formatted OPTION/OPTGROUP elements
+ *
+ * @param array $elements
+ * @param array $parents
+ * @param boolean $showParents
+ * @param array $attributes
+ * @return array
+ */
+ protected function _selectOptions($elements = array(), $parents = array(), $showParents = null, $attributes = array()) {
+ $select = array();
+ $attributes = array_merge(
+ array('escape' => true, 'style' => null, 'value' => null, 'class' => null),
+ $attributes
+ );
+ $selectedIsEmpty = ($attributes['value'] === '' || $attributes['value'] === null);
+ $selectedIsArray = is_array($attributes['value']);
+
+ foreach ($elements as $name => $title) {
+ $htmlOptions = array();
+ if (is_array($title) && (!isset($title['name']) || !isset($title['value']))) {
+ if (!empty($name)) {
+ if ($attributes['style'] === 'checkbox') {
+ $select[] = $this->Html->useTag('fieldsetend');
+ } else {
+ $select[] = $this->Html->useTag('optiongroupend');
+ }
+ $parents[] = $name;
+ }
+ $select = array_merge($select, $this->_selectOptions(
+ $title, $parents, $showParents, $attributes
+ ));
+
+ if (!empty($name)) {
+ $name = $attributes['escape'] ? h($name) : $name;
+ if ($attributes['style'] === 'checkbox') {
+ $select[] = $this->Html->useTag('fieldsetstart', $name);
+ } else {
+ $select[] = $this->Html->useTag('optiongroup', $name, '');
+ }
+ }
+ $name = null;
+ } elseif (is_array($title)) {
+ $htmlOptions = $title;
+ $name = $title['value'];
+ $title = $title['name'];
+ unset($htmlOptions['name'], $htmlOptions['value']);
+ }
+
+ if ($name !== null) {
+ if (
+ (!$selectedIsArray && !$selectedIsEmpty && (string)$attributes['value'] == (string)$name) ||
+ ($selectedIsArray && in_array($name, $attributes['value']))
+ ) {
+ if ($attributes['style'] === 'checkbox') {
+ $htmlOptions['checked'] = true;
+ } else {
+ $htmlOptions['selected'] = 'selected';
+ }
+ }
+
+ if ($showParents || (!in_array($title, $parents))) {
+ $title = ($attributes['escape']) ? h($title) : $title;
+
+ if ($attributes['style'] === 'checkbox') {
+ $htmlOptions['value'] = $name;
+
+ $tagName = $attributes['id'] . Inflector::camelize(Inflector::slug($name));
+ $htmlOptions['id'] = $tagName;
+ $label = array('for' => $tagName);
+
+ if (isset($htmlOptions['checked']) && $htmlOptions['checked'] === true) {
+ $label['class'] = 'selected';
+ }
+
+ $name = $attributes['name'];
+
+ if (empty($attributes['class'])) {
+ $attributes['class'] = 'checkbox';
+ } elseif ($attributes['class'] === 'form-error') {
+ $attributes['class'] = 'checkbox ' . $attributes['class'];
+ }
+ $label = $this->label(null, $title, $label);
+ $item = $this->Html->useTag('checkboxmultiple', $name, $htmlOptions);
+ $select[] = $this->Html->div($attributes['class'], $item . $label);
+ } else {
+ $select[] = $this->Html->useTag('selectoption', $name, $htmlOptions, $title);
+ }
+ }
+ }
+ }
+
+ return array_reverse($select, true);
+ }
+
+/**
+ * Generates option lists for common <select /> menus
+ *
+ * @param string $name
+ * @param array $options
+ * @return array
+ */
+ protected function _generateOptions($name, $options = array()) {
+ if (!empty($this->options[$name])) {
+ return $this->options[$name];
+ }
+ $data = array();
+
+ switch ($name) {
+ case 'minute':
+ if (isset($options['interval'])) {
+ $interval = $options['interval'];
+ } else {
+ $interval = 1;
+ }
+ $i = 0;
+ while ($i < 60) {
+ $data[sprintf('%02d', $i)] = sprintf('%02d', $i);
+ $i += $interval;
+ }
+ break;
+ case 'hour':
+ for ($i = 1; $i <= 12; $i++) {
+ $data[sprintf('%02d', $i)] = $i;
+ }
+ break;
+ case 'hour24':
+ for ($i = 0; $i <= 23; $i++) {
+ $data[sprintf('%02d', $i)] = $i;
+ }
+ break;
+ case 'meridian':
+ $data = array('am' => 'am', 'pm' => 'pm');
+ break;
+ case 'day':
+ $min = 1;
+ $max = 31;
+
+ if (isset($options['min'])) {
+ $min = $options['min'];
+ }
+ if (isset($options['max'])) {
+ $max = $options['max'];
+ }
+
+ for ($i = $min; $i <= $max; $i++) {
+ $data[sprintf('%02d', $i)] = $i;
+ }
+ break;
+ case 'month':
+ if ($options['monthNames'] === true) {
+ $data['01'] = __d('cake', 'January');
+ $data['02'] = __d('cake', 'February');
+ $data['03'] = __d('cake', 'March');
+ $data['04'] = __d('cake', 'April');
+ $data['05'] = __d('cake', 'May');
+ $data['06'] = __d('cake', 'June');
+ $data['07'] = __d('cake', 'July');
+ $data['08'] = __d('cake', 'August');
+ $data['09'] = __d('cake', 'September');
+ $data['10'] = __d('cake', 'October');
+ $data['11'] = __d('cake', 'November');
+ $data['12'] = __d('cake', 'December');
+ } elseif (is_array($options['monthNames'])) {
+ $data = $options['monthNames'];
+ } else {
+ for ($m = 1; $m <= 12; $m++) {
+ $data[sprintf("%02s", $m)] = strftime("%m", mktime(1, 1, 1, $m, 1, 1999));
+ }
+ }
+ break;
+ case 'year':
+ $current = intval(date('Y'));
+
+ $min = !isset($options['min']) ? $current - 20 : (int)$options['min'];
+ $max = !isset($options['max']) ? $current + 20 : (int)$options['max'];
+
+ if ($min > $max) {
+ list($min, $max) = array($max, $min);
+ }
+ for ($i = $min; $i <= $max; $i++) {
+ $data[$i] = $i;
+ }
+ if ($options['order'] != 'asc') {
+ $data = array_reverse($data, true);
+ }
+ break;
+ }
+ $this->_options[$name] = $data;
+ return $this->_options[$name];
+ }
+
+/**
+ * Sets field defaults and adds field to form security input hash
+ *
+ * ### Options
+ *
+ * - `secure` - boolean whether or not the field should be added to the security fields.
+ * Disabling the field using the `disabled` option, will also omit the field from being
+ * part of the hashed key.
+ *
+ * @param string $field Name of the field to initialize options for.
+ * @param array $options Array of options to append options into.
+ * @return array Array of options for the input.
+ */
+ protected function _initInputField($field, $options = array()) {
+ if (isset($options['secure'])) {
+ $secure = $options['secure'];
+ unset($options['secure']);
+ } else {
+ $secure = (isset($this->request['_Token']) && !empty($this->request['_Token']));
+ }
+
+ $result = parent::_initInputField($field, $options);
+ if ($this->tagIsInvalid() !== false) {
+ $result = $this->addClass($result, 'form-error');
+ }
+ if (!empty($result['disabled']) || $secure === self::SECURE_SKIP) {
+ return $result;
+ }
+
+ $fieldName = null;
+ if (!empty($options['name'])) {
+ preg_match_all('/\[(.*?)\]/', $options['name'], $matches);
+ if (isset($matches[1])) {
+ $fieldName = $matches[1];
+ }
+ }
+
+ $this->_secure($secure, $fieldName);
+ return $result;
+ }
+
+/**
+ * Set/Get inputDefaults for form elements
+ *
+ * @param array $defaults New default values
+ * @param boolean Merge with current defaults
+ * @return array inputDefaults
+ */
+ public function inputDefaults($defaults = null, $merge = false) {
+ if (!is_null($defaults)) {
+ if ($merge) {
+ $this->_inputDefaults = array_merge($this->_inputDefaults, (array)$defaults);
+ } else {
+ $this->_inputDefaults = (array)$defaults;
+ }
+ }
+ return $this->_inputDefaults;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php
new file mode 100644
index 0000000..fb53cf3
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/HtmlHelper.php
@@ -0,0 +1,1214 @@
+<?php
+/**
+ * Html Helper class file.
+ *
+ * Simplifies the construction of HTML elements.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 0.9.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * Html Helper class for easy use of HTML widgets.
+ *
+ * HtmlHelper encloses all methods needed while working with HTML pages.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html
+ */
+class HtmlHelper extends AppHelper {
+
+/**
+ * Reference to the Response object
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * html tags used by this helper.
+ *
+ * @var array
+ */
+ protected $_tags = array(
+ 'meta' => '<meta%s/>',
+ 'metalink' => '<link href="%s"%s/>',
+ 'link' => '<a href="%s"%s>%s</a>',
+ 'mailto' => '<a href="mailto:%s" %s>%s</a>',
+ 'form' => '<form action="%s"%s>',
+ 'formend' => '</form>',
+ 'input' => '<input name="%s"%s/>',
+ 'textarea' => '<textarea name="%s"%s>%s</textarea>',
+ 'hidden' => '<input type="hidden" name="%s"%s/>',
+ 'checkbox' => '<input type="checkbox" name="%s" %s/>',
+ 'checkboxmultiple' => '<input type="checkbox" name="%s[]"%s />',
+ 'radio' => '<input type="radio" name="%s" id="%s"%s />%s',
+ 'selectstart' => '<select name="%s"%s>',
+ 'selectmultiplestart' => '<select name="%s[]"%s>',
+ 'selectempty' => '<option value=""%s>&nbsp;</option>',
+ 'selectoption' => '<option value="%s"%s>%s</option>',
+ 'selectend' => '</select>',
+ 'optiongroup' => '<optgroup label="%s"%s>',
+ 'optiongroupend' => '</optgroup>',
+ 'checkboxmultiplestart' => '',
+ 'checkboxmultipleend' => '',
+ 'password' => '<input type="password" name="%s" %s/>',
+ 'file' => '<input type="file" name="%s" %s/>',
+ 'file_no_model' => '<input type="file" name="%s" %s/>',
+ 'submit' => '<input %s/>',
+ 'submitimage' => '<input type="image" src="%s" %s/>',
+ 'button' => '<button%s>%s</button>',
+ 'image' => '<img src="%s" %s/>',
+ 'tableheader' => '<th%s>%s</th>',
+ 'tableheaderrow' => '<tr%s>%s</tr>',
+ 'tablecell' => '<td%s>%s</td>',
+ 'tablerow' => '<tr%s>%s</tr>',
+ 'block' => '<div%s>%s</div>',
+ 'blockstart' => '<div%s>',
+ 'blockend' => '</div>',
+ 'tag' => '<%s%s>%s</%s>',
+ 'tagstart' => '<%s%s>',
+ 'tagend' => '</%s>',
+ 'tagselfclosing' => '<%s%s/>',
+ 'para' => '<p%s>%s</p>',
+ 'parastart' => '<p%s>',
+ 'label' => '<label for="%s"%s>%s</label>',
+ 'fieldset' => '<fieldset%s>%s</fieldset>',
+ 'fieldsetstart' => '<fieldset><legend>%s</legend>',
+ 'fieldsetend' => '</fieldset>',
+ 'legend' => '<legend>%s</legend>',
+ 'css' => '<link rel="%s" type="text/css" href="%s" %s/>',
+ 'style' => '<style type="text/css"%s>%s</style>',
+ 'charset' => '<meta http-equiv="Content-Type" content="text/html; charset=%s" />',
+ 'ul' => '<ul%s>%s</ul>',
+ 'ol' => '<ol%s>%s</ol>',
+ 'li' => '<li%s>%s</li>',
+ 'error' => '<div%s>%s</div>',
+ 'javascriptblock' => '<script type="text/javascript"%s>%s</script>',
+ 'javascriptstart' => '<script type="text/javascript">',
+ 'javascriptlink' => '<script type="text/javascript" src="%s"%s></script>',
+ 'javascriptend' => '</script>'
+ );
+
+/**
+ * Breadcrumbs.
+ *
+ * @var array
+ */
+ protected $_crumbs = array();
+
+/**
+ * Names of script files that have been included once
+ *
+ * @var array
+ */
+ protected $_includedScripts = array();
+
+/**
+ * Options for the currently opened script block buffer if any.
+ *
+ * @var array
+ */
+ protected $_scriptBlockOptions = array();
+
+/**
+ * Document type definitions
+ *
+ * @var array
+ */
+ protected $_docTypes = array(
+ 'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+ 'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+ 'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
+ 'html5' => '<!DOCTYPE html>',
+ 'xhtml-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+ 'xhtml-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+ 'xhtml-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+ 'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
+ );
+
+/**
+ * Constructor
+ *
+ * ### Settings
+ *
+ * - `configFile` A file containing an array of tags you wish to redefine.
+ *
+ * ### Customizing tag sets
+ *
+ * Using the `configFile` option you can redefine the tag HtmlHelper will use.
+ * The file named should be compatible with HtmlHelper::loadConfig().
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ parent::__construct($View, $settings);
+ if (is_object($this->_View->response)) {
+ $this->response = $this->_View->response;
+ } else {
+ $this->response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ }
+ if (!empty($settings['configFile'])) {
+ $this->loadConfig($settings['configFile']);
+ }
+ }
+
+/**
+ * Adds a link to the breadcrumbs array.
+ *
+ * @param string $name Text for link
+ * @param string $link URL for link (if empty it won't be a link)
+ * @param string|array $options Link attributes e.g. array('id' => 'selected')
+ * @return void
+ * @see HtmlHelper::link() for details on $options that can be used.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
+ */
+ public function addCrumb($name, $link = null, $options = null) {
+ $this->_crumbs[] = array($name, $link, $options);
+ }
+
+/**
+ * Returns a doctype string.
+ *
+ * Possible doctypes:
+ *
+ * - html4-strict: HTML4 Strict.
+ * - html4-trans: HTML4 Transitional.
+ * - html4-frame: HTML4 Frameset.
+ * - html5: HTML5. Default value.
+ * - xhtml-strict: XHTML1 Strict.
+ * - xhtml-trans: XHTML1 Transitional.
+ * - xhtml-frame: XHTML1 Frameset.
+ * - xhtml11: XHTML1.1.
+ *
+ * @param string $type Doctype to use.
+ * @return string Doctype string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::docType
+ */
+ public function docType($type = 'html5') {
+ if (isset($this->_docTypes[$type])) {
+ return $this->_docTypes[$type];
+ }
+ return null;
+ }
+
+/**
+ * Creates a link to an external resource and handles basic meta tags
+ *
+ * Create a meta tag that is output inline:
+ *
+ * `$this->Html->meta('icon', 'favicon.ico');
+ *
+ * Append the meta tag to `$scripts_for_layout`:
+ *
+ * `$this->Html->meta('description', 'A great page', array('inline' => false));`
+ *
+ * Append the meta tag to custom view block:
+ *
+ * `$this->Html->meta('description', 'A great page', array('block' => 'metaTags'));`
+ *
+ * ### Options
+ *
+ * - `inline` Whether or not the link element should be output inline. Set to false to
+ * have the meta tag included in `$scripts_for_layout`, and appended to the 'meta' view block.
+ * - `block` Choose a custom block to append the meta tag to. Using this option
+ * will override the inline option.
+ *
+ * @param string $type The title of the external resource
+ * @param string|array $url The address of the external resource or string for content attribute
+ * @param array $options Other attributes for the generated tag. If the type attribute is html,
+ * rss, atom, or icon, the mime-type is returned.
+ * @return string A completed `<link />` element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::meta
+ */
+ public function meta($type, $url = null, $options = array()) {
+ $options += array('inline' => true, 'block' => null);
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = __FUNCTION__;
+ }
+ unset($options['inline']);
+
+ if (!is_array($type)) {
+ $types = array(
+ 'rss' => array('type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => $type, 'link' => $url),
+ 'atom' => array('type' => 'application/atom+xml', 'title' => $type, 'link' => $url),
+ 'icon' => array('type' => 'image/x-icon', 'rel' => 'icon', 'link' => $url),
+ 'keywords' => array('name' => 'keywords', 'content' => $url),
+ 'description' => array('name' => 'description', 'content' => $url),
+ );
+
+ if ($type === 'icon' && $url === null) {
+ $types['icon']['link'] = $this->webroot('favicon.ico');
+ }
+
+ if (isset($types[$type])) {
+ $type = $types[$type];
+ } elseif (!isset($options['type']) && $url !== null) {
+ if (is_array($url) && isset($url['ext'])) {
+ $type = $types[$url['ext']];
+ } else {
+ $type = $types['rss'];
+ }
+ } elseif (isset($options['type']) && isset($types[$options['type']])) {
+ $type = $types[$options['type']];
+ unset($options['type']);
+ } else {
+ $type = array();
+ }
+ } elseif ($url !== null) {
+ $inline = $url;
+ }
+ $options = array_merge($type, $options);
+ $out = null;
+
+ if (isset($options['link'])) {
+ if (isset($options['rel']) && $options['rel'] === 'icon') {
+ $out = sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
+ $options['rel'] = 'shortcut icon';
+ } else {
+ $options['link'] = $this->url($options['link'], true);
+ }
+ $out .= sprintf($this->_tags['metalink'], $options['link'], $this->_parseAttributes($options, array('block', 'link'), ' ', ' '));
+ } else {
+ $out = sprintf($this->_tags['meta'], $this->_parseAttributes($options, array('block', 'type'), ' ', ' '));
+ }
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Returns a charset META-tag.
+ *
+ * @param string $charset The character set to be used in the meta tag. If empty,
+ * The App.encoding value will be used. Example: "utf-8".
+ * @return string A meta tag containing the specified character set.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::charset
+ */
+ public function charset($charset = null) {
+ if (empty($charset)) {
+ $charset = strtolower(Configure::read('App.encoding'));
+ }
+ return sprintf($this->_tags['charset'], (!empty($charset) ? $charset : 'utf-8'));
+ }
+
+/**
+ * Creates an HTML link.
+ *
+ * If $url starts with "http://" this is treated as an external link. Else,
+ * it is treated as a path to controller/action and parsed with the
+ * HtmlHelper::url() method.
+ *
+ * If the $url is empty, $title is used instead.
+ *
+ * ### Options
+ *
+ * - `escape` Set to false to disable escaping of title and attributes.
+ * - `confirm` JavaScript confirmation message.
+ *
+ * @param string $title The content to be wrapped by <a> tags.
+ * @param string|array $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
+ * @param array $options Array of HTML attributes.
+ * @param string $confirmMessage JavaScript confirmation message.
+ * @return string An `<a />` element.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::link
+ */
+ public function link($title, $url = null, $options = array(), $confirmMessage = false) {
+ $escapeTitle = true;
+ if ($url !== null) {
+ $url = $this->url($url);
+ } else {
+ $url = $this->url($title);
+ $title = htmlspecialchars_decode($url, ENT_QUOTES);
+ $title = h(urldecode($title));
+ $escapeTitle = false;
+ }
+
+ if (isset($options['escape'])) {
+ $escapeTitle = $options['escape'];
+ }
+
+ if ($escapeTitle === true) {
+ $title = h($title);
+ } elseif (is_string($escapeTitle)) {
+ $title = htmlentities($title, ENT_QUOTES, $escapeTitle);
+ }
+
+ if (!empty($options['confirm'])) {
+ $confirmMessage = $options['confirm'];
+ unset($options['confirm']);
+ }
+ if ($confirmMessage) {
+ $confirmMessage = str_replace("'", "\'", $confirmMessage);
+ $confirmMessage = str_replace('"', '\"', $confirmMessage);
+ $options['onclick'] = "return confirm('{$confirmMessage}');";
+ } elseif (isset($options['default']) && $options['default'] == false) {
+ if (isset($options['onclick'])) {
+ $options['onclick'] .= ' event.returnValue = false; return false;';
+ } else {
+ $options['onclick'] = 'event.returnValue = false; return false;';
+ }
+ unset($options['default']);
+ }
+ return sprintf($this->_tags['link'], $url, $this->_parseAttributes($options), $title);
+ }
+
+/**
+ * Creates a link element for CSS stylesheets.
+ *
+ * ### Usage
+ *
+ * Include one CSS file:
+ *
+ * `echo $this->Html->css('styles.css');`
+ *
+ * Include multiple CSS files:
+ *
+ * `echo $this->Html->css(array('one.css', 'two.css'));`
+ *
+ * Add the stylesheet to the `$scripts_for_layout` layout var:
+ *
+ * `$this->Html->css('styles.css', null, array('inline' => false));`
+ *
+ * Add the stylesheet to a custom block:
+ *
+ * `$this->Html->css('styles.css', null, array('block' => 'layoutCss'));`
+ *
+ * ### Options
+ *
+ * - `inline` If set to false, the generated tag will be appended to the 'css' block,
+ * and included in the `$scripts_for_layout` layout variable. Defaults to true.
+ * - `block` Set the name of the block link/style tag will be appended to. This overrides the `inline`
+ * option.
+ * - `plugin` False value will prevent parsing path as a plugin
+ *
+ * @param string|array $path The name of a CSS style sheet or an array containing names of
+ * CSS stylesheets. If `$path` is prefixed with '/', the path will be relative to the webroot
+ * of your application. Otherwise, the path will be relative to your CSS path, usually webroot/css.
+ * @param string $rel Rel attribute. Defaults to "stylesheet". If equal to 'import' the stylesheet will be imported.
+ * @param array $options Array of HTML attributes.
+ * @return string CSS <link /> or <style /> tag, depending on the type of link.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::css
+ */
+ public function css($path, $rel = null, $options = array()) {
+ $options += array('block' => null, 'inline' => true);
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = __FUNCTION__;
+ }
+ unset($options['inline']);
+
+ if (is_array($path)) {
+ $out = '';
+ foreach ($path as $i) {
+ $out .= "\n\t" . $this->css($i, $rel, $options);
+ }
+ if (empty($options['block'])) {
+ return $out . "\n";
+ }
+ return;
+ }
+
+ if (strpos($path, '//') !== false) {
+ $url = $path;
+ } else {
+ $url = $this->assetUrl($path, $options + array('pathPrefix' => CSS_URL, 'ext' => '.css'));
+
+ if (Configure::read('Asset.filter.css')) {
+ $pos = strpos($url, CSS_URL);
+ if ($pos !== false) {
+ $url = substr($url, 0, $pos) . 'ccss/' . substr($url, $pos + strlen(CSS_URL));
+ }
+ }
+ }
+
+ if ($rel == 'import') {
+ $out = sprintf($this->_tags['style'], $this->_parseAttributes($options, array('inline', 'block'), '', ' '), '@import url(' . $url . ');');
+ } else {
+ if ($rel == null) {
+ $rel = 'stylesheet';
+ }
+ $out = sprintf($this->_tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline', 'block'), '', ' '));
+ }
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Returns one or many `<script>` tags depending on the number of scripts given.
+ *
+ * If the filename is prefixed with "/", the path will be relative to the base path of your
+ * application. Otherwise, the path will be relative to your JavaScript path, usually webroot/js.
+ *
+ *
+ * ### Usage
+ *
+ * Include one script file:
+ *
+ * `echo $this->Html->script('styles.js');`
+ *
+ * Include multiple script files:
+ *
+ * `echo $this->Html->script(array('one.js', 'two.js'));`
+ *
+ * Add the script file to the `$scripts_for_layout` layout var:
+ *
+ * `$this->Html->script('styles.js', array('inline' => false));`
+ *
+ * Add the script file to a custom block:
+ *
+ * `$this->Html->script('styles.js', null, array('block' => 'bodyScript'));`
+ *
+ * ### Options
+ *
+ * - `inline` Whether script should be output inline or into `$scripts_for_layout`. When set to false,
+ * the script tag will be appended to the 'script' view block as well as `$scripts_for_layout`.
+ * - `block` The name of the block you want the script appended to. Leave undefined to output inline.
+ * Using this option will override the inline option.
+ * - `once` Whether or not the script should be checked for uniqueness. If true scripts will only be
+ * included once, use false to allow the same script to be included more than once per request.
+ * - `plugin` False value will prevent parsing path as a plugin
+ *
+ * @param string|array $url String or array of javascript files to include
+ * @param array|boolean $options Array of options, and html attributes see above. If boolean sets $options['inline'] = value
+ * @return mixed String of `<script />` tags or null if $inline is false or if $once is true and the file has been
+ * included before.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::script
+ */
+ public function script($url, $options = array()) {
+ if (is_bool($options)) {
+ list($inline, $options) = array($options, array());
+ $options['inline'] = $inline;
+ }
+ $options = array_merge(array('block' => null, 'inline' => true, 'once' => true), $options);
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = __FUNCTION__;
+ }
+ unset($options['inline']);
+
+ if (is_array($url)) {
+ $out = '';
+ foreach ($url as $i) {
+ $out .= "\n\t" . $this->script($i, $options);
+ }
+ if (empty($options['block'])) {
+ return $out . "\n";
+ }
+ return null;
+ }
+ if ($options['once'] && isset($this->_includedScripts[$url])) {
+ return null;
+ }
+ $this->_includedScripts[$url] = true;
+
+ if (strpos($url, '//') === false) {
+ $url = $this->assetUrl($url, $options + array('pathPrefix' => JS_URL, 'ext' => '.js'));
+
+ if (Configure::read('Asset.filter.js')) {
+ $url = str_replace(JS_URL, 'cjs/', $url);
+ }
+ }
+ $attributes = $this->_parseAttributes($options, array('block', 'once'), ' ');
+ $out = sprintf($this->_tags['javascriptlink'], $url, $attributes);
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Wrap $script in a script tag.
+ *
+ * ### Options
+ *
+ * - `safe` (boolean) Whether or not the $script should be wrapped in <![CDATA[ ]]>
+ * - `inline` (boolean) Whether or not the $script should be added to
+ * `$scripts_for_layout` / `script` block, or output inline. (Deprecated, use `block` instead)
+ * - `block` Which block you want this script block appended to.
+ * Defaults to `script`.
+ *
+ * @param string $script The script to wrap
+ * @param array $options The options to use. Options not listed above will be
+ * treated as HTML attributes.
+ * @return mixed string or null depending on the value of `$options['block']`
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptBlock
+ */
+ public function scriptBlock($script, $options = array()) {
+ $options += array('safe' => true, 'inline' => true);
+ if ($options['safe']) {
+ $script = "\n" . '//<![CDATA[' . "\n" . $script . "\n" . '//]]>' . "\n";
+ }
+ if (!$options['inline'] && empty($options['block'])) {
+ $options['block'] = 'script';
+ }
+ unset($options['inline'], $options['safe']);
+
+ $attributes = $this->_parseAttributes($options, array('block'), ' ');
+ $out = sprintf($this->_tags['javascriptblock'], $attributes, $script);
+
+ if (empty($options['block'])) {
+ return $out;
+ } else {
+ $this->_View->append($options['block'], $out);
+ }
+ }
+
+/**
+ * Begin a script block that captures output until HtmlHelper::scriptEnd()
+ * is called. This capturing block will capture all output between the methods
+ * and create a scriptBlock from it.
+ *
+ * ### Options
+ *
+ * - `safe` Whether the code block should contain a CDATA
+ * - `inline` Should the generated script tag be output inline or in `$scripts_for_layout`
+ *
+ * @param array $options Options for the code block.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptStart
+ */
+ public function scriptStart($options = array()) {
+ $options += array('safe' => true, 'inline' => true);
+ $this->_scriptBlockOptions = $options;
+ ob_start();
+ return null;
+ }
+
+/**
+ * End a Buffered section of Javascript capturing.
+ * Generates a script tag inline or in `$scripts_for_layout` depending on the settings
+ * used when the scriptBlock was started
+ *
+ * @return mixed depending on the settings of scriptStart() either a script tag or null
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptEnd
+ */
+ public function scriptEnd() {
+ $buffer = ob_get_clean();
+ $options = $this->_scriptBlockOptions;
+ $this->_scriptBlockOptions = array();
+ return $this->scriptBlock($buffer, $options);
+ }
+
+/**
+ * Builds CSS style data from an array of CSS properties
+ *
+ * ### Usage:
+ *
+ * {{{
+ * echo $html->style(array('margin' => '10px', 'padding' => '10px'), true);
+ *
+ * // creates
+ * 'margin:10px;padding:10px;'
+ * }}}
+ *
+ * @param array $data Style data array, keys will be used as property names, values as property values.
+ * @param boolean $oneline Whether or not the style block should be displayed on one line.
+ * @return string CSS styling data
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::style
+ */
+ public function style($data, $oneline = true) {
+ if (!is_array($data)) {
+ return $data;
+ }
+ $out = array();
+ foreach ($data as $key => $value) {
+ $out[] = $key . ':' . $value . ';';
+ }
+ if ($oneline) {
+ return join(' ', $out);
+ }
+ return implode("\n", $out);
+ }
+
+/**
+ * Returns the breadcrumb trail as a sequence of &raquo;-separated links.
+ *
+ * If `$startText` is an array, the accepted keys are:
+ *
+ * - `text` Define the text/content for the link.
+ * - `url` Define the target of the created link.
+ *
+ * All other keys will be passed to HtmlHelper::link() as the `$options` parameter.
+ *
+ * @param string $separator Text to separate crumbs.
+ * @param string|array|boolean $startText This will be the first crumb, if false it defaults to first crumb in array. Can
+ * also be an array, see above for details.
+ * @return string Composed bread crumbs
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
+ */
+ public function getCrumbs($separator = '&raquo;', $startText = false) {
+ $crumbs = $this->_prepareCrumbs($startText);
+ if (!empty($crumbs)) {
+ $out = array();
+ foreach ($crumbs as $crumb) {
+ if (!empty($crumb[1])) {
+ $out[] = $this->link($crumb[0], $crumb[1], $crumb[2]);
+ } else {
+ $out[] = $crumb[0];
+ }
+ }
+ return join($separator, $out);
+ } else {
+ return null;
+ }
+ }
+
+/**
+ * Returns breadcrumbs as a (x)html list
+ *
+ * This method uses HtmlHelper::tag() to generate list and its elements. Works
+ * similar to HtmlHelper::getCrumbs(), so it uses options which every
+ * crumb was added with.
+ *
+ * @param array $options Array of html attributes to apply to the generated list elements.
+ * @param string|array|boolean $startText This will be the first crumb, if false it defaults to first crumb in array. Can
+ * also be an array, see `HtmlHelper::getCrumbs` for details.
+ * @return string breadcrumbs html list
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
+ */
+ public function getCrumbList($options = array(), $startText = false) {
+ $crumbs = $this->_prepareCrumbs($startText);
+ if (!empty($crumbs)) {
+ $result = '';
+ $crumbCount = count($crumbs);
+ $ulOptions = $options;
+ foreach ($crumbs as $which => $crumb) {
+ $options = array();
+ if (empty($crumb[1])) {
+ $elementContent = $crumb[0];
+ } else {
+ $elementContent = $this->link($crumb[0], $crumb[1], $crumb[2]);
+ }
+ if ($which == 0) {
+ $options['class'] = 'first';
+ } elseif ($which == $crumbCount - 1) {
+ $options['class'] = 'last';
+ }
+ $result .= $this->tag('li', $elementContent, $options);
+ }
+ return $this->tag('ul', $result, $ulOptions);
+ } else {
+ return null;
+ }
+ }
+
+/**
+ * Prepends startText to crumbs array if set
+ *
+ * @param $startText
+ * @return array Crumb list including startText (if provided)
+ */
+ protected function _prepareCrumbs($startText) {
+ $crumbs = $this->_crumbs;
+ if ($startText) {
+ if (!is_array($startText)) {
+ $startText = array(
+ 'url' => '/',
+ 'text' => $startText
+ );
+ }
+ $startText += array('url' => '/', 'text' => __('Home'));
+ list($url, $text) = array($startText['url'], $startText['text']);
+ unset($startText['url'], $startText['text']);
+ array_unshift($crumbs, array($text, $url, $startText));
+ }
+ return $crumbs;
+ }
+
+/**
+ * Creates a formatted IMG element.
+ *
+ * This method will set an empty alt attribute if one is not supplied.
+ *
+ * ### Usage:
+ *
+ * Create a regular image:
+ *
+ * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP'));`
+ *
+ * Create an image link:
+ *
+ * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP', 'url' => 'http://cakephp.org'));`
+ *
+ * ### Options:
+ *
+ * - `url` If provided an image link will be generated and the link will point at
+ * `$options['url']`.
+ * - `fullBase` If true the src attribute will get a full address for the image file.
+ * - `plugin` False value will prevent parsing path as a plugin
+ *
+ * @param string $path Path to the image file, relative to the app/webroot/img/ directory.
+ * @param array $options Array of HTML attributes. See above for special options.
+ * @return string completed img tag
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::image
+ */
+ public function image($path, $options = array()) {
+ $path = $this->assetUrl($path, $options + array('pathPrefix' => IMAGES_URL));
+ $options = array_diff_key($options, array('fullBase' => '', 'pathPrefix' => ''));
+
+ if (!isset($options['alt'])) {
+ $options['alt'] = '';
+ }
+
+ $url = false;
+ if (!empty($options['url'])) {
+ $url = $options['url'];
+ unset($options['url']);
+ }
+
+ $image = sprintf($this->_tags['image'], $path, $this->_parseAttributes($options, null, '', ' '));
+
+ if ($url) {
+ return sprintf($this->_tags['link'], $this->url($url), null, $image);
+ }
+ return $image;
+ }
+
+/**
+ * Returns a row of formatted and named TABLE headers.
+ *
+ * @param array $names Array of tablenames. Each tablename also can be a key that points to an array with a set
+ * of attributes to its specific tag
+ * @param array $trOptions HTML options for TR elements.
+ * @param array $thOptions HTML options for TH elements.
+ * @return string Completed table headers
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tableHeaders
+ */
+ public function tableHeaders($names, $trOptions = null, $thOptions = null) {
+ $out = array();
+ foreach ($names as $arg) {
+ if (!is_array($arg)) {
+ $out[] = sprintf($this->_tags['tableheader'], $this->_parseAttributes($thOptions), $arg);
+ } else {
+ $out[] = sprintf($this->_tags['tableheader'], $this->_parseAttributes(current($arg)), key($arg));
+ }
+ }
+ return sprintf($this->_tags['tablerow'], $this->_parseAttributes($trOptions), join(' ', $out));
+ }
+
+/**
+ * Returns a formatted string of table rows (TR's with TD's in them).
+ *
+ * @param array $data Array of table data
+ * @param array $oddTrOptions HTML options for odd TR elements if true useCount is used
+ * @param array $evenTrOptions HTML options for even TR elements
+ * @param boolean $useCount adds class "column-$i"
+ * @param boolean $continueOddEven If false, will use a non-static $count variable,
+ * so that the odd/even count is reset to zero just for that call.
+ * @return string Formatted HTML
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tableCells
+ */
+ public function tableCells($data, $oddTrOptions = null, $evenTrOptions = null, $useCount = false, $continueOddEven = true) {
+ if (empty($data[0]) || !is_array($data[0])) {
+ $data = array($data);
+ }
+
+ if ($oddTrOptions === true) {
+ $useCount = true;
+ $oddTrOptions = null;
+ }
+
+ if ($evenTrOptions === false) {
+ $continueOddEven = false;
+ $evenTrOptions = null;
+ }
+
+ if ($continueOddEven) {
+ static $count = 0;
+ } else {
+ $count = 0;
+ }
+
+ foreach ($data as $line) {
+ $count++;
+ $cellsOut = array();
+ $i = 0;
+ foreach ($line as $cell) {
+ $cellOptions = array();
+
+ if (is_array($cell)) {
+ $cellOptions = $cell[1];
+ $cell = $cell[0];
+ } elseif ($useCount) {
+ $cellOptions['class'] = 'column-' . ++$i;
+ }
+ $cellsOut[] = sprintf($this->_tags['tablecell'], $this->_parseAttributes($cellOptions), $cell);
+ }
+ $options = $this->_parseAttributes($count % 2 ? $oddTrOptions : $evenTrOptions);
+ $out[] = sprintf($this->_tags['tablerow'], $options, implode(' ', $cellsOut));
+ }
+ return implode("\n", $out);
+ }
+
+/**
+ * Returns a formatted block tag, i.e DIV, SPAN, P.
+ *
+ * ### Options
+ *
+ * - `escape` Whether or not the contents should be html_entity escaped.
+ *
+ * @param string $name Tag name.
+ * @param string $text String content that will appear inside the div element.
+ * If null, only a start tag will be printed
+ * @param array $options Additional HTML attributes of the DIV tag, see above.
+ * @return string The formatted tag element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::tag
+ */
+ public function tag($name, $text = null, $options = array()) {
+ if (is_array($options) && isset($options['escape']) && $options['escape']) {
+ $text = h($text);
+ unset($options['escape']);
+ }
+ if (!is_array($options)) {
+ $options = array('class' => $options);
+ }
+ if ($text === null) {
+ $tag = 'tagstart';
+ } else {
+ $tag = 'tag';
+ }
+ return sprintf($this->_tags[$tag], $name, $this->_parseAttributes($options, null, ' ', ''), $text, $name);
+ }
+
+/**
+ * Returns a formatted existent block of $tags
+ *
+ * @param string $tag Tag name
+ * @return string Formatted block
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::useTag
+ */
+ public function useTag($tag) {
+ if (!isset($this->_tags[$tag])) {
+ return '';
+ }
+ $args = func_get_args();
+ array_shift($args);
+ foreach ($args as &$arg) {
+ if (is_array($arg)) {
+ $arg = $this->_parseAttributes($arg, null, ' ', '');
+ }
+ }
+ return vsprintf($this->_tags[$tag], $args);
+ }
+
+/**
+ * Returns a formatted DIV tag for HTML FORMs.
+ *
+ * ### Options
+ *
+ * - `escape` Whether or not the contents should be html_entity escaped.
+ *
+ * @param string $class CSS class name of the div element.
+ * @param string $text String content that will appear inside the div element.
+ * If null, only a start tag will be printed
+ * @param array $options Additional HTML attributes of the DIV tag
+ * @return string The formatted DIV element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::div
+ */
+ public function div($class = null, $text = null, $options = array()) {
+ if (!empty($class)) {
+ $options['class'] = $class;
+ }
+ return $this->tag('div', $text, $options);
+ }
+
+/**
+ * Returns a formatted P tag.
+ *
+ * ### Options
+ *
+ * - `escape` Whether or not the contents should be html_entity escaped.
+ *
+ * @param string $class CSS class name of the p element.
+ * @param string $text String content that will appear inside the p element.
+ * @param array $options Additional HTML attributes of the P tag
+ * @return string The formatted P element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::para
+ */
+ public function para($class, $text, $options = array()) {
+ if (isset($options['escape'])) {
+ $text = h($text);
+ }
+ if ($class != null && !empty($class)) {
+ $options['class'] = $class;
+ }
+ if ($text === null) {
+ $tag = 'parastart';
+ } else {
+ $tag = 'para';
+ }
+ return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $text);
+ }
+
+/**
+ * Returns an audio/video element
+ *
+ * ### Usage
+ *
+ * Using an audio file:
+ *
+ * `echo $this->Html->media('audio.mp3', array('fullBase' => true));`
+ *
+ * Outputs:
+ *
+ * `<video src="http://www.somehost.com/files/audio.mp3">Fallback text</video>`
+ *
+ * Using a video file:
+ *
+ * `echo $this->Html->media('video.mp4', array('text' => 'Fallback text'));`
+ *
+ * Outputs:
+ *
+ * `<video src="/files/video.mp4">Fallback text</video>`
+ *
+ * Using multiple video files:
+ *
+ * {{{
+ * echo $this->Html->media(
+ * array('video.mp4', array('src' => 'video.ogv', 'type' => "video/ogg; codecs='theora, vorbis'")),
+ * array('tag' => 'video', 'autoplay')
+ * );
+ * }}}
+ *
+ * Outputs:
+ *
+ * {{{
+ * <video autoplay="autoplay">
+ * <source src="/files/video.mp4" type="video/mp4"/>
+ * <source src="/files/video.ogv" type="video/ogv; codecs='theora, vorbis'"/>
+ * </video>
+ * }}}
+ *
+ * ### Options
+ *
+ * - `tag` Type of media element to generate, either "audio" or "video".
+ * If tag is not provided it's guessed based on file's mime type.
+ * - `text` Text to include inside the audio/video tag
+ * - `pathPrefix` Path prefix to use for relative urls, defaults to 'files/'
+ * - `fullBase` If provided the src attribute will get a full address including domain name
+ *
+ * @param string|array $path Path to the video file, relative to the webroot/{$options['pathPrefix']} directory.
+ * Or an array where each item itself can be a path string or an associate array containing keys `src` and `type`
+ * @param array $options Array of HTML attributes, and special options above.
+ * @return string Generated media element
+ */
+ public function media($path, $options = array()) {
+ $options += array(
+ 'tag' => null,
+ 'pathPrefix' => 'files/',
+ 'text' => ''
+ );
+
+ if (!empty($options['tag'])) {
+ $tag = $options['tag'];
+ } else {
+ $tag = null;
+ }
+
+ if (is_array($path)) {
+ $sourceTags = '';
+ foreach ($path as &$source) {
+ if (is_string($source)) {
+ $source = array(
+ 'src' => $source,
+ );
+ }
+ if (!isset($source['type'])) {
+ $ext = pathinfo($source['src'], PATHINFO_EXTENSION);
+ $source['type'] = $this->response->getMimeType($ext);
+ }
+ $source['src'] = $this->assetUrl($source['src'], $options);
+ $sourceTags .= $this->useTag('tagselfclosing', 'source', $source);
+ }
+ unset($source);
+ $options['text'] = $sourceTags . $options['text'];
+ unset($options['fullBase']);
+ } else {
+ if (empty($path) && !empty($options['src'])) {
+ $path = $options['src'];
+ }
+ $options['src'] = $this->assetUrl($path, $options);
+ }
+
+ if ($tag === null) {
+ if (is_array($path)) {
+ $mimeType = $path[0]['type'];
+ } else {
+ $mimeType = $this->response->getMimeType(pathinfo($path, PATHINFO_EXTENSION));
+ }
+ if (preg_match('#^video/#', $mimeType)) {
+ $tag = 'video';
+ } else {
+ $tag = 'audio';
+ }
+ }
+
+ if (isset($options['poster'])) {
+ $options['poster'] = $this->assetUrl($options['poster'], array('pathPrefix' => IMAGES_URL) + $options);
+ }
+ $text = $options['text'];
+
+ $options = array_diff_key($options, array(
+ 'tag' => '',
+ 'fullBase' => '',
+ 'pathPrefix' => '',
+ 'text' => ''
+ ));
+ return $this->tag($tag, $text, $options);
+ }
+
+/**
+ * Build a nested list (UL/OL) out of an associative array.
+ *
+ * @param array $list Set of elements to list
+ * @param array $options Additional HTML attributes of the list (ol/ul) tag or if ul/ol use that as tag
+ * @param array $itemOptions Additional HTML attributes of the list item (LI) tag
+ * @param string $tag Type of list tag to use (ol/ul)
+ * @return string The nested list
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::nestedList
+ */
+ public function nestedList($list, $options = array(), $itemOptions = array(), $tag = 'ul') {
+ if (is_string($options)) {
+ $tag = $options;
+ $options = array();
+ }
+ $items = $this->_nestedListItem($list, $options, $itemOptions, $tag);
+ return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $items);
+ }
+
+/**
+ * Internal function to build a nested list (UL/OL) out of an associative array.
+ *
+ * @param array $items Set of elements to list
+ * @param array $options Additional HTML attributes of the list (ol/ul) tag
+ * @param array $itemOptions Additional HTML attributes of the list item (LI) tag
+ * @param string $tag Type of list tag to use (ol/ul)
+ * @return string The nested list element
+ * @see HtmlHelper::nestedList()
+ */
+ protected function _nestedListItem($items, $options, $itemOptions, $tag) {
+ $out = '';
+
+ $index = 1;
+ foreach ($items as $key => $item) {
+ if (is_array($item)) {
+ $item = $key . $this->nestedList($item, $options, $itemOptions, $tag);
+ }
+ if (isset($itemOptions['even']) && $index % 2 == 0) {
+ $itemOptions['class'] = $itemOptions['even'];
+ } elseif (isset($itemOptions['odd']) && $index % 2 != 0) {
+ $itemOptions['class'] = $itemOptions['odd'];
+ }
+ $out .= sprintf($this->_tags['li'], $this->_parseAttributes($itemOptions, array('even', 'odd'), ' ', ''), $item);
+ $index++;
+ }
+ return $out;
+ }
+
+/**
+ * Load Html tag configuration.
+ *
+ * Loads a file from APP/Config that contains tag data. By default the file is expected
+ * to be compatible with PhpReader:
+ *
+ * `$this->Html->loadConfig('tags.php');`
+ *
+ * tags.php could look like:
+ *
+ * {{{
+ * $tags = array(
+ * 'meta' => '<meta %s>'
+ * );
+ * }}}
+ *
+ * If you wish to store tag definitions in another format you can give an array
+ * containing the file name, and reader class name:
+ *
+ * `$this->Html->loadConfig(array('tags.ini', 'ini'));`
+ *
+ * Its expected that the `tags` index will exist from any configuration file that is read.
+ * You can also specify the path to read the configuration file from, if APP/Config is not
+ * where the file is.
+ *
+ * `$this->Html->loadConfig('tags.php', APP . 'Lib' . DS);`
+ *
+ * Configuration files can define the following sections:
+ *
+ * - `tags` The tags to replace.
+ * - `minimizedAttributes` The attributes that are represented like `disabled="disabled"`
+ * - `docTypes` Additional doctypes to use.
+ * - `attributeFormat` Format for long attributes e.g. `'%s="%s"'`
+ * - `minimizedAttributeFormat` Format for minimized attributes e.g. `'%s="%s"'`
+ *
+ * @param string|array $configFile String with the config file (load using PhpReader) or an array with file and reader name
+ * @param string $path Path with config file
+ * @return mixed False to error or loaded configs
+ * @throws ConfigureException
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#changing-the-tags-output-by-htmlhelper
+ */
+ public function loadConfig($configFile, $path = null) {
+ if (!$path) {
+ $path = APP . 'Config' . DS;
+ }
+ $file = null;
+ $reader = 'php';
+
+ if (!is_array($configFile)) {
+ $file = $configFile;
+ } elseif (isset($configFile[0])) {
+ $file = $configFile[0];
+ if (isset($configFile[1])) {
+ $reader = $configFile[1];
+ }
+ } else {
+ throw new ConfigureException(__d('cake_dev', 'Cannot load the configuration file. Wrong "configFile" configuration.'));
+ }
+
+ $readerClass = Inflector::camelize($reader) . 'Reader';
+ App::uses($readerClass, 'Configure');
+ if (!class_exists($readerClass)) {
+ throw new ConfigureException(__d('cake_dev', 'Cannot load the configuration file. Unknown reader.'));
+ }
+
+ $readerObj = new $readerClass($path);
+ $configs = $readerObj->read($file);
+ if (isset($configs['tags']) && is_array($configs['tags'])) {
+ $this->_tags = array_merge($this->_tags, $configs['tags']);
+ }
+ if (isset($configs['minimizedAttributes']) && is_array($configs['minimizedAttributes'])) {
+ $this->_minimizedAttributes = array_merge($this->_minimizedAttributes, $configs['minimizedAttributes']);
+ }
+ if (isset($configs['docTypes']) && is_array($configs['docTypes'])) {
+ $this->_docTypes = array_merge($this->_docTypes, $configs['docTypes']);
+ }
+ if (isset($configs['attributeFormat'])) {
+ $this->_attributeFormat = $configs['attributeFormat'];
+ }
+ if (isset($configs['minimizedAttributeFormat'])) {
+ $this->_minimizedAttributeFormat = $configs['minimizedAttributeFormat'];
+ }
+ return $configs;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php
new file mode 100644
index 0000000..d79a8ef
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JqueryEngineHelper.php
@@ -0,0 +1,361 @@
+<?php
+/**
+ * jQuery Engine Helper for JsHelper
+ *
+ * Provides jQuery specific Javascript for JsHelper.
+ *
+ * Implements the JsHelper interface for jQuery. All $options arrays
+ * support all options found in the JsHelper, as well as those in the jQuery
+ * documentation.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('JsBaseEngineHelper', 'View/Helper');
+
+/**
+ * jQuery Engine Helper for JsHelper
+ *
+ * Provides jQuery specific Javascript for JsHelper.
+ *
+ * Implements the JsHelper interface for jQuery. All $options arrays
+ * support all options found in the JsHelper, as well as those in the jQuery
+ * documentation.
+ *
+ * @package Cake.View.Helper
+ */
+class JqueryEngineHelper extends JsBaseEngineHelper {
+
+/**
+ * Option mappings for jQuery
+ *
+ * @var array
+ */
+ protected $_optionMap = array(
+ 'request' => array(
+ 'type' => 'dataType',
+ 'before' => 'beforeSend',
+ 'method' => 'type',
+ ),
+ 'sortable' => array(
+ 'complete' => 'stop',
+ ),
+ 'drag' => array(
+ 'snapGrid' => 'grid',
+ 'container' => 'containment',
+ ),
+ 'drop' => array(
+ 'leave' => 'out',
+ 'hover' => 'over'
+ ),
+ 'slider' => array(
+ 'complete' => 'stop',
+ 'direction' => 'orientation'
+ )
+ );
+
+/**
+ * Callback arguments lists
+ *
+ * @var string
+ */
+ protected $_callbackArguments = array(
+ 'slider' => array(
+ 'start' => 'event, ui',
+ 'slide' => 'event, ui',
+ 'change' => 'event, ui',
+ 'stop' => 'event, ui'
+ ),
+ 'sortable' => array(
+ 'start' => 'event, ui',
+ 'sort' => 'event, ui',
+ 'change' => 'event, ui',
+ 'beforeStop' => 'event, ui',
+ 'stop' => 'event, ui',
+ 'update' => 'event, ui',
+ 'receive' => 'event, ui',
+ 'remove' => 'event, ui',
+ 'over' => 'event, ui',
+ 'out' => 'event, ui',
+ 'activate' => 'event, ui',
+ 'deactivate' => 'event, ui'
+ ),
+ 'drag' => array(
+ 'start' => 'event, ui',
+ 'drag' => 'event, ui',
+ 'stop' => 'event, ui',
+ ),
+ 'drop' => array(
+ 'activate' => 'event, ui',
+ 'deactivate' => 'event, ui',
+ 'over' => 'event, ui',
+ 'out' => 'event, ui',
+ 'drop' => 'event, ui'
+ ),
+ 'request' => array(
+ 'beforeSend' => 'XMLHttpRequest',
+ 'error' => 'XMLHttpRequest, textStatus, errorThrown',
+ 'success' => 'data, textStatus',
+ 'complete' => 'XMLHttpRequest, textStatus',
+ 'xhr' => ''
+ )
+ );
+
+/**
+ * The variable name of the jQuery Object, useful
+ * when jQuery is put into noConflict() mode.
+ *
+ * @var string
+ */
+ public $jQueryObject = '$';
+
+/**
+ * Helper function to wrap repetitive simple method templating.
+ *
+ * @param string $method The method name being generated.
+ * @param string $template The method template
+ * @param array $options Array of options for method
+ * @param array $extraSafeKeys Extra safe keys
+ * @return string Composed method string
+ */
+ protected function _methodTemplate($method, $template, $options, $extraSafeKeys = array()) {
+ $options = $this->_mapOptions($method, $options);
+ $options = $this->_prepareCallbacks($method, $options);
+ $callbacks = array_keys($this->_callbackArguments[$method]);
+ if (!empty($extraSafeKeys)) {
+ $callbacks = array_merge($callbacks, $extraSafeKeys);
+ }
+ $options = $this->_parseOptions($options, $callbacks);
+ return sprintf($template, $this->selection, $options);
+ }
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return JqueryEngineHelper instance of $this. Allows chained methods.
+ */
+ public function get($selector) {
+ if ($selector == 'window' || $selector == 'document') {
+ $this->selection = $this->jQueryObject . '(' . $selector . ')';
+ } else {
+ $this->selection = $this->jQueryObject . '("' . $selector . '")';
+ }
+ return $this;
+ }
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
+ * - 'stop' - Whether you want the event to stopped. (defaults true)
+ *
+ * @param string $type Type of event to bind to the current dom id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ public function event($type, $callback, $options = array()) {
+ $defaults = array('wrap' => true, 'stop' => true);
+ $options = array_merge($defaults, $options);
+
+ $function = 'function (event) {%s}';
+ if ($options['wrap'] && $options['stop']) {
+ $callback .= "\nreturn false;";
+ }
+ if ($options['wrap']) {
+ $callback = sprintf($function, $callback);
+ }
+ return sprintf('%s.bind("%s", %s);', $this->selection, $type, $callback);
+ }
+
+/**
+ * Create a domReady event. For jQuery. This method does not
+ * bind a 'traditional event' as `$(document).bind('ready', fn)`
+ * Works in an entirely different fashion than `$(document).ready()`
+ * The first will not run the function when eval()'d as part of a response
+ * The second will. Because of the way that ajax pagination is done
+ * `$().ready()` is used.
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ public function domReady($functionBody) {
+ return $this->jQueryObject . '(document).ready(function () {' . $functionBody . '});';
+ }
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ public function each($callback) {
+ return $this->selection . '.each(function () {' . $callback . '});';
+ }
+
+/**
+ * Trigger an Effect.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ * @see JsBaseEngineHelper::effect()
+ */
+ public function effect($name, $options = array()) {
+ $speed = null;
+ if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
+ $speed = $this->value($options['speed']);
+ }
+ $effect = '';
+ switch ($name) {
+ case 'slideIn':
+ case 'slideOut':
+ $name = ($name == 'slideIn') ? 'slideDown' : 'slideUp';
+ case 'hide':
+ case 'show':
+ case 'fadeIn':
+ case 'fadeOut':
+ case 'slideDown':
+ case 'slideUp':
+ $effect = ".$name($speed);";
+ break;
+ }
+ return $this->selection . $effect;
+ }
+
+/**
+ * Create an $.ajax() call.
+ *
+ * If the 'update' key is set, success callback will be overridden.
+ *
+ * @param string|array $url
+ * @param array $options See JsHelper::request() for options.
+ * @return string The completed ajax call.
+ * @see JsBaseEngineHelper::request() for options list.
+ */
+ public function request($url, $options = array()) {
+ $url = $this->url($url);
+ $options = $this->_mapOptions('request', $options);
+ if (isset($options['data']) && is_array($options['data'])) {
+ $options['data'] = $this->_toQuerystring($options['data']);
+ }
+ $options['url'] = $url;
+ if (isset($options['update'])) {
+ $wrapCallbacks = isset($options['wrapCallbacks']) ? $options['wrapCallbacks'] : true;
+ $success = '';
+ if (isset($options['success']) && !empty($options['success'])) {
+ $success .= $options['success'];
+ }
+ $success .= $this->jQueryObject . '("' . $options['update'] . '").html(data);';
+ if (!$wrapCallbacks) {
+ $success = 'function (data, textStatus) {' . $success . '}';
+ }
+ $options['dataType'] = 'html';
+ $options['success'] = $success;
+ unset($options['update']);
+ }
+ $callbacks = array('success', 'error', 'beforeSend', 'complete');
+ if (!empty($options['dataExpression'])) {
+ $callbacks[] = 'data';
+ unset($options['dataExpression']);
+ }
+ $options = $this->_prepareCallbacks('request', $options);
+ $options = $this->_parseOptions($options, $callbacks);
+ return $this->jQueryObject . '.ajax({' . $options . '});';
+ }
+
+/**
+ * Create a sortable element.
+ *
+ * Requires both Ui.Core and Ui.Sortables to be loaded.
+ *
+ * @param array $options Array of options for the sortable.
+ * @return string Completed sortable script.
+ * @see JsBaseEngineHelper::sortable() for options list.
+ */
+ public function sortable($options = array()) {
+ $template = '%s.sortable({%s});';
+ return $this->_methodTemplate('sortable', $template, $options);
+ }
+
+/**
+ * Create a Draggable element
+ *
+ * Requires both Ui.Core and Ui.Draggable to be loaded.
+ *
+ * @param array $options Array of options for the draggable element.
+ * @return string Completed Draggable script.
+ * @see JsBaseEngineHelper::drag() for options list.
+ */
+ public function drag($options = array()) {
+ $template = '%s.draggable({%s});';
+ return $this->_methodTemplate('drag', $template, $options);
+ }
+
+/**
+ * Create a Droppable element
+ *
+ * Requires both Ui.Core and Ui.Droppable to be loaded.
+ *
+ * @param array $options Array of options for the droppable element.
+ * @return string Completed Droppable script.
+ * @see JsBaseEngineHelper::drop() for options list.
+ */
+ public function drop($options = array()) {
+ $template = '%s.droppable({%s});';
+ return $this->_methodTemplate('drop', $template, $options);
+ }
+
+/**
+ * Create a Slider element
+ *
+ * Requires both Ui.Core and Ui.Slider to be loaded.
+ *
+ * @param array $options Array of options for the droppable element.
+ * @return string Completed Slider script.
+ * @see JsBaseEngineHelper::slider() for options list.
+ */
+ public function slider($options = array()) {
+ $callbacks = array('start', 'change', 'slide', 'stop');
+ $template = '%s.slider({%s});';
+ return $this->_methodTemplate('slider', $template, $options, $callbacks);
+ }
+
+/**
+ * Serialize a form attached to $selector. If the current selection is not an input or
+ * form, errors will be created in the Javascript.
+ *
+ * @param array $options Options for the serialization
+ * @return string completed form serialization script.
+ * @see JsBaseEngineHelper::serializeForm() for option list.
+ */
+ public function serializeForm($options = array()) {
+ $options = array_merge(array('isForm' => false, 'inline' => false), $options);
+ $selector = $this->selection;
+ if (!$options['isForm']) {
+ $selector = $this->selection . '.closest("form")';
+ }
+ $method = '.serialize()';
+ if (!$options['inline']) {
+ $method .= ';';
+ }
+ return $selector . $method;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php
new file mode 100644
index 0000000..b3a293a
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsBaseEngineHelper.php
@@ -0,0 +1,592 @@
+<?php
+/**
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * JsEngineBaseClass
+ *
+ * Abstract Base Class for All JsEngines to extend. Provides generic methods.
+ *
+ * @package Cake.View.Helper
+ */
+abstract class JsBaseEngineHelper extends AppHelper {
+
+/**
+ * The js snippet for the current selection.
+ *
+ * @var string
+ */
+ public $selection;
+
+/**
+ * Collection of option maps. Option maps allow other helpers to use generic names for engine
+ * callbacks and options. Allowing uniform code access for all engine types. Their use is optional
+ * for end user use though.
+ *
+ * @var array
+ */
+ protected $_optionMap = array();
+
+/**
+ * An array of lowercase method names in the Engine that are buffered unless otherwise disabled.
+ * This allows specific 'end point' methods to be automatically buffered by the JsHelper.
+ *
+ * @var array
+ */
+ public $bufferedMethods = array('event', 'sortable', 'drag', 'drop', 'slider');
+
+/**
+ * Contains a list of callback names -> default arguments.
+ *
+ * @var array
+ */
+ protected $_callbackArguments = array();
+
+/**
+ * Create an `alert()` message in Javascript
+ *
+ * @param string $message Message you want to alter.
+ * @return string completed alert()
+ */
+ public function alert($message) {
+ return 'alert("' . $this->escape($message) . '");';
+ }
+
+/**
+ * Redirects to a URL. Creates a window.location modification snippet
+ * that can be used to trigger 'redirects' from Javascript.
+ *
+ * @param string|array $url
+ * @param array $options
+ * @return string completed redirect in javascript
+ */
+ public function redirect($url = null) {
+ return 'window.location = "' . Router::url($url) . '";';
+ }
+
+/**
+ * Create a `confirm()` message
+ *
+ * @param string $message Message you want confirmed.
+ * @return string completed confirm()
+ */
+ public function confirm($message) {
+ return 'confirm("' . $this->escape($message) . '");';
+ }
+
+/**
+ * Generate a confirm snippet that returns false from the current
+ * function scope.
+ *
+ * @param string $message Message to use in the confirm dialog.
+ * @return string completed confirm with return script
+ */
+ public function confirmReturn($message) {
+ $out = 'var _confirm = ' . $this->confirm($message);
+ $out .= "if (!_confirm) {\n\treturn false;\n}";
+ return $out;
+ }
+
+/**
+ * Create a `prompt()` Javascript function
+ *
+ * @param string $message Message you want to prompt.
+ * @param string $default Default message
+ * @return string completed prompt()
+ */
+ public function prompt($message, $default = '') {
+ return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
+ }
+
+/**
+ * Generates a JavaScript object in JavaScript Object Notation (JSON)
+ * from an array. Will use native JSON encode method if available, and $useNative == true
+ *
+ * ### Options:
+ *
+ * - `prefix` - String prepended to the returned data.
+ * - `postfix` - String appended to the returned data.
+ *
+ * @param array $data Data to be converted.
+ * @param array $options Set of options, see above.
+ * @return string A JSON code block
+ */
+ public function object($data = array(), $options = array()) {
+ $defaultOptions = array(
+ 'prefix' => '', 'postfix' => '',
+ );
+ $options = array_merge($defaultOptions, $options);
+
+ return $options['prefix'] . json_encode($data) . $options['postfix'];
+ }
+
+/**
+ * Converts a PHP-native variable of any type to a JSON-equivalent representation
+ *
+ * @param mixed $val A PHP variable to be converted to JSON
+ * @param boolean $quoteString If false, leaves string values unquoted
+ * @return string a JavaScript-safe/JSON representation of $val
+ */
+ public function value($val = array(), $quoteString = null, $key = 'value') {
+ if ($quoteString === null) {
+ $quoteString = true;
+ }
+ switch (true) {
+ case (is_array($val) || is_object($val)):
+ $val = $this->object($val);
+ break;
+ case ($val === null):
+ $val = 'null';
+ break;
+ case (is_bool($val)):
+ $val = ($val === true) ? 'true' : 'false';
+ break;
+ case (is_int($val)):
+ $val = $val;
+ break;
+ case (is_float($val)):
+ $val = sprintf("%.11f", $val);
+ break;
+ default:
+ $val = $this->escape($val);
+ if ($quoteString) {
+ $val = '"' . $val . '"';
+ }
+ break;
+ }
+ return $val;
+ }
+
+/**
+ * Escape a string to be JSON friendly.
+ *
+ * List of escaped elements:
+ *
+ * - "\r" => '\n'
+ * - "\n" => '\n'
+ * - '"' => '\"'
+ *
+ * @param string $string String that needs to get escaped.
+ * @return string Escaped string.
+ */
+ public function escape($string) {
+ return $this->_utf8ToHex($string);
+ }
+
+/**
+ * Encode a string into JSON. Converts and escapes necessary characters.
+ *
+ * @param string $string The string that needs to be utf8->hex encoded
+ * @return void
+ */
+ protected function _utf8ToHex($string) {
+ $length = strlen($string);
+ $return = '';
+ for ($i = 0; $i < $length; ++$i) {
+ $ord = ord($string{$i});
+ switch (true) {
+ case $ord == 0x08:
+ $return .= '\b';
+ break;
+ case $ord == 0x09:
+ $return .= '\t';
+ break;
+ case $ord == 0x0A:
+ $return .= '\n';
+ break;
+ case $ord == 0x0C:
+ $return .= '\f';
+ break;
+ case $ord == 0x0D:
+ $return .= '\r';
+ break;
+ case $ord == 0x22:
+ case $ord == 0x2F:
+ case $ord == 0x5C:
+ $return .= '\\' . $string{$i};
+ break;
+ case (($ord >= 0x20) && ($ord <= 0x7F)):
+ $return .= $string{$i};
+ break;
+ case (($ord & 0xE0) == 0xC0):
+ if ($i + 1 >= $length) {
+ $i += 1;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 1;
+ break;
+ case (($ord & 0xF0) == 0xE0):
+ if ($i + 2 >= $length) {
+ $i += 2;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 2;
+ break;
+ case (($ord & 0xF8) == 0xF0):
+ if ($i + 3 >= $length) {
+ $i += 3;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 3;
+ break;
+ case (($ord & 0xFC) == 0xF8):
+ if ($i + 4 >= $length) {
+ $i += 4;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 4;
+ break;
+ case (($ord & 0xFE) == 0xFC):
+ if ($i + 5 >= $length) {
+ $i += 5;
+ $return .= '?';
+ break;
+ }
+ $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4} . $string{$i + 5};
+ $char = Multibyte::utf8($charbits);
+ $return .= sprintf('\u%04s', dechex($char[0]));
+ $i += 5;
+ break;
+ }
+ }
+ return $return;
+ }
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return JsBaseEngineHelper instance of $this. Allows chained methods.
+ */
+ abstract public function get($selector);
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - `wrap` - Whether you want the callback wrapped in an anonymous function. (defaults to true)
+ * - `stop` - Whether you want the event to stopped. (defaults to true)
+ *
+ * @param string $type Type of event to bind to the current dom id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ abstract public function event($type, $callback, $options = array());
+
+/**
+ * Create a domReady event. This is a special event in many libraries
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ abstract public function domReady($functionBody);
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ abstract public function each($callback);
+
+/**
+ * Trigger an Effect.
+ *
+ * ### Supported Effects
+ *
+ * The following effects are supported by all core JsEngines
+ *
+ * - `show` - reveal an element.
+ * - `hide` - hide an element.
+ * - `fadeIn` - Fade in an element.
+ * - `fadeOut` - Fade out an element.
+ * - `slideIn` - Slide an element in.
+ * - `slideOut` - Slide an element out.
+ *
+ * ### Options
+ *
+ * - `speed` - Speed at which the animation should occur. Accepted values are 'slow', 'fast'. Not all effects use
+ * the speed option.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ */
+ abstract public function effect($name, $options = array());
+
+/**
+ * Make an XHR request
+ *
+ * ### Event Options
+ *
+ * - `complete` - Callback to fire on complete.
+ * - `success` - Callback to fire on success.
+ * - `before` - Callback to fire on request initialization.
+ * - `error` - Callback to fire on request failure.
+ *
+ * ### Options
+ *
+ * - `method` - The method to make the request with defaults to GET in more libraries
+ * - `async` - Whether or not you want an asynchronous request.
+ * - `data` - Additional data to send.
+ * - `update` - Dom id to update with the content of the request.
+ * - `type` - Data type for response. 'json' and 'html' are supported. Default is html for most libraries.
+ * - `evalScripts` - Whether or not <script> tags should be eval'ed.
+ * - `dataExpression` - Should the `data` key be treated as a callback. Useful for supplying `$options['data']` as
+ * another Javascript expression.
+ *
+ * @param string|array $url Array or String URL to target with the request.
+ * @param array $options Array of options. See above for cross library supported options
+ * @return string XHR request.
+ */
+ abstract public function request($url, $options = array());
+
+/**
+ * Create a draggable element. Works on the currently selected element.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `handle` - selector to the handle element.
+ * - `snapGrid` - The pixel grid that movement snaps to, an array(x, y)
+ * - `container` - The element that acts as a bounding box for the draggable element.
+ *
+ * ### Event Options
+ *
+ * - `start` - Event fired when the drag starts
+ * - `drag` - Event fired on every step of the drag
+ * - `stop` - Event fired when dragging stops (mouse release)
+ *
+ * @param array $options Options array see above.
+ * @return string Completed drag script
+ */
+ abstract public function drag($options = array());
+
+/**
+ * Create a droppable element. Allows for draggable elements to be dropped on it.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `accept` - Selector for elements this droppable will accept.
+ * - `hoverclass` - Class to add to droppable when a draggable is over.
+ *
+ * ### Event Options
+ *
+ * - `drop` - Event fired when an element is dropped into the drop zone.
+ * - `hover` - Event fired when a drag enters a drop zone.
+ * - `leave` - Event fired when a drag is removed from a drop zone without being dropped.
+ *
+ * @param array $options Array of options for the drop. See above.
+ * @return string Completed drop script
+ */
+ abstract public function drop($options = array());
+
+/**
+ * Create a sortable element.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `containment` - Container for move action
+ * - `handle` - Selector to handle element. Only this element will start sort action.
+ * - `revert` - Whether or not to use an effect to move sortable into final position.
+ * - `opacity` - Opacity of the placeholder
+ * - `distance` - Distance a sortable must be dragged before sorting starts.
+ *
+ * ### Event Options
+ *
+ * - `start` - Event fired when sorting starts
+ * - `sort` - Event fired during sorting
+ * - `complete` - Event fired when sorting completes.
+ *
+ * @param array $options Array of options for the sortable. See above.
+ * @return string Completed sortable script.
+ */
+ abstract public function sortable($options = array());
+
+/**
+ * Create a slider UI widget. Comprised of a track and knob.
+ * Additional options may be supported by the library implementation.
+ *
+ * ### Options
+ *
+ * - `handle` - The id of the element used in sliding.
+ * - `direction` - The direction of the slider either 'vertical' or 'horizontal'
+ * - `min` - The min value for the slider.
+ * - `max` - The max value for the slider.
+ * - `step` - The number of steps or ticks the slider will have.
+ * - `value` - The initial offset of the slider.
+ *
+ * ### Events
+ *
+ * - `change` - Fired when the slider's value is updated
+ * - `complete` - Fired when the user stops sliding the handle
+ *
+ * @param array $options Array of options for the slider. See above.
+ * @return string Completed slider script
+ */
+ abstract public function slider($options = array());
+
+/**
+ * Serialize the form attached to $selector.
+ * Pass `true` for $isForm if the current selection is a form element.
+ * Converts the form or the form element attached to the current selection into a string/json object
+ * (depending on the library implementation) for use with XHR operations.
+ *
+ * ### Options
+ *
+ * - `isForm` - is the current selection a form, or an input? (defaults to false)
+ * - `inline` - is the rendered statement going to be used inside another JS statement? (defaults to false)
+ *
+ * @param array $options options for serialization generation.
+ * @return string completed form serialization script
+ */
+ abstract public function serializeForm($options = array());
+
+/**
+ * Parse an options assoc array into an Javascript object literal.
+ * Similar to object() but treats any non-integer value as a string,
+ * does not include `{ }`
+ *
+ * @param array $options Options to be converted
+ * @param array $safeKeys Keys that should not be escaped.
+ * @return string Parsed JSON options without enclosing { }.
+ */
+ protected function _parseOptions($options, $safeKeys = array()) {
+ $out = array();
+ $safeKeys = array_flip($safeKeys);
+ foreach ($options as $key => $value) {
+ if (!is_int($value) && !isset($safeKeys[$key])) {
+ $value = $this->value($value);
+ }
+ $out[] = $key . ':' . $value;
+ }
+ sort($out);
+ return join(', ', $out);
+ }
+
+/**
+ * Maps Abstract options to engine specific option names.
+ * If attributes are missing from the map, they are not changed.
+ *
+ * @param string $method Name of method whose options are being worked with.
+ * @param array $options Array of options to map.
+ * @return array Array of mapped options.
+ */
+ protected function _mapOptions($method, $options) {
+ if (!isset($this->_optionMap[$method])) {
+ return $options;
+ }
+ foreach ($this->_optionMap[$method] as $abstract => $concrete) {
+ if (isset($options[$abstract])) {
+ $options[$concrete] = $options[$abstract];
+ unset($options[$abstract]);
+ }
+ }
+ return $options;
+ }
+
+/**
+ * Prepare callbacks and wrap them with function ([args]) { } as defined in
+ * _callbackArgs array.
+ *
+ * @param string $method Name of the method you are preparing callbacks for.
+ * @param array $options Array of options being parsed
+ * @param array $callbacks Additional Keys that contain callbacks
+ * @return array Array of options with callbacks added.
+ */
+ protected function _prepareCallbacks($method, $options, $callbacks = array()) {
+ $wrapCallbacks = true;
+ if (isset($options['wrapCallbacks'])) {
+ $wrapCallbacks = $options['wrapCallbacks'];
+ }
+ unset($options['wrapCallbacks']);
+ if (!$wrapCallbacks) {
+ return $options;
+ }
+ $callbackOptions = array();
+ if (isset($this->_callbackArguments[$method])) {
+ $callbackOptions = $this->_callbackArguments[$method];
+ }
+ $callbacks = array_unique(array_merge(array_keys($callbackOptions), (array)$callbacks));
+
+ foreach ($callbacks as $callback) {
+ if (empty($options[$callback])) {
+ continue;
+ }
+ $args = null;
+ if (!empty($callbackOptions[$callback])) {
+ $args = $callbackOptions[$callback];
+ }
+ $options[$callback] = 'function (' . $args . ') {' . $options[$callback] . '}';
+ }
+ return $options;
+ }
+
+/**
+ * Convenience wrapper method for all common option processing steps.
+ * Runs _mapOptions, _prepareCallbacks, and _parseOptions in order.
+ *
+ * @param string $method Name of method processing options for.
+ * @param array $options Array of options to process.
+ * @return string Parsed options string.
+ */
+ protected function _processOptions($method, $options) {
+ $options = $this->_mapOptions($method, $options);
+ $options = $this->_prepareCallbacks($method, $options);
+ $options = $this->_parseOptions($options, array_keys($this->_callbackArguments[$method]));
+ return $options;
+ }
+
+/**
+ * Convert an array of data into a query string
+ *
+ * @param array $parameters Array of parameters to convert to a query string
+ * @return string Querystring fragment
+ */
+ protected function _toQuerystring($parameters) {
+ $out = '';
+ $keys = array_keys($parameters);
+ $count = count($parameters);
+ for ($i = 0; $i < $count; $i++) {
+ $out .= $keys[$i] . '=' . $parameters[$keys[$i]];
+ if ($i < $count - 1) {
+ $out .= '&';
+ }
+ }
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php
new file mode 100644
index 0000000..5490fbb
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/JsHelper.php
@@ -0,0 +1,434 @@
+<?php
+/**
+ * Javascript Generator class file.
+ *
+ * PHP 5
+ *
+ * CakePHP : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc.
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('JsBaseEngineHelper', 'View/Helper');
+App::uses('Multibyte', 'I18n');
+
+/**
+ * Javascript Generator helper class for easy use of JavaScript.
+ *
+ * JsHelper provides an abstract interface for authoring JavaScript with a
+ * given client-side library.
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @property FormHelper $Form
+ */
+class JsHelper extends AppHelper {
+
+/**
+ * Whether or not you want scripts to be buffered or output.
+ *
+ * @var boolean
+ */
+ public $bufferScripts = true;
+
+/**
+ * Helper dependencies
+ *
+ * @var array
+ */
+ public $helpers = array('Html', 'Form');
+
+/**
+ * Variables to pass to Javascript.
+ *
+ * @var array
+ * @see JsHelper::set()
+ */
+ protected $_jsVars = array();
+
+/**
+ * Scripts that are queued for output
+ *
+ * @var array
+ * @see JsHelper::buffer()
+ */
+ protected $_bufferedScripts = array();
+
+/**
+ * Current Javascript Engine that is being used
+ *
+ * @var string
+ */
+ protected $_engineName;
+
+/**
+ * The javascript variable created by set() variables.
+ *
+ * @var string
+ */
+ public $setVariable = 'app';
+
+/**
+ * Constructor - determines engine helper
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Settings array contains name of engine helper.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $className = 'Jquery';
+ if (is_array($settings) && isset($settings[0])) {
+ $className = $settings[0];
+ } elseif (is_string($settings)) {
+ $className = $settings;
+ }
+ $engineName = $className;
+ list($plugin, $className) = pluginSplit($className);
+
+ $this->_engineName = $className . 'Engine';
+ $engineClass = $engineName . 'Engine';
+ $this->helpers[] = $engineClass;
+ parent::__construct($View, $settings);
+ }
+
+/**
+ * call__ Allows for dispatching of methods to the Engine Helper.
+ * methods in the Engines bufferedMethods list will be automatically buffered.
+ * You can control buffering with the buffer param as well. By setting the last parameter to
+ * any engine method to a boolean you can force or disable buffering.
+ *
+ * e.g. `$js->get('#foo')->effect('fadeIn', array('speed' => 'slow'), true);`
+ *
+ * Will force buffering for the effect method. If the method takes an options array you may also add
+ * a 'buffer' param to the options array and control buffering there as well.
+ *
+ * e.g. `$js->get('#foo')->event('click', $functionContents, array('buffer' => true));`
+ *
+ * The buffer parameter will not be passed onto the EngineHelper.
+ *
+ * @param string $method Method to be called
+ * @param array $params Parameters for the method being called.
+ * @return mixed Depends on the return of the dispatched method, or it could be an instance of the EngineHelper
+ */
+ public function __call($method, $params) {
+ if ($this->{$this->_engineName} && method_exists($this->{$this->_engineName}, $method)) {
+ $buffer = false;
+ $engineHelper = $this->{$this->_engineName};
+ if (in_array(strtolower($method), $engineHelper->bufferedMethods)) {
+ $buffer = true;
+ }
+ if (count($params) > 0) {
+ $lastParam = $params[count($params) - 1];
+ $hasBufferParam = (is_bool($lastParam) || is_array($lastParam) && isset($lastParam['buffer']));
+ if ($hasBufferParam && is_bool($lastParam)) {
+ $buffer = $lastParam;
+ unset($params[count($params) - 1]);
+ } elseif ($hasBufferParam && is_array($lastParam)) {
+ $buffer = $lastParam['buffer'];
+ unset($params['buffer']);
+ }
+ }
+
+ $out = call_user_func_array(array(&$engineHelper, $method), $params);
+ if ($this->bufferScripts && $buffer && is_string($out)) {
+ $this->buffer($out);
+ return null;
+ }
+ if (is_object($out) && is_a($out, 'JsBaseEngineHelper')) {
+ return $this;
+ }
+ return $out;
+ }
+ if (method_exists($this, $method . '_')) {
+ return call_user_func(array(&$this, $method . '_'), $params);
+ }
+ trigger_error(__d('cake_dev', 'JsHelper:: Missing Method %s is undefined', $method), E_USER_WARNING);
+ }
+
+/**
+ * Overwrite inherited Helper::value()
+ * See JsBaseEngineHelper::value() for more information on this method.
+ *
+ * @param mixed $val A PHP variable to be converted to JSON
+ * @param boolean $quoteString If false, leaves string values unquoted
+ * @return string a JavaScript-safe/JSON representation of $val
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::value
+ **/
+ public function value($val = array(), $quoteString = null, $key = 'value') {
+ if ($quoteString === null) {
+ $quoteString = true;
+ }
+ return $this->{$this->_engineName}->value($val, $quoteString);
+ }
+
+/**
+ * Writes all Javascript generated so far to a code block or
+ * caches them to a file and returns a linked script. If no scripts have been
+ * buffered this method will return null. If the request is an XHR(ajax) request
+ * onDomReady will be set to false. As the dom is already 'ready'.
+ *
+ * ### Options
+ *
+ * - `inline` - Set to true to have scripts output as a script block inline
+ * if `cache` is also true, a script link tag will be generated. (default true)
+ * - `cache` - Set to true to have scripts cached to a file and linked in (default false)
+ * - `clear` - Set to false to prevent script cache from being cleared (default true)
+ * - `onDomReady` - wrap cached scripts in domready event (default true)
+ * - `safe` - if an inline block is generated should it be wrapped in <![CDATA[ ... ]]> (default true)
+ *
+ * @param array $options options for the code block
+ * @return mixed Completed javascript tag if there are scripts, if there are no buffered
+ * scripts null will be returned.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::writeBuffer
+ */
+ public function writeBuffer($options = array()) {
+ $domReady = !$this->request->is('ajax');
+ $defaults = array(
+ 'onDomReady' => $domReady, 'inline' => true,
+ 'cache' => false, 'clear' => true, 'safe' => true
+ );
+ $options = array_merge($defaults, $options);
+ $script = implode("\n", $this->getBuffer($options['clear']));
+
+ if (empty($script)) {
+ return null;
+ }
+
+ if ($options['onDomReady']) {
+ $script = $this->{$this->_engineName}->domReady($script);
+ }
+ $opts = $options;
+ unset($opts['onDomReady'], $opts['cache'], $opts['clear']);
+
+ if (!$options['cache'] && $options['inline']) {
+ return $this->Html->scriptBlock($script, $opts);
+ }
+
+ if ($options['cache'] && $options['inline']) {
+ $filename = md5($script);
+ if (!file_exists(JS . $filename . '.js')) {
+ cache(str_replace(WWW_ROOT, '', JS) . $filename . '.js', $script, '+999 days', 'public');
+ }
+ return $this->Html->script($filename);
+ }
+ $this->Html->scriptBlock($script, $opts);
+ return null;
+ }
+
+/**
+ * Write a script to the buffered scripts.
+ *
+ * @param string $script Script string to add to the buffer.
+ * @param boolean $top If true the script will be added to the top of the
+ * buffered scripts array. If false the bottom.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::buffer
+ */
+ public function buffer($script, $top = false) {
+ if ($top) {
+ array_unshift($this->_bufferedScripts, $script);
+ } else {
+ $this->_bufferedScripts[] = $script;
+ }
+ }
+
+/**
+ * Get all the buffered scripts
+ *
+ * @param boolean $clear Whether or not to clear the script caches (default true)
+ * @return array Array of scripts added to the request.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::getBuffer
+ */
+ public function getBuffer($clear = true) {
+ $this->_createVars();
+ $scripts = $this->_bufferedScripts;
+ if ($clear) {
+ $this->_bufferedScripts = array();
+ $this->_jsVars = array();
+ }
+ return $scripts;
+ }
+
+/**
+ * Generates the object string for variables passed to javascript.
+ *
+ * @return string Generated JSON object of all set vars
+ */
+ protected function _createVars() {
+ if (!empty($this->_jsVars)) {
+ $setVar = (strpos($this->setVariable, '.')) ? $this->setVariable : 'window.' . $this->setVariable;
+ $this->buffer($setVar . ' = ' . $this->object($this->_jsVars) . ';', true);
+ }
+ }
+
+/**
+ * Generate an 'Ajax' link. Uses the selected JS engine to create a link
+ * element that is enhanced with Javascript. Options can include
+ * both those for HtmlHelper::link() and JsBaseEngine::request(), JsBaseEngine::event();
+ *
+ * ### Options
+ *
+ * - `confirm` - Generate a confirm() dialog before sending the event.
+ * - `id` - use a custom id.
+ * - `htmlAttributes` - additional non-standard htmlAttributes. Standard attributes are class, id,
+ * rel, title, escape, onblur and onfocus.
+ * - `buffer` - Disable the buffering and return a script tag in addition to the link.
+ *
+ * @param string $title Title for the link.
+ * @param string|array $url Mixed either a string URL or an cake url array.
+ * @param array $options Options for both the HTML element and Js::request()
+ * @return string Completed link. If buffering is disabled a script tag will be returned as well.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::link
+ */
+ public function link($title, $url = null, $options = array()) {
+ if (!isset($options['id'])) {
+ $options['id'] = 'link-' . intval(mt_rand());
+ }
+ list($options, $htmlOptions) = $this->_getHtmlOptions($options);
+ $out = $this->Html->link($title, $url, $htmlOptions);
+ $this->get('#' . $htmlOptions['id']);
+ $requestString = $event = '';
+ if (isset($options['confirm'])) {
+ $requestString = $this->confirmReturn($options['confirm']);
+ unset($options['confirm']);
+ }
+ $buffer = isset($options['buffer']) ? $options['buffer'] : null;
+ $safe = isset($options['safe']) ? $options['safe'] : true;
+ unset($options['buffer'], $options['safe']);
+
+ $requestString .= $this->request($url, $options);
+
+ if (!empty($requestString)) {
+ $event = $this->event('click', $requestString, $options + array('buffer' => $buffer));
+ }
+ if (isset($buffer) && !$buffer) {
+ $opts = array('safe' => $safe);
+ $out .= $this->Html->scriptBlock($event, $opts);
+ }
+ return $out;
+ }
+
+/**
+ * Pass variables into Javascript. Allows you to set variables that will be
+ * output when the buffer is fetched with `JsHelper::getBuffer()` or `JsHelper::writeBuffer()`
+ * The Javascript variable used to output set variables can be controlled with `JsHelper::$setVariable`
+ *
+ * @param string|array $one Either an array of variables to set, or the name of the variable to set.
+ * @param string|array $two If $one is a string, $two is the value for that key.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::set
+ */
+ public function set($one, $two = null) {
+ $data = null;
+ if (is_array($one)) {
+ if (is_array($two)) {
+ $data = array_combine($one, $two);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($one => $two);
+ }
+ if ($data == null) {
+ return false;
+ }
+ $this->_jsVars = array_merge($this->_jsVars, $data);
+ }
+
+/**
+ * Uses the selected JS engine to create a submit input
+ * element that is enhanced with Javascript. Options can include
+ * both those for FormHelper::submit() and JsBaseEngine::request(), JsBaseEngine::event();
+ *
+ * Forms submitting with this method, cannot send files. Files do not transfer over XmlHttpRequest
+ * and require an iframe or flash.
+ *
+ * ### Options
+ *
+ * - `url` The url you wish the XHR request to submit to.
+ * - `confirm` A string to use for a confirm() message prior to submitting the request.
+ * - `method` The method you wish the form to send by, defaults to POST
+ * - `buffer` Whether or not you wish the script code to be buffered, defaults to true.
+ * - Also see options for JsHelper::request() and JsHelper::event()
+ *
+ * @param string $caption The display text of the submit button.
+ * @param array $options Array of options to use. See the options for the above mentioned methods.
+ * @return string Completed submit button.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::submit
+ */
+ public function submit($caption = null, $options = array()) {
+ if (!isset($options['id'])) {
+ $options['id'] = 'submit-' . intval(mt_rand());
+ }
+ $formOptions = array('div');
+ list($options, $htmlOptions) = $this->_getHtmlOptions($options, $formOptions);
+ $out = $this->Form->submit($caption, $htmlOptions);
+
+ $this->get('#' . $htmlOptions['id']);
+
+ $options['data'] = $this->serializeForm(array('isForm' => false, 'inline' => true));
+ $requestString = $url = '';
+ if (isset($options['confirm'])) {
+ $requestString = $this->confirmReturn($options['confirm']);
+ unset($options['confirm']);
+ }
+ if (isset($options['url'])) {
+ $url = $options['url'];
+ unset($options['url']);
+ }
+ if (!isset($options['method'])) {
+ $options['method'] = 'post';
+ }
+ $options['dataExpression'] = true;
+
+ $buffer = isset($options['buffer']) ? $options['buffer'] : null;
+ $safe = isset($options['safe']) ? $options['safe'] : true;
+ unset($options['buffer'], $options['safe']);
+
+ $requestString .= $this->request($url, $options);
+ if (!empty($requestString)) {
+ $event = $this->event('click', $requestString, $options + array('buffer' => $buffer));
+ }
+ if (isset($buffer) && !$buffer) {
+ $opts = array('safe' => $safe);
+ $out .= $this->Html->scriptBlock($event, $opts);
+ }
+ return $out;
+ }
+
+/**
+ * Parse a set of Options and extract the Html options.
+ * Extracted Html Options are removed from the $options param.
+ *
+ * @param array $options Options to filter.
+ * @param array $additional Array of additional keys to extract and include in the return options array.
+ * @return array Array of js options and Htmloptions
+ */
+ protected function _getHtmlOptions($options, $additional = array()) {
+ $htmlKeys = array_merge(
+ array('class', 'id', 'escape', 'onblur', 'onfocus', 'rel', 'title', 'style'),
+ $additional
+ );
+ $htmlOptions = array();
+ foreach ($htmlKeys as $key) {
+ if (isset($options[$key])) {
+ $htmlOptions[$key] = $options[$key];
+ }
+ unset($options[$key]);
+ }
+ if (isset($options['htmlAttributes'])) {
+ $htmlOptions = array_merge($htmlOptions, $options['htmlAttributes']);
+ unset($options['htmlAttributes']);
+ }
+ return array($options, $htmlOptions);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php
new file mode 100644
index 0000000..3919754
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/MootoolsEngineHelper.php
@@ -0,0 +1,376 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('JsBaseEngineHelper', 'View/Helper');
+
+/**
+ * MooTools Engine Helper for JsHelper
+ *
+ * Provides MooTools specific Javascript for JsHelper.
+ * Assumes that you have the following MooTools packages
+ *
+ * - Remote, Remote.HTML, Remote.JSON
+ * - Fx, Fx.Tween, Fx.Morph
+ * - Selectors, DomReady,
+ * - Drag, Drag.Move
+ *
+ * @package Cake.View.Helper
+ */
+class MootoolsEngineHelper extends JsBaseEngineHelper {
+
+/**
+ * Option mappings for MooTools
+ *
+ * @var array
+ */
+ protected $_optionMap = array(
+ 'request' => array(
+ 'complete' => 'onComplete',
+ 'success' => 'onSuccess',
+ 'before' => 'onRequest',
+ 'error' => 'onFailure'
+ ),
+ 'sortable' => array(
+ 'distance' => 'snap',
+ 'containment' => 'constrain',
+ 'sort' => 'onSort',
+ 'complete' => 'onComplete',
+ 'start' => 'onStart',
+ ),
+ 'drag' => array(
+ 'snapGrid' => 'snap',
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ 'stop' => 'onComplete',
+ ),
+ 'drop' => array(
+ 'drop' => 'onDrop',
+ 'hover' => 'onEnter',
+ 'leave' => 'onLeave',
+ ),
+ 'slider' => array(
+ 'complete' => 'onComplete',
+ 'change' => 'onChange',
+ 'direction' => 'mode',
+ 'step' => 'steps'
+ )
+ );
+
+/**
+ * Contains a list of callback names -> default arguments.
+ *
+ * @var array
+ */
+ protected $_callbackArguments = array(
+ 'slider' => array(
+ 'onTick' => 'position',
+ 'onChange' => 'step',
+ 'onComplete' => 'event'
+ ),
+ 'request' => array(
+ 'onRequest' => '',
+ 'onComplete' => '',
+ 'onCancel' => '',
+ 'onSuccess' => 'responseText, responseXML',
+ 'onFailure' => 'xhr',
+ 'onException' => 'headerName, value',
+ ),
+ 'drag' => array(
+ 'onBeforeStart' => 'element',
+ 'onStart' => 'element',
+ 'onSnap' => 'element',
+ 'onDrag' => 'element, event',
+ 'onComplete' => 'element, event',
+ 'onCancel' => 'element',
+ ),
+ 'drop' => array(
+ 'onBeforeStart' => 'element',
+ 'onStart' => 'element',
+ 'onSnap' => 'element',
+ 'onDrag' => 'element, event',
+ 'onComplete' => 'element, event',
+ 'onCancel' => 'element',
+ 'onDrop' => 'element, droppable, event',
+ 'onLeave' => 'element, droppable',
+ 'onEnter' => 'element, droppable',
+ ),
+ 'sortable' => array(
+ 'onStart' => 'element, clone',
+ 'onSort' => 'element, clone',
+ 'onComplete' => 'element',
+ )
+ );
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return MootoolsEngineHelper instance of $this. Allows chained methods.
+ */
+ public function get($selector) {
+ $this->_multipleSelection = false;
+ if ($selector == 'window' || $selector == 'document') {
+ $this->selection = "$(" . $selector . ")";
+ return $this;
+ }
+ if (preg_match('/^#[^\s.]+$/', $selector)) {
+ $this->selection = '$("' . substr($selector, 1) . '")';
+ return $this;
+ }
+ $this->_multipleSelection = true;
+ $this->selection = '$$("' . $selector . '")';
+ return $this;
+ }
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
+ * - 'stop' - Whether you want the event to stopped. (defaults true)
+ *
+ * @param string $type Type of event to bind to the current dom id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ public function event($type, $callback, $options = array()) {
+ $defaults = array('wrap' => true, 'stop' => true);
+ $options = array_merge($defaults, $options);
+
+ $function = 'function (event) {%s}';
+ if ($options['wrap'] && $options['stop']) {
+ $callback = "event.stop();\n" . $callback;
+ }
+ if ($options['wrap']) {
+ $callback = sprintf($function, $callback);
+ }
+ $out = $this->selection . ".addEvent(\"{$type}\", $callback);";
+ return $out;
+ }
+
+/**
+ * Create a domReady event. This is a special event in many libraries
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ public function domReady($functionBody) {
+ $this->selection = 'window';
+ return $this->event('domready', $functionBody, array('stop' => false));
+ }
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ public function each($callback) {
+ return $this->selection . '.each(function (item, index) {' . $callback . '});';
+ }
+
+/**
+ * Trigger an Effect.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ * @see JsBaseEngineHelper::effect()
+ */
+ public function effect($name, $options = array()) {
+ $speed = null;
+ if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
+ if ($options['speed'] == 'fast') {
+ $speed = '"short"';
+ } elseif ($options['speed'] == 'slow') {
+ $speed = '"long"';
+ }
+ }
+ $effect = '';
+ switch ($name) {
+ case 'hide':
+ $effect = 'setStyle("display", "none")';
+ break;
+ case 'show':
+ $effect = 'setStyle("display", "")';
+ break;
+ case 'fadeIn':
+ case 'fadeOut':
+ case 'slideIn':
+ case 'slideOut':
+ list($effectName, $direction) = preg_split('/([A-Z][a-z]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $direction = strtolower($direction);
+ if ($speed) {
+ $effect .= "set(\"$effectName\", {duration:$speed}).";
+ }
+ $effect .= "$effectName(\"$direction\")";
+ break;
+ }
+ return $this->selection . '.' . $effect . ';';
+ }
+
+/**
+ * Create an new Request.
+ *
+ * Requires `Request`. If you wish to use 'update' key you must have ```Request.HTML```
+ * if you wish to do Json requests you will need ```JSON``` and ```Request.JSON```.
+ *
+ * @param string|array $url
+ * @param array $options
+ * @return string The completed ajax call.
+ */
+ public function request($url, $options = array()) {
+ $url = $this->url($url);
+ $options = $this->_mapOptions('request', $options);
+ $type = $data = null;
+ if (isset($options['type']) || isset($options['update'])) {
+ if (isset($options['type']) && strtolower($options['type']) == 'json') {
+ $type = '.JSON';
+ }
+ if (isset($options['update'])) {
+ $options['update'] = str_replace('#', '', $options['update']);
+ $type = '.HTML';
+ }
+ unset($options['type']);
+ }
+ if (!empty($options['data'])) {
+ $data = $options['data'];
+ unset($options['data']);
+ }
+ $options['url'] = $url;
+ $options = $this->_prepareCallbacks('request', $options);
+ if (!empty($options['dataExpression'])) {
+ $callbacks[] = 'data';
+ unset($options['dataExpression']);
+ } elseif (!empty($data)) {
+ $data = $this->object($data);
+ }
+ $options = $this->_parseOptions($options, array_keys($this->_callbackArguments['request']));
+ return "var jsRequest = new Request$type({{$options}}).send($data);";
+ }
+
+/**
+ * Create a sortable element.
+ *
+ * Requires the `Sortables` plugin from MootoolsMore
+ *
+ * @param array $options Array of options for the sortable.
+ * @return string Completed sortable script.
+ * @see JsBaseEngineHelper::sortable() for options list.
+ */
+ public function sortable($options = array()) {
+ $options = $this->_processOptions('sortable', $options);
+ return 'var jsSortable = new Sortables(' . $this->selection . ', {' . $options . '});';
+ }
+
+/**
+ * Create a Draggable element.
+ *
+ * Requires the `Drag` plugin from MootoolsMore
+ *
+ * @param array $options Array of options for the draggable.
+ * @return string Completed draggable script.
+ * @see JsHelper::drag() for options list.
+ */
+ public function drag($options = array()) {
+ $options = $this->_processOptions('drag', $options);
+ return $this->selection . '.makeDraggable({' . $options . '});';
+ }
+
+/**
+ * Create a Droppable element.
+ *
+ * Requires the `Drag` and `Drag.Move` plugins from MootoolsMore
+ *
+ * Droppables in Mootools function differently from other libraries. Droppables
+ * are implemented as an extension of Drag. So in addition to making a get() selection for
+ * the droppable element. You must also provide a selector rule to the draggable element. Furthermore,
+ * Mootools droppables inherit all options from Drag.
+ *
+ * @param array $options Array of options for the droppable.
+ * @return string Completed droppable script.
+ * @see JsBaseEngineHelper::drop() for options list.
+ */
+ public function drop($options = array()) {
+ if (empty($options['drag'])) {
+ trigger_error(
+ __d('cake_dev', 'MootoolsEngine::drop() requires a "drag" option to properly function'), E_USER_WARNING
+ );
+ return false;
+ }
+ $options['droppables'] = $this->selection;
+
+ $this->get($options['drag']);
+ unset($options['drag']);
+
+ $options = $this->_mapOptions('drag', $this->_mapOptions('drop', $options));
+ $options = $this->_prepareCallbacks('drop', $options);
+ $safe = array_merge(array_keys($this->_callbackArguments['drop']), array('droppables'));
+ $optionString = $this->_parseOptions($options, $safe);
+ $out = $this->selection . '.makeDraggable({' . $optionString . '});';
+ $this->selection = $options['droppables'];
+ return $out;
+ }
+
+/**
+ * Create a slider control
+ *
+ * Requires `Slider` from MootoolsMore
+ *
+ * @param array $options Array of options for the slider.
+ * @return string Completed slider script.
+ * @see JsBaseEngineHelper::slider() for options list.
+ */
+ public function slider($options = array()) {
+ $slider = $this->selection;
+ $this->get($options['handle']);
+ unset($options['handle']);
+
+ if (isset($options['min']) && isset($options['max'])) {
+ $options['range'] = array($options['min'], $options['max']);
+ unset($options['min'], $options['max']);
+ }
+ $optionString = $this->_processOptions('slider', $options);
+ if (!empty($optionString)) {
+ $optionString = ', {' . $optionString . '}';
+ }
+ $out = 'var jsSlider = new Slider(' . $slider . ', ' . $this->selection . $optionString . ');';
+ $this->selection = $slider;
+ return $out;
+ }
+
+/**
+ * Serialize the form attached to $selector.
+ *
+ * @param array $options Array of options.
+ * @return string Completed serializeForm() snippet
+ * @see JsBaseEngineHelper::serializeForm()
+ */
+ public function serializeForm($options = array()) {
+ $options = array_merge(array('isForm' => false, 'inline' => false), $options);
+ $selection = $this->selection;
+ if (!$options['isForm']) {
+ $selection = '$(' . $this->selection . '.form)';
+ }
+ $method = '.toQueryString()';
+ if (!$options['inline']) {
+ $method .= ';';
+ }
+ return $selection . $method;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php
new file mode 100644
index 0000000..5889484
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/NumberHelper.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * Number Helper.
+ *
+ * Methods to make numbers more readable.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeNumber', 'Utility');
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Number helper library.
+ *
+ * Methods to make numbers more readable.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html
+ * @see CakeNumber
+ */
+class NumberHelper extends AppHelper {
+
+/**
+ * CakeNumber instance
+ *
+ * @var CakeNumber
+ */
+ protected $_engine = null;
+
+/**
+ * Default Constructor
+ *
+ * ### Settings:
+ *
+ * - `engine` Class name to use to replace CakeNumber functionality
+ * The class needs to be placed in the `Utility` directory.
+ *
+ * @param View $View The View this helper is being attached to.
+ * @param array $settings Configuration settings for the helper
+ * @throws CakeException When the engine class could not be found.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $settings = Hash::merge(array('engine' => 'CakeNumber'), $settings);
+ parent::__construct($View, $settings);
+ list($plugin, $engineClass) = pluginSplit($settings['engine'], true);
+ App::uses($engineClass, $plugin . 'Utility');
+ if (class_exists($engineClass)) {
+ $this->_engine = new $engineClass($settings);
+ } else {
+ throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+ }
+ }
+
+/**
+ * Call methods from CakeNumber utility class
+ */
+ public function __call($method, $params) {
+ return call_user_func_array(array($this->_engine, $method), $params);
+ }
+
+/**
+ * @see: CakeNumber::precision()
+ *
+ * @param float $number A floating point number.
+ * @param integer $precision The precision of the returned number.
+ * @return float Formatted float.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::precision
+ */
+ public function precision($number, $precision = 3) {
+ return $this->_engine->precision($number, $precision);
+ }
+
+/**
+ * @see: CakeNumber::toReadableSize()
+ *
+ * @param integer $size Size in bytes
+ * @return string Human readable size
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
+ */
+ public function toReadableSize($size) {
+ return $this->_engine->toReadableSize($size);
+ }
+
+/**
+ * @see: CakeNumber::toPercentage()
+ *
+ * @param float $number A floating point number
+ * @param integer $precision The precision of the returned number
+ * @return string Percentage string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage
+ */
+ public function toPercentage($number, $precision = 2) {
+ return $this->_engine->toPercentage($number, $precision);
+ }
+
+/**
+ * @see: CakeNumber::format()
+ *
+ * @param float $number A floating point number
+ * @param integer $options if int then places, if string then before, if (,.-) then use it
+ * or array with places and before keys
+ * @return string formatted number
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::format
+ */
+ public function format($number, $options = false) {
+ return $this->_engine->format($number, $options);
+ }
+
+/**
+ * @see: CakeNumber::currency()
+ *
+ * @param float $number
+ * @param string $currency Shortcut to default options. Valid values are 'USD', 'EUR', 'GBP', otherwise
+ * set at least 'before' and 'after' options.
+ * @param array $options
+ * @return string Number formatted as a currency.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
+ */
+ public function currency($number, $currency = 'USD', $options = array()) {
+ return $this->_engine->currency($number, $currency, $options);
+ }
+
+/**
+ * @see: CakeNumber::addFormat()
+ *
+ * @param string $formatName The format name to be used in the future.
+ * @param array $options The array of options for this format.
+ * @return void
+ * @see NumberHelper::currency()
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::addFormat
+ */
+ public function addFormat($formatName, $options) {
+ return $this->_engine->addFormat($formatName, $options);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php
new file mode 100644
index 0000000..05a9935
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PaginatorHelper.php
@@ -0,0 +1,901 @@
+<?php
+/**
+ * Pagination Helper class file.
+ *
+ * Generates pagination links
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Pagination Helper class for easy generation of pagination links.
+ *
+ * PaginationHelper encloses all methods needed when working with pagination.
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html
+ */
+class PaginatorHelper extends AppHelper {
+
+/**
+ * Helper dependencies
+ *
+ * @var array
+ */
+ public $helpers = array('Html');
+
+/**
+ * The class used for 'Ajax' pagination links. Defaults to JsHelper. You should make sure
+ * that JsHelper is defined as a helper before PaginatorHelper, if you want to customize the JsHelper.
+ *
+ * @var string
+ */
+ protected $_ajaxHelperClass = 'Js';
+
+/**
+ * Holds the default options for pagination links
+ *
+ * The values that may be specified are:
+ *
+ * - `format` Format of the counter. Supported formats are 'range' and 'pages'
+ * and custom (default). In the default mode the supplied string is parsed and constants are replaced
+ * by their actual values.
+ * placeholders: %page%, %pages%, %current%, %count%, %start%, %end% .
+ * - `separator` The separator of the actual page and number of pages (default: ' of ').
+ * - `url` Url of the action. See Router::url()
+ * - `url['sort']` the key that the recordset is sorted.
+ * - `url['direction']` Direction of the sorting (default: 'asc').
+ * - `url['page']` Page number to use in links.
+ * - `model` The name of the model.
+ * - `escape` Defines if the title field for the link should be escaped (default: true).
+ * - `update` DOM id of the element updated with the results of the AJAX call.
+ * If this key isn't specified Paginator will use plain HTML links.
+ * - `paging['paramType']` The type of parameters to use when creating links. Valid options are
+ * 'querystring' and 'named'. See PaginatorComponent::$settings for more information.
+ * - `convertKeys` - A list of keys in url arrays that should be converted to querysting params
+ * if paramType == 'querystring'.
+ *
+ * @var array
+ */
+ public $options = array(
+ 'convertKeys' => array('page', 'limit', 'sort', 'direction')
+ );
+
+/**
+ * Constructor for the helper. Sets up the helper that is used for creating 'AJAX' links.
+ *
+ * Use `public $helpers = array('Paginator' => array('ajax' => 'CustomHelper'));` to set a custom Helper
+ * or choose a non JsHelper Helper. If you want to use a specific library with JsHelper declare JsHelper and its
+ * adapter before including PaginatorHelper in your helpers array.
+ *
+ * The chosen custom helper must implement a `link()` method.
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Array of settings.
+ * @throws CakeException When the AjaxProvider helper does not implement a link method.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $ajaxProvider = isset($settings['ajax']) ? $settings['ajax'] : 'Js';
+ $this->helpers[] = $ajaxProvider;
+ $this->_ajaxHelperClass = $ajaxProvider;
+ App::uses($ajaxProvider . 'Helper', 'View/Helper');
+ $classname = $ajaxProvider . 'Helper';
+ if (!class_exists($classname) || !method_exists($classname, 'link')) {
+ throw new CakeException(sprintf(
+ __d('cake_dev', '%s does not implement a link() method, it is incompatible with PaginatorHelper'), $classname
+ ));
+ }
+ parent::__construct($View, $settings);
+ }
+
+/**
+ * Before render callback. Overridden to merge passed args with url options.
+ *
+ * @param string $viewFile
+ * @return void
+ */
+ public function beforeRender($viewFile) {
+ $this->options['url'] = array_merge($this->request->params['pass'], $this->request->params['named']);
+ if (!empty($this->request->query)) {
+ $this->options['url']['?'] = $this->request->query;
+ }
+ parent::beforeRender($viewFile);
+ }
+
+/**
+ * Gets the current paging parameters from the resultset for the given model
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return array The array of paging parameters for the paginated resultset.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::params
+ */
+ public function params($model = null) {
+ if (empty($model)) {
+ $model = $this->defaultModel();
+ }
+ if (!isset($this->request->params['paging']) || empty($this->request->params['paging'][$model])) {
+ return null;
+ }
+ return $this->request->params['paging'][$model];
+ }
+
+/**
+ * Sets default options for all pagination links
+ *
+ * @param array|string $options Default options for pagination links. If a string is supplied - it
+ * is used as the DOM id element to update. See PaginatorHelper::$options for list of keys.
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::options
+ */
+ public function options($options = array()) {
+ if (is_string($options)) {
+ $options = array('update' => $options);
+ }
+
+ if (!empty($options['paging'])) {
+ if (!isset($this->request->params['paging'])) {
+ $this->request->params['paging'] = array();
+ }
+ $this->request->params['paging'] = array_merge($this->request->params['paging'], $options['paging']);
+ unset($options['paging']);
+ }
+ $model = $this->defaultModel();
+
+ if (!empty($options[$model])) {
+ if (!isset($this->request->params['paging'][$model])) {
+ $this->request->params['paging'][$model] = array();
+ }
+ $this->request->params['paging'][$model] = array_merge(
+ $this->request->params['paging'][$model], $options[$model]
+ );
+ unset($options[$model]);
+ }
+ if (!empty($options['convertKeys'])) {
+ $options['convertKeys'] = array_merge($this->options['convertKeys'], $options['convertKeys']);
+ }
+ $this->options = array_filter(array_merge($this->options, $options));
+ }
+
+/**
+ * Gets the current page of the recordset for the given model
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return string The current page number of the recordset.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::current
+ */
+ public function current($model = null) {
+ $params = $this->params($model);
+
+ if (isset($params['page'])) {
+ return $params['page'];
+ }
+ return 1;
+ }
+
+/**
+ * Gets the current key by which the recordset is sorted
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @param array $options Options for pagination links. See #options for list of keys.
+ * @return string The name of the key by which the recordset is being sorted, or
+ * null if the results are not currently sorted.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortKey
+ */
+ public function sortKey($model = null, $options = array()) {
+ if (empty($options)) {
+ $params = $this->params($model);
+ $options = $params['options'];
+ }
+ if (isset($options['sort']) && !empty($options['sort'])) {
+ return $options['sort'];
+ }
+ if (isset($options['order'])) {
+ return is_array($options['order']) ? key($options['order']) : $options['order'];
+ }
+ if (isset($params['order'])) {
+ return is_array($params['order']) ? key($params['order']) : $params['order'];
+ }
+ return null;
+ }
+
+/**
+ * Gets the current direction the recordset is sorted
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @param array $options Options for pagination links. See #options for list of keys.
+ * @return string The direction by which the recordset is being sorted, or
+ * null if the results are not currently sorted.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sortDir
+ */
+ public function sortDir($model = null, $options = array()) {
+ $dir = null;
+
+ if (empty($options)) {
+ $params = $this->params($model);
+ $options = $params['options'];
+ }
+
+ if (isset($options['direction'])) {
+ $dir = strtolower($options['direction']);
+ } elseif (isset($options['order']) && is_array($options['order'])) {
+ $dir = strtolower(current($options['order']));
+ } elseif (isset($params['order']) && is_array($params['order'])) {
+ $dir = strtolower(current($params['order']));
+ }
+
+ if ($dir == 'desc') {
+ return 'desc';
+ }
+ return 'asc';
+ }
+
+/**
+ * Generates a "previous" link for a set of paged records
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ *
+ * @param string $title Title for the link. Defaults to '<< Previous'.
+ * @param array $options Options for pagination link. See #options for list of keys.
+ * @param string $disabledTitle Title when the link is disabled.
+ * @param array $disabledOptions Options for the disabled pagination link. See #options for list of keys.
+ * @return string A "previous" link or $disabledTitle text if the link is disabled.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::prev
+ */
+ public function prev($title = '<< Previous', $options = array(), $disabledTitle = null, $disabledOptions = array()) {
+ $defaults = array(
+ 'rel' => 'prev'
+ );
+ $options = array_merge($defaults, (array)$options);
+ return $this->_pagingLink('Prev', $title, $options, $disabledTitle, $disabledOptions);
+ }
+
+/**
+ * Generates a "next" link for a set of paged records
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ *
+ * @param string $title Title for the link. Defaults to 'Next >>'.
+ * @param array $options Options for pagination link. See above for list of keys.
+ * @param string $disabledTitle Title when the link is disabled.
+ * @param array $disabledOptions Options for the disabled pagination link. See above for list of keys.
+ * @return string A "next" link or or $disabledTitle text if the link is disabled.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::next
+ */
+ public function next($title = 'Next >>', $options = array(), $disabledTitle = null, $disabledOptions = array()) {
+ $defaults = array(
+ 'rel' => 'next'
+ );
+ $options = array_merge($defaults, (array)$options);
+ return $this->_pagingLink('Next', $title, $options, $disabledTitle, $disabledOptions);
+ }
+
+/**
+ * Generates a sorting link. Sets named parameters for the sort and direction. Handles
+ * direction switching automatically.
+ *
+ * ### Options:
+ *
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ * - `direction` The default direction to use when this link isn't active.
+ *
+ * @param string $key The name of the key that the recordset should be sorted.
+ * @param string $title Title for the link. If $title is null $key will be used
+ * for the title and will be generated by inflection.
+ * @param array $options Options for sorting link. See above for list of keys.
+ * @return string A link sorting default by 'asc'. If the resultset is sorted 'asc' by the specified
+ * key the returned link will sort by 'desc'.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::sort
+ */
+ public function sort($key, $title = null, $options = array()) {
+ $options = array_merge(array('url' => array(), 'model' => null), $options);
+ $url = $options['url'];
+ unset($options['url']);
+
+ if (empty($title)) {
+ $title = $key;
+ $title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)));
+ }
+ $dir = isset($options['direction']) ? $options['direction'] : 'asc';
+ unset($options['direction']);
+
+ $sortKey = $this->sortKey($options['model']);
+ $defaultModel = $this->defaultModel();
+ $isSorted = (
+ $sortKey === $key ||
+ $sortKey === $defaultModel . '.' . $key ||
+ $key === $defaultModel . '.' . $sortKey
+ );
+
+ if ($isSorted) {
+ $dir = $this->sortDir($options['model']) === 'asc' ? 'desc' : 'asc';
+ $class = $dir === 'asc' ? 'desc' : 'asc';
+ if (!empty($options['class'])) {
+ $options['class'] .= ' ' . $class;
+ } else {
+ $options['class'] = $class;
+ }
+ }
+ if (is_array($title) && array_key_exists($dir, $title)) {
+ $title = $title[$dir];
+ }
+
+ $url = array_merge(array('sort' => $key, 'direction' => $dir), $url, array('order' => null));
+ return $this->link($title, $url, $options);
+ }
+
+/**
+ * Generates a plain or Ajax link with pagination parameters
+ *
+ * ### Options
+ *
+ * - `update` The Id of the DOM element you wish to update. Creates Ajax enabled links
+ * with the AjaxHelper.
+ * - `escape` Whether you want the contents html entity encoded, defaults to true
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel()
+ *
+ * @param string $title Title for the link.
+ * @param string|array $url Url for the action. See Router::url()
+ * @param array $options Options for the link. See #options for list of keys.
+ * @return string A link with pagination parameters.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::link
+ */
+ public function link($title, $url = array(), $options = array()) {
+ $options = array_merge(array('model' => null, 'escape' => true), $options);
+ $model = $options['model'];
+ unset($options['model']);
+
+ if (!empty($this->options)) {
+ $options = array_merge($this->options, $options);
+ }
+ if (isset($options['url'])) {
+ $url = array_merge((array)$options['url'], (array)$url);
+ unset($options['url']);
+ }
+ unset($options['convertKeys']);
+
+ $url = $this->url($url, true, $model);
+
+ $obj = isset($options['update']) ? $this->_ajaxHelperClass : 'Html';
+ return $this->{$obj}->link($title, $url, $options);
+ }
+
+/**
+ * Merges passed URL options with current pagination state to generate a pagination URL.
+ *
+ * @param array $options Pagination/URL options array
+ * @param boolean $asArray Return the url as an array, or a URI string
+ * @param string $model Which model to paginate on
+ * @return mixed By default, returns a full pagination URL string for use in non-standard contexts (i.e. JavaScript)
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::url
+ */
+ public function url($options = array(), $asArray = false, $model = null) {
+ $paging = $this->params($model);
+ $url = array_merge(array_filter($paging['options']), $options);
+
+ if (isset($url['order'])) {
+ $sort = $direction = null;
+ if (is_array($url['order'])) {
+ list($sort, $direction) = array($this->sortKey($model, $url), current($url['order']));
+ }
+ unset($url['order']);
+ $url = array_merge($url, compact('sort', 'direction'));
+ }
+ $url = $this->_convertUrlKeys($url, $paging['paramType']);
+
+ if ($asArray) {
+ return $url;
+ }
+ return parent::url($url);
+ }
+
+/**
+ * Converts the keys being used into the format set by options.paramType
+ *
+ * @param array $url Array of url params to convert
+ * @param string $type
+ * @return array converted url params.
+ */
+ protected function _convertUrlKeys($url, $type) {
+ if ($type == 'named') {
+ return $url;
+ }
+ if (!isset($url['?'])) {
+ $url['?'] = array();
+ }
+ foreach ($this->options['convertKeys'] as $key) {
+ if (isset($url[$key])) {
+ $url['?'][$key] = $url[$key];
+ unset($url[$key]);
+ }
+ }
+ return $url;
+ }
+
+/**
+ * Protected method for generating prev/next links
+ *
+ * @param string $which
+ * @param string $title
+ * @param array $options
+ * @param string $disabledTitle
+ * @param array $disabledOptions
+ * @return string
+ */
+ protected function _pagingLink($which, $title = null, $options = array(), $disabledTitle = null, $disabledOptions = array()) {
+ $check = 'has' . $which;
+ $_defaults = array(
+ 'url' => array(), 'step' => 1, 'escape' => true,
+ 'model' => null, 'tag' => 'span', 'class' => strtolower($which)
+ );
+ $options = array_merge($_defaults, (array)$options);
+ $paging = $this->params($options['model']);
+ if (empty($disabledOptions)) {
+ $disabledOptions = $options;
+ }
+
+ if (!$this->{$check}($options['model']) && (!empty($disabledTitle) || !empty($disabledOptions))) {
+ if (!empty($disabledTitle) && $disabledTitle !== true) {
+ $title = $disabledTitle;
+ }
+ $options = array_merge($_defaults, (array)$disabledOptions);
+ } elseif (!$this->{$check}($options['model'])) {
+ return null;
+ }
+
+ foreach (array_keys($_defaults) as $key) {
+ ${$key} = $options[$key];
+ unset($options[$key]);
+ }
+ $url = array_merge(array('page' => $paging['page'] + ($which == 'Prev' ? $step * -1 : $step)), $url);
+
+ if ($this->{$check}($model)) {
+ return $this->Html->tag($tag, $this->link($title, $url, array_merge($options, compact('escape'))), compact('class'));
+ } else {
+ unset($options['rel']);
+ return $this->Html->tag($tag, $title, array_merge($options, compact('escape', 'class')));
+ }
+ }
+
+/**
+ * Returns true if the given result set is not at the first page
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return boolean True if the result set is not at the first page.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPrev
+ */
+ public function hasPrev($model = null) {
+ return $this->_hasPage($model, 'prev');
+ }
+
+/**
+ * Returns true if the given result set is not at the last page
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @return boolean True if the result set is not at the last page.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasNext
+ */
+ public function hasNext($model = null) {
+ return $this->_hasPage($model, 'next');
+ }
+
+/**
+ * Returns true if the given result set has the page number given by $page
+ *
+ * @param string $model Optional model name. Uses the default if none is specified.
+ * @param integer $page The page number - if not set defaults to 1.
+ * @return boolean True if the given result set has the specified page number.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::hasPage
+ */
+ public function hasPage($model = null, $page = 1) {
+ if (is_numeric($model)) {
+ $page = $model;
+ $model = null;
+ }
+ $paging = $this->params($model);
+ return $page <= $paging['pageCount'];
+ }
+
+/**
+ * Does $model have $page in its range?
+ *
+ * @param string $model Model name to get parameters for.
+ * @param integer $page Page number you are checking.
+ * @return boolean Whether model has $page
+ */
+ protected function _hasPage($model, $page) {
+ $params = $this->params($model);
+ if (!empty($params)) {
+ if ($params["{$page}Page"] == true) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Gets the default model of the paged sets
+ *
+ * @return string Model name or null if the pagination isn't initialized.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::defaultModel
+ */
+ public function defaultModel() {
+ if ($this->_defaultModel != null) {
+ return $this->_defaultModel;
+ }
+ if (empty($this->request->params['paging'])) {
+ return null;
+ }
+ list($this->_defaultModel) = array_keys($this->request->params['paging']);
+ return $this->_defaultModel;
+ }
+
+/**
+ * Returns a counter string for the paged result set
+ *
+ * ### Options
+ *
+ * - `model` The model to use, defaults to PaginatorHelper::defaultModel();
+ * - `format` The format string you want to use, defaults to 'pages' Which generates output like '1 of 5'
+ * set to 'range' to generate output like '1 - 3 of 13'. Can also be set to a custom string, containing
+ * the following placeholders `{:page}`, `{:pages}`, `{:current}`, `{:count}`, `{:model}`, `{:start}`, `{:end}` and any
+ * custom content you would like.
+ * - `separator` The separator string to use, default to ' of '
+ *
+ * The `%page%` style placeholders also work, but are deprecated and will be removed in a future version.
+ * @param array $options Options for the counter string. See #options for list of keys.
+ * @return string Counter string.
+ * @deprecated The %page% style placeholders are deprecated.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::counter
+ */
+ public function counter($options = array()) {
+ if (is_string($options)) {
+ $options = array('format' => $options);
+ }
+
+ $options = array_merge(
+ array(
+ 'model' => $this->defaultModel(),
+ 'format' => 'pages',
+ 'separator' => __d('cake', ' of ')
+ ),
+ $options);
+
+ $paging = $this->params($options['model']);
+ if ($paging['pageCount'] == 0) {
+ $paging['pageCount'] = 1;
+ }
+ $start = 0;
+ if ($paging['count'] >= 1) {
+ $start = (($paging['page'] - 1) * $paging['limit']) + 1;
+ }
+ $end = $start + $paging['limit'] - 1;
+ if ($paging['count'] < $end) {
+ $end = $paging['count'];
+ }
+
+ switch ($options['format']) {
+ case 'range':
+ if (!is_array($options['separator'])) {
+ $options['separator'] = array(' - ', $options['separator']);
+ }
+ $out = $start . $options['separator'][0] . $end . $options['separator'][1];
+ $out .= $paging['count'];
+ break;
+ case 'pages':
+ $out = $paging['page'] . $options['separator'] . $paging['pageCount'];
+ break;
+ default:
+ $map = array(
+ '%page%' => $paging['page'],
+ '%pages%' => $paging['pageCount'],
+ '%current%' => $paging['current'],
+ '%count%' => $paging['count'],
+ '%start%' => $start,
+ '%end%' => $end,
+ '%model%' => strtolower(Inflector::humanize(Inflector::tableize($options['model'])))
+ );
+ $out = str_replace(array_keys($map), array_values($map), $options['format']);
+
+ $newKeys = array(
+ '{:page}', '{:pages}', '{:current}', '{:count}', '{:start}', '{:end}', '{:model}'
+ );
+ $out = str_replace($newKeys, array_values($map), $out);
+ break;
+ }
+ return $out;
+ }
+
+/**
+ * Returns a set of numbers for the paged result set
+ * uses a modulus to decide how many numbers to show on each side of the current page (default: 8).
+ *
+ * `$this->Paginator->numbers(array('first' => 2, 'last' => 2));`
+ *
+ * Using the first and last options you can create links to the beginning and end of the page set.
+ *
+ * ### Options
+ *
+ * - `before` Content to be inserted before the numbers
+ * - `after` Content to be inserted after the numbers
+ * - `model` Model to create numbers for, defaults to PaginatorHelper::defaultModel()
+ * - `modulus` how many numbers to include on either side of the current page, defaults to 8.
+ * - `separator` Separator content defaults to ' | '
+ * - `tag` The tag to wrap links in, defaults to 'span'
+ * - `first` Whether you want first links generated, set to an integer to define the number of 'first'
+ * links to generate.
+ * - `last` Whether you want last links generated, set to an integer to define the number of 'last'
+ * links to generate.
+ * - `ellipsis` Ellipsis content, defaults to '...'
+ * - `class` Class for wrapper tag
+ * - `currentClass` Class for wrapper tag on current active page, defaults to 'current'
+ *
+ * @param array $options Options for the numbers, (before, after, model, modulus, separator)
+ * @return string numbers string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::numbers
+ */
+ public function numbers($options = array()) {
+ if ($options === true) {
+ $options = array(
+ 'before' => ' | ', 'after' => ' | ', 'first' => 'first', 'last' => 'last'
+ );
+ }
+
+ $defaults = array(
+ 'tag' => 'span', 'before' => null, 'after' => null, 'model' => $this->defaultModel(), 'class' => null,
+ 'modulus' => '8', 'separator' => ' | ', 'first' => null, 'last' => null, 'ellipsis' => '...', 'currentClass' => 'current'
+ );
+ $options += $defaults;
+
+ $params = (array)$this->params($options['model']) + array('page' => 1);
+ unset($options['model']);
+
+ if ($params['pageCount'] <= 1) {
+ return false;
+ }
+
+ extract($options);
+ unset($options['tag'], $options['before'], $options['after'], $options['model'],
+ $options['modulus'], $options['separator'], $options['first'], $options['last'],
+ $options['ellipsis'], $options['class'], $options['currentClass']
+ );
+
+ $out = '';
+
+ if ($modulus && $params['pageCount'] > $modulus) {
+ $half = intval($modulus / 2);
+ $end = $params['page'] + $half;
+
+ if ($end > $params['pageCount']) {
+ $end = $params['pageCount'];
+ }
+ $start = $params['page'] - ($modulus - ($end - $params['page']));
+ if ($start <= 1) {
+ $start = 1;
+ $end = $params['page'] + ($modulus - $params['page']) + 1;
+ }
+
+ if ($first && $start > 1) {
+ $offset = ($start <= (int)$first) ? $start - 1 : $first;
+ if ($offset < $start - 1) {
+ $out .= $this->first($offset, compact('tag', 'separator', 'ellipsis', 'class'));
+ } else {
+ $out .= $this->first($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('after' => $separator));
+ }
+ }
+
+ $out .= $before;
+
+ for ($i = $start; $i < $params['page']; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator;
+ }
+
+ if ($class) {
+ $currentClass .= ' ' . $class;
+ }
+ $out .= $this->Html->tag($tag, $params['page'], array('class' => $currentClass));
+ if ($i != $params['pageCount']) {
+ $out .= $separator;
+ }
+
+ $start = $params['page'] + 1;
+ for ($i = $start; $i < $end; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class')) . $separator;
+ }
+
+ if ($end != $params['page']) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $end), $options), compact('class'));
+ }
+
+ $out .= $after;
+
+ if ($last && $end < $params['pageCount']) {
+ $offset = ($params['pageCount'] < $end + (int)$last) ? $params['pageCount'] - $end : $last;
+ if ($offset <= $last && $params['pageCount'] - $end > $offset) {
+ $out .= $this->last($offset, compact('tag', 'separator', 'ellipsis', 'class'));
+ } else {
+ $out .= $this->last($offset, compact('tag', 'separator', 'class', 'ellipsis') + array('before' => $separator));
+ }
+ }
+
+ } else {
+ $out .= $before;
+
+ for ($i = 1; $i <= $params['pageCount']; $i++) {
+ if ($i == $params['page']) {
+ if ($class) {
+ $currentClass .= ' ' . $class;
+ }
+ $out .= $this->Html->tag($tag, $i, array('class' => $currentClass));
+ } else {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
+ }
+ if ($i != $params['pageCount']) {
+ $out .= $separator;
+ }
+ }
+
+ $out .= $after;
+ }
+
+ return $out;
+ }
+
+/**
+ * Returns a first or set of numbers for the first pages.
+ *
+ * `echo $this->Paginator->first('< first');`
+ *
+ * Creates a single link for the first page. Will output nothing if you are on the first page.
+ *
+ * `echo $this->Paginator->first(3);`
+ *
+ * Will create links for the first 3 pages, once you get to the third or greater page. Prior to that
+ * nothing will be output.
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `after` Content to insert after the link/tag
+ * - `model` The model to use defaults to PaginatorHelper::defaultModel()
+ * - `separator` Content between the generated links, defaults to ' | '
+ * - `ellipsis` Content for ellipsis, defaults to '...'
+ *
+ * @param string|integer $first if string use as label for the link. If numeric, the number of page links
+ * you want at the beginning of the range.
+ * @param array $options An array of options.
+ * @return string numbers string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::first
+ */
+ public function first($first = '<< first', $options = array()) {
+ $options = array_merge(
+ array(
+ 'tag' => 'span',
+ 'after' => null,
+ 'model' => $this->defaultModel(),
+ 'separator' => ' | ',
+ 'ellipsis' => '...',
+ 'class' => null
+ ),
+ (array)$options);
+
+ $params = array_merge(array('page' => 1), (array)$this->params($options['model']));
+ unset($options['model']);
+
+ if ($params['pageCount'] <= 1) {
+ return false;
+ }
+ extract($options);
+ unset($options['tag'], $options['after'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
+
+ $out = '';
+
+ if (is_int($first) && $params['page'] >= $first) {
+ if ($after === null) {
+ $after = $ellipsis;
+ }
+ for ($i = 1; $i <= $first; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
+ if ($i != $first) {
+ $out .= $separator;
+ }
+ }
+ $out .= $after;
+ } elseif ($params['page'] > 1 && is_string($first)) {
+ $options += array('rel' => 'first');
+ $out = $this->Html->tag($tag, $this->link($first, array('page' => 1), $options), compact('class')) . $after;
+ }
+ return $out;
+ }
+
+/**
+ * Returns a last or set of numbers for the last pages.
+ *
+ * `echo $this->Paginator->last('last >');`
+ *
+ * Creates a single link for the last page. Will output nothing if you are on the last page.
+ *
+ * `echo $this->Paginator->last(3);`
+ *
+ * Will create links for the last 3 pages. Once you enter the page range, no output will be created.
+ *
+ * ### Options:
+ *
+ * - `tag` The tag wrapping tag you want to use, defaults to 'span'
+ * - `before` Content to insert before the link/tag
+ * - `model` The model to use defaults to PaginatorHelper::defaultModel()
+ * - `separator` Content between the generated links, defaults to ' | '
+ * - `ellipsis` Content for ellipsis, defaults to '...'
+ *
+ * @param string|integer $last if string use as label for the link, if numeric print page numbers
+ * @param array $options Array of options
+ * @return string numbers string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html#PaginatorHelper::last
+ */
+ public function last($last = 'last >>', $options = array()) {
+ $options = array_merge(
+ array(
+ 'tag' => 'span',
+ 'before' => null,
+ 'model' => $this->defaultModel(),
+ 'separator' => ' | ',
+ 'ellipsis' => '...',
+ 'class' => null
+ ),
+ (array)$options);
+
+ $params = array_merge(array('page' => 1), (array)$this->params($options['model']));
+ unset($options['model']);
+
+ if ($params['pageCount'] <= 1) {
+ return false;
+ }
+
+ extract($options);
+ unset($options['tag'], $options['before'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
+
+ $out = '';
+ $lower = $params['pageCount'] - $last + 1;
+
+ if (is_int($last) && $params['page'] <= $lower) {
+ if ($before === null) {
+ $before = $ellipsis;
+ }
+ for ($i = $lower; $i <= $params['pageCount']; $i++) {
+ $out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
+ if ($i != $params['pageCount']) {
+ $out .= $separator;
+ }
+ }
+ $out = $before . $out;
+ } elseif ($params['page'] < $params['pageCount'] && is_string($last)) {
+ $options += array('rel' => 'last');
+ $out = $before . $this->Html->tag(
+ $tag, $this->link($last, array('page' => $params['pageCount']), $options), compact('class')
+ );
+ }
+ return $out;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php
new file mode 100644
index 0000000..c1feb6d
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/PrototypeEngineHelper.php
@@ -0,0 +1,370 @@
+<?php
+/**
+ * Prototype Engine Helper for JsHelper
+ *
+ * Provides Prototype specific Javascript for JsHelper. Requires at least
+ * Prototype 1.6
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.3
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('JsBaseEngineHelper', 'View/Helper');
+
+/**
+ * Prototype Engine Helper for JsHelper
+ *
+ * Provides Prototype specific Javascript for JsHelper. Requires at least
+ * Prototype 1.6
+ *
+ * @package Cake.View.Helper
+ */
+class PrototypeEngineHelper extends JsBaseEngineHelper {
+
+/**
+ * Is the current selection a multiple selection? or is it just a single element.
+ *
+ * @var boolean
+ */
+ protected $_multiple = false;
+
+/**
+ * Option mappings for Prototype
+ *
+ * @var array
+ */
+ protected $_optionMap = array(
+ 'request' => array(
+ 'async' => 'asynchronous',
+ 'data' => 'parameters',
+ 'before' => 'onCreate',
+ 'success' => 'onSuccess',
+ 'complete' => 'onComplete',
+ 'error' => 'onFailure'
+ ),
+ 'sortable' => array(
+ 'sort' => 'onChange',
+ 'complete' => 'onUpdate',
+ ),
+ 'drag' => array(
+ 'snapGrid' => 'snap',
+ 'container' => 'constraint',
+ 'stop' => 'onEnd',
+ 'start' => 'onStart',
+ 'drag' => 'onDrag',
+ ),
+ 'drop' => array(
+ 'hover' => 'onHover',
+ 'drop' => 'onDrop',
+ 'hoverClass' => 'hoverclass',
+ ),
+ 'slider' => array(
+ 'direction' => 'axis',
+ 'change' => 'onSlide',
+ 'complete' => 'onChange',
+ 'value' => 'sliderValue',
+ )
+ );
+
+/**
+ * Contains a list of callback names -> default arguments.
+ *
+ * @var array
+ */
+ protected $_callbackArguments = array(
+ 'slider' => array(
+ 'onSlide' => 'value',
+ 'onChange' => 'value',
+ ),
+ 'drag' => array(
+ 'onStart' => 'event',
+ 'onDrag' => 'event',
+ 'change' => 'draggable',
+ 'onEnd' => 'event',
+ ),
+ 'drop' => array(
+ 'onHover' => 'draggable, droppable, event',
+ 'onDrop' => 'draggable, droppable, event',
+ ),
+ 'request' => array(
+ 'onCreate' => 'transport',
+ 'onComplete' => 'transport',
+ 'onFailure' => 'response, jsonHeader',
+ 'onRequest' => 'transport',
+ 'onSuccess' => 'response, jsonHeader'
+ ),
+ 'sortable' => array(
+ 'onStart' => 'element',
+ 'onChange' => 'element',
+ 'onUpdate' => 'element',
+ ),
+ );
+
+/**
+ * Create javascript selector for a CSS rule
+ *
+ * @param string $selector The selector that is targeted
+ * @return PrototypeEngineHelper instance of $this. Allows chained methods.
+ */
+ public function get($selector) {
+ $this->_multiple = false;
+ if ($selector == 'window' || $selector == 'document') {
+ $this->selection = "$(" . $selector . ")";
+ return $this;
+ }
+ if (preg_match('/^#[^\s.]+$/', $selector)) {
+ $this->selection = '$("' . substr($selector, 1) . '")';
+ return $this;
+ }
+ $this->_multiple = true;
+ $this->selection = '$$("' . $selector . '")';
+ return $this;
+ }
+
+/**
+ * Add an event to the script cache. Operates on the currently selected elements.
+ *
+ * ### Options
+ *
+ * - `wrap` - Whether you want the callback wrapped in an anonymous function. (defaults true)
+ * - `stop` - Whether you want the event to stopped. (defaults true)
+ *
+ * @param string $type Type of event to bind to the current 946 id
+ * @param string $callback The Javascript function you wish to trigger or the function literal
+ * @param array $options Options for the event.
+ * @return string completed event handler
+ */
+ public function event($type, $callback, $options = array()) {
+ $defaults = array('wrap' => true, 'stop' => true);
+ $options = array_merge($defaults, $options);
+
+ $function = 'function (event) {%s}';
+ if ($options['wrap'] && $options['stop']) {
+ $callback = "event.stop();\n" . $callback;
+ }
+ if ($options['wrap']) {
+ $callback = sprintf($function, $callback);
+ }
+ $out = $this->selection . ".observe(\"{$type}\", $callback);";
+ return $out;
+ }
+
+/**
+ * Create a domReady event. This is a special event in many libraries
+ *
+ * @param string $functionBody The code to run on domReady
+ * @return string completed domReady method
+ */
+ public function domReady($functionBody) {
+ $this->selection = 'document';
+ return $this->event('dom:loaded', $functionBody, array('stop' => false));
+ }
+
+/**
+ * Create an iteration over the current selection result.
+ *
+ * @param string $callback The function body you wish to apply during the iteration.
+ * @return string completed iteration
+ */
+ public function each($callback) {
+ return $this->selection . '.each(function (item, index) {' . $callback . '});';
+ }
+
+/**
+ * Trigger an Effect.
+ *
+ * ### Note: Effects require Scriptaculous to be loaded.
+ *
+ * @param string $name The name of the effect to trigger.
+ * @param array $options Array of options for the effect.
+ * @return string completed string with effect.
+ * @see JsBaseEngineHelper::effect()
+ */
+ public function effect($name, $options = array()) {
+ $effect = '';
+ $optionString = null;
+ if (isset($options['speed'])) {
+ if ($options['speed'] == 'fast') {
+ $options['duration'] = 0.5;
+ } elseif ($options['speed'] == 'slow') {
+ $options['duration'] = 2;
+ } else {
+ $options['duration'] = 1;
+ }
+ unset($options['speed']);
+ }
+ if (!empty($options)) {
+ $optionString = ', {' . $this->_parseOptions($options) . '}';
+ }
+ switch ($name) {
+ case 'hide':
+ case 'show':
+ $effect = $this->selection . '.' . $name . '();';
+ break;
+ case 'slideIn':
+ case 'slideOut':
+ $name = ($name == 'slideIn') ? 'slideDown' : 'slideUp';
+ $effect = 'Effect.' . $name . '(' . $this->selection . $optionString . ');';
+ break;
+ case 'fadeIn':
+ case 'fadeOut':
+ $name = ($name == 'fadeIn') ? 'appear' : 'fade';
+ $effect = $this->selection . '.' . $name . '(' . substr($optionString, 2) . ');';
+ break;
+ }
+ return $effect;
+ }
+
+/**
+ * Create an Ajax or Ajax.Updater call.
+ *
+ * @param string|array $url
+ * @param array $options
+ * @return string The completed ajax call.
+ */
+ public function request($url, $options = array()) {
+ $url = '"' . $this->url($url) . '"';
+ $options = $this->_mapOptions('request', $options);
+ $type = '.Request';
+ $data = null;
+ if (isset($options['type']) && strtolower($options['type']) == 'json') {
+ unset($options['type']);
+ }
+ if (isset($options['update'])) {
+ $url = '"' . str_replace('#', '', $options['update']) . '", ' . $url;
+ $type = '.Updater';
+ unset($options['update'], $options['type']);
+ }
+ $safe = array_keys($this->_callbackArguments['request']);
+ $options = $this->_prepareCallbacks('request', $options, $safe);
+ if (!empty($options['dataExpression'])) {
+ $safe[] = 'parameters';
+ unset($options['dataExpression']);
+ }
+ $options = $this->_parseOptions($options, $safe);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ return "var jsRequest = new Ajax$type($url$options);";
+ }
+
+/**
+ * Create a sortable element.
+ *
+ * #### Note: Requires scriptaculous to be loaded.
+ *
+ * The scriptaculous implementation of sortables does not support the 'start'
+ * and 'distance' options.
+ *
+ * @param array $options Array of options for the sortable.
+ * @return string Completed sortable script.
+ * @see JsBaseEngineHelper::sortable() for options list.
+ */
+ public function sortable($options = array()) {
+ $options = $this->_processOptions('sortable', $options);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ return 'var jsSortable = Sortable.create(' . $this->selection . $options . ');';
+ }
+
+/**
+ * Create a Draggable element.
+ *
+ * #### Note: Requires scriptaculous to be loaded.
+ *
+ * @param array $options Array of options for the draggable.
+ * @return string Completed draggable script.
+ * @see JsBaseEngineHelper::draggable() for options list.
+ */
+ public function drag($options = array()) {
+ $options = $this->_processOptions('drag', $options);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ if ($this->_multiple) {
+ return $this->each('new Draggable(item' . $options . ');');
+ }
+ return 'var jsDrag = new Draggable(' . $this->selection . $options . ');';
+ }
+
+/**
+ * Create a Droppable element.
+ *
+ * #### Note: Requires scriptaculous to be loaded.
+ *
+ * @param array $options Array of options for the droppable.
+ * @return string Completed droppable script.
+ * @see JsBaseEngineHelper::droppable() for options list.
+ */
+ public function drop($options = array()) {
+ $options = $this->_processOptions('drop', $options);
+ if (!empty($options)) {
+ $options = ', {' . $options . '}';
+ }
+ return 'Droppables.add(' . $this->selection . $options . ');';
+ }
+
+/**
+ * Creates a slider control widget.
+ *
+ * ### Note: Requires scriptaculous to be loaded.
+ *
+ * @param array $options Array of options for the slider.
+ * @return string Completed slider script.
+ * @see JsBaseEngineHelper::slider() for options list.
+ */
+ public function slider($options = array()) {
+ $slider = $this->selection;
+ $this->get($options['handle']);
+ unset($options['handle']);
+
+ if (isset($options['min']) && isset($options['max'])) {
+ $options['range'] = sprintf('$R(%s,%s)', $options['min'], $options['max']);
+ unset($options['min'], $options['max']);
+ }
+ $options = $this->_mapOptions('slider', $options);
+ $options = $this->_prepareCallbacks('slider', $options);
+ $optionString = $this->_parseOptions(
+ $options, array_merge(array_keys($this->_callbackArguments['slider']), array('range'))
+ );
+ if (!empty($optionString)) {
+ $optionString = ', {' . $optionString . '}';
+ }
+ $out = 'var jsSlider = new Control.Slider(' . $this->selection . ', ' . $slider . $optionString . ');';
+ $this->selection = $slider;
+ return $out;
+ }
+
+/**
+ * Serialize the form attached to $selector.
+ *
+ * @param array $options Array of options.
+ * @return string Completed serializeForm() snippet
+ * @see JsBaseEngineHelper::serializeForm()
+ */
+ public function serializeForm($options = array()) {
+ $options = array_merge(array('isForm' => false, 'inline' => false), $options);
+ $selection = $this->selection;
+ if (!$options['isForm']) {
+ $selection = '$(' . $this->selection . '.form)';
+ }
+ $method = '.serialize()';
+ if (!$options['inline']) {
+ $method .= ';';
+ }
+ return $selection . $method;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php
new file mode 100644
index 0000000..bd41284
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/RssHelper.php
@@ -0,0 +1,345 @@
+<?php
+/**
+ * RSS Helper class file.
+ *
+ * Simplifies the output of RSS feeds.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.2
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('Xml', 'Utility');
+
+/**
+ * RSS Helper class for easy output RSS structures.
+ *
+ * @package Cake.View.Helper
+ * @property TimeHelper $Time
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html
+ */
+class RssHelper extends AppHelper {
+
+/**
+ * Helpers used by RSS Helper
+ *
+ * @var array
+ */
+ public $helpers = array('Time');
+
+/**
+ * Base URL
+ *
+ * @var string
+ */
+ public $base = null;
+
+/**
+ * URL to current action.
+ *
+ * @var string
+ */
+ public $here = null;
+
+/**
+ * Parameter array.
+ *
+ * @var array
+ */
+ public $params = array();
+
+/**
+ * Current action.
+ *
+ * @var string
+ */
+ public $action = null;
+
+/**
+ * POSTed model data
+ *
+ * @var array
+ */
+ public $data = null;
+
+/**
+ * Name of the current model
+ *
+ * @var string
+ */
+ public $model = null;
+
+/**
+ * Name of the current field
+ *
+ * @var string
+ */
+ public $field = null;
+
+/**
+ * Default spec version of generated RSS
+ *
+ * @var string
+ */
+ public $version = '2.0';
+
+/**
+ * Returns an RSS document wrapped in `<rss />` tags
+ *
+ * @param array $attrib `<rss />` tag attributes
+ * @param string $content
+ * @return string An RSS document
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::document
+ */
+ public function document($attrib = array(), $content = null) {
+ if ($content === null) {
+ $content = $attrib;
+ $attrib = array();
+ }
+ if (!isset($attrib['version']) || empty($attrib['version'])) {
+ $attrib['version'] = $this->version;
+ }
+
+ return $this->elem('rss', $attrib, $content);
+ }
+
+/**
+ * Returns an RSS `<channel />` element
+ *
+ * @param array $attrib `<channel />` tag attributes
+ * @param array $elements Named array elements which are converted to tags
+ * @param string $content Content (`<item />`'s belonging to this channel
+ * @return string An RSS `<channel />`
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::channel
+ */
+ public function channel($attrib = array(), $elements = array(), $content = null) {
+ if (!isset($elements['title']) && !empty($this->_View->pageTitle)) {
+ $elements['title'] = $this->_View->pageTitle;
+ }
+ if (!isset($elements['link'])) {
+ $elements['link'] = '/';
+ }
+ if (!isset($elements['description'])) {
+ $elements['description'] = '';
+ }
+ $elements['link'] = $this->url($elements['link'], true);
+
+ $elems = '';
+ foreach ($elements as $elem => $data) {
+ $attributes = array();
+ if (is_array($data)) {
+ if (strtolower($elem) == 'cloud') {
+ $attributes = $data;
+ $data = array();
+ } elseif (isset($data['attrib']) && is_array($data['attrib'])) {
+ $attributes = $data['attrib'];
+ unset($data['attrib']);
+ } else {
+ $innerElements = '';
+ foreach ($data as $subElement => $value) {
+ $innerElements .= $this->elem($subElement, array(), $value);
+ }
+ $data = $innerElements;
+ }
+ }
+ $elems .= $this->elem($elem, $attributes, $data);
+ }
+ return $this->elem('channel', $attrib, $elems . $content, !($content === null));
+ }
+
+/**
+ * Transforms an array of data using an optional callback, and maps it to a set
+ * of `<item />` tags
+ *
+ * @param array $items The list of items to be mapped
+ * @param string|array $callback A string function name, or array containing an object
+ * and a string method name
+ * @return string A set of RSS `<item />` elements
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::items
+ */
+ public function items($items, $callback = null) {
+ if ($callback != null) {
+ $items = array_map($callback, $items);
+ }
+
+ $out = '';
+ $c = count($items);
+
+ for ($i = 0; $i < $c; $i++) {
+ $out .= $this->item(array(), $items[$i]);
+ }
+ return $out;
+ }
+
+/**
+ * Converts an array into an `<item />` element and its contents
+ *
+ * @param array $att The attributes of the `<item />` element
+ * @param array $elements The list of elements contained in this `<item />`
+ * @return string An RSS `<item />` element
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::item
+ */
+ public function item($att = array(), $elements = array()) {
+ $content = null;
+
+ if (isset($elements['link']) && !isset($elements['guid'])) {
+ $elements['guid'] = $elements['link'];
+ }
+
+ foreach ($elements as $key => $val) {
+ $attrib = array();
+
+ $escape = true;
+ if (is_array($val) && isset($val['convertEntities'])) {
+ $escape = $val['convertEntities'];
+ unset($val['convertEntities']);
+ }
+
+ switch ($key) {
+ case 'pubDate' :
+ $val = $this->time($val);
+ break;
+ case 'category' :
+ if (is_array($val) && !empty($val[0])) {
+ foreach ($val as $category) {
+ $attrib = array();
+ if (is_array($category) && isset($category['domain'])) {
+ $attrib['domain'] = $category['domain'];
+ unset($category['domain']);
+ }
+ $categories[] = $this->elem($key, $attrib, $category);
+ }
+ $elements[$key] = implode('', $categories);
+ continue 2;
+ } elseif (is_array($val) && isset($val['domain'])) {
+ $attrib['domain'] = $val['domain'];
+ }
+ break;
+ case 'link':
+ case 'guid':
+ case 'comments':
+ if (is_array($val) && isset($val['url'])) {
+ $attrib = $val;
+ unset($attrib['url']);
+ $val = $val['url'];
+ }
+ $val = $this->url($val, true);
+ break;
+ case 'source':
+ if (is_array($val) && isset($val['url'])) {
+ $attrib['url'] = $this->url($val['url'], true);
+ $val = $val['title'];
+ } elseif (is_array($val)) {
+ $attrib['url'] = $this->url($val[0], true);
+ $val = $val[1];
+ }
+ break;
+ case 'enclosure':
+ if (is_string($val['url']) && is_file(WWW_ROOT . $val['url']) && file_exists(WWW_ROOT . $val['url'])) {
+ if (!isset($val['length']) && strpos($val['url'], '://') === false) {
+ $val['length'] = sprintf("%u", filesize(WWW_ROOT . $val['url']));
+ }
+ if (!isset($val['type']) && function_exists('mime_content_type')) {
+ $val['type'] = mime_content_type(WWW_ROOT . $val['url']);
+ }
+ }
+ $val['url'] = $this->url($val['url'], true);
+ $attrib = $val;
+ $val = null;
+ break;
+ }
+ if (!is_null($val) && $escape) {
+ $val = h($val);
+ }
+ $elements[$key] = $this->elem($key, $attrib, $val);
+ }
+ if (!empty($elements)) {
+ $content = implode('', $elements);
+ }
+ return $this->elem('item', (array)$att, $content, !($content === null));
+ }
+
+/**
+ * Converts a time in any format to an RSS time
+ *
+ * @param integer|string|DateTime $time
+ * @return string An RSS-formatted timestamp
+ * @see TimeHelper::toRSS
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::time
+ */
+ public function time($time) {
+ return $this->Time->toRSS($time);
+ }
+
+/**
+ * Generates an XML element
+ *
+ * @param string $name The name of the XML element
+ * @param array $attrib The attributes of the XML element
+ * @param string|array $content XML element content
+ * @param boolean $endTag Whether the end tag of the element should be printed
+ * @return string XML
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::elem
+ */
+ public function elem($name, $attrib = array(), $content = null, $endTag = true) {
+ $namespace = null;
+ if (isset($attrib['namespace'])) {
+ $namespace = $attrib['namespace'];
+ unset($attrib['namespace']);
+ }
+ $cdata = false;
+ if (is_array($content) && isset($content['cdata'])) {
+ $cdata = true;
+ unset($content['cdata']);
+ }
+ if (is_array($content) && array_key_exists('value', $content)) {
+ $content = $content['value'];
+ }
+ $children = array();
+ if (is_array($content)) {
+ $children = $content;
+ $content = null;
+ }
+
+ $xml = '<' . $name;
+ if (!empty($namespace)) {
+ $xml .= ' xmlns:"' . $namespace . '"';
+ }
+ $bareName = $name;
+ if (strpos($name, ':') !== false) {
+ list($prefix, $bareName) = explode(':', $name, 2);
+ switch ($prefix) {
+ case 'atom':
+ $xml .= ' xmlns:atom="http://www.w3.org/2005/Atom"';
+ break;
+ }
+ }
+ if ($cdata && !empty($content)) {
+ $content = '<![CDATA[' . $content . ']]>';
+ }
+ $xml .= '>' . $content . '</' . $name . '>';
+ $elem = Xml::build($xml, array('return' => 'domdocument'));
+ $nodes = $elem->getElementsByTagName($bareName);
+ foreach ($attrib as $key => $value) {
+ $nodes->item(0)->setAttribute($key, $value);
+ }
+ foreach ($children as $k => $child) {
+ $child = $elem->createElement($name, $child);
+ $nodes->item(0)->appendChild($child);
+ }
+
+ $xml = $elem->saveXml();
+ $xml = trim(substr($xml, strpos($xml, '?>') + 2));
+ return $xml;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php
new file mode 100644
index 0000000..259c4df
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/SessionHelper.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Session Helper provides access to the Session in the Views.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 1.1.7.3328
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+App::uses('CakeSession', 'Model/Datasource');
+
+/**
+ * Session Helper.
+ *
+ * Session reading from the view.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html
+ */
+class SessionHelper extends AppHelper {
+
+/**
+ * Used to read a session values set in a controller for a key or return values for all keys.
+ *
+ * In your view: `$this->Session->read('Controller.sessKey');`
+ * Calling the method without a param will return all session vars
+ *
+ * @param string $name the name of the session key you want to read
+ * @return mixed values from the session vars
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::read
+ */
+ public function read($name = null) {
+ return CakeSession::read($name);
+ }
+
+/**
+ * Used to check is a session key has been set
+ *
+ * In your view: `$this->Session->check('Controller.sessKey');`
+ *
+ * @param string $name
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::check
+ */
+ public function check($name) {
+ return CakeSession::check($name);
+ }
+
+/**
+ * Returns last error encountered in a session
+ *
+ * In your view: `$this->Session->error();`
+ *
+ * @return string last error
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#displaying-notifcations-or-flash-messages
+ */
+ public function error() {
+ return CakeSession::error();
+ }
+
+/**
+ * Used to render the message set in Controller::Session::setFlash()
+ *
+ * In your view: $this->Session->flash('somekey');
+ * Will default to flash if no param is passed
+ *
+ * You can pass additional information into the flash message generation. This allows you
+ * to consolidate all the parameters for a given type of flash message into the view.
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array('params' => array('class' => 'new-flash')));
+ * }}}
+ *
+ * The above would generate a flash message with a custom class name. Using $attrs['params'] you
+ * can pass additional data into the element rendering that will be made available as local variables
+ * when the element is rendered:
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array('params' => array('name' => $user['User']['name'])));
+ * }}}
+ *
+ * This would pass the current user's name into the flash message, so you could create personalized
+ * messages without the controller needing access to that data.
+ *
+ * Lastly you can choose the element that is rendered when creating the flash message. Using
+ * custom elements allows you to fully customize how flash messages are generated.
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array('element' => 'my_custom_element'));
+ * }}}
+ *
+ * If you want to use an element from a plugin for rendering your flash message you can do that using the
+ * plugin param:
+ *
+ * {{{
+ * echo $this->Session->flash('flash', array(
+ * 'element' => 'my_custom_element',
+ * 'params' => array('plugin' => 'my_plugin')
+ * ));
+ * }}}
+ *
+ * @param string $key The [Message.]key you are rendering in the view.
+ * @param array $attrs Additional attributes to use for the creation of this flash message.
+ * Supports the 'params', and 'element' keys that are used in the helper.
+ * @return string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::flash
+ */
+ public function flash($key = 'flash', $attrs = array()) {
+ $out = false;
+
+ if (CakeSession::check('Message.' . $key)) {
+ $flash = CakeSession::read('Message.' . $key);
+ $message = $flash['message'];
+ unset($flash['message']);
+
+ if (!empty($attrs)) {
+ $flash = array_merge($flash, $attrs);
+ }
+
+ if ($flash['element'] == 'default') {
+ $class = 'message';
+ if (!empty($flash['params']['class'])) {
+ $class = $flash['params']['class'];
+ }
+ $out = '<div id="' . $key . 'Message" class="' . $class . '">' . $message . '</div>';
+ } elseif ($flash['element'] == '' || $flash['element'] == null) {
+ $out = $message;
+ } else {
+ $options = array();
+ if (isset($flash['params']['plugin'])) {
+ $options['plugin'] = $flash['params']['plugin'];
+ }
+ $tmpVars = $flash['params'];
+ $tmpVars['message'] = $message;
+ $out = $this->_View->element($flash['element'], $tmpVars, $options);
+ }
+ CakeSession::delete('Message.' . $key);
+ }
+ return $out;
+ }
+
+/**
+ * Used to check is a session is valid in a view
+ *
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/session.html#SessionHelper::valid
+ */
+ public function valid() {
+ return CakeSession::valid();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php
new file mode 100644
index 0000000..096029e
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TextHelper.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * Text Helper
+ *
+ * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Text helper library.
+ *
+ * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
+ *
+ * @package Cake.View.Helper
+ * @property HtmlHelper $Html
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html
+ * @see String
+ */
+class TextHelper extends AppHelper {
+
+/**
+ * helpers
+ *
+ * @var array
+ */
+ public $helpers = array('Html');
+
+/**
+ * An array of md5sums and their contents.
+ * Used when inserting links into text.
+ *
+ * @var array
+ */
+ protected $_placeholders = array();
+
+/**
+ * String utility instance
+ */
+ protected $_engine;
+
+/**
+ * Constructor
+ *
+ * ### Settings:
+ *
+ * - `engine` Class name to use to replace String functionality.
+ * The class needs to be placed in the `Utility` directory.
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Settings array Settings array
+ * @throws CakeException when the engine class could not be found.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $settings = Hash::merge(array('engine' => 'String'), $settings);
+ parent::__construct($View, $settings);
+ list($plugin, $engineClass) = pluginSplit($settings['engine'], true);
+ App::uses($engineClass, $plugin . 'Utility');
+ if (class_exists($engineClass)) {
+ $this->_engine = new $engineClass($settings);
+ } else {
+ throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+ }
+ }
+
+/**
+ * Call methods from String utility class
+ */
+ public function __call($method, $params) {
+ return call_user_func_array(array($this->_engine, $method), $params);
+ }
+
+/**
+ * Adds links (<a href=....) to a given text, by finding text that begins with
+ * strings like http:// and ftp://.
+ *
+ * ### Options
+ *
+ * - `escape` Control HTML escaping of input. Defaults to true.
+ *
+ * @param string $text Text
+ * @param array $options Array of HTML options, and options listed above.
+ * @return string The text with links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLinkUrls
+ */
+ public function autoLinkUrls($text, $options = array()) {
+ $this->_placeholders = array();
+ $options += array('escape' => true);
+
+ $text = preg_replace_callback(
+ '#(?<!href="|src="|">)((?:https?|ftp|nntp)://[^\s<>()]+)#i',
+ array(&$this, '_insertPlaceHolder'),
+ $text
+ );
+ $text = preg_replace_callback(
+ '#(?<!href="|">)(?<!\b[[:punct:]])(?<!http://|https://|ftp://|nntp://)www.[^\n\%\ <]+[^<\n\%\,\.\ <](?<!\))#i',
+ array(&$this, '_insertPlaceHolder'),
+ $text
+ );
+ if ($options['escape']) {
+ $text = h($text);
+ }
+ return $this->_linkUrls($text, $options);
+ }
+
+/**
+ * Saves the placeholder for a string, for later use. This gets around double
+ * escaping content in URL's.
+ *
+ * @param array $matches An array of regexp matches.
+ * @return string Replaced values.
+ */
+ protected function _insertPlaceHolder($matches) {
+ $key = md5($matches[0]);
+ $this->_placeholders[$key] = $matches[0];
+ return $key;
+ }
+
+/**
+ * Replace placeholders with links.
+ *
+ * @param string $text The text to operate on.
+ * @param array $htmlOptions The options for the generated links.
+ * @return string The text with links inserted.
+ */
+ protected function _linkUrls($text, $htmlOptions) {
+ $replace = array();
+ foreach ($this->_placeholders as $hash => $url) {
+ $link = $url;
+ if (!preg_match('#^[a-z]+\://#', $url)) {
+ $url = 'http://' . $url;
+ }
+ $replace[$hash] = $this->Html->link($link, $url, $htmlOptions);
+ }
+ return strtr($text, $replace);
+ }
+
+/**
+ * Links email addresses
+ *
+ * @param string $text The text to operate on
+ * @param array $options An array of options to use for the HTML.
+ * @return string
+ * @see TextHelper::autoLinkEmails()
+ */
+ protected function _linkEmails($text, $options) {
+ $replace = array();
+ foreach ($this->_placeholders as $hash => $url) {
+ $replace[$hash] = $this->Html->link($url, 'mailto:' . $url, $options);
+ }
+ return strtr($text, $replace);
+ }
+
+/**
+ * Adds email links (<a href="mailto:....) to a given text.
+ *
+ * ### Options
+ *
+ * - `escape` Control HTML escaping of input. Defaults to true.
+ *
+ * @param string $text Text
+ * @param array $options Array of HTML options, and options listed above.
+ * @return string The text with links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLinkEmails
+ */
+ public function autoLinkEmails($text, $options = array()) {
+ $options += array('escape' => true);
+ $this->_placeholders = array();
+
+ $atom = '[a-z0-9!#$%&\'*+\/=?^_`{|}~-]';
+ $text = preg_replace_callback(
+ '/(' . $atom . '+(?:\.' . $atom . '+)*@[a-z0-9-]+(?:\.[a-z0-9-]+)+)/i',
+ array(&$this, '_insertPlaceholder'),
+ $text
+ );
+ if ($options['escape']) {
+ $text = h($text);
+ }
+ return $this->_linkEmails($text, $options);
+ }
+
+/**
+ * Convert all links and email addresses to HTML links.
+ *
+ * ### Options
+ *
+ * - `escape` Control HTML escaping of input. Defaults to true.
+ *
+ * @param string $text Text
+ * @param array $options Array of HTML options, and options listed above.
+ * @return string The text with links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::autoLink
+ */
+ public function autoLink($text, $options = array()) {
+ $text = $this->autoLinkUrls($text, $options);
+ return $this->autoLinkEmails($text, array_merge($options, array('escape' => false)));
+ }
+
+/**
+ * @see String::highlight()
+ *
+ * @param string $text Text to search the phrase in
+ * @param string $phrase The phrase that will be searched
+ * @param array $options An array of html attributes and options.
+ * @return string The highlighted text
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
+ */
+ public function highlight($text, $phrase, $options = array()) {
+ return $this->_engine->highlight($text, $phrase, $options);
+ }
+
+/**
+ * @see String::stripLinks()
+ *
+ * @param string $text Text
+ * @return string The text without links
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
+ */
+ public function stripLinks($text) {
+ return $this->_engine->stripLinks($text);
+ }
+
+/**
+ * @see String::truncate()
+ *
+ * @param string $text String to truncate.
+ * @param integer $length Length of returned string, including ellipsis.
+ * @param array $options An array of html attributes and options.
+ * @return string Trimmed string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::truncate
+ */
+ public function truncate($text, $length = 100, $options = array()) {
+ return $this->_engine->truncate($text, $length, $options);
+ }
+
+/**
+ * @see String::excerpt()
+ *
+ * @param string $text String to search the phrase in
+ * @param string $phrase Phrase that will be searched for
+ * @param integer $radius The amount of characters that will be returned on each side of the founded phrase
+ * @param string $ending Ending that will be appended
+ * @return string Modified string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::excerpt
+ */
+ public function excerpt($text, $phrase, $radius = 100, $ending = '...') {
+ return $this->_engine->excerpt($text, $phrase, $radius, $ending);
+ }
+
+/**
+ * @see String::toList()
+ *
+ * @param array $list The list to be joined
+ * @param string $and The word used to join the last and second last items together with. Defaults to 'and'
+ * @param string $separator The separator used to join all the other items together. Defaults to ', '
+ * @return string The glued together string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
+ */
+ public function toList($list, $and = 'and', $separator = ', ') {
+ return $this->_engine->toList($list, $and, $separator);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php
new file mode 100644
index 0000000..2849179
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Helper/TimeHelper.php
@@ -0,0 +1,458 @@
+<?php
+/**
+ * Time Helper class file.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Helper
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('CakeTime', 'Utility');
+App::uses('Multibyte', 'I18n');
+App::uses('AppHelper', 'View/Helper');
+
+/**
+ * Time Helper class for easy use of time data.
+ *
+ * Manipulation of time data.
+ *
+ * @package Cake.View.Helper
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html
+ * @see CakeTime
+ */
+class TimeHelper extends AppHelper {
+
+/**
+ * CakeTime instance
+ */
+ protected $_engine = null;
+
+/**
+ * Constructor
+ *
+ * ### Settings:
+ *
+ * - `engine` Class name to use to replace CakeTime functionality
+ * The class needs to be placed in the `Utility` directory.
+ *
+ * @param View $View the view object the helper is attached to.
+ * @param array $settings Settings array Settings array
+ * @throws CakeException When the engine class could not be found.
+ */
+ public function __construct(View $View, $settings = array()) {
+ $settings = Hash::merge(array('engine' => 'CakeTime'), $settings);
+ parent::__construct($View, $settings);
+ list($plugin, $engineClass) = pluginSplit($settings['engine'], true);
+ App::uses($engineClass, $plugin . 'Utility');
+ if (class_exists($engineClass)) {
+ $this->_engine = new $engineClass($settings);
+ } else {
+ throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+ }
+ }
+
+/**
+ * Magic accessor for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to set.
+ * @param string $value Value of the attribute to set.
+ * @return mixed
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'niceFormat':
+ $this->_engine->{$name} = $value;
+ break;
+ default:
+ $this->{$name} = $value;
+ break;
+ }
+ }
+
+/**
+ * Magic isset check for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to check.
+ * @return boolean
+ */
+ public function __isset($name) {
+ if (isset($this->{$name})) {
+ return true;
+ }
+ $magicGet = array('niceFormat');
+ if (in_array($name, $magicGet)) {
+ return $this->__get($name) !== null;
+ }
+ return null;
+ }
+
+/**
+ * Magic accessor for attributes that were deprecated.
+ *
+ * @param string $name Name of the attribute to get.
+ * @return mixed
+ */
+ public function __get($name) {
+ if (isset($this->_engine->{$name})) {
+ return $this->_engine->{$name};
+ }
+ $magicGet = array('niceFormat');
+ if (in_array($name, $magicGet)) {
+ return $this->_engine->{$name};
+ }
+ return null;
+ }
+
+/**
+ * Call methods from CakeTime utility class
+ */
+ public function __call($method, $params) {
+ return call_user_func_array(array($this->_engine, $method), $params);
+ }
+
+/**
+ * @see CakeTime::convertSpecifiers()
+ *
+ * @param string $format Format with specifiers for strftime function.
+ * Accepts the special specifier %S which mimics the modifier S for date()
+ * @param string $time UNIX timestamp
+ * @return string windows safe and date() function compatible format for strftime
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function convertSpecifiers($format, $time = null) {
+ return $this->_engine->convertSpecifiers($format, $time);
+ }
+
+/**
+ * @see CakeTime::convert()
+ *
+ * @param string $serverTime UNIX timestamp
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return integer UNIX timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function convert($serverTime, $timezone) {
+ return $this->_engine->convert($serverTime, $timezone);
+ }
+
+/**
+ * @see CakeTime::serverOffset()
+ *
+ * @return integer Offset
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function serverOffset() {
+ return $this->_engine->serverOffset();
+ }
+
+/**
+ * @see CakeTime::fromString()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Parsed timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function fromString($dateString, $timezone = null) {
+ return $this->_engine->fromString($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::nice()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function nice($dateString = null, $timezone = null, $format = null) {
+ return $this->_engine->nice($dateString, $timezone, $format);
+ }
+
+/**
+ * @see CakeTime::niceShort()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime objectp
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Described, relative date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function niceShort($dateString = null, $timezone = null) {
+ return $this->_engine->niceShort($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::daysAsSql()
+ *
+ * @param integer|string|DateTime $begin UNIX timestamp, strtotime() valid string or DateTime object
+ * @param integer|string|DateTime $end UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $fieldName Name of database field to compare with
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Partial SQL string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function daysAsSql($begin, $end, $fieldName, $timezone = null) {
+ return $this->_engine->daysAsSql($begin, $end, $fieldName, $timezone);
+ }
+
+/**
+ * @see CakeTime::dayAsSql()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $fieldName Name of database field to compare with
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Partial SQL string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function dayAsSql($dateString, $fieldName, $timezone = null) {
+ return $this->_engine->dayAsSql($dateString, $fieldName, $timezone);
+ }
+
+/**
+ * @see CakeTime::isToday()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is today
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isToday($dateString, $timezone = null) {
+ return $this->_engine->isToday($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isThisWeek()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current week
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isThisWeek($dateString, $timezone = null) {
+ return $this->_engine->isThisWeek($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isThisMonth()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current month
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isThisMonth($dateString, $timezone = null) {
+ return $this->_engine->isThisMonth($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isThisYear()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string is within current year
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isThisYear($dateString, $timezone = null) {
+ return $this->_engine->isThisYear($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::wasYesterday()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string was yesterday
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ *
+ */
+ public function wasYesterday($dateString, $timezone = null) {
+ return $this->_engine->wasYesterday($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isTomorrow()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean True if datetime string was yesterday
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isTomorrow($dateString, $timezone = null) {
+ return $this->_engine->isTomorrow($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::toQuarter()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param boolean $range if true returns a range in Y-m-d format
+ * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toQuarter($dateString, $range = false) {
+ return $this->_engine->toQuarter($dateString, $range);
+ }
+
+/**
+ * @see CakeTime::toUnix()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return integer Unix timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toUnix($dateString, $timezone = null) {
+ return $this->_engine->toUnix($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::toAtom()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toAtom($dateString, $timezone = null) {
+ return $this->_engine->toAtom($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::toRSS()
+ *
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function toRSS($dateString, $timezone = null) {
+ return $this->_engine->toRSS($dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::timeAgoInWords()
+ *
+ * ## Addition options
+ *
+ * - `element` - The element to wrap the formatted time in.
+ * Has a few additional options:
+ * - `tag` - The tag to use, defaults to 'span'.
+ * - `class` - The classname to use, defaults to `time-ago-in-words`.
+ * - `title` - Defaults to the $dateTime input.
+ *
+ * @param integer|string|DateTime $dateTime UNIX timestamp, strtotime() valid string or DateTime object
+ * @param array $options Default format if timestamp is used in $dateString
+ * @return string Relative time string.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function timeAgoInWords($dateTime, $options = array()) {
+ $element = null;
+ $stringDate = '';
+
+ if (is_array($options) && !empty($options['element'])) {
+ $element = array(
+ 'tag' => 'span',
+ 'class' => 'time-ago-in-words',
+ 'title' => $dateTime
+ );
+
+ if (is_array($options['element'])) {
+ $element = array_merge($element, $options['element']);
+ } else {
+ $element['tag'] = $options['element'];
+ }
+ unset($options['element']);
+ }
+ $relativeDate = $this->_engine->timeAgoInWords($dateTime, $options);
+
+ if ($element) {
+ $relativeDate = sprintf(
+ '<%s%s>%s</%s>',
+ $element['tag'],
+ $this->_parseAttributes($element, array('tag')),
+ $relativeDate,
+ $element['tag']
+ );
+ }
+ return $relativeDate;
+ }
+
+/**
+ * @see CakeTime::wasWithinLast()
+ *
+ * @param string|integer $timeInterval the numeric value with space then time type.
+ * Example of valid types: 6 hours, 2 days, 1 minute.
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function wasWithinLast($timeInterval, $dateString, $timezone = null) {
+ return $this->_engine->wasWithinLast($timeInterval, $dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::isWithinLast()
+ *
+ * @param string|integer $timeInterval the numeric value with space then time type.
+ * Example of valid types: 6 hours, 2 days, 1 minute.
+ * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return boolean
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
+ */
+ public function isWithinNext($timeInterval, $dateString, $timezone = null) {
+ return $this->_engine->isWithinNext($timeInterval, $dateString, $timezone);
+ }
+
+/**
+ * @see CakeTime::gmt()
+ *
+ * @param integer|string|DateTime $string UNIX timestamp, strtotime() valid string or DateTime object
+ * @return integer UNIX timestamp
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function gmt($string = null) {
+ return $this->_engine->gmt($string);
+ }
+
+/**
+ * @see CakeTime::format()
+ *
+ * @param integer|string|DateTime $format date format string (or a UNIX timestamp, strtotime() valid string or DateTime object)
+ * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string)
+ * @param boolean $invalid flag to ignore results of fromString == false
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function format($format, $date = null, $invalid = false, $timezone = null) {
+ return $this->_engine->format($format, $date, $invalid, $timezone);
+ }
+
+/**
+ * @see CakeTime::i18nFormat()
+ *
+ * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object
+ * @param string $format strftime format string.
+ * @param boolean $invalid flag to ignore results of fromString == false
+ * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
+ * @return string Formatted and translated date string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
+ */
+ public function i18nFormat($date, $format = null, $invalid = false, $timezone = null) {
+ return $this->_engine->i18nFormat($date, $format, $invalid, $timezone);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php
new file mode 100644
index 0000000..f07019c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/HelperCollection.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Helpers collection is used as a registry for loaded helpers and handles loading
+ * and constructing helper class objects.
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View
+ * @since CakePHP(tm) v 2.0
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ObjectCollection', 'Utility');
+App::uses('CakeEventListener', 'Event');
+
+/**
+ * Helpers collection is used as a registry for loaded helpers and handles loading
+ * and constructing helper class objects.
+ *
+ * @package Cake.View
+ */
+class HelperCollection extends ObjectCollection implements CakeEventListener {
+
+/**
+ * View object to use when making helpers.
+ *
+ * @var View
+ */
+ protected $_View;
+
+/**
+ * Constructor
+ *
+ * @param View $view
+ */
+ public function __construct(View $view) {
+ $this->_View = $view;
+ }
+
+/**
+ * Tries to lazy load a helper based on its name, if it cannot be found
+ * in the application folder, then it tries looking under the current plugin
+ * if any
+ *
+ * @param string $helper The helper name to be loaded
+ * @return boolean wheter the helper could be loaded or not
+ * @throws MissingHelperException When a helper could not be found.
+ * App helpers are searched, and then plugin helpers.
+ */
+ public function __isset($helper) {
+ if (parent::__isset($helper)) {
+ return true;
+ }
+
+ try {
+ $this->load($helper);
+ } catch (MissingHelperException $exception) {
+ if ($this->_View->plugin) {
+ $this->load($this->_View->plugin . '.' . $helper);
+ return true;
+ }
+ }
+
+ if (!empty($exception)) {
+ throw $exception;
+ }
+
+ return true;
+ }
+
+/**
+ * Provide public read access to the loaded objects
+ *
+ * @param string $name Name of property to read
+ * @return mixed
+ */
+ public function __get($name) {
+ if ($result = parent::__get($name)) {
+ return $result;
+ }
+ if ($this->__isset($name)) {
+ return $this->_loaded[$name];
+ }
+ return null;
+ }
+
+/**
+ * Loads/constructs a helper. Will return the instance in the registry if it already exists.
+ * By setting `$enable` to false you can disable callbacks for a helper. Alternatively you
+ * can set `$settings['enabled'] = false` to disable callbacks. This alias is provided so that when
+ * declaring $helpers arrays you can disable callbacks on helpers.
+ *
+ * You can alias your helper as an existing helper by setting the 'className' key, i.e.,
+ * {{{
+ * public $helpers = array(
+ * 'Html' => array(
+ * 'className' => 'AliasedHtml'
+ * );
+ * );
+ * }}}
+ * All calls to the `Html` helper would use `AliasedHtml` instead.
+ *
+ * @param string $helper Helper name to load
+ * @param array $settings Settings for the helper.
+ * @return Helper A helper object, Either the existing loaded helper or a new one.
+ * @throws MissingHelperException when the helper could not be found
+ */
+ public function load($helper, $settings = array()) {
+ if (is_array($settings) && isset($settings['className'])) {
+ $alias = $helper;
+ $helper = $settings['className'];
+ }
+ list($plugin, $name) = pluginSplit($helper, true);
+ if (!isset($alias)) {
+ $alias = $name;
+ }
+
+ if (isset($this->_loaded[$alias])) {
+ return $this->_loaded[$alias];
+ }
+ $helperClass = $name . 'Helper';
+ App::uses($helperClass, $plugin . 'View/Helper');
+ if (!class_exists($helperClass)) {
+ throw new MissingHelperException(array(
+ 'class' => $helperClass,
+ 'plugin' => substr($plugin, 0, -1)
+ ));
+ }
+ $this->_loaded[$alias] = new $helperClass($this->_View, $settings);
+
+ $vars = array('request', 'theme', 'plugin');
+ foreach ($vars as $var) {
+ $this->_loaded[$alias]->{$var} = $this->_View->{$var};
+ }
+ $enable = isset($settings['enabled']) ? $settings['enabled'] : true;
+ if ($enable) {
+ $this->enable($alias);
+ }
+ return $this->_loaded[$alias];
+ }
+
+/**
+ * Returns a list of all events that will fire in the View during it's lifecycle.
+ *
+ * @return array
+ */
+ public function implementedEvents() {
+ return array(
+ 'View.beforeRenderFile' => 'trigger',
+ 'View.afterRenderFile' => 'trigger',
+ 'View.beforeRender' => 'trigger',
+ 'View.afterRender' => 'trigger',
+ 'View.beforeLayout' => 'trigger',
+ 'View.afterLayout' => 'trigger'
+ );
+ }
+
+/**
+ * Trigger a callback method on every object in the collection.
+ * Used to trigger methods on objects in the collection. Will fire the methods in the
+ * order they were attached.
+ *
+ * ### Options
+ *
+ * - `breakOn` Set to the value or values you want the callback propagation to stop on.
+ * Can either be a scalar value, or an array of values to break on. Defaults to `false`.
+ *
+ * - `break` Set to true to enabled breaking. When a trigger is broken, the last returned value
+ * will be returned. If used in combination with `collectReturn` the collected results will be returned.
+ * Defaults to `false`.
+ *
+ * - `collectReturn` Set to true to collect the return of each object into an array.
+ * This array of return values will be returned from the trigger() call. Defaults to `false`.
+ *
+ * - `modParams` Allows each object the callback gets called on to modify the parameters to the next object.
+ * Setting modParams to an integer value will allow you to modify the parameter with that index.
+ * Any non-null value will modify the parameter index indicated.
+ * Defaults to false.
+ *
+ *
+ * @param string $callback|CakeEvent Method to fire on all the objects. Its assumed all the objects implement
+ * the method you are calling. If an instance of CakeEvent is provided, then then Event name will parsed to
+ * get the callback name. This is done by getting the last word after any dot in the event name
+ * (eg. `Model.afterSave` event will trigger the `afterSave` callback)
+ * @param array $params Array of parameters for the triggered callback.
+ * @param array $options Array of options.
+ * @return mixed Either the last result or all results if collectReturn is on.
+ * @throws CakeException when modParams is used with an index that does not exist.
+ */
+ public function trigger($callback, $params = array(), $options = array()) {
+ if ($callback instanceof CakeEvent) {
+ $callback->omitSubject = true;
+ }
+ return parent::trigger($callback, $params, $options);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php
new file mode 100644
index 0000000..3cf669c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/JsonView.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+
+/**
+ * A view class that is used for JSON responses.
+ *
+ * By setting the '_serialize' key in your controller, you can specify a view variable
+ * that should be serialized to JSON and used as the response for the request.
+ * This allows you to omit views + layouts, if your just need to emit a single view
+ * variable as the JSON response.
+ *
+ * In your controller, you could do the following:
+ *
+ * `$this->set(array('posts' => $posts, '_serialize' => 'posts'));`
+ *
+ * When the view is rendered, the `$posts` view variable will be serialized
+ * into JSON.
+ *
+ * You can also define `'_serialize'` as an array. This will create a top level object containing
+ * all the named view variables:
+ *
+ * {{{
+ * $this->set(compact('posts', 'users', 'stuff'));
+ * $this->set('_serialize', array('posts', 'users'));
+ * }}}
+ *
+ * The above would generate a JSON object that looks like:
+ *
+ * `{"posts": [...], "users": [...]}`
+ *
+ * If you don't use the `_serialize` key, you will need a view. You can use extended
+ * views to provide layout like functionality.
+ *
+ * @package Cake.View
+ * @since CakePHP(tm) v 2.1.0
+ */
+class JsonView extends View {
+
+/**
+ * JSON views are always located in the 'json' sub directory for a
+ * controllers views.
+ *
+ * @var string
+ */
+ public $subDir = 'json';
+
+/**
+ * Constructor
+ *
+ * @param Controller $controller
+ */
+ public function __construct(Controller $controller = null) {
+ parent::__construct($controller);
+ if (isset($controller->response) && $controller->response instanceof CakeResponse) {
+ $controller->response->type('json');
+ }
+ }
+
+/**
+ * Render a JSON view.
+ *
+ * Uses the special '_serialize' parameter to convert a set of
+ * view variables into a JSON response. Makes generating simple
+ * JSON responses very easy. You can omit the '_serialize' parameter,
+ * and use a normal view + layout as well.
+ *
+ * @param string $view The view being rendered.
+ * @param string $layout The layout being rendered.
+ * @return string The rendered view.
+ */
+ public function render($view = null, $layout = null) {
+ if (isset($this->viewVars['_serialize'])) {
+ $serialize = $this->viewVars['_serialize'];
+ if (is_array($serialize)) {
+ $data = array();
+ foreach ($serialize as $key) {
+ $data[$key] = $this->viewVars[$key];
+ }
+ } else {
+ $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null;
+ }
+ $content = json_encode($data);
+ $this->Blocks->set('content', $content);
+ return $content;
+ }
+ if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ $content = $this->_render($viewFileName);
+ $this->Blocks->set('content', $content);
+ return $content;
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php
new file mode 100644
index 0000000..49a3140
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/MediaView.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * Methods to display or download any type of file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View
+ * @since CakePHP(tm) v 1.2.0.5714
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('CakeRequest', 'Network');
+
+/**
+ * Media View provides a custom view implementation for sending files to visitors. Its great
+ * for making the response of a controller action be a file that is saved somewhere on the filesystem.
+ *
+ * An example use comes from the CakePHP internals. MediaView is used to serve plugin and theme assets,
+ * as they are not normally accessible from an application's webroot. Unlike other views, MediaView
+ * uses several viewVars that have special meaning:
+ *
+ * - `id` The filename on the server's filesystem, including extension.
+ * - `name` The filename that will be sent to the user, specified without the extension.
+ * - `download` Set to true to set a `Content-Disposition` header. This is ideal for file downloads.
+ * - `extension` The extension of the file being served. This is used to set the mimetype.
+ * If not provided its extracted from filename provided as `id`.
+ * - `path` The absolute path, including the trailing / on the server's filesystem to `id`.
+ * - `mimeType` The mime type of the file if CakeResponse doesn't know about it.
+ * Must be an associative array with extension as key and mime type as value eg. array('ini' => 'text/plain')
+ *
+ * ### Usage
+ *
+ * {{{
+ * class ExampleController extends AppController {
+ * public function download() {
+ * $this->viewClass = 'Media';
+ * $params = array(
+ * 'id' => 'example.zip',
+ * 'name' => 'example',
+ * 'download' => true,
+ * 'extension' => 'zip',
+ * 'path' => APP . 'files' . DS
+ * );
+ * $this->set($params);
+ * }
+ * }
+ * }}}
+ *
+ * @package Cake.View
+ */
+class MediaView extends View {
+
+/**
+ * Indicates whether response gzip compression was enabled for this class
+ *
+ * @var boolean
+ */
+ protected $_compressionEnabled = false;
+
+/**
+ * Display or download the given file
+ *
+ * @param string $view Not used
+ * @param string $layout Not used
+ * @return mixed
+ * @throws NotFoundException
+ */
+ public function render($view = null, $layout = null) {
+ $name = $download = $extension = $id = $modified = $path = $cache = $mimeType = $compress = null;
+ extract($this->viewVars, EXTR_OVERWRITE);
+
+ if (is_dir($path)) {
+ $path = $path . $id;
+ } else {
+ $path = APP . $path . $id;
+ }
+
+ if (!is_file($path)) {
+ if (Configure::read('debug')) {
+ throw new NotFoundException(sprintf('The requested file %s was not found', $path));
+ }
+ throw new NotFoundException('The requested file was not found');
+ }
+
+ if (is_array($mimeType)) {
+ $this->response->type($mimeType);
+ }
+
+ if (!isset($extension)) {
+ $extension = pathinfo($id, PATHINFO_EXTENSION);
+ }
+
+ if ($this->_isActive()) {
+ $extension = strtolower($extension);
+ $chunkSize = 8192;
+ $buffer = '';
+ $fileSize = @filesize($path);
+ $handle = fopen($path, 'rb');
+
+ if ($handle === false) {
+ return false;
+ }
+ if (!empty($modified) && !is_numeric($modified)) {
+ $modified = strtotime($modified, time());
+ } else {
+ $modified = time();
+ }
+ if (!$extension || $this->response->type($extension) === false) {
+ $download = true;
+ }
+
+ if ($cache) {
+ $this->response->cache($modified, $cache);
+ } else {
+ $this->response->header(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+ }
+
+ if ($download) {
+ $agent = env('HTTP_USER_AGENT');
+
+ if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) {
+ $contentType = 'application/octetstream';
+ } elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
+ $contentType = 'application/force-download';
+ }
+
+ if (!empty($contentType)) {
+ $this->response->type($contentType);
+ }
+ if (is_null($name)) {
+ $name = $id;
+ } elseif ($extension) {
+ $name .= '.' . $extension;
+ }
+ $this->response->download($name);
+ $this->response->header(array('Accept-Ranges' => 'bytes'));
+
+ $httpRange = env('HTTP_RANGE');
+ if (isset($httpRange)) {
+ list($toss, $range) = explode('=', $httpRange);
+
+ $size = $fileSize - 1;
+ $length = $fileSize - $range;
+
+ $this->response->header(array(
+ 'Content-Length' => $length,
+ 'Content-Range' => 'bytes ' . $range . $size . '/' . $fileSize
+ ));
+
+ $this->response->statusCode(206);
+ fseek($handle, $range);
+ } else {
+ $this->response->header('Content-Length', $fileSize);
+ }
+ } else {
+ $this->response->header(array(
+ 'Content-Length' => $fileSize
+ ));
+ }
+ $this->_clearBuffer();
+ if ($compress) {
+ $this->_compressionEnabled = $this->response->compress();
+ }
+
+ $this->response->send();
+ return $this->_sendFile($handle);
+ }
+
+ return false;
+ }
+
+/**
+ * Reads out a file handle, and echos the content to the client.
+ *
+ * @param resource $handle A file handle or stream
+ * @return void
+ */
+ protected function _sendFile($handle) {
+ $chunkSize = 8192;
+ $buffer = '';
+ while (!feof($handle)) {
+ if (!$this->_isActive()) {
+ fclose($handle);
+ return false;
+ }
+ set_time_limit(0);
+ $buffer = fread($handle, $chunkSize);
+ echo $buffer;
+ if (!$this->_compressionEnabled) {
+ $this->_flushBuffer();
+ }
+ }
+ fclose($handle);
+ }
+
+/**
+ * Returns true if connection is still active
+ *
+ * @return boolean
+ */
+ protected function _isActive() {
+ return connection_status() == 0 && !connection_aborted();
+ }
+
+/**
+ * Clears the contents of the topmost output buffer and discards them
+ *
+ * @return boolean
+ */
+ protected function _clearBuffer() {
+ return @ob_end_clean();
+ }
+
+/**
+ * Flushes the contents of the output buffer
+ *
+ * @return void
+ */
+ protected function _flushBuffer() {
+ @flush();
+ @ob_flush();
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php
new file mode 100644
index 0000000..5cb9fb6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ScaffoldView.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Scaffold.
+ *
+ * Automatic forms and actions generation for rapid web application development.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View
+ * @since Cake v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('ThemeView', 'View');
+
+/**
+ * ScaffoldView provides specific view file loading features for scaffolded views.
+ *
+ * @package Cake.View
+ */
+class ScaffoldView extends ThemeView {
+
+/**
+ * Override _getViewFileName Appends special scaffolding views in.
+ *
+ * @param string $name name of the view file to get.
+ * @return string action
+ * @throws MissingViewException
+ */
+ protected function _getViewFileName($name = null) {
+ if ($name === null) {
+ $name = $this->action;
+ }
+ $name = Inflector::underscore($name);
+ $prefixes = Configure::read('Routing.prefixes');
+
+ if (!empty($prefixes)) {
+ foreach ($prefixes as $prefix) {
+ if (strpos($name, $prefix . '_') !== false) {
+ $name = substr($name, strlen($prefix) + 1);
+ break;
+ }
+ }
+ }
+
+ if ($name === 'add' || $name == 'edit') {
+ $name = 'form';
+ }
+
+ $scaffoldAction = 'scaffold.' . $name;
+
+ if (!is_null($this->subDir)) {
+ $subDir = strtolower($this->subDir) . DS;
+ } else {
+ $subDir = null;
+ }
+
+ $names[] = $this->viewPath . DS . $subDir . $scaffoldAction;
+ $names[] = 'Scaffolds' . DS . $subDir . $name;
+
+ $paths = $this->_paths($this->plugin);
+ $exts = array($this->ext);
+ if ($this->ext !== '.ctp') {
+ array_push($exts, '.ctp');
+ }
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ foreach ($names as $name) {
+ if (file_exists($path . $name . $ext)) {
+ return $path . $name . $ext;
+ }
+ }
+ }
+ }
+
+ if ($name === 'Scaffolds' . DS . $subDir . 'error') {
+ return CAKE . 'View' . DS . 'Errors' . DS . 'scaffold_error.ctp';
+ }
+
+ throw new MissingViewException($paths[0] . $name . $this->ext);
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp
new file mode 100644
index 0000000..b672595
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/form.ctp
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> form">
+<?php
+ echo $this->Form->create();
+ echo $this->Form->inputs($scaffoldFields, array('created', 'modified', 'updated'));
+ echo $this->Form->end(__d('cake', 'Submit'));
+?>
+</div>
+<div class="actions">
+ <h3><?php echo __d('cake', 'Actions'); ?></h3>
+ <ul>
+<?php if ($this->request->action != 'add'): ?>
+ <li><?php echo $this->Form->postLink(
+ __d('cake', 'Delete'),
+ array('action' => 'delete', $this->Form->value($modelClass . '.' . $primaryKey)),
+ null,
+ __d('cake', 'Are you sure you want to delete # %s?', $this->Form->value($modelClass . '.' . $primaryKey)));
+ ?></li>
+<?php endif; ?>
+ <li><?php echo $this->Html->link(__d('cake', 'List') . ' ' . $pluralHumanName, array('action' => 'index')); ?></li>
+<?php
+ $done = array();
+ foreach ($associations as $_type => $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>\n";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp
new file mode 100644
index 0000000..fffec7f
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/index.ctp
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> index">
+<h2><?php echo $pluralHumanName; ?></h2>
+<table cellpadding="0" cellspacing="0">
+<tr>
+<?php foreach ($scaffoldFields as $_field): ?>
+ <th><?php echo $this->Paginator->sort($_field); ?></th>
+<?php endforeach; ?>
+ <th><?php echo __d('cake', 'Actions'); ?></th>
+</tr>
+<?php
+$i = 0;
+foreach (${$pluralVar} as ${$singularVar}):
+ echo "<tr>";
+ foreach ($scaffoldFields as $_field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $_alias => $_details) {
+ if ($_field === $_details['foreignKey']) {
+ $isKey = true;
+ echo "<td>" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "</td>";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "<td>" . h(${$singularVar}[$modelClass][$_field]) . "</td>";
+ }
+ }
+
+ echo '<td class="actions">';
+ echo $this->Html->link(__d('cake', 'View'), array('action' => 'view', ${$singularVar}[$modelClass][$primaryKey]));
+ echo $this->Html->link(__d('cake', 'Edit'), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey]));
+ echo $this->Form->postLink(
+ __d('cake', 'Delete'),
+ array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]),
+ null,
+ __d('cake', 'Are you sure you want to delete').' #' . ${$singularVar}[$modelClass][$primaryKey]
+ );
+ echo '</td>';
+ echo '</tr>';
+
+endforeach;
+
+?>
+</table>
+ <p><?php
+ echo $this->Paginator->counter(array(
+ 'format' => __d('cake', 'Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
+ ));
+ ?></p>
+ <div class="paging">
+ <?php
+ echo $this->Paginator->prev('< ' . __d('cake', 'previous'), array(), null, array('class' => 'prev disabled'));
+ echo $this->Paginator->numbers(array('separator' => ''));
+ echo $this->Paginator->next(__d('cake', 'next') .' >', array(), null, array('class' => 'next disabled'));
+ ?>
+ </div>
+</div>
+<div class="actions">
+ <h3><?php echo __d('cake', 'Actions'); ?></h3>
+ <ul>
+ <li><?php echo $this->Html->link(__d('cake', 'New %s', $singularHumanName), array('action' => 'add')); ?></li>
+<?php
+ $done = array();
+ foreach ($associations as $_type => $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "<li>" . $this->Html->link(__d('cake', 'List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>";
+ echo "<li>" . $this->Html->link(__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp
new file mode 100644
index 0000000..c383d12
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/Scaffolds/view.ctp
@@ -0,0 +1,146 @@
+<?php
+/**
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View.Scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+?>
+<div class="<?php echo $pluralVar; ?> view">
+<h2><?php echo __d('cake', 'View %s', $singularHumanName); ?></h2>
+ <dl>
+<?php
+$i = 0;
+foreach ($scaffoldFields as $_field) {
+ $isKey = false;
+ if (!empty($associations['belongsTo'])) {
+ foreach ($associations['belongsTo'] as $_alias => $_details) {
+ if ($_field === $_details['foreignKey']) {
+ $isKey = true;
+ echo "\t\t<dt>" . Inflector::humanize($_alias) . "</dt>\n";
+ echo "\t\t<dd>\n\t\t\t" . $this->Html->link(${$singularVar}[$_alias][$_details['displayField']], array('controller' => $_details['controller'], 'action' => 'view', ${$singularVar}[$_alias][$_details['primaryKey']])) . "\n\t\t&nbsp;</dd>\n";
+ break;
+ }
+ }
+ }
+ if ($isKey !== true) {
+ echo "\t\t<dt>" . Inflector::humanize($_field) . "</dt>\n";
+ echo "\t\t<dd>" . h(${$singularVar}[$modelClass][$_field]) . "&nbsp;</dd>\n";
+ }
+}
+?>
+ </dl>
+</div>
+<div class="actions">
+ <h3><?php echo __d('cake', 'Actions'); ?></h3>
+ <ul>
+<?php
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'Edit %s', $singularHumanName), array('action' => 'edit', ${$singularVar}[$modelClass][$primaryKey])) . " </li>\n";
+ echo "\t\t<li>" . $this->Form->postLink(__d('cake', 'Delete %s', $singularHumanName), array('action' => 'delete', ${$singularVar}[$modelClass][$primaryKey]), null, __d('cake', 'Are you sure you want to delete').' #' . ${$singularVar}[$modelClass][$primaryKey] . '?') . " </li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'List %s', $pluralHumanName), array('action' => 'index')) . " </li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'New %s', $singularHumanName), array('action' => 'add')) . " </li>\n";
+
+ $done = array();
+ foreach ($associations as $_type => $_data) {
+ foreach ($_data as $_alias => $_details) {
+ if ($_details['controller'] != $this->name && !in_array($_details['controller'], $done)) {
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'List %s', Inflector::humanize($_details['controller'])), array('controller' => $_details['controller'], 'action' => 'index')) . "</li>\n";
+ echo "\t\t<li>" . $this->Html->link(__d('cake', 'New %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')) . "</li>\n";
+ $done[] = $_details['controller'];
+ }
+ }
+ }
+?>
+ </ul>
+</div>
+<?php
+if (!empty($associations['hasOne'])) :
+foreach ($associations['hasOne'] as $_alias => $_details): ?>
+<div class="related">
+ <h3><?php echo __d('cake', "Related %s", Inflector::humanize($_details['controller'])); ?></h3>
+<?php if (!empty(${$singularVar}[$_alias])): ?>
+ <dl>
+<?php
+ $i = 0;
+ $otherFields = array_keys(${$singularVar}[$_alias]);
+ foreach ($otherFields as $_field) {
+ echo "\t\t<dt>" . Inflector::humanize($_field) . "</dt>\n";
+ echo "\t\t<dd>\n\t" . ${$singularVar}[$_alias][$_field] . "\n&nbsp;</dd>\n";
+ }
+?>
+ </dl>
+<?php endif; ?>
+ <div class="actions">
+ <ul>
+ <li><?php echo $this->Html->link(__d('cake', 'Edit %s', Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'edit', ${$singularVar}[$_alias][$_details['primaryKey']]))."</li>\n"; ?>
+ </ul>
+ </div>
+</div>
+<?php
+endforeach;
+endif;
+
+if (empty($associations['hasMany'])) {
+ $associations['hasMany'] = array();
+}
+if (empty($associations['hasAndBelongsToMany'])) {
+ $associations['hasAndBelongsToMany'] = array();
+}
+$relations = array_merge($associations['hasMany'], $associations['hasAndBelongsToMany']);
+$i = 0;
+foreach ($relations as $_alias => $_details):
+$otherSingularVar = Inflector::variable($_alias);
+?>
+<div class="related">
+ <h3><?php echo __d('cake', "Related %s", Inflector::humanize($_details['controller'])); ?></h3>
+<?php if (!empty(${$singularVar}[$_alias])): ?>
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+<?php
+ $otherFields = array_keys(${$singularVar}[$_alias][0]);
+ if (isset($_details['with'])) {
+ $index = array_search($_details['with'], $otherFields);
+ unset($otherFields[$index]);
+ }
+ foreach ($otherFields as $_field) {
+ echo "\t\t<th>" . Inflector::humanize($_field) . "</th>\n";
+ }
+?>
+ <th class="actions">Actions</th>
+ </tr>
+<?php
+ $i = 0;
+ foreach (${$singularVar}[$_alias] as ${$otherSingularVar}):
+ echo "\t\t<tr>\n";
+
+ foreach ($otherFields as $_field) {
+ echo "\t\t\t<td>" . ${$otherSingularVar}[$_field] . "</td>\n";
+ }
+
+ echo "\t\t\t<td class=\"actions\">\n";
+ echo "\t\t\t\t" . $this->Html->link(__d('cake', 'View'), array('controller' => $_details['controller'], 'action' => 'view', ${$otherSingularVar}[$_details['primaryKey']])). "\n";
+ echo "\t\t\t\t" . $this->Html->link(__d('cake', 'Edit'), array('controller' => $_details['controller'], 'action' => 'edit', ${$otherSingularVar}[$_details['primaryKey']])). "\n";
+ echo "\t\t\t\t" . $this->Form->postLink(__d('cake', 'Delete'), array('controller' => $_details['controller'], 'action' => 'delete', ${$otherSingularVar}[$_details['primaryKey']]), null, __d('cake', 'Are you sure you want to delete', true).' #' . ${$otherSingularVar}[$_details['primaryKey']] . '?'). "\n";
+ echo "\t\t\t</td>\n";
+ echo "\t\t</tr>\n";
+ endforeach;
+?>
+ </table>
+<?php endif; ?>
+ <div class="actions">
+ <ul>
+ <li><?php echo $this->Html->link(__d('cake', "New %s", Inflector::humanize(Inflector::underscore($_alias))), array('controller' => $_details['controller'], 'action' => 'add')); ?> </li>
+ </ul>
+ </div>
+</div>
+<?php endforeach; ?>
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php
new file mode 100644
index 0000000..6b3617c
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ThemeView.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * A custom view class that is used for themeing
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+
+/**
+ * Theme view class
+ *
+ * Stub class for 2.1 Compatibility
+ *
+ * @package Cake.View
+ */
+class ThemeView extends View {
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php
new file mode 100644
index 0000000..59ce0ac
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/View.php
@@ -0,0 +1,1129 @@
+<?php
+/**
+ * Methods for displaying presentation data in the view.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake.View
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('HelperCollection', 'View');
+App::uses('AppHelper', 'View/Helper');
+App::uses('Router', 'Routing');
+App::uses('ViewBlock', 'View');
+App::uses('CakeEvent', 'Event');
+App::uses('CakeEventManager', 'Event');
+App::uses('CakeResponse', 'Network');
+
+/**
+ * View, the V in the MVC triad. View interacts with Helpers and view variables passed
+ * in from the controller to render the results of the controller action. Often this is HTML,
+ * but can also take the form of JSON, XML, PDF's or streaming files.
+ *
+ * CakePHP uses a two-step-view pattern. This means that the view content is rendered first,
+ * and then inserted into the selected layout. This also means you can pass data from the view to the
+ * layout using `$this->set()`
+ *
+ * Since 2.1, the base View class also includes support for themes by default. Theme views are regular
+ * view files that can provide unique HTML and static assets. If theme views are not found for the
+ * current view the default app view files will be used. You can set `$this->theme = 'mytheme'`
+ * in your Controller to use the Themes.
+ *
+ * Example of theme path with `$this->theme = 'SuperHot';` Would be `app/View/Themed/SuperHot/Posts`
+ *
+ * @package Cake.View
+ * @property CacheHelper $Cache
+ * @property FormHelper $Form
+ * @property HtmlHelper $Html
+ * @property JsHelper $Js
+ * @property NumberHelper $Number
+ * @property PaginatorHelper $Paginator
+ * @property RssHelper $Rss
+ * @property SessionHelper $Session
+ * @property TextHelper $Text
+ * @property TimeHelper $Time
+ * @property ViewBlock $Blocks
+ */
+class View extends Object {
+
+/**
+ * Helpers collection
+ *
+ * @var HelperCollection
+ */
+ public $Helpers;
+
+/**
+ * ViewBlock instance.
+ *
+ * @var ViewBlock
+ */
+ public $Blocks;
+
+/**
+ * Name of the plugin.
+ *
+ * @link http://manual.cakephp.org/chapter/plugins
+ * @var string
+ */
+ public $plugin = null;
+
+/**
+ * Name of the controller.
+ *
+ * @var string Name of controller
+ */
+ public $name = null;
+
+/**
+ * Current passed params
+ *
+ * @var mixed
+ */
+ public $passedArgs = array();
+
+/**
+ * An array of names of built-in helpers to include.
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ */
+ public $helpers = array('Html');
+
+/**
+ * Path to View.
+ *
+ * @var string Path to View
+ */
+ public $viewPath = null;
+
+/**
+ * Variables for the view
+ *
+ * @var array
+ */
+ public $viewVars = array();
+
+/**
+ * Name of view to use with this View.
+ *
+ * @var string
+ */
+ public $view = null;
+
+/**
+ * Name of layout to use with this View.
+ *
+ * @var string
+ */
+ public $layout = 'default';
+
+/**
+ * Path to Layout.
+ *
+ * @var string Path to Layout
+ */
+ public $layoutPath = null;
+
+/**
+ * Turns on or off Cake's conventional mode of applying layout files. On by default.
+ * Setting to off means that layouts will not be automatically applied to rendered views.
+ *
+ * @var boolean
+ */
+ public $autoLayout = true;
+
+/**
+ * File extension. Defaults to Cake's template ".ctp".
+ *
+ * @var string
+ */
+ public $ext = '.ctp';
+
+/**
+ * Sub-directory for this view file. This is often used for extension based routing.
+ * Eg. With an `xml` extension, $subDir would be `xml/`
+ *
+ * @var string
+ */
+ public $subDir = null;
+
+/**
+ * Theme name.
+ *
+ * @var string
+ */
+ public $theme = null;
+
+/**
+ * Used to define methods a controller that will be cached.
+ *
+ * @see Controller::$cacheAction
+ * @var mixed
+ */
+ public $cacheAction = false;
+
+/**
+ * Holds current errors for the model validation.
+ *
+ * @var array
+ */
+ public $validationErrors = array();
+
+/**
+ * True when the view has been rendered.
+ *
+ * @var boolean
+ */
+ public $hasRendered = false;
+
+/**
+ * List of generated DOM UUIDs.
+ *
+ * @var array
+ */
+ public $uuids = array();
+
+/**
+ * An instance of a CakeRequest object that contains information about the current request.
+ * This object contains all the information about a request and several methods for reading
+ * additional information about the request.
+ *
+ * @var CakeRequest
+ */
+ public $request;
+
+/**
+ * Reference to the Response object
+ *
+ * @var CakeResponse
+ */
+ public $response;
+
+/**
+ * The Cache configuration View will use to store cached elements. Changing this will change
+ * the default configuration elements are stored under. You can also choose a cache config
+ * per element.
+ *
+ * @var string
+ * @see View::element()
+ */
+ public $elementCache = 'default';
+
+/**
+ * List of variables to collect from the associated controller.
+ *
+ * @var array
+ */
+ protected $_passedVars = array(
+ 'viewVars', 'autoLayout', 'ext', 'helpers', 'view', 'layout', 'name', 'theme',
+ 'layoutPath', 'viewPath', 'request', 'plugin', 'passedArgs', 'cacheAction'
+ );
+
+/**
+ * Scripts (and/or other <head /> tags) for the layout.
+ *
+ * @var array
+ */
+ protected $_scripts = array();
+
+/**
+ * Holds an array of paths.
+ *
+ * @var array
+ */
+ protected $_paths = array();
+
+/**
+ * Indicate that helpers have been loaded.
+ *
+ * @var boolean
+ */
+ protected $_helpersLoaded = false;
+
+/**
+ * The names of views and their parents used with View::extend();
+ *
+ * @var array
+ */
+ protected $_parents = array();
+
+/**
+ * The currently rendering view file. Used for resolving parent files.
+ *
+ * @var string
+ */
+ protected $_current = null;
+
+/**
+ * Currently rendering an element. Used for finding parent fragments
+ * for elements.
+ *
+ * @var string
+ */
+ protected $_currentType = '';
+
+/**
+ * Content stack, used for nested templates that all use View::extend();
+ *
+ * @var array
+ */
+ protected $_stack = array();
+
+/**
+ * Instance of the CakeEventManager this View object is using
+ * to dispatch inner events. Usually the manager is shared with
+ * the controller, so it it possible to register view events in
+ * the controller layer.
+ *
+ * @var CakeEventManager
+ */
+ protected $_eventManager = null;
+
+/**
+ * The view file to be rendered, only used inside _execute()
+ */
+ private $__viewFileName = null;
+
+/**
+ * Whether the event manager was already configured for this object
+ *
+ * @var boolean
+ */
+ protected $_eventManagerConfigured = false;
+
+ const TYPE_VIEW = 'view';
+ const TYPE_ELEMENT = 'element';
+ const TYPE_LAYOUT = 'layout';
+
+/**
+ * Constructor
+ *
+ * @param Controller $controller A controller object to pull View::_passedVars from.
+ */
+ public function __construct(Controller $controller = null) {
+ if (is_object($controller)) {
+ $count = count($this->_passedVars);
+ for ($j = 0; $j < $count; $j++) {
+ $var = $this->_passedVars[$j];
+ $this->{$var} = $controller->{$var};
+ }
+ $this->_eventManager = $controller->getEventManager();
+ }
+ if (empty($this->request) && !($this->request = Router::getRequest(true))) {
+ $this->request = new CakeRequest(null, false);
+ $this->request->base = '';
+ $this->request->here = $this->request->webroot = '/';
+ }
+ if (is_object($controller) && isset($controller->response)) {
+ $this->response = $controller->response;
+ } else {
+ $this->response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+ }
+ $this->Helpers = new HelperCollection($this);
+ $this->Blocks = new ViewBlock();
+ parent::__construct();
+ }
+
+/**
+ * Returns the CakeEventManager manager instance that is handling any callbacks.
+ * You can use this instance to register any new listeners or callbacks to the
+ * controller events, or create your own events and trigger them at will.
+ *
+ * @return CakeEventManager
+ */
+ public function getEventManager() {
+ if (empty($this->_eventManager)) {
+ $this->_eventManager = new CakeEventManager();
+ }
+ if (!$this->_eventManagerConfigured) {
+ $this->_eventManager->attach($this->Helpers);
+ $this->_eventManagerConfigured = true;
+ }
+ return $this->_eventManager;
+ }
+
+/**
+ * Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string.
+ *
+ * This realizes the concept of Elements, (or "partial layouts") and the $params array is used to send
+ * data to be used in the element. Elements can be cached improving performance by using the `cache` option.
+ *
+ * @param string $name Name of template file in the/app/View/Elements/ folder,
+ * or `MyPlugin.template` to use the template element from MyPlugin. If the element
+ * is not found in the plugin, the normal view path cascade will be searched.
+ * @param array $data Array of data to be made available to the rendered view (i.e. the Element)
+ * @param array $options Array of options. Possible keys are:
+ * - `cache` - Can either be `true`, to enable caching using the config in View::$elementCache. Or an array
+ * If an array, the following keys can be used:
+ * - `config` - Used to store the cached element in a custom cache configuration.
+ * - `key` - Used to define the key used in the Cache::write(). It will be prefixed with `element_`
+ * - `plugin` - Load an element from a specific plugin. This option is deprecated, see below.
+ * - `callbacks` - Set to true to fire beforeRender and afterRender helper callbacks for this element.
+ * Defaults to false.
+ * @return string Rendered Element
+ * @deprecated The `$options['plugin']` is deprecated and will be removed in CakePHP 3.0. Use
+ * `Plugin.element_name` instead.
+ */
+ public function element($name, $data = array(), $options = array()) {
+ $file = $plugin = $key = null;
+ $callbacks = false;
+
+ if (isset($options['plugin'])) {
+ $name = Inflector::camelize($options['plugin']) . '.' . $name;
+ }
+
+ if (isset($options['callbacks'])) {
+ $callbacks = $options['callbacks'];
+ }
+
+ if (isset($options['cache'])) {
+ $underscored = null;
+ if ($plugin) {
+ $underscored = Inflector::underscore($plugin);
+ }
+ $keys = array_merge(array($underscored, $name), array_keys($options), array_keys($data));
+ $caching = array(
+ 'config' => $this->elementCache,
+ 'key' => implode('_', $keys)
+ );
+ if (is_array($options['cache'])) {
+ $defaults = array(
+ 'config' => $this->elementCache,
+ 'key' => $caching['key']
+ );
+ $caching = array_merge($defaults, $options['cache']);
+ }
+ $key = 'element_' . $caching['key'];
+ $contents = Cache::read($key, $caching['config']);
+ if ($contents !== false) {
+ return $contents;
+ }
+ }
+
+ $file = $this->_getElementFilename($name);
+
+ if ($file) {
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ if ($callbacks) {
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeRender', $this, array($file)));
+ }
+
+ $this->_currentType = self::TYPE_ELEMENT;
+ $element = $this->_render($file, array_merge($this->viewVars, $data));
+
+ if ($callbacks) {
+ $this->getEventManager()->dispatch(new CakeEvent('View.afterRender', $this, array($file, $element)));
+ }
+ if (isset($options['cache'])) {
+ Cache::write($key, $element, $caching['config']);
+ }
+ return $element;
+ }
+ $file = 'Elements' . DS . $name . $this->ext;
+
+ if (Configure::read('debug') > 0) {
+ return __d('cake_dev', 'Element Not Found: %s', $file);
+ }
+ }
+
+/**
+ * Renders view for given view file and layout.
+ *
+ * Render triggers helper callbacks, which are fired before and after the view are rendered,
+ * as well as before and after the layout. The helper callbacks are called:
+ *
+ * - `beforeRender`
+ * - `afterRender`
+ * - `beforeLayout`
+ * - `afterLayout`
+ *
+ * If View::$autoRender is false and no `$layout` is provided, the view will be returned bare.
+ *
+ * View and layout names can point to plugin views/layouts. Using the `Plugin.view` syntax
+ * a plugin view/layout can be used instead of the app ones. If the chosen plugin is not found
+ * the view will be located along the regular view path cascade.
+ *
+ * @param string $view Name of view file to use
+ * @param string $layout Layout to use.
+ * @return string Rendered Element
+ * @throws CakeException if there is an error in the view.
+ */
+ public function render($view = null, $layout = null) {
+ if ($this->hasRendered) {
+ return true;
+ }
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ $this->Blocks->set('content', '');
+
+ if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
+ $this->_currentType = self::TYPE_VIEW;
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeRender', $this, array($viewFileName)));
+ $this->Blocks->set('content', $this->_render($viewFileName));
+ $this->getEventManager()->dispatch(new CakeEvent('View.afterRender', $this, array($viewFileName)));
+ }
+
+ if ($layout === null) {
+ $layout = $this->layout;
+ }
+ if ($layout && $this->autoLayout) {
+ $this->Blocks->set('content', $this->renderLayout('', $layout));
+ }
+ $this->hasRendered = true;
+ return $this->Blocks->get('content');
+ }
+
+/**
+ * Renders a layout. Returns output from _render(). Returns false on error.
+ * Several variables are created for use in layout.
+ *
+ * - `title_for_layout` - A backwards compatible place holder, you should set this value if you want more control.
+ * - `content_for_layout` - contains rendered view file
+ * - `scripts_for_layout` - Contains content added with addScript() as well as any content in
+ * the 'meta', 'css', and 'script' blocks. They are appended in that order.
+ *
+ * Deprecated features:
+ *
+ * - `$scripts_for_layout` is deprecated and will be removed in CakePHP 3.0.
+ * Use the block features instead. `meta`, `css` and `script` will be populated
+ * by the matching methods on HtmlHelper.
+ * - `$title_for_layout` is deprecated and will be removed in CakePHP 3.0
+ * - `$content_for_layout` is deprecated and will be removed in CakePHP 3.0.
+ * Use the `content` block instead.
+ *
+ * @param string $content Content to render in a view, wrapped by the surrounding layout.
+ * @param string $layout Layout name
+ * @return mixed Rendered output, or false on error
+ * @throws CakeException if there is an error in the view.
+ */
+ public function renderLayout($content, $layout = null) {
+ $layoutFileName = $this->_getLayoutFileName($layout);
+ if (empty($layoutFileName)) {
+ return $this->Blocks->get('content');
+ }
+
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ if (empty($content)) {
+ $content = $this->Blocks->get('content');
+ }
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeLayout', $this, array($layoutFileName)));
+
+ $scripts = implode("\n\t", $this->_scripts);
+ $scripts .= $this->Blocks->get('meta') . $this->Blocks->get('css') . $this->Blocks->get('script');
+
+ $this->viewVars = array_merge($this->viewVars, array(
+ 'content_for_layout' => $content,
+ 'scripts_for_layout' => $scripts,
+ ));
+
+ if (!isset($this->viewVars['title_for_layout'])) {
+ $this->viewVars['title_for_layout'] = Inflector::humanize($this->viewPath);
+ }
+
+ $this->_currentType = self::TYPE_LAYOUT;
+ $this->Blocks->set('content', $this->_render($layoutFileName));
+
+ $this->getEventManager()->dispatch(new CakeEvent('View.afterLayout', $this, array($layoutFileName)));
+ return $this->Blocks->get('content');
+ }
+
+/**
+ * Render cached view. Works in concert with CacheHelper and Dispatcher to
+ * render cached view files.
+ *
+ * @param string $filename the cache file to include
+ * @param string $timeStart the page render start time
+ * @return boolean Success of rendering the cached file.
+ */
+ public function renderCache($filename, $timeStart) {
+ ob_start();
+ include ($filename);
+
+ if (Configure::read('debug') > 0 && $this->layout != 'xml') {
+ echo "<!-- Cached Render Time: " . round(microtime(true) - $timeStart, 4) . "s -->";
+ }
+ $out = ob_get_clean();
+
+ if (preg_match('/^<!--cachetime:(\\d+)-->/', $out, $match)) {
+ if (time() >= $match['1']) {
+ @unlink($filename);
+ unset ($out);
+ return false;
+ } else {
+ if ($this->layout === 'xml') {
+ header('Content-type: text/xml');
+ }
+ $commentLength = strlen('<!--cachetime:' . $match['1'] . '-->');
+ return substr($out, $commentLength);
+ }
+ }
+ }
+
+/**
+ * Returns a list of variables available in the current View context
+ *
+ * @return array Array of the set view variable names.
+ */
+ public function getVars() {
+ return array_keys($this->viewVars);
+ }
+
+/**
+ * Returns the contents of the given View variable(s)
+ *
+ * @param string $var The view var you want the contents of.
+ * @return mixed The content of the named var if its set, otherwise null.
+ * @deprecated Will be removed in 3.0 Use View::get() instead.
+ */
+ public function getVar($var) {
+ return $this->get($var);
+ }
+
+/**
+ * Returns the contents of the given View variable or a block.
+ * Blocks are checked before view variables.
+ *
+ * @param string $var The view var you want the contents of.
+ * @return mixed The content of the named var if its set, otherwise null.
+ */
+ public function get($var) {
+ if (!isset($this->viewVars[$var])) {
+ return null;
+ }
+ return $this->viewVars[$var];
+ }
+
+/**
+ * Get the names of all the existing blocks.
+ *
+ * @return array An array containing the blocks.
+ * @see ViewBlock::keys()
+ */
+ public function blocks() {
+ return $this->Blocks->keys();
+ }
+
+/**
+ * Start capturing output for a 'block'
+ *
+ * @param string $name The name of the block to capture for.
+ * @return void
+ * @see ViewBlock::start()
+ */
+ public function start($name) {
+ return $this->Blocks->start($name);
+ }
+
+/**
+ * Append to an existing or new block. Appending to a new
+ * block will create the block.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ * @see ViewBlock::append()
+ */
+ public function append($name, $value = null) {
+ return $this->Blocks->append($name, $value);
+ }
+
+/**
+ * Set the content for a block. This will overwrite any
+ * existing content.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ * @see ViewBlock::assign()
+ */
+ public function assign($name, $value) {
+ return $this->Blocks->set($name, $value);
+ }
+
+/**
+ * Fetch the content for a block. If a block is
+ * empty or undefined '' will be returned.
+ *
+ * @param string $name Name of the block
+ * @return The block content or '' if the block does not exist.
+ * @see ViewBlock::fetch()
+ */
+ public function fetch($name) {
+ return $this->Blocks->get($name);
+ }
+
+/**
+ * End a capturing block. The compliment to View::start()
+ *
+ * @return void
+ * @see ViewBlock::start()
+ */
+ public function end() {
+ return $this->Blocks->end();
+ }
+
+/**
+ * Provides view or element extension/inheritance. Views can extends a
+ * parent view and populate blocks in the parent template.
+ *
+ * @param string $name The view or element to 'extend' the current one with.
+ * @return void
+ * @throws LogicException when you extend a view with itself or make extend loops.
+ * @throws LogicException when you extend an element which doesn't exist
+ */
+ public function extend($name) {
+ if ($name[0] === '/' || $this->_currentType === self::TYPE_VIEW) {
+ $parent = $this->_getViewFileName($name);
+ } else {
+ switch ($this->_currentType) {
+ case self::TYPE_ELEMENT:
+ $parent = $this->_getElementFileName($name);
+ if (!$parent) {
+ list($plugin, $name) = $this->pluginSplit($name);
+ $paths = $this->_paths($plugin);
+ $defaultPath = $paths[0] . 'Elements' . DS;
+ throw new LogicException(__d(
+ 'cake_dev',
+ 'You cannot extend an element which does not exist (%s).',
+ $defaultPath . $name . $this->ext
+ ));
+ }
+ break;
+ case self::TYPE_LAYOUT:
+ $parent = $this->_getLayoutFileName($name);
+ break;
+ default:
+ $parent = $this->_getViewFileName($name);
+ }
+ }
+
+ if ($parent == $this->_current) {
+ throw new LogicException(__d('cake_dev', 'You cannot have views extend themselves.'));
+ }
+ if (isset($this->_parents[$parent]) && $this->_parents[$parent] == $this->_current) {
+ throw new LogicException(__d('cake_dev', 'You cannot have views extend in a loop.'));
+ }
+ $this->_parents[$this->_current] = $parent;
+ }
+
+/**
+ * Adds a script block or other element to be inserted in $scripts_for_layout in
+ * the `<head />` of a document layout
+ *
+ * @param string $name Either the key name for the script, or the script content. Name can be used to
+ * update/replace a script element.
+ * @param string $content The content of the script being added, optional.
+ * @return void
+ * @deprecated Will be removed in 3.0. Supersceeded by blocks functionality.
+ * @see View::start()
+ */
+ public function addScript($name, $content = null) {
+ if (empty($content)) {
+ if (!in_array($name, array_values($this->_scripts))) {
+ $this->_scripts[] = $name;
+ }
+ } else {
+ $this->_scripts[$name] = $content;
+ }
+ }
+
+/**
+ * Generates a unique, non-random DOM ID for an object, based on the object type and the target URL.
+ *
+ * @param string $object Type of object, i.e. 'form' or 'link'
+ * @param string $url The object's target URL
+ * @return string
+ */
+ public function uuid($object, $url) {
+ $c = 1;
+ $url = Router::url($url);
+ $hash = $object . substr(md5($object . $url), 0, 10);
+ while (in_array($hash, $this->uuids)) {
+ $hash = $object . substr(md5($object . $url . $c), 0, 10);
+ $c++;
+ }
+ $this->uuids[] = $hash;
+ return $hash;
+ }
+
+/**
+ * Allows a template or element to set a variable that will be available in
+ * a layout or other element. Analogous to Controller::set().
+ *
+ * @param string|array $one A string or an array of data.
+ * @param string|array $two Value in case $one is a string (which then works as the key).
+ * Unused if $one is an associative array, otherwise serves as the values to $one's keys.
+ * @return void
+ */
+ public function set($one, $two = null) {
+ $data = null;
+ if (is_array($one)) {
+ if (is_array($two)) {
+ $data = array_combine($one, $two);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($one => $two);
+ }
+ if ($data == null) {
+ return false;
+ }
+ $this->viewVars = $data + $this->viewVars;
+ }
+
+/**
+ * Magic accessor for helpers. Provides access to attributes that were deprecated.
+ *
+ * @param string $name Name of the attribute to get.
+ * @return mixed
+ */
+ public function __get($name) {
+ switch ($name) {
+ case 'base':
+ case 'here':
+ case 'webroot':
+ case 'data':
+ return $this->request->{$name};
+ case 'action':
+ return $this->request->params['action'];
+ case 'params':
+ return $this->request;
+ case 'output':
+ return $this->Blocks->get('content');
+ }
+ if (isset($this->Helpers->{$name})) {
+ $this->{$name} = $this->Helpers->{$name};
+ return $this->Helpers->{$name};
+ }
+ return $this->{$name};
+ }
+
+/**
+ * Magic accessor for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to set.
+ * @param string $value Value of the attribute to set.
+ * @return mixed
+ */
+ public function __set($name, $value) {
+ switch ($name) {
+ case 'output':
+ return $this->Blocks->set('content', $value);
+ default:
+ $this->{$name} = $value;
+ }
+ }
+
+/**
+ * Magic isset check for deprecated attributes.
+ *
+ * @param string $name Name of the attribute to check.
+ * @return boolean
+ */
+ public function __isset($name) {
+ if (isset($this->{$name})) {
+ return true;
+ }
+ $magicGet = array('base', 'here', 'webroot', 'data', 'action', 'params', 'output');
+ if (in_array($name, $magicGet)) {
+ return $this->__get($name) !== null;
+ }
+ return false;
+ }
+
+/**
+ * Interact with the HelperCollection to load all the helpers.
+ *
+ * @return void
+ */
+ public function loadHelpers() {
+ $helpers = HelperCollection::normalizeObjectArray($this->helpers);
+ foreach ($helpers as $name => $properties) {
+ list($plugin, $class) = pluginSplit($properties['class']);
+ $this->{$class} = $this->Helpers->load($properties['class'], $properties['settings']);
+ }
+ $this->_helpersLoaded = true;
+ }
+
+/**
+ * Renders and returns output for given view filename with its
+ * array of data. Handles parent/extended views.
+ *
+ * @param string $viewFile Filename of the view
+ * @param array $data Data to include in rendered view. If empty the current View::$viewVars will be used.
+ * @return string Rendered output
+ * @throws CakeException when a block is left open.
+ */
+ protected function _render($viewFile, $data = array()) {
+ if (empty($data)) {
+ $data = $this->viewVars;
+ }
+ $this->_current = $viewFile;
+ $initialBlocks = count($this->Blocks->unclosed());
+
+ $this->getEventManager()->dispatch(new CakeEvent('View.beforeRenderFile', $this, array($viewFile)));
+ $content = $this->_evaluate($viewFile, $data);
+ $afterEvent = new CakeEvent('View.afterRenderFile', $this, array($viewFile, $content));
+ //TODO: For BC puporses, set extra info in the event object. Remove when appropriate
+ $afterEvent->modParams = 1;
+ $this->getEventManager()->dispatch($afterEvent);
+ $content = $afterEvent->data[1];
+
+ if (isset($this->_parents[$viewFile])) {
+ $this->_stack[] = $this->fetch('content');
+ $this->assign('content', $content);
+
+ $content = $this->_render($this->_parents[$viewFile]);
+ $this->assign('content', array_pop($this->_stack));
+ }
+
+ $remainingBlocks = count($this->Blocks->unclosed());
+
+ if ($initialBlocks !== $remainingBlocks) {
+ throw new CakeException(__d('cake_dev', 'The "%s" block was left open. Blocks are not allowed to cross files.', $this->Blocks->active()));
+ }
+
+ return $content;
+ }
+
+/**
+ * Sandbox method to evaluate a template / view script in.
+ *
+ * @param string $viewFn Filename of the view
+ * @param array $___dataForView Data to include in rendered view.
+ * If empty the current View::$viewVars will be used.
+ * @return string Rendered output
+ */
+ protected function _evaluate($viewFile, $dataForView) {
+ $this->__viewFile = $viewFile;
+ extract($dataForView);
+ ob_start();
+
+ include $this->__viewFile;
+
+ unset($this->_viewFile);
+ return ob_get_clean();
+ }
+
+/**
+ * Loads a helper. Delegates to the `HelperCollection::load()` to load the helper
+ *
+ * @param string $helperName Name of the helper to load.
+ * @param array $settings Settings for the helper
+ * @return Helper a constructed helper object.
+ * @see HelperCollection::load()
+ */
+ public function loadHelper($helperName, $settings = array()) {
+ return $this->Helpers->load($helperName, $settings);
+ }
+
+/**
+ * Returns filename of given action's template file (.ctp) as a string.
+ * CamelCased action names will be under_scored! This means that you can have
+ * LongActionNames that refer to long_action_names.ctp views.
+ *
+ * @param string $name Controller action to find template filename for
+ * @return string Template filename
+ * @throws MissingViewException when a view file could not be found.
+ */
+ protected function _getViewFileName($name = null) {
+ $subDir = null;
+
+ if (!is_null($this->subDir)) {
+ $subDir = $this->subDir . DS;
+ }
+
+ if ($name === null) {
+ $name = $this->view;
+ }
+ $name = str_replace('/', DS, $name);
+ list($plugin, $name) = $this->pluginSplit($name);
+
+ if (strpos($name, DS) === false && $name[0] !== '.') {
+ $name = $this->viewPath . DS . $subDir . Inflector::underscore($name);
+ } elseif (strpos($name, DS) !== false) {
+ if ($name[0] === DS || $name[1] === ':') {
+ if (is_file($name)) {
+ return $name;
+ }
+ $name = trim($name, DS);
+ } elseif ($name[0] === '.') {
+ $name = substr($name, 3);
+ } elseif (!$plugin || $this->viewPath !== $this->name) {
+ $name = $this->viewPath . DS . $subDir . $name;
+ }
+ }
+ $paths = $this->_paths($plugin);
+ $exts = $this->_getExtensions();
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ if (file_exists($path . $name . $ext)) {
+ return $path . $name . $ext;
+ }
+ }
+ }
+ $defaultPath = $paths[0];
+
+ if ($this->plugin) {
+ $pluginPaths = App::path('plugins');
+ foreach ($paths as $path) {
+ if (strpos($path, $pluginPaths[0]) === 0) {
+ $defaultPath = $path;
+ break;
+ }
+ }
+ }
+ throw new MissingViewException(array('file' => $defaultPath . $name . $this->ext));
+ }
+
+/**
+ * Splits a dot syntax plugin name into its plugin and filename.
+ * If $name does not have a dot, then index 0 will be null.
+ * It checks if the plugin is loaded, else filename will stay unchanged for filenames containing dot
+ *
+ * @param string $name The name you want to plugin split.
+ * @param boolean $fallback If true uses the plugin set in the current CakeRequest when parsed plugin is not loaded
+ * @return array Array with 2 indexes. 0 => plugin name, 1 => filename
+ */
+ public function pluginSplit($name, $fallback = true) {
+ $plugin = null;
+ list($first, $second) = pluginSplit($name);
+ if (CakePlugin::loaded($first) === true) {
+ $name = $second;
+ $plugin = $first;
+ }
+ if (isset($this->plugin) && !$plugin && $fallback) {
+ $plugin = $this->plugin;
+ }
+ return array($plugin, $name);
+ }
+
+/**
+ * Returns layout filename for this template as a string.
+ *
+ * @param string $name The name of the layout to find.
+ * @return string Filename for layout file (.ctp).
+ * @throws MissingLayoutException when a layout cannot be located
+ */
+ protected function _getLayoutFileName($name = null) {
+ if ($name === null) {
+ $name = $this->layout;
+ }
+ $subDir = null;
+
+ if (!is_null($this->layoutPath)) {
+ $subDir = $this->layoutPath . DS;
+ }
+ list($plugin, $name) = $this->pluginSplit($name);
+ $paths = $this->_paths($plugin);
+ $file = 'Layouts' . DS . $subDir . $name;
+
+ $exts = $this->_getExtensions();
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ if (file_exists($path . $file . $ext)) {
+ return $path . $file . $ext;
+ }
+ }
+ }
+ throw new MissingLayoutException(array('file' => $paths[0] . $file . $this->ext));
+ }
+
+/**
+ * Get the extensions that view files can use.
+ *
+ * @return array Array of extensions view files use.
+ */
+ protected function _getExtensions() {
+ $exts = array($this->ext);
+ if ($this->ext !== '.ctp') {
+ array_push($exts, '.ctp');
+ }
+ return $exts;
+ }
+
+/**
+ * Finds an element filename, returns false on failure.
+ *
+ * @param string $name The name of the element to find.
+ * @return mixed Either a string to the element filename or false when one can't be found.
+ */
+ protected function _getElementFileName($name) {
+ list($plugin, $name) = $this->pluginSplit($name);
+
+ $paths = $this->_paths($plugin);
+ $exts = $this->_getExtensions();
+ foreach ($exts as $ext) {
+ foreach ($paths as $path) {
+ if (file_exists($path . 'Elements' . DS . $name . $ext)) {
+ return $path . 'Elements' . DS . $name . $ext;
+ }
+ }
+ }
+ return false;
+ }
+
+/**
+ * Return all possible paths to find view files in order
+ *
+ * @param string $plugin Optional plugin name to scan for view files.
+ * @param boolean $cached Set to true to force a refresh of view paths.
+ * @return array paths
+ */
+ protected function _paths($plugin = null, $cached = true) {
+ if ($plugin === null && $cached === true && !empty($this->_paths)) {
+ return $this->_paths;
+ }
+ $paths = array();
+ $viewPaths = App::path('View');
+ $corePaths = array_merge(App::core('View'), App::core('Console/Templates/skel/View'));
+
+ if (!empty($plugin)) {
+ $count = count($viewPaths);
+ for ($i = 0; $i < $count; $i++) {
+ if (!in_array($viewPaths[$i], $corePaths)) {
+ $paths[] = $viewPaths[$i] . 'Plugin' . DS . $plugin . DS;
+ }
+ }
+ $paths = array_merge($paths, App::path('View', $plugin));
+ }
+
+ $paths = array_unique(array_merge($paths, $viewPaths));
+ if (!empty($this->theme)) {
+ $themePaths = array();
+ foreach ($paths as $path) {
+ if (strpos($path, DS . 'Plugin' . DS) === false) {
+ if ($plugin) {
+ $themePaths[] = $path . 'Themed' . DS . $this->theme . DS . 'Plugin' . DS . $plugin . DS;
+ }
+ $themePaths[] = $path . 'Themed' . DS . $this->theme . DS;
+ }
+ }
+ $paths = array_merge($themePaths, $paths);
+ }
+ $paths = array_merge($paths, $corePaths);
+ if ($plugin !== null) {
+ return $paths;
+ }
+ return $this->_paths = $paths;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php
new file mode 100644
index 0000000..5636d74
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/ViewBlock.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @since CakePHP(tm) v2.1
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+/**
+ * ViewBlock implements the concept of Blocks or Slots in the View layer.
+ * Slots or blocks are combined with extending views and layouts to afford slots
+ * of content that are present in a layout or parent view, but are defined by the child
+ * view or elements used in the view.
+ *
+ * @package Cake.View
+ */
+class ViewBlock {
+
+/**
+ * Block content. An array of blocks indexed by name.
+ *
+ * @var array
+ */
+ protected $_blocks = array();
+
+/**
+ * The active blocks being captured.
+ *
+ * @var array
+ */
+ protected $_active = array();
+
+/**
+ * Start capturing output for a 'block'
+ *
+ * Blocks allow you to create slots or blocks of dynamic content in the layout.
+ * view files can implement some or all of a layout's slots.
+ *
+ * You can end capturing blocks using View::end(). Blocks can be output
+ * using View::get();
+ *
+ * @param string $name The name of the block to capture for.
+ * @return void
+ */
+ public function start($name) {
+ $this->_active[] = $name;
+ ob_start();
+ }
+
+/**
+ * End a capturing block. The compliment to ViewBlock::start()
+ *
+ * @return void
+ * @see ViewBlock::start()
+ */
+ public function end() {
+ if (!empty($this->_active)) {
+ $active = end($this->_active);
+ $content = ob_get_clean();
+ if (!isset($this->_blocks[$active])) {
+ $this->_blocks[$active] = '';
+ }
+ $this->_blocks[$active] .= $content;
+ array_pop($this->_active);
+ }
+ }
+
+/**
+ * Append to an existing or new block. Appending to a new
+ * block will create the block.
+ *
+ * Calling append() without a value will create a new capturing
+ * block that needs to be finished with View::end(). The content
+ * of the new capturing context will be added to the existing block context.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ */
+ public function append($name, $value = null) {
+ if (isset($value)) {
+ if (!is_string($value)) {
+ throw new CakeException(__d('cake_dev', '$value must be a string.'));
+ }
+ if (!isset($this->_blocks[$name])) {
+ $this->_blocks[$name] = '';
+ }
+ $this->_blocks[$name] .= $value;
+ } else {
+ $this->start($name);
+ }
+ }
+
+/**
+ * Set the content for a block. This will overwrite any
+ * existing content.
+ *
+ * @param string $name Name of the block
+ * @param string $value The content for the block.
+ * @return void
+ * @throws CakeException when you use non-string values.
+ */
+ public function set($name, $value) {
+ if (!is_string($value)) {
+ throw new CakeException(__d('cake_dev', 'Blocks can only contain strings.'));
+ }
+ $this->_blocks[$name] = $value;
+ }
+
+/**
+ * Get the content for a block.
+ *
+ * @param string $name Name of the block
+ * @return The block content or '' if the block does not exist.
+ */
+ public function get($name) {
+ if (!isset($this->_blocks[$name])) {
+ return '';
+ }
+ return $this->_blocks[$name];
+ }
+
+/**
+ * Get the names of all the existing blocks.
+ *
+ * @return array An array containing the blocks.
+ */
+ public function keys() {
+ return array_keys($this->_blocks);
+ }
+
+/**
+ * Get the name of the currently open block.
+ *
+ * @return mixed Either null or the name of the last open block.
+ */
+ public function active() {
+ return end($this->_active);
+ }
+
+/**
+ * Get the names of the unclosed/active blocks.
+ *
+ * @return array An array of unclosed blocks.
+ */
+ public function unclosed() {
+ return $this->_active;
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php
new file mode 100644
index 0000000..f89efa6
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/View/XmlView.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('View', 'View');
+App::uses('Xml', 'Utility');
+
+/**
+ * A view class that is used for creating XML responses.
+ *
+ * By setting the '_serialize' key in your controller, you can specify a view variable
+ * that should be serialized to XML and used as the response for the request.
+ * This allows you to omit views + layouts, if your just need to emit a single view
+ * variable as the XML response.
+ *
+ * In your controller, you could do the following:
+ *
+ * `$this->set(array('posts' => $posts, '_serialize' => 'posts'));`
+ *
+ * When the view is rendered, the `$posts` view variable will be serialized
+ * into XML.
+ *
+ * **Note** The view variable you specify must be compatible with Xml::fromArray().
+ *
+ * You can also define `'_serialize'` as an array. This will create an additional
+ * top level element named `<response>` containing all the named view variables:
+ *
+ * {{{
+ * $this->set(compact('posts', 'users', 'stuff'));
+ * $this->set('_serialize', array('posts', 'users'));
+ * }}}
+ *
+ * The above would generate a XML object that looks like:
+ *
+ * `<response><posts>...</posts><users>...</users></response>`
+ *
+ * If you don't use the `_serialize` key, you will need a view. You can use extended
+ * views to provide layout like functionality.
+ *
+ * @package Cake.View
+ * @since CakePHP(tm) v 2.1.0
+ */
+class XmlView extends View {
+
+/**
+ * The subdirectory. XML views are always in xml.
+ *
+ * @var string
+ */
+ public $subDir = 'xml';
+
+/**
+ * Constructor
+ *
+ * @param Controller $controller
+ */
+ public function __construct(Controller $controller = null) {
+ parent::__construct($controller);
+
+ if (isset($controller->response) && $controller->response instanceof CakeResponse) {
+ $controller->response->type('xml');
+ }
+ }
+
+/**
+ * Render a XML view.
+ *
+ * Uses the special '_serialize' parameter to convert a set of
+ * view variables into a XML response. Makes generating simple
+ * XML responses very easy. You can omit the '_serialize' parameter,
+ * and use a normal view + layout as well.
+ *
+ * @param string $view The view being rendered.
+ * @param string $layout The layout being rendered.
+ * @return string The rendered view.
+ */
+ public function render($view = null, $layout = null) {
+ if (isset($this->viewVars['_serialize'])) {
+ $serialize = $this->viewVars['_serialize'];
+ if (is_array($serialize)) {
+ $data = array('response' => array());
+ foreach ($serialize as $key) {
+ $data['response'][$key] = $this->viewVars[$key];
+ }
+ } else {
+ $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null;
+ if (is_array($data) && Set::numeric(array_keys($data))) {
+ $data = array('response' => array($serialize => $data));
+ }
+ }
+ $content = Xml::fromArray($data)->asXML();
+ return $content;
+ }
+ if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {
+ if (!$this->_helpersLoaded) {
+ $this->loadHelpers();
+ }
+ $content = $this->_render($viewFileName);
+ $this->Blocks->set('content', (string)$content);
+ return $content;
+ }
+ }
+
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/basics.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/basics.php
new file mode 100644
index 0000000..13af931
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/basics.php
@@ -0,0 +1,755 @@
+<?php
+/**
+ * Basic Cake functionality.
+ *
+ * Core functions for including other source files, loading models and so forth.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Basic defines for timing functions.
+ */
+ define('SECOND', 1);
+ define('MINUTE', 60);
+ define('HOUR', 3600);
+ define('DAY', 86400);
+ define('WEEK', 604800);
+ define('MONTH', 2592000);
+ define('YEAR', 31536000);
+
+/**
+ * Loads configuration files. Receives a set of configuration files
+ * to load.
+ * Example:
+ *
+ * `config('config1', 'config2');`
+ *
+ * @return boolean Success
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#config
+ */
+function config() {
+ $args = func_get_args();
+ foreach ($args as $arg) {
+ if (file_exists(APP . 'Config' . DS . $arg . '.php')) {
+ include_once APP . 'Config' . DS . $arg . '.php';
+
+ if (count($args) == 1) {
+ return true;
+ }
+ } else {
+ if (count($args) == 1) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * Prints out debug information about given variable.
+ *
+ * Only runs if debug level is greater than zero.
+ *
+ * @param boolean $var Variable to show debug information for.
+ * @param boolean $showHtml If set to true, the method prints the debug data in a browser-friendly way.
+ * @param boolean $showFrom If set to true, the method prints from where the function was called.
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#basic-debugging
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#debug
+ */
+function debug($var = false, $showHtml = null, $showFrom = true) {
+ if (Configure::read('debug') > 0) {
+ App::uses('Debugger', 'Utility');
+ $file = '';
+ $line = '';
+ $lineInfo = '';
+ if ($showFrom) {
+ $trace = Debugger::trace(array('start' => 1, 'depth' => 2, 'format' => 'array'));
+ $file = str_replace(array(CAKE_CORE_INCLUDE_PATH, ROOT), '', $trace[0]['file']);
+ $line = $trace[0]['line'];
+ }
+ $html = <<<HTML
+<div class="cake-debug-output">
+%s
+<pre class="cake-debug">
+%s
+</pre>
+</div>
+HTML;
+ $text = <<<TEXT
+%s
+########## DEBUG ##########
+%s
+###########################
+TEXT;
+ $template = $html;
+ if (php_sapi_name() == 'cli' || $showHtml === false) {
+ $template = $text;
+ if ($showFrom) {
+ $lineInfo = sprintf('%s (line %s)', $file, $line);
+ }
+ }
+ if ($showHtml === null && $template !== $text) {
+ $showHtml = true;
+ }
+ $var = Debugger::exportVar($var, 25);
+ if ($showHtml) {
+ $template = $html;
+ $var = h($var);
+ if ($showFrom) {
+ $lineInfo = sprintf('<span><strong>%s</strong> (line <strong>%s</strong>)</span>', $file, $line);
+ }
+ }
+ printf($template, $lineInfo, $var);
+ }
+}
+
+if (!function_exists('sortByKey')) {
+
+/**
+ * Sorts given $array by key $sortby.
+ *
+ * @param array $array Array to sort
+ * @param string $sortby Sort by this key
+ * @param string $order Sort order asc/desc (ascending or descending).
+ * @param integer $type Type of sorting to perform
+ * @return mixed Sorted array
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#sortByKey
+ */
+ function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) {
+ if (!is_array($array)) {
+ return null;
+ }
+
+ foreach ($array as $key => $val) {
+ $sa[$key] = $val[$sortby];
+ }
+
+ if ($order == 'asc') {
+ asort($sa, $type);
+ } else {
+ arsort($sa, $type);
+ }
+
+ foreach ($sa as $key => $val) {
+ $out[] = $array[$key];
+ }
+ return $out;
+ }
+
+}
+
+/**
+ * Convenience method for htmlspecialchars.
+ *
+ * @param string|array|object $text Text to wrap through htmlspecialchars. Also works with arrays, and objects.
+ * Arrays will be mapped and have all their elements escaped. Objects will be string cast if they
+ * implement a `__toString` method. Otherwise the class name will be used.
+ * @param boolean $double Encode existing html entities
+ * @param string $charset Character set to use when escaping. Defaults to config value in 'App.encoding' or 'UTF-8'
+ * @return string Wrapped text
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#h
+ */
+function h($text, $double = true, $charset = null) {
+ if (is_array($text)) {
+ $texts = array();
+ foreach ($text as $k => $t) {
+ $texts[$k] = h($t, $double, $charset);
+ }
+ return $texts;
+ } elseif (is_object($text)) {
+ if (method_exists($text, '__toString')) {
+ $text = (string)$text;
+ } else {
+ $text = '(object)' . get_class($text);
+ }
+ }
+
+ static $defaultCharset = false;
+ if ($defaultCharset === false) {
+ $defaultCharset = Configure::read('App.encoding');
+ if ($defaultCharset === null) {
+ $defaultCharset = 'UTF-8';
+ }
+ }
+ if (is_string($double)) {
+ $charset = $double;
+ }
+ return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double);
+}
+
+/**
+ * Splits a dot syntax plugin name into its plugin and classname.
+ * If $name does not have a dot, then index 0 will be null.
+ *
+ * Commonly used like `list($plugin, $name) = pluginSplit($name);`
+ *
+ * @param string $name The name you want to plugin split.
+ * @param boolean $dotAppend Set to true if you want the plugin to have a '.' appended to it.
+ * @param string $plugin Optional default plugin to use if no plugin is found. Defaults to null.
+ * @return array Array with 2 indexes. 0 => plugin name, 1 => classname
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#pluginSplit
+ */
+function pluginSplit($name, $dotAppend = false, $plugin = null) {
+ if (strpos($name, '.') !== false) {
+ $parts = explode('.', $name, 2);
+ if ($dotAppend) {
+ $parts[0] .= '.';
+ }
+ return $parts;
+ }
+ return array($plugin, $name);
+}
+
+/**
+ * Print_r convenience function, which prints out <PRE> tags around
+ * the output of given array. Similar to debug().
+ *
+ * @see debug()
+ * @param array $var Variable to print out
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#pr
+ */
+function pr($var) {
+ if (Configure::read('debug') > 0) {
+ echo '<pre>';
+ print_r($var);
+ echo '</pre>';
+ }
+}
+
+/**
+ * Merge a group of arrays
+ *
+ * @param array First array
+ * @param array Second array
+ * @param array Third array
+ * @param array Etc...
+ * @return array All array parameters merged into one
+ * @link http://book.cakephp.org/2.0/en/development/debugging.html#am
+ */
+function am() {
+ $r = array();
+ $args = func_get_args();
+ foreach ($args as $a) {
+ if (!is_array($a)) {
+ $a = array($a);
+ }
+ $r = array_merge($r, $a);
+ }
+ return $r;
+}
+
+/**
+ * Gets an environment variable from available sources, and provides emulation
+ * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
+ * IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom
+ * environment information.
+ *
+ * @param string $key Environment variable name.
+ * @return string Environment variable setting.
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#env
+ */
+function env($key) {
+ if ($key === 'HTTPS') {
+ if (isset($_SERVER['HTTPS'])) {
+ return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
+ }
+ return (strpos(env('SCRIPT_URI'), 'https://') === 0);
+ }
+
+ if ($key === 'SCRIPT_NAME') {
+ if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
+ $key = 'SCRIPT_URL';
+ }
+ }
+
+ $val = null;
+ if (isset($_SERVER[$key])) {
+ $val = $_SERVER[$key];
+ } elseif (isset($_ENV[$key])) {
+ $val = $_ENV[$key];
+ } elseif (getenv($key) !== false) {
+ $val = getenv($key);
+ }
+
+ if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
+ $addr = env('HTTP_PC_REMOTE_ADDR');
+ if ($addr !== null) {
+ $val = $addr;
+ }
+ }
+
+ if ($val !== null) {
+ return $val;
+ }
+
+ switch ($key) {
+ case 'SCRIPT_FILENAME':
+ if (defined('SERVER_IIS') && SERVER_IIS === true) {
+ return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
+ }
+ break;
+ case 'DOCUMENT_ROOT':
+ $name = env('SCRIPT_NAME');
+ $filename = env('SCRIPT_FILENAME');
+ $offset = 0;
+ if (!strpos($name, '.php')) {
+ $offset = 4;
+ }
+ return substr($filename, 0, -(strlen($name) + $offset));
+ break;
+ case 'PHP_SELF':
+ return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
+ break;
+ case 'CGI_MODE':
+ return (PHP_SAPI === 'cgi');
+ break;
+ case 'HTTP_BASE':
+ $host = env('HTTP_HOST');
+ $parts = explode('.', $host);
+ $count = count($parts);
+
+ if ($count === 1) {
+ return '.' . $host;
+ } elseif ($count === 2) {
+ return '.' . $host;
+ } elseif ($count === 3) {
+ $gTLD = array(
+ 'aero',
+ 'asia',
+ 'biz',
+ 'cat',
+ 'com',
+ 'coop',
+ 'edu',
+ 'gov',
+ 'info',
+ 'int',
+ 'jobs',
+ 'mil',
+ 'mobi',
+ 'museum',
+ 'name',
+ 'net',
+ 'org',
+ 'pro',
+ 'tel',
+ 'travel',
+ 'xxx'
+ );
+ if (in_array($parts[1], $gTLD)) {
+ return '.' . $host;
+ }
+ }
+ array_shift($parts);
+ return '.' . implode('.', $parts);
+ break;
+ }
+ return null;
+}
+
+/**
+ * Reads/writes temporary data to cache files or session.
+ *
+ * @param string $path File path within /tmp to save the file.
+ * @param mixed $data The data to save to the temporary file.
+ * @param mixed $expires A valid strtotime string when the data expires.
+ * @param string $target The target of the cached data; either 'cache' or 'public'.
+ * @return mixed The contents of the temporary file.
+ * @deprecated Please use Cache::write() instead
+ */
+function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
+ if (Configure::read('Cache.disable')) {
+ return null;
+ }
+ $now = time();
+
+ if (!is_numeric($expires)) {
+ $expires = strtotime($expires, $now);
+ }
+
+ switch (strtolower($target)) {
+ case 'cache':
+ $filename = CACHE . $path;
+ break;
+ case 'public':
+ $filename = WWW_ROOT . $path;
+ break;
+ case 'tmp':
+ $filename = TMP . $path;
+ break;
+ }
+ $timediff = $expires - $now;
+ $filetime = false;
+
+ if (file_exists($filename)) {
+ $filetime = @filemtime($filename);
+ }
+
+ if ($data === null) {
+ if (file_exists($filename) && $filetime !== false) {
+ if ($filetime + $timediff < $now) {
+ @unlink($filename);
+ } else {
+ $data = @file_get_contents($filename);
+ }
+ }
+ } elseif (is_writable(dirname($filename))) {
+ @file_put_contents($filename, $data, LOCK_EX);
+ }
+ return $data;
+}
+
+/**
+ * Used to delete files in the cache directories, or clear contents of cache directories
+ *
+ * @param string|array $params As String name to be searched for deletion, if name is a directory all files in
+ * directory will be deleted. If array, names to be searched for deletion. If clearCache() without params,
+ * all files in app/tmp/cache/views will be deleted
+ * @param string $type Directory in tmp/cache defaults to view directory
+ * @param string $ext The file extension you are deleting
+ * @return true if files found and deleted false otherwise
+ */
+function clearCache($params = null, $type = 'views', $ext = '.php') {
+ if (is_string($params) || $params === null) {
+ $params = preg_replace('/\/\//', '/', $params);
+ $cache = CACHE . $type . DS . $params;
+
+ if (is_file($cache . $ext)) {
+ @unlink($cache . $ext);
+ return true;
+ } elseif (is_dir($cache)) {
+ $files = glob($cache . '*');
+
+ if ($files === false) {
+ return false;
+ }
+
+ foreach ($files as $file) {
+ if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
+ @unlink($file);
+ }
+ }
+ return true;
+ } else {
+ $cache = array(
+ CACHE . $type . DS . '*' . $params . $ext,
+ CACHE . $type . DS . '*' . $params . '_*' . $ext
+ );
+ $files = array();
+ while ($search = array_shift($cache)) {
+ $results = glob($search);
+ if ($results !== false) {
+ $files = array_merge($files, $results);
+ }
+ }
+ if (empty($files)) {
+ return false;
+ }
+ foreach ($files as $file) {
+ if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
+ @unlink($file);
+ }
+ }
+ return true;
+ }
+ } elseif (is_array($params)) {
+ foreach ($params as $file) {
+ clearCache($file, $type, $ext);
+ }
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Recursively strips slashes from all values in an array
+ *
+ * @param array $values Array of values to strip slashes
+ * @return mixed What is returned from calling stripslashes
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#stripslashes_deep
+ */
+function stripslashes_deep($values) {
+ if (is_array($values)) {
+ foreach ($values as $key => $value) {
+ $values[$key] = stripslashes_deep($value);
+ }
+ } else {
+ $values = stripslashes($values);
+ }
+ return $values;
+}
+
+/**
+ * Returns a translated string if one is found; Otherwise, the submitted message.
+ *
+ * @param string $singular Text to translate
+ * @param mixed $args Array with arguments or multiple arguments in function
+ * @return mixed translated string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__
+ */
+function __($singular, $args = null) {
+ if (!$singular) {
+ return;
+ }
+
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 1);
+ }
+ return vsprintf($translated, $args);
+}
+
+/**
+ * Returns correct plural form of message identified by $singular and $plural for count $count.
+ * Some languages have more than one form for plural messages dependent on the count.
+ *
+ * @param string $singular Singular text to translate
+ * @param string $plural Plural text
+ * @param integer $count Count
+ * @param mixed $args Array with arguments or multiple arguments in function
+ * @return mixed plural form of translated string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__n
+ */
+function __n($singular, $plural, $count, $args = null) {
+ if (!$singular) {
+ return;
+ }
+
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular, $plural, null, 6, $count);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 3);
+ }
+ return vsprintf($translated, $args);
+}
+
+/**
+ * Allows you to override the current domain for a single message lookup.
+ *
+ * @param string $domain Domain
+ * @param string $msg String to translate
+ * @param mixed $args Array with arguments or multiple arguments in function
+ * @return translated string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__d
+ */
+function __d($domain, $msg, $args = null) {
+ if (!$msg) {
+ return;
+ }
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($msg, null, $domain);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 2);
+ }
+ return vsprintf($translated, $args);
+}
+
+/**
+ * Allows you to override the current domain for a single plural message lookup.
+ * Returns correct plural form of message identified by $singular and $plural for count $count
+ * from domain $domain.
+ *
+ * @param string $domain Domain
+ * @param string $singular Singular string to translate
+ * @param string $plural Plural
+ * @param integer $count Count
+ * @param mixed $args Array with arguments or multiple arguments in function
+ * @return plural form of translated string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dn
+ */
+function __dn($domain, $singular, $plural, $count, $args = null) {
+ if (!$singular) {
+ return;
+ }
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular, $plural, $domain, 6, $count);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 4);
+ }
+ return vsprintf($translated, $args);
+}
+
+/**
+ * Allows you to override the current domain for a single message lookup.
+ * It also allows you to specify a category.
+ *
+ * The category argument allows a specific category of the locale settings to be used for fetching a message.
+ * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
+ *
+ * Note that the category must be specified with a numeric value, instead of the constant name. The values are:
+ *
+ * - LC_ALL 0
+ * - LC_COLLATE 1
+ * - LC_CTYPE 2
+ * - LC_MONETARY 3
+ * - LC_NUMERIC 4
+ * - LC_TIME 5
+ * - LC_MESSAGES 6
+ *
+ * @param string $domain Domain
+ * @param string $msg Message to translate
+ * @param integer $category Category
+ * @param mixed $args Array with arguments or multiple arguments in function
+ * @return translated string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dc
+ */
+function __dc($domain, $msg, $category, $args = null) {
+ if (!$msg) {
+ return;
+ }
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($msg, null, $domain, $category);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 3);
+ }
+ return vsprintf($translated, $args);
+}
+
+/**
+ * Allows you to override the current domain for a single plural message lookup.
+ * It also allows you to specify a category.
+ * Returns correct plural form of message identified by $singular and $plural for count $count
+ * from domain $domain.
+ *
+ * The category argument allows a specific category of the locale settings to be used for fetching a message.
+ * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
+ *
+ * Note that the category must be specified with a numeric value, instead of the constant name. The values are:
+ *
+ * - LC_ALL 0
+ * - LC_COLLATE 1
+ * - LC_CTYPE 2
+ * - LC_MONETARY 3
+ * - LC_NUMERIC 4
+ * - LC_TIME 5
+ * - LC_MESSAGES 6
+ *
+ * @param string $domain Domain
+ * @param string $singular Singular string to translate
+ * @param string $plural Plural
+ * @param integer $count Count
+ * @param integer $category Category
+ * @param mixed $args Array with arguments or multiple arguments in function
+ * @return plural form of translated string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dcn
+ */
+function __dcn($domain, $singular, $plural, $count, $category, $args = null) {
+ if (!$singular) {
+ return;
+ }
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular, $plural, $domain, $category, $count);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 5);
+ }
+ return vsprintf($translated, $args);
+}
+
+/**
+ * The category argument allows a specific category of the locale settings to be used for fetching a message.
+ * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
+ *
+ * Note that the category must be specified with a numeric value, instead of the constant name. The values are:
+ *
+ * - LC_ALL 0
+ * - LC_COLLATE 1
+ * - LC_CTYPE 2
+ * - LC_MONETARY 3
+ * - LC_NUMERIC 4
+ * - LC_TIME 5
+ * - LC_MESSAGES 6
+ *
+ * @param string $msg String to translate
+ * @param integer $category Category
+ * @param mixed $args Array with arguments or multiple arguments in function
+ * @return translated string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__c
+ */
+function __c($msg, $category, $args = null) {
+ if (!$msg) {
+ return;
+ }
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($msg, null, null, $category);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 2);
+ }
+ return vsprintf($translated, $args);
+}
+
+/**
+ * Shortcut to Log::write.
+ *
+ * @param string $message Message to write to log
+ * @return void
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#LogError
+ */
+function LogError($message) {
+ App::uses('CakeLog', 'Log');
+ $bad = array("\n", "\r", "\t");
+ $good = ' ';
+ CakeLog::write('error', str_replace($bad, $good, $message));
+}
+
+/**
+ * Searches include path for files.
+ *
+ * @param string $file File to look for
+ * @return Full path to file if exists, otherwise false
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#fileExistsInPath
+ */
+function fileExistsInPath($file) {
+ $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
+ foreach ($paths as $path) {
+ $fullPath = $path . DS . $file;
+
+ if (file_exists($fullPath)) {
+ return $fullPath;
+ } elseif (file_exists($file)) {
+ return $file;
+ }
+ }
+ return false;
+}
+
+/**
+ * Convert forward slashes to underscores and removes first and last underscores in a string
+ *
+ * @param string String to convert
+ * @return string with underscore remove from start and end of string
+ * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#convertSlash
+ */
+function convertSlash($string) {
+ $string = trim($string, '/');
+ $string = preg_replace('/\/\//', '/', $string);
+ $string = str_replace('/', '_', $string);
+ return $string;
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/bootstrap.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/bootstrap.php
new file mode 100644
index 0000000..40ac76b
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/bootstrap.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Basic Cake functionality.
+ *
+ * Handles loading of core files needed on every request
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package Cake
+ * @since CakePHP(tm) v 0.2.9
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+define('TIME_START', microtime(true));
+
+if (!defined('E_DEPRECATED')) {
+ define('E_DEPRECATED', 8192);
+}
+
+if (!defined('E_USER_DEPRECATED')) {
+ define('E_USER_DEPRECATED', E_USER_NOTICE);
+}
+error_reporting(E_ALL & ~E_DEPRECATED);
+
+if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(__FILE__)));
+}
+
+if (!defined('CORE_PATH')) {
+ define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+}
+
+if (!defined('WEBROOT_DIR')) {
+ define('WEBROOT_DIR', 'webroot');
+}
+
+/**
+ * Path to the cake directory.
+ */
+ define('CAKE', CORE_PATH . 'Cake' . DS);
+
+/**
+ * Path to the application's directory.
+ */
+if (!defined('APP')) {
+ define('APP', ROOT . DS . APP_DIR . DS);
+}
+
+/**
+ * Path to the application's libs directory.
+ */
+ define('APPLIBS', APP . 'Lib' . DS);
+
+/**
+ * Path to the public CSS directory.
+ */
+ define('CSS', WWW_ROOT . 'css' . DS);
+
+/**
+ * Path to the public JavaScript directory.
+ */
+ define('JS', WWW_ROOT . 'js' . DS);
+
+/**
+ * Path to the public images directory.
+ */
+ define('IMAGES', WWW_ROOT . 'img' . DS);
+
+/**
+ * Path to the tests directory.
+ */
+if (!defined('TESTS')) {
+ define('TESTS', APP . 'Test' . DS);
+}
+
+/**
+ * Path to the temporary files directory.
+ */
+if (!defined('TMP')) {
+ define('TMP', APP . 'tmp' . DS);
+}
+
+/**
+ * Path to the logs directory.
+ */
+ define('LOGS', TMP . 'logs' . DS);
+
+/**
+ * Path to the cache files directory. It can be shared between hosts in a multi-server setup.
+ */
+ define('CACHE', TMP . 'cache' . DS);
+
+/**
+ * Path to the vendors directory.
+ */
+if (!defined('VENDORS')) {
+ define('VENDORS', ROOT . DS . 'vendors' . DS);
+}
+
+/**
+ * Web path to the public images directory.
+ */
+if (!defined('IMAGES_URL')) {
+ define('IMAGES_URL', 'img/');
+}
+
+/**
+ * Web path to the CSS files directory.
+ */
+if (!defined('CSS_URL')) {
+ define('CSS_URL', 'css/');
+}
+
+/**
+ * Web path to the js files directory.
+ */
+if (!defined('JS_URL')) {
+ define('JS_URL', 'js/');
+}
+
+
+require CAKE . 'basics.php';
+require CAKE . 'Core' . DS . 'App.php';
+require CAKE . 'Error' . DS . 'exceptions.php';
+
+spl_autoload_register(array('App', 'load'));
+
+App::uses('ErrorHandler', 'Error');
+App::uses('Configure', 'Core');
+App::uses('CakePlugin', 'Core');
+App::uses('Cache', 'Cache');
+App::uses('Object', 'Core');
+App::$bootstrapping = true;
+
+Configure::bootstrap(isset($boot) ? $boot : true);
+
+
+/**
+ * Full url prefix
+ */
+if (!defined('FULL_BASE_URL')) {
+ $s = null;
+ if (env('HTTPS')) {
+ $s = 's';
+ }
+
+ $httpHost = env('HTTP_HOST');
+
+ if (isset($httpHost)) {
+ define('FULL_BASE_URL', 'http' . $s . '://' . $httpHost);
+ }
+ unset($httpHost, $s);
+}
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/plugins/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/plugins/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/plugins/empty
diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/vendors/empty b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/vendors/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/vendors/empty
diff --git a/poc/poc02-compiling-cake/src/workdir/in/.htaccess b/poc/poc02-compiling-cake/src/workdir/in/.htaccess
index 609f003..12757be 120000
--- a/poc/poc02-compiling-cake/src/workdir/in/.htaccess
+++ b/poc/poc02-compiling-cake/src/workdir/in/.htaccess
@@ -1 +1 @@
-../../vendor/cake_1.1.20.7692/.htaccess \ No newline at end of file
+../../vendor/cakephp-2.2.1-0-gcc44130/.htaccess \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/acl.ini.php b/poc/poc02-compiling-cake/src/workdir/in/app/config/acl.ini.php
deleted file mode 100644
index 486e790..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/acl.ini.php
+++ /dev/null
@@ -1,76 +0,0 @@
-;<?php die() ?>
-; SVN FILE: $Id: acl.ini.php 6305 2008-01-02 02:33:56Z phpnut $
-;/**
-; * Short description for file.
-; *
-; *
-; * PHP versions 4 and 5
-; *
-; * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
-; * Copyright 2005-2008, Cake Software Foundation, Inc.
-; * 1785 E. Sahara Avenue, Suite 490-204
-; * Las Vegas, Nevada 89104
-; *
-; * Licensed under The MIT License
-; * Redistributions of files must retain the above copyright notice.
-; *
-; * @filesource
-; * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
-; * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
-; * @package cake
-; * @subpackage cake.app.config
-; * @since CakePHP(tm) v 0.10.0.1076
-; * @version $Revision: 6305 $
-; * @modifiedby $LastChangedBy: phpnut $
-; * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
-; * @license http://www.opensource.org/licenses/mit-license.php The MIT License
-; */
-
-; acl.ini.php - Cake ACL Configuration
-; ---------------------------------------------------------------------
-; Use this file to specify user permissions.
-; aco = access control object (something in your application)
-; aro = access request object (something requesting access)
-;
-; User records are added as follows:
-;
-; [uid]
-; groups = group1, group2, group3
-; allow = aco1, aco2, aco3
-; deny = aco4, aco5, aco6
-;
-; Group records are added in a similar manner:
-;
-; [gid]
-; allow = aco1, aco2, aco3
-; deny = aco4, aco5, aco6
-;
-; The allow, deny, and groups sections are all optional.
-; NOTE: groups names *cannot* ever be the same as usernames!
-;
-; ACL permissions are checked in the following order:
-; 1. Check for user denies (and DENY if specified)
-; 2. Check for user allows (and ALLOW if specified)
-; 3. Gather user's groups
-; 4. Check group denies (and DENY if specified)
-; 5. Check group allows (and ALLOW if specified)
-; 6. If no aro, aco, or group information is found, DENY
-;
-; ---------------------------------------------------------------------
-
-;-------------------------------------
-;Users
-;-------------------------------------
-
-[username-goes-here]
-groups = group1, group2
-deny = aco1, aco2
-allow = aco3, aco4
-
-;-------------------------------------
-;Groups
-;-------------------------------------
-
-[groupname-goes-here]
-deny = aco5, aco6
-allow = aco7, aco8 \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/bootstrap.php b/poc/poc02-compiling-cake/src/workdir/in/app/config/bootstrap.php
deleted file mode 100644
index ef4cedf..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/bootstrap.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/* SVN FILE: $Id: bootstrap.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.10.8.2117
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- *
- * This file is loaded automatically by the app/webroot/index.php file after the core bootstrap.php is loaded
- * This is an application wide file to load any function that is not used within a class define.
- * You can also use this to include or require any files in your application.
- *
- */
-/**
- * The settings below can be used to set additional paths to models, views and controllers.
- * This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
- *
- * $modelPaths = array('full path to models', 'second full path to models', 'etc...');
- * $viewPaths = array('this path to views', 'second full path to views', 'etc...');
- * $controllerPaths = array('this path to controllers', 'second full path to controllers', 'etc...');
- *
- */
-//EOF
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/core.php b/poc/poc02-compiling-cake/src/workdir/in/app/config/core.php
deleted file mode 100644
index 77cf1ff..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/core.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-/* SVN FILE: $Id: core.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * If you do not have mod rewrite on your system
- * or if you prefer to use CakePHP pretty urls.
- * uncomment the line below.
- * Note: If you do have mod rewrite but prefer the
- * CakePHP pretty urls, you also have to remove the
- * .htaccess files
- * release/.htaccess
- * release/app/.htaccess
- * release/app/webroot/.htaccess
- */
-// define ('BASE_URL', env('SCRIPT_NAME'));
-/**
- * Set debug level here:
- * - 0: production
- * - 1: development
- * - 2: full debug with sql
- * - 3: full debug with sql and dump of the current object
- *
- * In production, the "flash messages" redirect after a time interval.
- * With the other debug levels you get to click the "flash message" to continue.
- *
- */
- define('DEBUG', 1);
-/**
- * Turn of caching checking wide.
- * You must still use the controller var cacheAction inside you controller class.
- * You can either set it controller wide, or in each controller method.
- * use var $cacheAction = true; or in the controller method $this->cacheAction = true;
- */
- define('CACHE_CHECK', false);
-/**
- * Error constant. Used for differentiating error logging and debugging.
- * Currently PHP supports LOG_DEBUG
- */
- define('LOG_ERROR', 2);
-/**
- * CakePHP includes 3 types of session saves
- * database or file. Set this to your preferred method.
- * If you want to use your own save handler place it in
- * app/config/name.php DO NOT USE file or database as the name.
- * and use just the name portion below.
- *
- * Setting this to cake will save files to /cakedistro/tmp directory
- * Setting it to php will use the php default save path
- * Setting it to database will use the database
- *
- */
- define('CAKE_SESSION_SAVE', 'php');
-/**
- * If using you own table name for storing sessions
- * set the table name here.
- * DO NOT INCLUDE PREFIX IF YOU HAVE SET ONE IN database.php
- *
- */
- define('CAKE_SESSION_TABLE', 'cake_sessions');
-/**
- * Set a random string of used in session.
- *
- */
- define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
-/**
- * Set the name of session cookie
- *
- */
- define('CAKE_SESSION_COOKIE', 'CAKEPHP');
-/**
- * Set level of Cake security.
- *
- */
- define('CAKE_SECURITY', 'high');
-/**
- * Set Cake Session time out.
- * If CAKE_SECURITY define is set
- * high: multiplied by 10
- * medium: is multiplied by 100
- * low is: multiplied by 300
- *
- * Number below is seconds.
- */
- define('CAKE_SESSION_TIMEOUT', '120');
-/**
- * Uncomment the define below to use cake built in admin routes.
- * You can set this value to anything you want.
- * All methods related to the admin route should be prefixed with the
- * name you set CAKE_ADMIN to.
- * For example: admin_index, admin_edit
- */
-// define('CAKE_ADMIN', 'admin');
-/**
- * The define below is used to turn cake built webservices
- * on or off. Default setting is off.
- */
- define('WEBSERVICES', 'off');
-/**
- * Compress output CSS (removing comments, whitespace, repeating tags etc.)
- * This requires a/var/cache directory to be writable by the web server (caching).
- * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use Controller::cssTag().
- */
- define('COMPRESS_CSS', false);
-/**
- * If set to true, helpers would output data instead of returning it.
- */
- define('AUTO_OUTPUT', false);
-/**
- * If set to false, session would not automatically be started.
- */
- define('AUTO_SESSION', true);
-/**
- * Set the max size of file to use md5() .
- */
- define('MAX_MD5SIZE', (5 * 1024) * 1024);
-/**
- * To use Access Control Lists with Cake...
- */
- define('ACL_CLASSNAME', 'DB_ACL');
- define('ACL_FILENAME', 'dbacl' . DS . 'db_acl');
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/database.php.default b/poc/poc02-compiling-cake/src/workdir/in/app/config/database.php.default
deleted file mode 100644
index 4df48e1..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/database.php.default
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/* SVN FILE: $Id: database.php.default 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * This is core configuration file.
- *
- * Use it to configure core behaviour ofCake.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * In this file you set up your database connection details.
- *
- * @package cake
- * @subpackage cake.config
- */
-/**
- * Database configuration class.
- * You can specify multiple configurations for production, development and testing.
- *
- * driver =>
- * mysql, postgres, sqlite, adodb, pear-drivername
- *
- * connect =>
- * MySQL set the connect to either mysql_pconnect of mysql_connect
- * PostgreSQL set the connect to either pg_pconnect of pg_connect
- * SQLite set the connect to sqlite_popen sqlite_open
- * ADOdb set the connect to one of these
- * (http://phplens.com/adodb/supported.databases.html) and
- * append it '|p' for persistent connection. (mssql|p for example, or just mssql for not persistent)
- *
- * host =>
- * the host you connect to the database
- * MySQL 'localhost' to add a port number use 'localhost:port#'
- * PostgreSQL 'localhost' to add a port number use 'localhost port=5432'
- *
- */
-class DATABASE_CONFIG
-{
- var $default = array('driver' => 'mysql',
- 'connect' => 'mysql_connect',
- 'host' => 'localhost',
- 'login' => 'user',
- 'password' => 'password',
- 'database' => 'project_name',
- 'prefix' => '');
-
- var $test = array('driver' => 'mysql',
- 'connect' => 'mysql_connect',
- 'host' => 'localhost',
- 'login' => 'user',
- 'password' => 'password',
- 'database' => 'project_name-test',
- 'prefix' => '');
-}
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/inflections.php b/poc/poc02-compiling-cake/src/workdir/in/app/config/inflections.php
deleted file mode 100644
index e08a7d8..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/inflections.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/* SVN FILE: $Id: inflections.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Custom Inflected Words.
- *
- * This file is used to hold words that are not matched in the normail Inflector::pluralize() and
- * Inflector::singularize()
- *
- * PHP versions 4 and %
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 1.0.0.2312
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * This is a key => value array of regex used to match words.
- * If key matches then the value is returned.
- *
- * $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
- */
- $pluralRules = array();
-/**
- * This is a key only array of plural words that should not be inflected.
- * Notice the last comma
- *
- * $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
- */
- $uninflectedPlural = array();
-/**
- * This is a key => value array of plural irregular words.
- * If key matches then the value is returned.
- *
- * $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
- */
- $irregularPlural = array();
-/**
- * This is a key => value array of regex used to match words.
- * If key matches then the value is returned.
- *
- * $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
- */
- $singularRules = array();
-/**
- * This is a key only array of singular words that should not be inflected.
- * You should not have to change this value below if you do change it use same format
- * as the $uninflectedPlural above.
- */
- $uninflectedSingular = $uninflectedPlural;
-/**
- * This is a key => value array of singular irregular words.
- * Most of the time this will be a reverse of the above $irregularPlural array
- * You should not have to change this value below if you do change it use same format
- *
- * $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
- */
- $irregularSingular = array_flip($irregularPlural);
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/routes.php b/poc/poc02-compiling-cake/src/workdir/in/app/config/routes.php
deleted file mode 100644
index 45ae36a..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/routes.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/* SVN FILE: $Id: routes.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * In this file, you set up routes to your controllers and their actions.
- * Routes are very important mechanism that allows you to freely connect
- * different urls to chosen controllers and their actions (functions).
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.config
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Here, we are connecting '/' (base path) to controller called 'Pages',
- * its action called 'display', and we pass a param to select the view file
- * to use (in this case, /app/views/pages/home.thtml)...
- */
- $Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
-/**
- * ...and connect the rest of 'Pages' controller's urls.
- */
- $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
-/**
- * Then we connect url '/test' to our test controller. This is helpfull in
- * developement.
- */
- $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index'));
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/config/sql/db_acl.sql b/poc/poc02-compiling-cake/src/workdir/in/app/config/sql/db_acl.sql
deleted file mode 100644
index be8f200..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/config/sql/db_acl.sql
+++ /dev/null
@@ -1,38 +0,0 @@
-# $Id: db_acl.sql 6305 2008-01-02 02:33:56Z phpnut $
-#
-# Copyright 2005-2008, Cake Software Foundation, Inc.
-# 1785 E. Sahara Avenue, Suite 490-204
-# Las Vegas, Nevada 89104
-#
-# Licensed under The MIT License
-# Redistributions of files must retain the above copyright notice.
-# http://www.opensource.org/licenses/mit-license.php The MIT License
-
-CREATE TABLE acos (
- id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
- object_id INTEGER(10) NULL DEFAULT NULL,
- alias VARCHAR(255) NOT NULL DEFAULT '',
- lft INTEGER(10) NULL DEFAULT NULL,
- rght INTEGER(10) NULL DEFAULT NULL,
- PRIMARY KEY(id)
-);
-
-CREATE TABLE aros_acos (
- id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
- aro_id INTEGER(10) UNSIGNED NOT NULL,
- aco_id INTEGER(10) UNSIGNED NOT NULL,
- _create CHAR(2) NOT NULL DEFAULT 0,
- _read CHAR(2) NOT NULL DEFAULT 0,
- _update CHAR(2) NOT NULL DEFAULT 0,
- _delete CHAR(2) NOT NULL DEFAULT 0,
- PRIMARY KEY(id)
-);
-
-CREATE TABLE aros (
- id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
- foreign_key INTEGER(10) UNSIGNED NULL DEFAULT NULL,
- alias VARCHAR(255) NOT NULL DEFAULT '',
- lft INTEGER(10) NULL DEFAULT NULL,
- rght INTEGER(10) NULL DEFAULT NULL,
- PRIMARY KEY(id)
-); \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/index.php b/poc/poc02-compiling-cake/src/workdir/in/app/index.php
deleted file mode 100644
index bd8993b..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/index.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app
- * @since CakePHP(tm) v 0.10.0.1076
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/css.php b/poc/poc02-compiling-cake/src/workdir/in/app/webroot/css.php
deleted file mode 100644
index dc87218..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/css.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-/* SVN FILE: $Id: css.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-if (!defined('CAKE_CORE_INCLUDE_PATH')) {
- header('HTTP/1.1 404 Not Found');
- exit('File Not Found');
-}
-/**
- * Enter description here...
- */
- uses('file');
-/**
- * Enter description here...
- *
- * @param unknown_type $path
- * @param unknown_type $name
- * @return unknown
- */
- function make_clean_css($path, $name) {
- require(VENDORS . 'csspp' . DS . 'csspp.php');
- $data = file_get_contents($path);
- $csspp = new csspp();
- $output = $csspp->compress($data);
- $ratio = 100 - (round(strlen($output) / strlen($data), 3) * 100);
- $output = " /* file: $name, ratio: $ratio% */ " . $output;
- return $output;
- }
-/**
- * Enter description here...
- *
- * @param unknown_type $path
- * @param unknown_type $content
- * @return unknown
- */
- function write_css_cache($path, $content) {
- if (!is_dir(dirname($path))) {
- mkdir(dirname($path));
- }
- $cache = new File($path);
- return $cache->write($content);
- }
-
- if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
- die('Wrong file name.');
- }
-
- $filename = 'css/' . $regs[1];
- $filepath = CSS . $regs[1];
- $cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
-
- if (!file_exists($filepath)) {
- die('Wrong file name.');
- }
-
- if (file_exists($cachepath)) {
- $templateModified = filemtime($filepath);
- $cacheModified = filemtime($cachepath);
-
- if ($templateModified > $cacheModified) {
- $output = make_clean_css($filepath, $filename);
- write_css_cache($cachepath, $output);
- } else {
- $output = file_get_contents($cachepath);
- }
- } else {
- $output = make_clean_css($filepath, $filename);
- write_css_cache($cachepath, $output);
- $templateModified = time();
- }
-
- header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT');
- header("Content-Type: text/css");
- header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
- header("Cache-Control: cache"); // HTTP/1.1
- header("Pragma: cache"); // HTTP/1.0
- print $output;
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/css/cake.generic.css b/poc/poc02-compiling-cake/src/workdir/in/app/webroot/css/cake.generic.css
deleted file mode 100644
index bc27d22..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/css/cake.generic.css
+++ /dev/null
@@ -1,250 +0,0 @@
-*{
-margin:0;
-padding:0;
-}
-
-body{
-font-family:"frutiger linotype","lucida grande",helvetica,arial,sans-serif;
-text-align:center;
-color:#333;
-font-size: 76%;
-}
-
-/* General Style Info */
-a{
-color:#003d4c;
-text-decoration:underline;
-}
-a:hover{
-color:#003d4c;
-text-decoration:none;
-}
-
-a img{
-border:none;
-}
-
-h1, h2, h3, h4{
-font-weight:normal;
-}
-
-h1{
-color: #003d4c;
-margin:0.3em 0;
-font-size: 180%;
-}
-
-h2{
-color:#c6c65b;
-padding-top: 1em;
-margin:0.3em 0;
-font-size: 180%;
-}
-
-h3{
-color:#c6c65b;
-padding-top:2em;
-font-size: 140%;
-}
-
-h4{
-color:#c6c65b;
-padding-top:0.5em;
-font-weight:normal;
-}
-
-em {
-font-size: 12px;
-}
-
-ul, li {
-margin: 0 12px;
-}
-
-/* Layout */
-
-#container{
-text-align:left;
-}
-
-#header{
-margin-top: 1em;
-padding: 4px 20px;
-}
-
-#content{
-clear:both;
-padding: 0px 40px 10px 40px;
-background-color: #fff;
-color: #333;
-}
-#footer{
-clear:both;
-padding: 6px 10px;
-text-align: right;
-}
-
-/* tables */
-
-table {
-width: 100%;
-border-top: 1px solid #ccc;
-border-left: 1px solid #ccc;
-border-bottom: 1px solid #ccc;
-color:#333;
-background-color: #fff;
-clear:both;
-padding: 0;
-margin: 0 0 2em 0;
-white-space: normal;
-}
-th {
-background-color: #e2e2e2;
-border-top: 1px solid #fff;
-border-left: 1px solid #fff;
-border-right: 1px solid #003d4c;
-border-bottom: 1px solid #003d4c;
-text-align: center;
-padding:1px 4px;
-}
-table tr td {
-border-right: 1px solid #ddd;
-padding:4px 4px;
-vertical-align:top;
-text-align: center;
-}
-table tr.altRow td {
-background: #f4f4f4;
-}
-table td.actions {
- white-space: nowrap;
-}
-#cakeSqlLog td {
-text-align: left;
-padding: 4px 8px;
-background: #fff;
-border-bottom: 2px solid #ccc;
-}
-
-/* scaffold show */
-
-div.related {
-clear:both;
-display:block;
-}
-dl {
-line-height:2em;
-margin:0em 1em;
-float:left;
-width: 400px;
-}
-dt {
-font-weight: bold;
-vertical-align:top;
-}
-dd {
-margin-left:10em;
-margin-top:-2em;
-vertical-align:top;
-}
-
-/* notices and errors */
-
-#flashMessage, .error, .error_message {
-color:#900;
-font-size: 16px;
-background-color: #fff;
-margin: 8px 0px;
-font-weight: bold;
-}
-.error_message {
-clear: both;
-}
-.error em {
-font-size: 18px;
-color: #003d4c;
-}
-.notice {
-color: #656565;
-font-size: 14px;
-background-color: #f4f4f4;
-padding: 0.5em;
-margin: 1em 0;
-display:block;
-}
-.tip {
-color: #656565;
-background-color: #ddd;
-}
-
-/* forms */
-
-form {
-margin-top: 2em;
-}
-form div{
-vertical-align: text-top;
-margin-left: 1em;
-margin-bottom:2em;
-}
-form div.date{
-margin-left: 0em;
-}
-label {
-display: block;
-width: 140px;
-font-size: 14px;
-padding-right: 20px;
-}
-input[type=checkbox] {
-float: left;
-clear: left;
-margin: 2px 6px 7px 2px;
-}
-input, textarea {
-clear: both;
-display:block;
-font-size: 14px;
-font-family: inherit;
-}
-select {
-clear: both;
-vertical-align: text-bottom;
-font-size: 14px;
-font-family: inherit;
-}
-option {
-font-size: 14px;
-font-family: inherit;
-padding: 0 0.3em;
-}
-input[type=submit] {
-display: inline;
-vertical-align: bottom;
-}
-div.required {
-clear: both;
-color:#222;
-font-weight:bold;
-}
-div.optional {
-clear: both;
-color:#555;
-}
-div.submit {
-clear: both;
-margin-top: 40px;
-margin-left: 140px;
-}
-/* action links */
-ul.actions {
-float: left;
-margin-left:20px;
-width: 200px;
-}
-ul.actions li {
-margin-top: 4px;
-}
-pre {
-padding: 1em;
-} \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/cake.power.png b/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/cake.power.png
deleted file mode 100644
index 699ef80..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/cake.power.png
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_css.png b/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_css.png
deleted file mode 100644
index 706325e..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_css.png
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_xhtml10.png b/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_xhtml10.png
deleted file mode 100644
index ec68644..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/img/w3c_xhtml10.png
+++ /dev/null
Binary files differ
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/index.php b/poc/poc02-compiling-cake/src/workdir/in/app/webroot/index.php
deleted file mode 100644
index 48771ff..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/index.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
-/**
- * Short description for file.
- *
- * Long description for file
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 6305 $
- * @modifiedby $LastChangedBy: phpnut $
- * @lastmodified $Date: 2008-01-01 21:33:56 -0500 (Tue, 01 Jan 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Do not change
- */
- if (!defined('DS')) {
- define('DS', DIRECTORY_SEPARATOR);
- }
-/**
- * These defines should only be edited if you have cake installed in
- * a directory layout other than the way it is distributed.
- * Each define has a commented line of code that explains what you would change.
- *
- */
- if (!defined('ROOT')) {
- //define('ROOT', 'FULL PATH TO DIRECTORY WHERE APP DIRECTORY IS LOCATED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
- //You should also use the DS define to seperate your directories
- define('ROOT', dirname(dirname(dirname(__FILE__))));
- }
- if (!defined('APP_DIR')) {
- //define('APP_DIR', 'DIRECTORY NAME OF APPLICATION';
- define('APP_DIR', basename(dirname(dirname(__FILE__))));
- }
-/**
- * This only needs to be changed if the cake installed libs are located
- * outside of the distributed directory structure.
- */
- if (!defined('CAKE_CORE_INCLUDE_PATH')) {
- //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
- //You should also use the DS define to seperate your directories
- define('CAKE_CORE_INCLUDE_PATH', ROOT);
- }
-///////////////////////////////
-//DO NOT EDIT BELOW THIS LINE//
-///////////////////////////////
- if (!defined('WEBROOT_DIR')) {
- define('WEBROOT_DIR', basename(dirname(__FILE__)));
- }
- if (!defined('WWW_ROOT')) {
- define('WWW_ROOT', dirname(__FILE__) . DS);
- }
- if (!defined('CORE_PATH')) {
- if (function_exists('ini_set')) {
- ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'));
- define('APP_PATH', null);
- define('CORE_PATH', null);
- } else {
- define('APP_PATH', ROOT . DS . APP_DIR . DS);
- define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
- }
- }
- require CORE_PATH . 'cake' . DS . 'bootstrap.php';
- if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
- } else {
- $Dispatcher = new Dispatcher();
- $Dispatcher->dispatch($url);
- }
- if (Configure::read() > 0) {
- echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
- }
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/js/vendors.php b/poc/poc02-compiling-cake/src/workdir/in/app/webroot/js/vendors.php
deleted file mode 100644
index cee6b77..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/app/webroot/js/vendors.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/* SVN FILE: $Id: vendors.php 7691 2008-10-02 04:59:12Z nate $ */
-/**
- * Short description for file.
- *
- * This file includes js vendor-files from /vendor/ directory if they need to
- * be accessible to the public.
- *
- * PHP versions 4 and 5
- *
- * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
- * Copyright 2005-2008, Cake Software Foundation, Inc.
- * 1785 E. Sahara Avenue, Suite 490-204
- * Las Vegas, Nevada 89104
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @filesource
- * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
- * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
- * @package cake
- * @subpackage cake.app.webroot.js
- * @since CakePHP(tm) v 0.2.9
- * @version $Revision: 7691 $
- * @modifiedby $LastChangedBy: nate $
- * @lastmodified $Date: 2008-10-02 00:59:12 -0400 (Thu, 02 Oct 2008) $
- * @license http://www.opensource.org/licenses/mit-license.php The MIT License
- */
-/**
- * Enter description here...
- */
-if (isset($_GET['file'])) {
- $file = $_GET['file'];
- $pos = strpos($file, '..');
- if ($pos === false) {
- if (is_file('../../vendors/javascript/'.$file) && (preg_match('/(\/.+)\\.js/', $file))) {
- readfile('../../vendors/javascript/'.$file);
- return;
- }
- }
-}
-header('HTTP/1.1 404 Not Found');
-?> \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/cake b/poc/poc02-compiling-cake/src/workdir/in/cake
deleted file mode 120000
index 4f6f8a7..0000000
--- a/poc/poc02-compiling-cake/src/workdir/in/cake
+++ /dev/null
@@ -1 +0,0 @@
-../../vendor/cake_1.1.20.7692/cake/ \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/index.php b/poc/poc02-compiling-cake/src/workdir/in/index.php
index 87aeb50..3aa892a 120000
--- a/poc/poc02-compiling-cake/src/workdir/in/index.php
+++ b/poc/poc02-compiling-cake/src/workdir/in/index.php
@@ -1 +1 @@
-../../vendor/cake_1.1.20.7692/index.php \ No newline at end of file
+../../vendor/cakephp-2.2.1-0-gcc44130/index.php \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/lib b/poc/poc02-compiling-cake/src/workdir/in/lib
new file mode 120000
index 0000000..7f5be74
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/workdir/in/lib
@@ -0,0 +1 @@
+../../vendor/cakephp-2.2.1-0-gcc44130/lib/ \ No newline at end of file
diff --git a/poc/poc02-compiling-cake/src/workdir/in/plugins b/poc/poc02-compiling-cake/src/workdir/in/plugins
new file mode 120000
index 0000000..22f5aac
--- /dev/null
+++ b/poc/poc02-compiling-cake/src/workdir/in/plugins
@@ -0,0 +1 @@
+../../vendor/cakephp-2.2.1-0-gcc44130/plugins/ \ No newline at end of file